From 2756d26f5f94a1e85a69e50e8a387f57529f4020 Mon Sep 17 00:00:00 2001 From: Hessam Taghvaei Date: Tue, 1 Oct 2024 17:50:22 +0330 Subject: [PATCH 1/4] chore: update zarinpal sandbox urls in config --- config/payment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/payment.php b/config/payment.php index d7a9367..8aa8102 100755 --- a/config/payment.php +++ b/config/payment.php @@ -350,9 +350,9 @@ 'apiVerificationUrl' => 'https://api.zarinpal.com/pg/v4/payment/verify.json', /* sandbox api */ - 'sandboxApiPurchaseUrl' => 'https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', - 'sandboxApiPaymentUrl' => 'https://sandbox.zarinpal.com/pg/StartPay/', - 'sandboxApiVerificationUrl' => 'https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', + 'sandboxApiPurchaseUrl' => 'https://sandbox.zarinpal.com/pg/v4/payment/request.json', + 'sandboxApiPaymentUrl' => 'https://sandbox.zarinpal.com/pg/StartPay/', + 'sandboxApiVerificationUrl' => 'https://sandbox.zarinpal.com/pg/v4/payment/verify.json', /* zarinGate api */ 'zaringateApiPurchaseUrl' => 'https://ir.zarinpal.com/pg/services/WebGate/wsdl', From 2e806c7ad2321a398bbb6840afc7d7e20e33106f Mon Sep 17 00:00:00 2001 From: Hessam Taghvaei Date: Tue, 1 Oct 2024 18:03:14 +0330 Subject: [PATCH 2/4] refactor: replaced SOAP with REST API in Zarinpal Sandbox strategy --- src/Drivers/Zarinpal/Strategies/Sandbox.php | 95 ++++++++++++++------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/src/Drivers/Zarinpal/Strategies/Sandbox.php b/src/Drivers/Zarinpal/Strategies/Sandbox.php index 9175410..fe17e59 100644 --- a/src/Drivers/Zarinpal/Strategies/Sandbox.php +++ b/src/Drivers/Zarinpal/Strategies/Sandbox.php @@ -2,6 +2,7 @@ namespace Shetabit\Multipay\Drivers\Zarinpal\Strategies; +use GuzzleHttp\Client; use Shetabit\Multipay\Abstracts\Driver; use Shetabit\Multipay\Exceptions\InvalidPaymentException; use Shetabit\Multipay\Exceptions\PurchaseFailedException; @@ -10,10 +11,12 @@ use Shetabit\Multipay\Receipt; use Shetabit\Multipay\RedirectionForm; use Shetabit\Multipay\Request; -use SoapClient; class Sandbox extends Driver { + + protected $client; + /** * Invoice * @@ -39,6 +42,7 @@ public function __construct(Invoice $invoice, $settings) { $this->invoice($invoice); $this->settings = (object) $settings; + $this->client = new Client(); } /** @@ -47,39 +51,48 @@ public function __construct(Invoice $invoice, $settings) * @return string * * @throws PurchaseFailedException - * @throws \SoapFault */ public function purchase() { + $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial + if (!empty($this->invoice->getDetails()['description'])) { $description = $this->invoice->getDetails()['description']; } else { $description = $this->settings->description; } - $mobile = !empty($this->invoice->getDetails()['mobile']) ? $this->invoice->getDetails()['mobile'] : ''; - $email = !empty($this->invoice->getDetails()['email']) ? $this->invoice->getDetails()['email'] : ''; - $amount = $this->invoice->getAmount() / ($this->settings->currency == 'T' ? 1 : 10); // convert to toman - - $data = array( - 'MerchantID' => $this->settings->merchantId, - 'Amount' => $amount, - 'CallbackURL' => $this->settings->callbackUrl, - 'Description' => $description, - 'Mobile' => $mobile ?? '', - 'Email' => $email ?? '', + $data = [ + "merchant_id" => $this->settings->merchantId, + "amount" => $amount, + "currency" => 'IRR', + "callback_url" => $this->settings->callbackUrl, + "description" => $description, 'AdditionalData' => $this->invoice->getDetails() - ); - - $client = new SoapClient($this->getPurchaseUrl(), ['encoding' => 'UTF-8']); - $result = $client->PaymentRequest($data); + ]; - $bodyResponse = $result->Status; - if ($bodyResponse != 100 || empty($result->Authority)) { + $response = $this + ->client + ->request( + 'POST', + $this->getPurchaseUrl(), + [ + "json" => $data, + "headers" => [ + 'Content-Type' => 'application/json', + ], + "http_errors" => false, + ] + ); + + $result = json_decode($response->getBody()->getContents(), true); + + if (!empty($result['errors']) || empty($result['data']) || $result['data']['code'] != 100) { + $bodyResponse = $result['errors']['code']; throw new PurchaseFailedException($this->translateStatus($bodyResponse), $bodyResponse); } - $this->invoice->transactionId($result->Authority); + $this->invoice->transactionId($result['data']["authority"]); // return the transaction's id return $this->invoice->getTransactionId(); @@ -106,26 +119,50 @@ public function pay() : RedirectionForm * @return ReceiptInterface * * @throws InvalidPaymentException - * @throws \SoapFault */ public function verify() : ReceiptInterface { $authority = $this->invoice->getTransactionId() ?? Request::input('Authority'); $data = [ - 'MerchantID' => $this->settings->merchantId, - 'Authority' => $authority, - 'Amount' => $this->invoice->getAmount() / ($this->settings->currency == 'T' ? 1 : 10), // convert to toman + "merchant_id" => $this->settings->merchantId, + "authority" => $authority, + "amount" => $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1), // convert to rial ]; - $client = new SoapClient($this->getVerificationUrl(), ['encoding' => 'UTF-8']); - $result = $client->PaymentVerification($data); + $response = $this->client->request( + 'POST', + $this->getVerificationUrl(), + [ + 'json' => $data, + "headers" => [ + 'Content-Type' => 'application/json', + ], + "http_errors" => false, + ] + ); + + $result = json_decode($response->getBody()->getContents(), true); - $bodyResponse = $result->Status; - if ($bodyResponse != 100) { + if (empty($result['data']) || !isset($result['data']['ref_id']) || ($result['data']['code'] != 100 && $result['data']['code'] != 101)) { + $bodyResponse = $result['errors']['code']; throw new InvalidPaymentException($this->translateStatus($bodyResponse), $bodyResponse); } - return $this->createReceipt($result->RefID); + $refId = $result['data']['ref_id']; + + $receipt = $this->createReceipt($refId); + $receipt->detail([ + 'code' => $result['data']['code'], + 'message' => $result['data']['message'] ?? null, + 'card_hash' => $result['data']['card_hash'] ?? null, + 'card_pan' => $result['data']['card_pan'] ?? null, + 'ref_id' => $refId, + 'fee_type' => $result['data']['fee_type'] ?? null, + 'fee' => $result['data']['fee'] ?? null, + 'order_id' => $result['data']['order_id'] ?? null, + ]); + + return $receipt; } /** From 4da8e5d59f996d54eb0fedefb85200e449472f05 Mon Sep 17 00:00:00 2001 From: Hessam Taghvaei Date: Tue, 1 Oct 2024 18:08:12 +0330 Subject: [PATCH 3/4] styles: fix code styles --- config/payment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/payment.php b/config/payment.php index 8aa8102..ebeb41f 100755 --- a/config/payment.php +++ b/config/payment.php @@ -350,8 +350,8 @@ 'apiVerificationUrl' => 'https://api.zarinpal.com/pg/v4/payment/verify.json', /* sandbox api */ - 'sandboxApiPurchaseUrl' => 'https://sandbox.zarinpal.com/pg/v4/payment/request.json', - 'sandboxApiPaymentUrl' => 'https://sandbox.zarinpal.com/pg/StartPay/', + 'sandboxApiPurchaseUrl' => 'https://sandbox.zarinpal.com/pg/v4/payment/request.json', + 'sandboxApiPaymentUrl' => 'https://sandbox.zarinpal.com/pg/StartPay/', 'sandboxApiVerificationUrl' => 'https://sandbox.zarinpal.com/pg/v4/payment/verify.json', /* zarinGate api */ From 206ba9d6336da4128e6e7142514edbc42f3410a5 Mon Sep 17 00:00:00 2001 From: Hessam Taghvaei Date: Tue, 1 Oct 2024 18:09:51 +0330 Subject: [PATCH 4/4] styles: fix code styles --- src/Drivers/Zarinpal/Strategies/Sandbox.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Drivers/Zarinpal/Strategies/Sandbox.php b/src/Drivers/Zarinpal/Strategies/Sandbox.php index fe17e59..6d733fc 100644 --- a/src/Drivers/Zarinpal/Strategies/Sandbox.php +++ b/src/Drivers/Zarinpal/Strategies/Sandbox.php @@ -14,7 +14,6 @@ class Sandbox extends Driver { - protected $client; /**