From da5913d7790ee885993ed041f2feaa089bda0ec7 Mon Sep 17 00:00:00 2001 From: pero1203 Date: Tue, 10 Nov 2020 14:15:44 +0100 Subject: [PATCH 1/2] Prenova stripe placil na sca --- .../classes/class.ApiNarocilaController.php | 28 +++ .../payments/classes/class.UserNarocila.php | 32 +-- .../classes/class.UserNarocilaStripe.php | 215 +++++++++++++++++- 3 files changed, 243 insertions(+), 32 deletions(-) diff --git a/frontend/payments/classes/class.ApiNarocilaController.php b/frontend/payments/classes/class.ApiNarocilaController.php index 43f803a6b..7c32d5482 100644 --- a/frontend/payments/classes/class.ApiNarocilaController.php +++ b/frontend/payments/classes/class.ApiNarocilaController.php @@ -281,6 +281,34 @@ class ApiNarocilaController{ $this->response['success'] = false; } + break; + + // Dokoncaj narocilo ce je placano preko stripe (ko je stranka potrdila placilo preko sca) + case 'stripe_checkout_success': + + if(isset($this->data['narocilo_id'])){ + $stripe = new UserNarocilaStripe($this->data['narocilo_id']); + $this->response = $stripe->stripeCheckoutSuccess(); + } + else{ + $this->response['error'] = 'Napaka! Manjka ID narocila!'; + $this->response['success'] = false; + } + + break; + + // Preklici narocilo za stripe (ko je stranka preklicala placilo preko sca) + case 'stripe_checkout_cancel': + + if(isset($this->data['narocilo_id'])){ + $stripe = new UserNarocilaStripe($this->data['narocilo_id']); + $this->response = $stripe->stripeCheckoutCancel(); + } + 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 622fa06e7..1b408f53c 100644 --- a/frontend/payments/classes/class.UserNarocila.php +++ b/frontend/payments/classes/class.UserNarocila.php @@ -792,42 +792,22 @@ class UserNarocila{ $response = array(); - $token = isset($narocilo_data['stripe_id']) ? $narocilo_data['stripe_id'] : ''; - if($token == ''){ - $response['error'] = 'ERROR! Missing token.'; - $response['success'] = false; - - return $response; - } - - // Inicializiramo stripe + // Inicializiramo paypal $stripe = new UserNarocilaStripe($narocilo_id); - $stripe_response = $stripe->stripePayment($token); + // Ustvarimo stripe session za placilo in vrnemo id sessiona, da uporabnik potrdi placilo + $stripe_response = $stripe->stripeCreateSession(); // Ce je bilo placilo preko stripa uspesno zgeneriramo racun in uporabniku aktiviramo paket - if($stripe_response['success'] == true){ - - $response['stripe_note'] = $stripe_response['stripe_note']; - - $payment_response = $this->payNarocilo($narocilo_id); - - if($payment_response['success'] == true){ - $response['racun'] = $payment_response['racun']; - $response['success'] = true; - } - else{ - $response['error'] = $payment_response['error']; - $response['success'] = false; - } + if($stripe_response['success'] == true){ + $response['session_id'] = $stripe_response['session_id']; + $response['success'] = true; } else{ $response['error'] = $stripe_response['error']; $response['success'] = false; } - $response['narocilo_id'] = $narocilo_id; - return $response; } diff --git a/frontend/payments/classes/class.UserNarocilaStripe.php b/frontend/payments/classes/class.UserNarocilaStripe.php index 2469c5a8f..30804af6e 100644 --- a/frontend/payments/classes/class.UserNarocilaStripe.php +++ b/frontend/payments/classes/class.UserNarocilaStripe.php @@ -12,6 +12,8 @@ use \Stripe\Customer; use \Stripe\ApiOperations\Create; use \Stripe\Charge; +use \Stripe\StripeClient; + class UserNarocilaStripe{ @@ -22,16 +24,12 @@ class UserNarocilaStripe{ private $stripeService; - public function __construct($narocilo_id ){ + public function __construct($narocilo_id){ global $app_settings; global $stripe_secret; global $stripe_key; - $this->apiKey = $stripe_secret; - - $this->stripeService = new \Stripe\Stripe(); - $this->stripeService->setVerifySslCerts(false); - $this->stripeService->setApiKey($this->apiKey); + $this->stripeService = new \Stripe\StripeClient($stripe_secret); if($narocilo_id > 0){ @@ -52,6 +50,210 @@ class UserNarocilaStripe{ } + // Ustvarimo session za placilo v stripe - V DELU + public function stripeCreateSession(){ + global $site_url; + global $lang; + + $response = array(); + + + $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']; + } + + + // URL po potrditvi oz preklicu + if($lang['id'] == '2'){ + $drupal_url_confirm = $site_url.'/d/en/stripe-purchase/success?narocilo_id='.$this->narocilo['id']; + $drupal_url_cancel = $site_url.'/d/en/stripe-purchase/cancel?narocilo_id='.$this->narocilo['id']; + } + else{ + $drupal_url_confirm = $site_url.'/d/narocilo/stripe?narocilo_id='.$this->narocilo['id']; + $drupal_url_cancel = $site_url.'/d/narocilo/stripe-cancel?narocilo_id='.$this->narocilo['id']; + } + + // Ustvarimo checkout session + try { + $stripe_response = $this->stripeService->checkout->sessions->create([ + 'success_url' => $drupal_url_confirm, + 'cancel_url' => $drupal_url_cancel, + + 'payment_method_types' => ['card'], + + 'line_items' => [ + [ + 'name' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', + 'price' => $cena_za_placilo, + 'quantity' => 1, + 'currency' => 'eur', + ], + ], + ]); + + // Dobimo id paypal narocila + $stripe_response['session_id'] = $stripe_response->session->id; + } + catch (HttpException $e) { + $response['error'] = $e->getMessage(); + $response['success'] = false; + + return $response; + } + + + // Vstavimo stripe charge v bazo + $sqlNarocilo = sisplet_query("INSERT INTO user_access_stripe_charge + (session_id, narocilo_id, price, time, status) + VALUES + ('".$stripe_response['session_id']."', '".$this->narocilo['id']."', '".$cena_za_placilo."', NOW(), 'CREATED') + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + + $response['session_id'] = $stripe_response['session_id']; + + $response['success'] = true; + + return $response; + } + + + // Zakljucimo placilo, ce je bilo placilo ok odobreno preko stripe s strani stranke - V DELU + public function stripeCheckoutSuccess(){ + + $response = array(); + + // Preverimo plačilo v bazo + $sqlNarociloStripe = sisplet_query("SELECT session_id + FROM user_access_stripe_charge + 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($sqlNarociloStripe) == 0){ + $response['error'] = 'ERROR! Stripe order session does not exist.'; + $response['success'] = false; + + return $response; + } + + $rowNarociloStripe = mysqli_fetch_array($sqlNarociloStripe); + + + // Preverimo, ce je bilo vse ok placano - POST request to /v2/checkout/orders + $request = new OrdersCaptureRequest($rowNarociloPaypal['transaction_id']); + + try { + // Poklicemo paypal api kjer preverimo placilo narocila + $paypal_response = $this->paypal_client->execute($request); + } + catch (HttpException $e) { + $response['error'] = $e->getMessage(); + $response['success'] = false; + + return $response; + } + + + // Posodobimo status narocila + $sqlNarocilo = sisplet_query("UPDATE user_access_stripe_charge + 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; + } + + + // Nastavimo narocilo na placano, aktiviramo paket in vrnemo racun + $narocilo = new UserNarocila(); + $payment_response = $narocilo->payNarocilo($this->narocilo['id']); + + if($payment_response['success'] == true){ + $response['racun'] = $payment_response['racun']; + $response['success'] = true; + } + else{ + $response['error'] = $payment_response['error']; + $response['success'] = false; + } + + $response['narocilo_id'] = $this->narocilo['id']; + + + $response['success'] = true; + + return $response; + } + + // Preklicemo placilo, ce je bilo placilo preklicano preko stripe s strani stranke + public function stripeCheckoutCancel(){ + + $response = array(); + + // Posodobimo status narocila + $sqlNarocilo = sisplet_query("UPDATE user_access_stripe_charge + SET status='CANCELLED' + WHERE narocilo_id='".$this->narocilo['id']."' + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + // Nastavimo status narocila na storniran + $sqlNarociloStatus = sisplet_query("UPDATE user_access_narocilo SET status='2' WHERE id='".$this->narocilo['id']."'"); + if (!$sqlNarociloStatus){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + + $response['success'] = true; + + return $response; + } + + + + /* // Placamo narocilo s kreditno kartico preko stripa public function stripePayment($token){ @@ -169,4 +371,5 @@ class UserNarocilaStripe{ return $customerDetails; } + */ } \ No newline at end of file From 1ebbdc95388027133894a2c5714130406633ab70 Mon Sep 17 00:00:00 2001 From: pero1203 Date: Wed, 11 Nov 2020 09:59:51 +0100 Subject: [PATCH 2/2] Dokoncan prehod na 2-stopenjsko avtentikacijo pri placevanju s stripe (novejsi api) --- .../classes/class.UserNarocilaStripe.php | 185 ++++-------------- sql/update2.sql | 4 + 2 files changed, 41 insertions(+), 148 deletions(-) diff --git a/frontend/payments/classes/class.UserNarocilaStripe.php b/frontend/payments/classes/class.UserNarocilaStripe.php index 30804af6e..bfc78d2c9 100644 --- a/frontend/payments/classes/class.UserNarocilaStripe.php +++ b/frontend/payments/classes/class.UserNarocilaStripe.php @@ -94,24 +94,29 @@ class UserNarocilaStripe{ // Ustvarimo checkout session try { - $stripe_response = $this->stripeService->checkout->sessions->create([ + $session = $this->stripeService->checkout->sessions->create([ 'success_url' => $drupal_url_confirm, 'cancel_url' => $drupal_url_cancel, 'payment_method_types' => ['card'], + 'mode' => 'payment', 'line_items' => [ - [ - 'name' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', - 'price' => $cena_za_placilo, - 'quantity' => 1, - 'currency' => 'eur', - ], + [ + 'price_data' => array( + 'currency' => 'EUR', + 'product_data' => array( + 'name' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', + ), + 'unit_amount' => $cena_za_placilo * 100, + ), + 'quantity' => 1, + ], ], ]); // Dobimo id paypal narocila - $stripe_response['session_id'] = $stripe_response->session->id; + $stripe_response['session_id'] = $session->id; } catch (HttpException $e) { $response['error'] = $e->getMessage(); @@ -153,14 +158,14 @@ class UserNarocilaStripe{ FROM user_access_stripe_charge WHERE narocilo_id='".$this->narocilo['id']."' "); - if (!$sqlNarociloPaypal){ + if (!$sqlNarociloStripe){ $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); $response['success'] = false; return $response; } - // Narocilo ne obstaja (ni v bazi paypal narocil) + // Narocilo ne obstaja (ni v bazi stripe narocil) if (mysqli_num_rows($sqlNarociloStripe) == 0){ $response['error'] = 'ERROR! Stripe order session does not exist.'; $response['success'] = false; @@ -171,35 +176,41 @@ class UserNarocilaStripe{ $rowNarociloStripe = mysqli_fetch_array($sqlNarociloStripe); - // Preverimo, ce je bilo vse ok placano - POST request to /v2/checkout/orders - $request = new OrdersCaptureRequest($rowNarociloPaypal['transaction_id']); - - try { + // Preverimo, ce je bilo vse ok placano + try{ // Poklicemo paypal api kjer preverimo placilo narocila - $paypal_response = $this->paypal_client->execute($request); + $session = $this->stripeService->checkout->sessions->retrieve($rowNarociloStripe['session_id']); } - catch (HttpException $e) { + catch(HttpException $e) { $response['error'] = $e->getMessage(); $response['success'] = false; return $response; } + // Ce je session placan, posodobimo status narocila + if($session->payment_status == 'paid'){ - // Posodobimo status narocila - $sqlNarocilo = sisplet_query("UPDATE user_access_stripe_charge - SET status='".$paypal_response->result->status."' - WHERE transaction_id='".$paypal_response->result->id."' - "); - if (!$sqlNarocilo){ - $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $sqlNarocilo = sisplet_query("UPDATE user_access_stripe_charge + SET status='PAID' + WHERE transaction_id='".$paypal_response->result->id."' + "); + if (!$sqlNarocilo){ + $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); + $response['success'] = false; + + return $response; + } + } + else{ + $response['error'] = 'ERROR! SESSION IS NOT PAID!'; $response['success'] = false; return $response; } + - - // Nastavimo narocilo na placano, aktiviramo paket in vrnemo racun + // Nastavimo narocilo na placano, aktiviramo paket in vrnemo id narocila $narocilo = new UserNarocila(); $payment_response = $narocilo->payNarocilo($this->narocilo['id']); @@ -212,8 +223,8 @@ class UserNarocilaStripe{ $response['success'] = false; } - $response['narocilo_id'] = $this->narocilo['id']; + $response['narocilo_id'] = $this->narocilo['id']; $response['success'] = true; @@ -250,126 +261,4 @@ class UserNarocilaStripe{ return $response; } - - - - /* - // Placamo narocilo s kreditno kartico preko stripa - public function stripePayment($token){ - - $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 kartico potrebni za placilo - $cardDetails = array( - 'email' => $this->narocilo['email'], - 'token' => $token, - - 'amount' => $cena_za_placilo * 100, - 'currency_code' => 'eur', - 'item_name' => '1KA naročnina (paket '.strtoupper($this->narocilo['package_name']). ' - '.$this->narocilo['trajanje'].' '.$months_string.')', - 'item_number' => $this->narocilo['id'], - ); - - // Izvedemo placilo - stripe response - try{ - $stripeResponse = $this->chargeAmountFromCard($cardDetails); - } - catch (Exception $e){ - $response['error'] = 'ERROR! '.$e->getMessage(); - return $response; - } - - // Vstavimo plačilo v bazo - $sqlNarocilo = sisplet_query("INSERT INTO user_access_stripe_charge - (narocilo_id, description, price, amount_paid, status, balance_transaction, time) - VALUES - ('".$this->narocilo['id']."', '".$cardDetails['item_name']."', '".$cena_za_placilo."', '".($stripeResponse['amount'] / 100)."', '".$stripeResponse['status']."', '".$stripeResponse['balance_transaction']."', NOW()) - "); - if (!$sqlNarocilo){ - $response['error'] = 'ERROR! '.mysqli_error($GLOBALS['connect_db']); - $response['success'] = false; - - return $response; - } - $response = array(); - - // Placilo uspesno - if ($stripeResponse['amount_refunded'] == 0 - && empty($stripeResponse['failure_code']) - && $stripeResponse['paid'] == 1 - && $stripeResponse['captured'] == 1 - && $stripeResponse['status'] == 'succeeded' - ) { - - $response['success'] = true; - $response['stripe_note'] = "Stripe payment is completed successfully. The TXN ID is " . $stripeResponse["balance_transaction"]; - } - // Placilo ni uspelo - else{ - $response['error'] = 'ERROR! Stripe payment failed. Failure code '.$stripeResponse['failure_code']; - $response['success'] = false; - } - - return $response; - } - - - private function chargeAmountFromCard($cardDetails){ - - // Iz emaila in tokena ustvarimo stranko - $customerDetailsAry = array( - 'email' => $cardDetails['email'], - 'source' => $cardDetails['token'] - ); - $customerResult = $this->addCustomer($customerDetailsAry); - $charge = new Charge(); - - // Napolnimo podatke za placilo - $cardDetailsAry = array( - 'customer' => $customerResult->id, - - 'amount' => $cardDetails['amount'], - 'currency' => $cardDetails['currency_code'], - 'description' => $cardDetails['item_name'], - - 'metadata' => array( - 'order_id' => $cardDetails['item_number'] - ) - ); - - // Izvedemo "charge" - $result = $charge->create($cardDetailsAry); - - return $result->jsonSerialize(); - } - - private function addCustomer($customerDetailsAry){ - - $customer = new Customer(); - $customerDetails = $customer->create($customerDetailsAry); - - return $customerDetails; - } - */ } \ No newline at end of file diff --git a/sql/update2.sql b/sql/update2.sql index 3f556efbc..b04708530 100644 --- a/sql/update2.sql +++ b/sql/update2.sql @@ -9343,3 +9343,7 @@ UPDATE misc SET value='20.10.29' WHERE what="version"; ALTER TABLE user_access_narocilo CHANGE COLUMN podjetje_zavezanec podjetje_no_ddv ENUM('0', '1') NOT NULL DEFAULT '0' AFTER podjetje_davcna; UPDATE misc SET value='20.11.04' WHERE what="version"; + +ALTER TABLE user_access_stripe_charge ADD COLUMN session_id VARCHAR(100) NOT NULL DEFAULT '' AFTER id; + +UPDATE misc SET value='20.11.11' WHERE what="version";