From 192d97bceef4a3315b03b95522b8c22a9c716a3a Mon Sep 17 00:00:00 2001 From: pero1203 Date: Mon, 7 Sep 2020 12:53:52 +0200 Subject: [PATCH 1/6] 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"; From 4f9bb1b658f5e486606492472c2a271b02595ac4 Mon Sep 17 00:00:00 2001 From: pero1203 Date: Wed, 9 Sep 2020 11:22:20 +0200 Subject: [PATCH 2/6] Narejen paypal paypalCreateOrder in paypalCaptureOrder --- composer.json | 3 +- composer.lock | 123 ++++++++++-- .../classes/class.ApiNarocilaController.php | 20 ++ .../payments/classes/class.UserNarocila.php | 29 ++- .../classes/class.UserNarocilaPaypal.php | 179 ++++++++++++++---- .../classes/class.UserNarocilaStripe.php | 3 + sql/update2.sql | 1 + 7 files changed, 304 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index d19331c14..9a4529108 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "phpmailer/phpmailer": "~6.0", "minishlink/web-push": "^5.2", "stripe/stripe-php": "^7.40", - "geoip2/geoip2": "~2.0" + "geoip2/geoip2": "~2.0", + "paypal/paypal-checkout-sdk": "^1.0" }, "require-dev": { "kint-php/kint": "^1.1", diff --git a/composer.lock b/composer.lock index 12251f820..54c328891 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "f48f2e76d23925213a1c248388654ed4", - "content-hash": "4faadcc7d5b72636e2d9ac9a18b062a2", + "hash": "c9fc655cdb58743c38114c03e68c1cc7", + "content-hash": "a150435d7f20bef4fdda8cb6c59eb1a6", "packages": [ { "name": "composer/ca-bundle", @@ -663,6 +663,95 @@ ], "time": "2020-03-20 21:48:09" }, + { + "name": "paypal/paypal-checkout-sdk", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/paypal/Checkout-PHP-SDK.git", + "reference": "ed6a55075448308b87a8b59dcb7fedf04a048cb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paypal/Checkout-PHP-SDK/zipball/ed6a55075448308b87a8b59dcb7fedf04a048cb1", + "reference": "ed6a55075448308b87a8b59dcb7fedf04a048cb1", + "shasum": "" + }, + "require": { + "paypal/paypalhttp": "1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "PayPalCheckoutSdk\\": "lib/PayPalCheckoutSdk", + "Sample\\": "samples/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "https://github.com/paypal/Checkout-PHP-SDK/blob/master/LICENSE" + ], + "authors": [ + { + "name": "PayPal", + "homepage": "https://github.com/paypal/Checkout-PHP-SDK/contributors" + } + ], + "description": "PayPal's PHP SDK for Checkout REST APIs", + "homepage": "http://github.com/paypal/Checkout-PHP-SDK/", + "keywords": [ + "checkout", + "orders", + "payments", + "paypal", + "rest", + "sdk" + ], + "time": "2019-11-07 23:16:44" + }, + { + "name": "paypal/paypalhttp", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/paypal/paypalhttp_php.git", + "reference": "1ad9b846a046f09d6135cbf2cbaa7701bbc630a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paypal/paypalhttp_php/zipball/1ad9b846a046f09d6135cbf2cbaa7701bbc630a3", + "reference": "1ad9b846a046f09d6135cbf2cbaa7701bbc630a3", + "shasum": "" + }, + "require": { + "ext-curl": "*" + }, + "require-dev": { + "phpunit/phpunit": "^5.7", + "wiremock-php/wiremock-php": "1.43.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PayPalHttp\\": "lib/PayPalHttp" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PayPal", + "homepage": "https://github.com/paypal/paypalhttp_php/contributors" + } + ], + "abandoned": true, + "time": "2019-11-06 21:27:12" + }, { "name": "phpmailer/phpmailer", "version": "v6.1.7", @@ -874,16 +963,16 @@ }, { "name": "spomky-labs/base64url", - "version": "v2.0.2", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/base64url.git", - "reference": "69e77e7d7c5407a253dacdd7bfe6b8978b7a4fb2" + "reference": "48ea8ff600cefe56b82d3d5b768b6f4f3bfe05a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/69e77e7d7c5407a253dacdd7bfe6b8978b7a4fb2", - "reference": "69e77e7d7c5407a253dacdd7bfe6b8978b7a4fb2", + "url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/48ea8ff600cefe56b82d3d5b768b6f4f3bfe05a1", + "reference": "48ea8ff600cefe56b82d3d5b768b6f4f3bfe05a1", "shasum": "" }, "require": { @@ -922,20 +1011,20 @@ "safe", "url" ], - "time": "2020-08-01 14:15:43" + "time": "2020-08-30 13:35:33" }, { "name": "stripe/stripe-php", - "version": "v7.49.0", + "version": "v7.52.0", "source": { "type": "git", "url": "https://github.com/stripe/stripe-php.git", - "reference": "db6229bff448f7f3bf7f6aee112d5d9ba34ca4ba" + "reference": "51e95c514aff45616dff09791ca5b2f10cf5c4e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stripe/stripe-php/zipball/db6229bff448f7f3bf7f6aee112d5d9ba34ca4ba", - "reference": "db6229bff448f7f3bf7f6aee112d5d9ba34ca4ba", + "url": "https://api.github.com/repos/stripe/stripe-php/zipball/51e95c514aff45616dff09791ca5b2f10cf5c4e8", + "reference": "51e95c514aff45616dff09791ca5b2f10cf5c4e8", "shasum": "" }, "require": { @@ -979,7 +1068,7 @@ "payment processing", "stripe" ], - "time": "2020-08-19 22:48:20" + "time": "2020-09-08 19:29:20" }, { "name": "symfony/polyfill-intl-idn", @@ -2230,16 +2319,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.11", + "version": "v4.4.13", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "2125805a1a4e57f2340bc566c3013ca94d2722dc" + "reference": "1bef32329f3166486ab7cb88599cae4875632b99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2125805a1a4e57f2340bc566c3013ca94d2722dc", - "reference": "2125805a1a4e57f2340bc566c3013ca94d2722dc", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1bef32329f3166486ab7cb88599cae4875632b99", + "reference": "1bef32329f3166486ab7cb88599cae4875632b99", "shasum": "" }, "require": { @@ -2303,7 +2392,7 @@ "debug", "dump" ], - "time": "2020-06-24 13:34:53" + "time": "2020-08-17 07:31:35" } ], "aliases": [], diff --git a/frontend/payments/classes/class.ApiNarocilaController.php b/frontend/payments/classes/class.ApiNarocilaController.php index 2051b6107..9ff60a0bf 100644 --- a/frontend/payments/classes/class.ApiNarocilaController.php +++ b/frontend/payments/classes/class.ApiNarocilaController.php @@ -76,6 +76,7 @@ class ApiNarocilaController{ return true; else{ $this->response['error'] = 'Napaka! Napačen token.'; + $this->response['success'] = false; return false; } @@ -88,6 +89,7 @@ class ApiNarocilaController{ if (!isset($this->params['action'])) { $this->response['error'] = 'Napaka! Manjkajo parametri!'; + $this->response['success'] = false; } else { @@ -122,6 +124,7 @@ class ApiNarocilaController{ } else{ $this->response['error'] = 'Napaka! Manjka ID narocila!'; + $this->response['success'] = false; } break; @@ -135,6 +138,7 @@ class ApiNarocilaController{ } else{ $this->response['error'] = 'Napaka! Manjka ID narocila!'; + $this->response['success'] = false; } break; @@ -208,6 +212,8 @@ class ApiNarocilaController{ if($usr_id == '' || $usr_id == 0){ $this->response['error'] = 'ERROR! Missing user ID.'; + $this->response['success'] = false; + break; } @@ -223,6 +229,20 @@ class ApiNarocilaController{ $this->response = $price; break; + + // Preveri, ce je narocilo placano preko paypala + case 'check_narocilo_paypal': + + if(isset($this->data['narocilo_id'])){ + $paypal = new UserNarocilaPaypal($this->data['narocilo_id']); + $this->response = $narocilo->paypalCaptureOrder(); + } + else{ + $this->response['error'] = 'Napaka! Manjka ID narocila!'; + $this->response['success'] = false; + } + + break; } } } diff --git a/frontend/payments/classes/class.UserNarocila.php b/frontend/payments/classes/class.UserNarocila.php index 58b8c6a57..f8655a72c 100644 --- a/frontend/payments/classes/class.UserNarocila.php +++ b/frontend/payments/classes/class.UserNarocila.php @@ -647,6 +647,8 @@ class UserNarocila{ if($usr_id <= 0){ $response['error'] = 'ERROR! Missing user ID.'; + $response['success'] = false; + return $response; } @@ -684,6 +686,8 @@ class UserNarocila{ "); if (!$sqlNarocilo){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } @@ -713,7 +717,6 @@ class UserNarocila{ } - return $response; } @@ -753,6 +756,8 @@ class UserNarocila{ } catch (Exception $e){ $response['error'] = 'ERROR! Sending email with invoice failed.'; + $response['success'] = false; + return $response; } @@ -768,6 +773,8 @@ class UserNarocila{ $token = isset($narocilo_data['stripe_id']) ? $narocilo_data['stripe_id'] : ''; if($token == ''){ $response['error'] = 'ERROR! Missing token.'; + $response['success'] = false; + return $response; } @@ -789,10 +796,12 @@ class UserNarocila{ } else{ $response['error'] = $payment_response['error']; + $response['success'] = false; } } else{ $response['error'] = $stripe_response['error']; + $response['success'] = false; } $response['narocilo_id'] = $narocilo_id; @@ -814,11 +823,12 @@ class UserNarocila{ // 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['paypal_link'] = $paypal_response['paypal_link']; $response['success'] = true; } else{ $response['error'] = $paypal_response['error']; + $response['success'] = false; } return $response; @@ -826,7 +836,7 @@ class UserNarocila{ - // Posodobi obstojece narocilo za uporabnika - ZA TESTIRATI + // Posodobi obstojece narocilo za uporabnika public function updateNarocilo($narocilo_data){ global $global_user_id; @@ -835,6 +845,7 @@ class UserNarocila{ // ce nimamo id-ja narocila vrnemo error if(!isset($narocilo_data['narocilo_id']) || $narocilo_data['narocilo_id'] == '0'){ $response['error'] = 'Napaka! Manjka ID narocila!'; + $response['success'] = false; return $response; } @@ -864,6 +875,8 @@ class UserNarocila{ $sqlNarocilo = sisplet_query("UPDATE user_access_narocilo SET ".$update.", cebelica_id_racun='0', cebelica_id_predracun='0' WHERE id='".$narocilo_data['narocilo_id']."'"); if (!$sqlNarocilo){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } @@ -882,6 +895,7 @@ class UserNarocila{ // Ce nimamo id-ja narocila vrnemo error if($narocilo_id == 0){ $response['error'] = 'Napaka! Manjka ID narocila!'; + $response['success'] = false; return $response; } @@ -894,6 +908,7 @@ class UserNarocila{ // Ce je bil racun ze placan ne naredimo nicesar if($rowNarocilo['status'] == 1){ $response['error'] = 'Napaka! Račun je že plačan!'; + $response['success'] = false; return $response; } @@ -924,6 +939,8 @@ class UserNarocila{ "); if (!$sqlAccess){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } } @@ -932,6 +949,8 @@ class UserNarocila{ $sqlAccess = sisplet_query("UPDATE user_access SET time_expire = time_expire + INTERVAL '".$rowNarocilo['trajanje']."' MONTH WHERE usr_id='".$rowNarocilo['usr_id']."'"); if (!$sqlAccess){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } } @@ -948,6 +967,8 @@ class UserNarocila{ "); if (!$sqlAccess){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } } @@ -957,6 +978,8 @@ class UserNarocila{ $sqlNarociloStatus = sisplet_query("UPDATE user_access_narocilo SET status='1' WHERE id='".$narocilo_id."'"); if (!$sqlNarociloStatus){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } diff --git a/frontend/payments/classes/class.UserNarocilaPaypal.php b/frontend/payments/classes/class.UserNarocilaPaypal.php index 503313c5f..e90c64406 100644 --- a/frontend/payments/classes/class.UserNarocilaPaypal.php +++ b/frontend/payments/classes/class.UserNarocilaPaypal.php @@ -7,14 +7,23 @@ */ +use PayPalCheckoutSdk\Core\PayPalHttpClient; +use PayPalCheckoutSdk\Core\SandboxEnvironment; +use PayPalCheckoutSdk\Orders\OrdersCreateRequest; +use PayPalCheckoutSdk\Orders\OrdersCaptureRequest; + + class UserNarocilaPaypal{ private $narocilo; + private $paypal_client; public function __construct($narocilo_id){ - global $app_settings; + global $app_settings; + global $paypal_client_id; + global $paypal_secret; if($narocilo_id > 0){ @@ -28,6 +37,10 @@ class UserNarocilaPaypal{ else{ die("Napaka pri komunikaciji s paypal! Narocilo ne obstaja."); } + + // Ustvarimo okolje za paypal + $environment = new SandboxEnvironment($paypal_client_id, $paypal_secret); + $this->paypal_client = new PayPalHttpClient($environment); } else { die("Napaka pri komunikaciji s paypal! Manjka ID naročila."); @@ -37,11 +50,10 @@ class UserNarocilaPaypal{ // Placamo narocilo s paypal public function paypalCreatePayment(){ - global $paypal_account; - global $paypal_client_id; - global $paypal_secret; global $site_url; + $response = array(); + $UA = new UserNarocila(); $cena = $UA->getPrice($this->narocilo['package_name'], $this->narocilo['trajanje'], $this->narocilo['discount']); @@ -67,60 +79,161 @@ class UserNarocilaPaypal{ } - // Podatki za paypal potrebni za placilo + // Podatki narocila $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' + 'ime' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', + 'narocilo_id' => $this->narocilo['id'], + 'cena' => $cena_za_placilo, ); - // Posljemo placilo na paypal, da se lahko potem user prijavi in ga placa - $paypalResponse = $this->paypalCreatePaymentSend($orderDetails); + // Ustvarimo order na paypal, da se lahko potem user prijavi in ga placa + $paypal_response = $this->paypalCreateOrder($orderDetails); + + if(!isset($paypal_response['success']) || $paypal_response['success'] == false){ + return $paypal_response; + } // 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()) + ('".$paypal_response['transaction_id']."', '".$this->narocilo['id']."', '".$cena_za_placilo."', 'EUR', NOW()) "); if (!$sqlNarocilo){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } - $response = array(); + $response['paypal_link'] = $paypal_response['paypal_link']; + + $response['success'] = true; return $response; } - - // Posljemo podatke za placilo paypalu - TODO - private function paypalCreatePaymentSend(){ - global $paypal_account; - global $paypal_client_id; - global $paypal_secret; + // Posljemo podatke za placilo paypalu + private function paypalCreateOrder($orderDetails){ + global $site_url; $response = array(); - $paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; + $request = new OrdersCreateRequest(); - /* - $response['transaction_id'] = $_GET['tx']; - $response['narocilo_id'] = $_GET['item_number']; - $response['price'] = $_GET['amt']; - $response['currency_type'] = $_GET['cc']; - */ + $request->prefer('return=representation'); + //$request->headers["prefer"] = "return=representation"; + + $request->body = [ + "intent" => "CAPTURE", + "purchase_units" => [[ + "reference_id" => $orderDetails['narocilo_id'], + "amount" => [ + "value" => $orderDetails['cena'], + "currency_code" => "EUR" + ] + ]], + "application_context" => [ + "cancel_url" => $site_url . '/d/narocilo/paypal-cancel', + "return_url" => $site_url . '/d/narocilo/paypal' + ] + ]; + + try { + // Poklicemo paypal api za ustvarjanje narocila + $paypal_response = $client->execute($request); + + if($paypal_response->result->status != 'CREATED'){ + $response['error'] = 'ERROR! Order was not created.'; + $response['success'] = false; + + return $response; + } + + // Dobimo id paypal narocila + $response['transaction_id'] = $paypal_response->result->id; + + // Dobimo link za preusmeritev stranke, da potrdi narocilo in potem lahko izvedemo "capture" + foreach($paypal_response->result->links as $link){ + + if($link->rel == 'capture') + $response['paypal_link'] = $link->href; + } + } + catch (HttpException $e) { + $response['error'] = $e->getMessage(); + return $response; + } + + $response['success'] = true; + + return $response; + } + + + // Zakljucimo placilo, ce je bilo placilo ok odobreno preko paypala s strani stranke + public function paypalCaptureOrder(){ + + $response = array(); + + // Preverimo plačilo v bazo + $sqlNarociloPaypal = sisplet_query("SELECT transaction_id + FROM user_access_paypal_transaction + WHERE narocilo_id='".$this->narocilo['id']."' + "); + if (!$sqlNarociloPaypal){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + // Narocilo ne obstaja (ni v bazi paypal narocil) + if (mysqli_num_rows($sqlNarociloPaypal) == 0){ + $response['error'] = 'ERROR! Paypal order does not exist.'; + $response['success'] = false; + + return $response; + } + + $rowNarociloPaypal = mysqli_fetch_array($sqlNarociloPaypal); + + // Preverimo, ce je bilo vse ok placano - POST request to /v2/checkout/orders + $request = new OrdersCaptureRequest($rowNarociloPaypal['transaction_id']); + //$request->prefer('return=representation'); + + try { + // Poklicemo paypal api kjer preverimo placilo narocila + $paypal_response = $client->execute($request); + } + catch (HttpException $e) { + $response['error'] = $e->getMessage(); + $response['success'] = false; + + return $response; + } + + + // Posodobimo status narocila + $sqlNarocilo = sisplet_query("UPDATE user_access_paypal_transaction + SET status='".$paypal_response->result->status."' + WHERE transaction_id='".$paypal_response->result->id."' + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + + $response['status'] = $paypal_response->result->status; + + $response['success'] = true; + return $response; } } \ No newline at end of file diff --git a/frontend/payments/classes/class.UserNarocilaStripe.php b/frontend/payments/classes/class.UserNarocilaStripe.php index 8ca6af29e..a9148cde2 100644 --- a/frontend/payments/classes/class.UserNarocilaStripe.php +++ b/frontend/payments/classes/class.UserNarocilaStripe.php @@ -100,6 +100,8 @@ class UserNarocilaStripe{ "); if (!$sqlNarocilo){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + return $response; } $response = array(); @@ -118,6 +120,7 @@ class UserNarocilaStripe{ // Placilo ni uspelo else{ $response['error'] = 'ERROR! Stripe payment failed. Failure code '.$stripeResponse['failure_code']; + $response['success'] = false; } return $response; diff --git a/sql/update2.sql b/sql/update2.sql index c7c94ed29..4b4f57512 100644 --- a/sql/update2.sql +++ b/sql/update2.sql @@ -9291,6 +9291,7 @@ CREATE TABLE user_access_paypal_transaction( price DECIMAL(7,2) NOT NULL DEFAULT '0', currency_type VARCHAR(100) NOT NULL DEFAULT '', time DATETIME(3) NOT NULL, + status VARCHAR(30) NOT NULL DEFAULT '', PRIMARY KEY (id), UNIQUE KEY (transaction_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 912ab1ed930acc114937e35629360a21b7ee3fc1 Mon Sep 17 00:00:00 2001 From: pero1203 Date: Thu, 10 Sep 2020 10:27:06 +0200 Subject: [PATCH 3/6] Dokoncan backend za paypal, dokoncani funkciji za cancel in capture paypal narocila - ZA TESTIRATI --- .../classes/class.ApiNarocilaController.php | 18 ++++++++- .../classes/class.UserNarocilaPaypal.php | 39 +++++++++++++++++-- sql/update2.sql | 3 +- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/frontend/payments/classes/class.ApiNarocilaController.php b/frontend/payments/classes/class.ApiNarocilaController.php index 9ff60a0bf..ebceea984 100644 --- a/frontend/payments/classes/class.ApiNarocilaController.php +++ b/frontend/payments/classes/class.ApiNarocilaController.php @@ -230,8 +230,22 @@ class ApiNarocilaController{ break; - // Preveri, ce je narocilo placano preko paypala - case 'check_narocilo_paypal': + // Dokoncaj narocilo ce je placano preko paypala (ko je stranka potrdila placilo v paypalu) + case 'capture_narocilo_paypal': + + if(isset($this->data['narocilo_id'])){ + $paypal = new UserNarocilaPaypal($this->data['narocilo_id']); + $this->response = $narocilo->paypalCaptureOrder(); + } + else{ + $this->response['error'] = 'Napaka! Manjka ID narocila!'; + $this->response['success'] = false; + } + + break; + + // Preklici narocilo za paypal (ko je stranka preklicala placilo v paypalu) + case 'cancel_narocilo_paypal': if(isset($this->data['narocilo_id'])){ $paypal = new UserNarocilaPaypal($this->data['narocilo_id']); diff --git a/frontend/payments/classes/class.UserNarocilaPaypal.php b/frontend/payments/classes/class.UserNarocilaPaypal.php index e90c64406..6f5e61e79 100644 --- a/frontend/payments/classes/class.UserNarocilaPaypal.php +++ b/frontend/payments/classes/class.UserNarocilaPaypal.php @@ -24,6 +24,7 @@ class UserNarocilaPaypal{ global $app_settings; global $paypal_client_id; global $paypal_secret; + global $mysql_database_name; if($narocilo_id > 0){ @@ -38,8 +39,13 @@ class UserNarocilaPaypal{ die("Napaka pri komunikaciji s paypal! Narocilo ne obstaja."); } + // Ustvarimo okolje za paypal - $environment = new SandboxEnvironment($paypal_client_id, $paypal_secret); + if($mysql_database_name == 'real1kasi') + $environment = new ProductionEnvironment($paypal_client_id, $paypal_secret); + else + $environment = new SandboxEnvironment($paypal_client_id, $paypal_secret); + $this->paypal_client = new PayPalHttpClient($environment); } else { @@ -130,14 +136,18 @@ class UserNarocilaPaypal{ "intent" => "CAPTURE", "purchase_units" => [[ "reference_id" => $orderDetails['narocilo_id'], + 'description' => $orderDetails['ime'], + "amount" => [ "value" => $orderDetails['cena'], "currency_code" => "EUR" ] ]], "application_context" => [ - "cancel_url" => $site_url . '/d/narocilo/paypal-cancel', - "return_url" => $site_url . '/d/narocilo/paypal' + "cancel_url" => $site_url . '/d/narocilo/paypal-cancel?narocilo_id='.$orderDetails['narocilo_id'], + "return_url" => $site_url . '/d/narocilo/paypal?narocilo_id='.$orderDetails['narocilo_id'], + + 'brand_name' => '1KA' ] ]; @@ -236,4 +246,27 @@ class UserNarocilaPaypal{ return $response; } + + + // Preklicemo placilo, ce je bilo placilo preklicano preko paypala s strani stranke + public function paypalCancelOrder(){ + + $response = array(); + + // Posodobimo status narocila + $sqlNarocilo = sisplet_query("UPDATE user_access_paypal_transaction + SET status='CANCELED' + WHERE narocilo_id='".$this->narocilo['id']."' + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + $response['success'] = true; + + return $response; + } } \ No newline at end of file diff --git a/sql/update2.sql b/sql/update2.sql index 4b4f57512..27a9fbfed 100644 --- a/sql/update2.sql +++ b/sql/update2.sql @@ -9293,7 +9293,8 @@ CREATE TABLE user_access_paypal_transaction( time DATETIME(3) NOT NULL, status VARCHAR(30) NOT NULL DEFAULT '', PRIMARY KEY (id), - UNIQUE KEY (transaction_id) + UNIQUE KEY (transaction_id), + UNIQUE KEY (narocilo_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; UPDATE misc SET value='20.09.07' WHERE what="version"; From dbb168b47988305e9603d610c0ad96e828f887b6 Mon Sep 17 00:00:00 2001 From: pero1203 Date: Fri, 11 Sep 2020 08:33:34 +0200 Subject: [PATCH 4/6] Dodan manjkajoc response za success --- frontend/payments/classes/class.UserNarocilaPaypal.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/payments/classes/class.UserNarocilaPaypal.php b/frontend/payments/classes/class.UserNarocilaPaypal.php index 6f5e61e79..431409b47 100644 --- a/frontend/payments/classes/class.UserNarocilaPaypal.php +++ b/frontend/payments/classes/class.UserNarocilaPaypal.php @@ -174,6 +174,8 @@ class UserNarocilaPaypal{ } catch (HttpException $e) { $response['error'] = $e->getMessage(); + $response['success'] = false; + return $response; } From 8f99a3072189975e2e9fc503674762a673d63173 Mon Sep 17 00:00:00 2001 From: Peter Hrvatin Date: Mon, 14 Sep 2020 10:47:15 +0200 Subject: [PATCH 5/6] Popravek paypal klica --- frontend/payments/classes/class.UserNarocilaPaypal.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/payments/classes/class.UserNarocilaPaypal.php b/frontend/payments/classes/class.UserNarocilaPaypal.php index 431409b47..85906d6c0 100644 --- a/frontend/payments/classes/class.UserNarocilaPaypal.php +++ b/frontend/payments/classes/class.UserNarocilaPaypal.php @@ -153,7 +153,7 @@ class UserNarocilaPaypal{ try { // Poklicemo paypal api za ustvarjanje narocila - $paypal_response = $client->execute($request); + $paypal_response = $this->paypal_client->execute($request); if($paypal_response->result->status != 'CREATED'){ $response['error'] = 'ERROR! Order was not created.'; @@ -219,7 +219,7 @@ class UserNarocilaPaypal{ try { // Poklicemo paypal api kjer preverimo placilo narocila - $paypal_response = $client->execute($request); + $paypal_response = $this->paypal_client->execute($request); } catch (HttpException $e) { $response['error'] = $e->getMessage(); From c2fd6366489104952c494b081a5ed08192bf38fb Mon Sep 17 00:00:00 2001 From: pero1203 Date: Wed, 16 Sep 2020 09:48:42 +0200 Subject: [PATCH 6/6] Popravek za paypal pri klicu cebelice --- frontend/payments/cebelica/InvoiceFox/cebelcaApi.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/payments/cebelica/InvoiceFox/cebelcaApi.php b/frontend/payments/cebelica/InvoiceFox/cebelcaApi.php index cef910a34..c8e4424c1 100644 --- a/frontend/payments/cebelica/InvoiceFox/cebelcaApi.php +++ b/frontend/payments/cebelica/InvoiceFox/cebelcaApi.php @@ -47,12 +47,14 @@ function racunIzPredracuna($api,$podatki,$proformaId,$lang='si') { // nastavi, da je plačano $api->markPayed($header); - // kartica in gotovina se potrjujeta - if($tip_placila == 3){ + // kartica in paypal se potrjujeta + if($tip_placila == 3 || $tip_placila == 5){ + $id_location = ($tip_placila == 5) ? 4 : 2; + $glava = array ( 'id' => $invId, - "id_location" => 2, + "id_location" => $id_location, "id_register" => 1, "fiscalize" => 1, 'op-tax-id' => IZDAJATELJ_DAVCNA,