diff --git a/README.md b/README.md index f48d668..863e1a9 100644 --- a/README.md +++ b/README.md @@ -104,12 +104,23 @@ For example create a POST route in routes folder, web.php like this: Route::post('payment/callback', 'YourController@handleCallback')->name('payment.callback'); ``` +`NOTE: SOME GATEWAYS MAY USE GET METHOD FOR CALLBACK (like Zarinpal)` + then set the route name in .env file: ```ini LARAPAY_PAYMENT_CALLBACK=payment.callback ``` +remember to add callback route to except array of validateCsrfToken + +add this in `withMiddleware` section in `bootstrap/app.php` : +```php +$middleware->validateCsrfTokens(except: [ + 'payment/*', +]); +``` + ## Usage diff --git a/config/larapay.php b/config/larapay.php index 7e352d7..0801d39 100644 --- a/config/larapay.php +++ b/config/larapay.php @@ -27,7 +27,7 @@ | the gateways list is comma separated | */ - 'gateways' => env('LARAPAY_GATES', 'Mellat,Saman,Pasargad,Parsian,ZarinPal,Idpay,Payir,Saderat,Zibal,Nextpay'), + 'gateways' => env('LARAPAY_GATES', 'Mellat,Saman,Pasargad,Parsian,Zarinpal,Idpay,Payir,Saderat,Zibal,Nextpay'), /* |-------------------------------------------------------------------------- diff --git a/src/Adapter/AdapterAbstract.php b/src/Adapter/AdapterAbstract.php index cd87fd6..0923b3b 100755 --- a/src/Adapter/AdapterAbstract.php +++ b/src/Adapter/AdapterAbstract.php @@ -217,6 +217,30 @@ protected function getEndPoint(): string } } + /** + * @return string + */ + protected function getPaymentRequestEndpPoint():string + { + if (config('larapay.mode') === 'production') { + return $this->paymentRequestEndPoint; + } else { + return $this->testPaymentRequestEndPoint; + } + } + + /** + * @return string + */ + protected function getPaymentVerifyEndpPoint():string + { + if (config('larapay.mode') === 'production') { + return $this->paymentVerifyEndPoint; + } else { + return $this->testPaymentVerifyEndPoint; + } + } + /** * @param array $options * diff --git a/src/Adapter/Zarinpal.php b/src/Adapter/Zarinpal.php index a1294d9..3333c19 100755 --- a/src/Adapter/Zarinpal.php +++ b/src/Adapter/Zarinpal.php @@ -5,6 +5,7 @@ use SoapClient; use SoapFault; +use PhpMonsters\Larapay\Adapter\Zarinpal\Helper; use PhpMonsters\Larapay\Adapter\Zarinpal\Exception; use PhpMonsters\Log\Facades\XLog; @@ -14,14 +15,18 @@ */ class Zarinpal extends AdapterAbstract implements AdapterInterface { - protected $WSDL = 'https://www.zarinpal.com/pg/services/WebGate/wsdl'; + protected $paymentRequestEndPoint = "https://payment.zarinpal.com/pg/v4/payment/request.json"; + protected $paymentVerifyEndPoint = "https://payment.zarinpal.com/pg/v4/payment/verify.json"; - protected $endPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}'; - protected $zarinEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/ZarinGate'; + + protected $endPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}'; + protected $zarinEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/ZarinGate'; protected $mobileEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/MobileGate'; - protected $testWSDL = 'https://banktest.ir/gateway/zarinpal/ws?wsdl'; - protected $testEndPoint = 'https://banktest.ir/gateway/zarinpal/gate/{authority}'; + protected $testEndPoint = 'https://sandbox.banktest.ir/zarinpal/www.zarinpal.com/pg/StartPay/{authority}'; + protected $testPaymentRequestEndPoint = "https://sandbox.banktest.ir/zarinpal/api.zarinpal.com/pg/v4/payment/request.json"; + protected $testPaymentVerifyEndPoint = "https://sandbox.banktest.ir/zarinpal/api.zarinpal.com/pg/v4/payment/verify.json"; + public $reverseSupport = false; @@ -43,42 +48,39 @@ protected function requestToken(): string ]); $sendParams = [ - 'MerchantID' => $this->merchant_id, - 'Amount' => intval($this->amount), - 'Description' => $this->description ? $this->description : '', - 'Email' => $this->email ? $this->email : '', - 'Mobile' => $this->mobile ? $this->mobile : '', - 'CallbackURL' => $this->redirect_url, + 'merchant_id' => $this->merchant_id, + 'amount' => intval($this->amount), + 'description' => $this->description ? $this->description : '', + "metadata" => [ + 'mobile' => $this->mobile ? $this->mobile : '', + 'email' => $this->email ? $this->email : '', + ], + 'callback_url' => $this->redirect_url, ]; try { - $soapClient = new SoapClient($this->getWSDL()); - XLog::debug('PaymentRequest call', $sendParams); - $response = $soapClient->PaymentRequest($sendParams); - - XLog::info('PaymentRequest response', $this->obj2array($response)); - + $response = Helper::post2https($sendParams, $this->getPaymentRequestEndpPoint()); + $result = json_decode($response); + XLog::info('reservation result', $result); - if (isset($response->Status)) { + if (empty($result->errors)) { + if ($result->data->code == 100) { + $this->getTransaction()->setGatewayToken(strval($result->data->authority)); // update transaction reference id - if ($response->Status == 100) { - $this->getTransaction()->setGatewayToken(strval($response->Authority)); // update transaction reference id - - return $response->Authority; + return $result->data->authority; } else { - throw new Exception($response->Status); + throw new Exception('no error provided and not 100'); } } else { - throw new Exception('larapay::larapay.invalid_response'); + throw new Exception('code: ' . $result->errors->code . "\n" . 'message: ' . $result->errors->message); } - } catch (SoapFault $e) { - throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode()); + } catch (\Exception $e) { + throw new Exception($e->getMessage()); } } - /** * @return string * @throws Exception @@ -89,9 +91,9 @@ protected function generateForm(): string $authority = $this->requestToken(); $form = view('larapay::zarinpal-form', [ - 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]), + 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]), 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"), - 'autoSubmit' => boolval($this->auto_submit), + 'autoSubmit' => boolval($this->auto_submit), ]); return $form->__toString(); @@ -106,8 +108,8 @@ public function formParams(): array { $authority = $this->requestToken(); - return [ - 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]), + return [ + 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]), ]; } @@ -128,38 +130,29 @@ protected function verifyTransaction(): bool ]); $sendParams = [ - 'MerchantID' => $this->merchant_id, - 'Authority' => $this->Authority, - 'Amount' => intval($this->transaction->amount), + 'merchant_id' => $this->merchant_id, + 'authority' => $this->Authority, + 'amount' => intval($this->transaction->amount), ]; - try { - $soapClient = new SoapClient($this->getWSDL()); - - XLog::debug('PaymentVerification call', $sendParams); - - $response = $soapClient->PaymentVerification($sendParams); + XLog::debug('PaymentVerification call', $sendParams); - XLog::info('PaymentVerification response', $this->obj2array($response)); - - - if (isset($response->Status, $response->RefID)) { - - if ($response->Status == 100) { - $this->getTransaction()->setVerified(); - $this->getTransaction()->setReferenceId((string)$response->RefID); // update transaction reference id - - return true; - } else { - throw new Exception($response->Status); - } + try { + $response = Helper::post2https($sendParams, $this->getPaymentVerifyEndpPoint()); + $result = json_decode($response); + XLog::info('PaymentVerification response', $this->obj2array($result)); + + if ($result->data->code === 100) { + $this->getTransaction()->setVerified(); + $this->getTransaction()->setReferenceId((string) $result->data->ref_id); // update transaction reference id + return true; + } else if ($result->data->code === 101) { + return true; } else { - throw new Exception('larapay::larapay.invalid_response'); + throw new Exception('code: ' . $result->errors->code . "\n" . 'message: ' . $result->errors->message); } - - } catch (SoapFault $e) { - - throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode()); + } catch (\Exception $e) { + throw new Exception("Payment Verify Error: " . $e->getMessage()); } } diff --git a/src/Adapter/Zarinpal/Helper.php b/src/Adapter/Zarinpal/Helper.php new file mode 100644 index 0000000..e91cf57 --- /dev/null +++ b/src/Adapter/Zarinpal/Helper.php @@ -0,0 +1,47 @@ +