From 192d97bceef4a3315b03b95522b8c22a9c716a3a Mon Sep 17 00:00:00 2001 From: pero1203 Date: Mon, 7 Sep 2020 12:53:52 +0200 Subject: [PATCH] Dodana sql tabela za paypal transakcije, dodan razred za placevanje s paypal (v delu), dodani skripti za obvestila s strani paypala (v delu) --- .../payments/classes/class.UserNarocila.php | 16 +- .../classes/class.UserNarocilaPaypal.php | 126 +++++++++++++ frontend/payments/paypal-cancel.php | 171 ++++++++++++++++++ frontend/payments/paypal-pay.php | 171 ++++++++++++++++++ sql/update2.sql | 14 ++ 5 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 frontend/payments/classes/class.UserNarocilaPaypal.php create mode 100644 frontend/payments/paypal-cancel.php create mode 100644 frontend/payments/paypal-pay.php diff --git a/frontend/payments/classes/class.UserNarocila.php b/frontend/payments/classes/class.UserNarocila.php index d50b4f811..58b8c6a57 100644 --- a/frontend/payments/classes/class.UserNarocila.php +++ b/frontend/payments/classes/class.UserNarocila.php @@ -805,7 +805,21 @@ class UserNarocila{ global $lang; $response = array(); - $response['narocilo_id'] = $narocilo_id; + + // Inicializiramo paypal + $paypal = new UserNarocilaPaypal($narocilo_id); + + // Ustvarimo paypal placilo in vrnemo url, da se uporabnik prijavi v paypal in potrdi placilo + $paypal_response = $paypal->paypalCreatePayment(); + + // Ce je bilo placilo preko stripa uspesno zgeneriramo racun in uporabniku aktiviramo paket + if($paypal_response['success'] == true){ + $response['paypal_url'] = $paypal_response['paypal_url']; + $response['success'] = true; + } + else{ + $response['error'] = $paypal_response['error']; + } return $response; } diff --git a/frontend/payments/classes/class.UserNarocilaPaypal.php b/frontend/payments/classes/class.UserNarocilaPaypal.php new file mode 100644 index 000000000..503313c5f --- /dev/null +++ b/frontend/payments/classes/class.UserNarocilaPaypal.php @@ -0,0 +1,126 @@ + 0){ + + // Dobimo podatke narocila + $sqlNarocilo = sisplet_query("SELECT un.*, u.name, u.surname, u.email, up.name AS package_name, up.description AS package_description, up.price AS package_price + FROM user_access_narocilo un, users u, user_access_paket up + WHERE un.id='".$narocilo_id."' AND un.usr_id=u.id AND un.package_id=up.id"); + if(mysqli_num_rows($sqlNarocilo) > 0){ + $this->narocilo = mysqli_fetch_array($sqlNarocilo); + } + else{ + die("Napaka pri komunikaciji s paypal! Narocilo ne obstaja."); + } + } + else { + die("Napaka pri komunikaciji s paypal! Manjka ID naročila."); + } + } + + + // Placamo narocilo s paypal + public function paypalCreatePayment(){ + global $paypal_account; + global $paypal_client_id; + global $paypal_secret; + global $site_url; + + + $UA = new UserNarocila(); + $cena = $UA->getPrice($this->narocilo['package_name'], $this->narocilo['trajanje'], $this->narocilo['discount']); + + if($this->narocilo['trajanje'] == 1) + $months_string = 'mesec'; + elseif($this->narocilo['trajanje'] == 2) + $months_string = 'meseca'; + elseif($this->narocilo['trajanje'] == 3 || $this->narocilo['trajanje'] == 4) + $months_string = 'mesece'; + else + $months_string = 'mesecev'; + + + // Zavezanec iz tujine ima racun/predracun brez ddv + if($UA->isWithoutDDV($this->narocilo['id'])){ + $ddv = 0; + $cena_za_placilo = $cena['final_without_tax']; + } + else{ + $ddv = 1; + $cena_za_placilo = $cena['final']; + } + + + // Podatki za paypal potrebni za placilo + $orderDetails = array( + 'business' => $paypal_client_id, + + 'item_name' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', + 'item_number' => $this->narocilo['id'], + 'amount' => $cena_za_placilo * 100, + 'currency_code' => 'EUR', + + 'return' => $site_url.'frontend/payments/paypal-pay.php', + 'cancel_return' => $site_url.'frontend/payments/paypal-cancel.php', + + 'cmd' => '_xclick' + ); + + // Posljemo placilo na paypal, da se lahko potem user prijavi in ga placa + $paypalResponse = $this->paypalCreatePaymentSend($orderDetails); + + + // Vstavimo plačilo v bazo + $sqlNarocilo = sisplet_query("INSERT INTO user_access_paypal_transaction + (transaction_id, narocilo_id, price, currency_type, time) + VALUES + ('".$paypalResponse['transaction_id']."', '".$paypalResponse['narocilo_id']."', '".$paypalResponse['price']."', '".$paypalResponse['currency_type']."',NOW()) + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + return $response; + } + + + $response = array(); + + return $response; + } + + + // Posljemo podatke za placilo paypalu - TODO + private function paypalCreatePaymentSend(){ + global $paypal_account; + global $paypal_client_id; + global $paypal_secret; + + $response = array(); + + $paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; + + /* + $response['transaction_id'] = $_GET['tx']; + $response['narocilo_id'] = $_GET['item_number']; + $response['price'] = $_GET['amt']; + $response['currency_type'] = $_GET['cc']; + */ + + return $response; + } +} \ No newline at end of file diff --git a/frontend/payments/paypal-cancel.php b/frontend/payments/paypal-cancel.php new file mode 100644 index 000000000..52fc9bd74 --- /dev/null +++ b/frontend/payments/paypal-cancel.php @@ -0,0 +1,171 @@ + $value) { + if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { + $value = urlencode(stripslashes($value)); + } else { + $value = urlencode($value); + } + $req .= "&$key=$value"; +} + + +// Post IPN data back to PayPal to validate the IPN data is genuine +// Without this step anyone can fake IPN data +if(USE_SANDBOX == true) { + $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; +} +else { + $paypal_url = "https://www.paypal.com/cgi-bin/webscr"; +} + +$ch = curl_init($paypal_url); +if ($ch == FALSE) { + return FALSE; +} + + +curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); +curl_setopt($ch, CURLOPT_POST, 1); +curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); +curl_setopt($ch, CURLOPT_POSTFIELDS, $req); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); +curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); +curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); + +if(DEBUG == true) { + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLINFO_HEADER_OUT, 1); +} + + + +// CONFIG: Optional proxy configuration +//curl_setopt($ch, CURLOPT_PROXY, $proxy); +//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); +// Set TCP timeout to 30 seconds +curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); +curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); +// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path +// of the certificate as shown below. Ensure the file is readable by the webserver. +// This is mandatory for some environments. +//$cert = __DIR__ . "./cacert.pem"; +//curl_setopt($ch, CURLOPT_CAINFO, $cert); +$res = curl_exec($ch); +if (curl_errno($ch) != 0) // cURL error + { + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE); + } + curl_close($ch); + exit; +} +else { + // Log the entire HTTP response if debug is switched on. + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE); + error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE); + } + curl_close($ch); +} + + + +// Inspect IPN validation result and act accordingly +// Split response headers and payload, a better way for strcmp +$tokens = explode("\r\n\r\n", trim($res)); +$res = trim(end($tokens)); +if (strcmp ($res, "VERIFIED") == 0) { + // assign posted variables to local variables + $item_name = $_POST['item_name']; + $item_number = $_POST['item_number']; + $payment_status = $_POST['payment_status']; + $payment_amount = $_POST['mc_gross']; + $payment_currency = $_POST['mc_currency']; + $txn_id = $_POST['txn_id']; + $receiver_email = $_POST['receiver_email']; + $payer_email = $_POST['payer_email']; + + include("DBController.php"); + $db = new DBController(); + + // check whether the payment_status is Completed + $isPaymentCompleted = false; + if($payment_status == "Completed") { + $isPaymentCompleted = true; + } + // check that txn_id has not been previously processed + $isUniqueTxnId = false; + $param_type="s"; + $param_value_array = array($txn_id); + $result = $db->runQuery("SELECT * FROM payment WHERE txn_id = ?",$param_type,$param_value_array); + if(empty($result)) { + $isUniqueTxnId = true; + } + // check that receiver_email is your PayPal email + // check that payment_amount/payment_currency are correct + if($isPaymentCompleted) { + $param_type = "sssdss"; + $param_value_array = array($item_number, $item_name, $payment_status, $payment_amount, $payment_currency, $txn_id); + $payment_id = $db->insert("INSERT INTO payment(item_number, item_name, payment_status, payment_amount, payment_currency, txn_id) VALUES(?, ?, ?, ?, ?, ?)", $param_type, $param_value_array); + + } + // process payment and mark item as paid. + + + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE); + } + +} +else if (strcmp ($res, "INVALID") == 0) { + // log for manual investigation + // Add business logic here which deals with invalid IPN messages + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE); + } +} + + +?> \ No newline at end of file diff --git a/frontend/payments/paypal-pay.php b/frontend/payments/paypal-pay.php new file mode 100644 index 000000000..52fc9bd74 --- /dev/null +++ b/frontend/payments/paypal-pay.php @@ -0,0 +1,171 @@ + $value) { + if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { + $value = urlencode(stripslashes($value)); + } else { + $value = urlencode($value); + } + $req .= "&$key=$value"; +} + + +// Post IPN data back to PayPal to validate the IPN data is genuine +// Without this step anyone can fake IPN data +if(USE_SANDBOX == true) { + $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; +} +else { + $paypal_url = "https://www.paypal.com/cgi-bin/webscr"; +} + +$ch = curl_init($paypal_url); +if ($ch == FALSE) { + return FALSE; +} + + +curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); +curl_setopt($ch, CURLOPT_POST, 1); +curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); +curl_setopt($ch, CURLOPT_POSTFIELDS, $req); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); +curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); +curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); + +if(DEBUG == true) { + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLINFO_HEADER_OUT, 1); +} + + + +// CONFIG: Optional proxy configuration +//curl_setopt($ch, CURLOPT_PROXY, $proxy); +//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); +// Set TCP timeout to 30 seconds +curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); +curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); +// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path +// of the certificate as shown below. Ensure the file is readable by the webserver. +// This is mandatory for some environments. +//$cert = __DIR__ . "./cacert.pem"; +//curl_setopt($ch, CURLOPT_CAINFO, $cert); +$res = curl_exec($ch); +if (curl_errno($ch) != 0) // cURL error + { + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE); + } + curl_close($ch); + exit; +} +else { + // Log the entire HTTP response if debug is switched on. + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE); + error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE); + } + curl_close($ch); +} + + + +// Inspect IPN validation result and act accordingly +// Split response headers and payload, a better way for strcmp +$tokens = explode("\r\n\r\n", trim($res)); +$res = trim(end($tokens)); +if (strcmp ($res, "VERIFIED") == 0) { + // assign posted variables to local variables + $item_name = $_POST['item_name']; + $item_number = $_POST['item_number']; + $payment_status = $_POST['payment_status']; + $payment_amount = $_POST['mc_gross']; + $payment_currency = $_POST['mc_currency']; + $txn_id = $_POST['txn_id']; + $receiver_email = $_POST['receiver_email']; + $payer_email = $_POST['payer_email']; + + include("DBController.php"); + $db = new DBController(); + + // check whether the payment_status is Completed + $isPaymentCompleted = false; + if($payment_status == "Completed") { + $isPaymentCompleted = true; + } + // check that txn_id has not been previously processed + $isUniqueTxnId = false; + $param_type="s"; + $param_value_array = array($txn_id); + $result = $db->runQuery("SELECT * FROM payment WHERE txn_id = ?",$param_type,$param_value_array); + if(empty($result)) { + $isUniqueTxnId = true; + } + // check that receiver_email is your PayPal email + // check that payment_amount/payment_currency are correct + if($isPaymentCompleted) { + $param_type = "sssdss"; + $param_value_array = array($item_number, $item_name, $payment_status, $payment_amount, $payment_currency, $txn_id); + $payment_id = $db->insert("INSERT INTO payment(item_number, item_name, payment_status, payment_amount, payment_currency, txn_id) VALUES(?, ?, ?, ?, ?, ?)", $param_type, $param_value_array); + + } + // process payment and mark item as paid. + + + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE); + } + +} +else if (strcmp ($res, "INVALID") == 0) { + // log for manual investigation + // Add business logic here which deals with invalid IPN messages + if(DEBUG == true) { + error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE); + } +} + + +?> \ No newline at end of file diff --git a/sql/update2.sql b/sql/update2.sql index 7cbb8ca8a..c7c94ed29 100644 --- a/sql/update2.sql +++ b/sql/update2.sql @@ -9282,3 +9282,17 @@ UPDATE misc SET value='20.07.29' WHERE what="version"; UPDATE srv_user_setting_for_survey SET value = '1ka' WHERE what = 'default_chart_profile_skin' AND value = '1ka'; UPDATE misc SET value='20.08.10' WHERE what="version"; + +## Tabela placil preko paypala +CREATE TABLE user_access_paypal_transaction( + id int(11) NOT NULL auto_increment, + transaction_id int(11) NOT NULL DEFAULT 0, + narocilo_id int(11) NOT NULL DEFAULT 0, + price DECIMAL(7,2) NOT NULL DEFAULT '0', + currency_type VARCHAR(100) NOT NULL DEFAULT '', + time DATETIME(3) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY (transaction_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +UPDATE misc SET value='20.09.07' WHERE what="version";