From e233b76ad88c7d94c1bd09ad49cbced829f144d9 Mon Sep 17 00:00:00 2001 From: Rahrayan Desktop Date: Mon, 6 Nov 2023 16:26:43 +0330 Subject: [PATCH] add "samankish" payment gateway --- config/gateway.php | 4 + src/Enum.php | 1 + src/GatewayResolver.php | 19 +- src/Samankish/Samankish.php | 225 +++++++++++++++++++ src/Samankish/SamankishCallbackException.php | 28 +++ src/Samankish/SamankishReceiveException.php | 25 +++ 6 files changed, 294 insertions(+), 8 deletions(-) create mode 100644 src/Samankish/Samankish.php create mode 100644 src/Samankish/SamankishCallbackException.php create mode 100644 src/Samankish/SamankishReceiveException.php diff --git a/config/gateway.php b/config/gateway.php index fffe3d7e..84a1e72e 100644 --- a/config/gateway.php +++ b/config/gateway.php @@ -123,6 +123,10 @@ ] ], + 'samankish' => [ + 'terminal_id' => 'xxxxxxxx', + 'callback_url' => '/' + ], //------------------------------- // Tables names //-------------------------------- diff --git a/src/Enum.php b/src/Enum.php index 266f0a6e..c409f485 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -17,6 +17,7 @@ class Enum const PAYIR = 'PAYIR'; const IRANKISH = 'IRANKISH'; const MASKAN = self::IRANKISH; + const SAMANKISH = 'SAMANKISH'; static function getIPGs(){ diff --git a/src/GatewayResolver.php b/src/GatewayResolver.php index 53071630..39375f0e 100644 --- a/src/GatewayResolver.php +++ b/src/GatewayResolver.php @@ -2,21 +2,22 @@ namespace Larabookir\Gateway; -use Larabookir\Gateway\Irankish\Irankish; -use Larabookir\Gateway\Parsian\Parsian; -use Larabookir\Gateway\Paypal\Paypal; +use Illuminate\Support\Facades\DB; +use Larabookir\Gateway\Payir\Payir; use Larabookir\Gateway\Sadad\Sadad; +use Larabookir\Gateway\Saman\Saman; use Larabookir\Gateway\Mellat\Mellat; +use Larabookir\Gateway\Paypal\Paypal; +use Larabookir\Gateway\Parsian\Parsian; +use Larabookir\Gateway\Irankish\Irankish; use Larabookir\Gateway\Pasargad\Pasargad; -use Larabookir\Gateway\Saman\Saman; -use Larabookir\Gateway\Asanpardakht\Asanpardakht; use Larabookir\Gateway\Zarinpal\Zarinpal; -use Larabookir\Gateway\Payir\Payir; +use Larabookir\Gateway\Samankish\Samankish; +use Larabookir\Gateway\Asanpardakht\Asanpardakht; use Larabookir\Gateway\Exceptions\RetryException; use Larabookir\Gateway\Exceptions\PortNotFoundException; use Larabookir\Gateway\Exceptions\InvalidRequestException; use Larabookir\Gateway\Exceptions\NotFoundTransactionException; -use Illuminate\Support\Facades\DB; class GatewayResolver { @@ -148,7 +149,9 @@ function make($port) $name = Enum::PASARGAD; } elseif ($port InstanceOf Irankish) { $name = Enum::IRANKISH; - } elseif (in_array(strtoupper($port), $this->getSupportedPorts())) { + } elseif ($port instanceof Samankish) { + $name = Enum::SAMANKISH; + } elseif (in_array(strtoupper($port), $this->getSupportedPorts())) { $port = ucfirst(strtolower($port)); $name = strtoupper($port); $class = __NAMESPACE__ . '\\' . $port . '\\' . $port; diff --git a/src/Samankish/Samankish.php b/src/Samankish/Samankish.php new file mode 100644 index 00000000..faa71412 --- /dev/null +++ b/src/Samankish/Samankish.php @@ -0,0 +1,225 @@ +amount = $amount; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function ready() + { + $this->sendPayRequest(); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function redirect() + { + return \Redirect::to($this->gateUrl . '?token=' . $this->token); + } + + /** + * {@inheritdoc} + */ + public function verify($transaction) + { + parent::verify($transaction); + + $this->userPayment(); + $this->verifyPayment(); + + return $this; + } + + /** + * Sets callback url + * @param $url + */ + function setCallback($url) + { + $this->callbackUrl = $url; + return $this; + } + + /** + * Sets mobile mobile + * @param $mobile + */ + function setMobile($mobile) + { + $this->mobile = $mobile; + return $this; + } + + /** + * Gets callback url + * @return string + */ + function getCallback() + { + if (!$this->callbackUrl) + $this->callbackUrl = $this->config->get('gateway.samankish.callback_url'); + + return $this->makeCallback($this->callbackUrl, ['transaction_id' => $this->transactionId()]); + } + + /** + * Send pay request to server + * + * @return void|boolean + * + * @throws Exception + */ + protected function sendPayRequest() + { + $transactionId = $this->newTransaction(); + + $params = array( + "action" => "token", + "TerminalId" => $this->config->get('gateway.samankish.terminal_id'), + "Amount" => $this->amount, + "ResNum" => $transactionId, + "RedirectUrl" => $this->getCallback(), + "CellNumber" => $this->mobile, + ); + + $response = $this->curlPost($this->tokenUrl, $params); + + if ($response->status === 1) { + $this->token = $response->token; + + return true; + } + + $this->transactionFailed(); + $this->newLog($response->errorCode, $response->errorDesc); + throw new Exception($response->errorDesc . ' # ' . $response->errorCode); + } + + /** + * Check user payment with GET data + * + * @return bool + * + * @throws SamankishReceiveException + */ + protected function userPayment() + { + $this->refIf = Request::input('RefNum'); + $this->cardNumber = Request::input('SecurePan'); + $trackingCode = Request::input('TraceNo'); + $state = Request::input('State'); + $status = Request::input('Status'); + + if ($state == 'OK' && $status == '2' && ((int) $this->amount === (int) Request::input('AffectiveAmount'))) { + $this->trackingCode = $trackingCode; + return true; + } + + $this->transactionFailed(); + $this->newLog($status, SamankishCallbackException::$errors[$status]); + throw new SamankishCallbackException($status); + } + + /** + * Verify user payment from zarinpal server + * + * @return bool + * + * @throws SamankishReceiveException + */ + protected function verifyPayment() + { + $params = array( + 'TerminalNumber' => $this->config->get('gateway.samankish.terminal_id'), + 'RefNum' => $this->refIf, + ); + + $response = $this->curlPost($this->serverVerifyUrl, $params); + + if ($response->ResultCode === 0 && $response->Success === true) { + $this->transactionSucceed(); + $this->newLog($response->ResultCode, Enum::TRANSACTION_SUCCEED_TEXT); + + return true; + } + + $this->transactionFailed(); + $this->newLog($response->ResultCode, SamankishReceiveException::$errors[$response->ResultCode]); + throw new SamankishReceiveException($response->ResultCode); + } + + public function curlPost($url, $params) + { + $curl = curl_init(); + + curl_setopt_array( + $curl, + array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 0, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => json_encode($params), + CURLOPT_HTTPHEADER => array( + 'Content-Type: application/json', + ), + ) + ); + + $response = curl_exec($curl); + + curl_close($curl); + return json_decode($response); + } +} diff --git a/src/Samankish/SamankishCallbackException.php b/src/Samankish/SamankishCallbackException.php new file mode 100644 index 00000000..de654529 --- /dev/null +++ b/src/Samankish/SamankishCallbackException.php @@ -0,0 +1,28 @@ + 'کاربر انصراف داده است', + 2 => 'پرداخت با موفقیت انجام شد', + 3 => 'پرداخت انجام نشد.', + 4 => 'کاربر در بازه زمانی تعیین شده پاسخی ارسال نکرده است.', + 5 => 'پارامترهای ارسالی نامعتبر است.', + 8 => 'آدرس سرور پذیرنده نامعتبر است (در پرداخت های بر پایهتوکن)', + 10 => 'توکن ارسال شده یافت نشد.', + 11 => 'با این شماره ترمینال فقط تراکنش های توکنی قابل پرداخت هستند.', + 12 => 'شماره ترمینال ارسال شده یافت نشد.', + 21 => 'محدودیت های مدل چند حسابی رعایت نشده ', + ); + + public function __construct($errorId) + { + $this->errorId = $errorId; + + parent::__construct(@self::$errors[$errorId] . ' #' . $errorId, $errorId); + } +} diff --git a/src/Samankish/SamankishReceiveException.php b/src/Samankish/SamankishReceiveException.php new file mode 100644 index 00000000..129fc2a1 --- /dev/null +++ b/src/Samankish/SamankishReceiveException.php @@ -0,0 +1,25 @@ + 'تراکنش یافت نشد.', + -6 => 'بیش از نیم ساعت از زمان اجرای تراکنش گذشته است.', + 0 => 'موفق', + 2 => 'درخواست تکراری می باشد.', + -105 => 'ترمینال ارسالی در س یستم موجود نمی باشد', + -104 => 'ترمینال ارسالی غیرفعال می باشد', + -1 => 'آدرس آ ی پی درخواستی غیر مجاز می باشد', + ); + + public function __construct($errorId) + { + $this->errorId = $errorId; + + parent::__construct(@self::$errors[$errorId] . ' #' . $errorId, $errorId); + } +}