diff --git a/composer.json b/composer.json index 196ad7f..8790ed1 100644 --- a/composer.json +++ b/composer.json @@ -38,9 +38,9 @@ "ext-curl": "*", "ext-json": "*", "ext-soap": "*", - "illuminate/support": "^5.7|^6.0|^7.0|^8.0|^9.0", - "illuminate/database": "^5.7|^6.0|^7.0|^8.0|^9.0", - "illuminate/http": "^5.7|^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^5.7|^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/database": "^5.7|^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/http": "^5.7|^6.0|^7.0|^8.0|^9.0|^10.0", "nesbot/carbon": "*" }, "require-dev": { diff --git a/config/iranpayment.php b/config/iranpayment.php index 70b9f96..11eeac6 100644 --- a/config/iranpayment.php +++ b/config/iranpayment.php @@ -103,4 +103,15 @@ 'merchant-id' => env('NOVINOPAY_MERCHANT_ID', 'xxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxx'), // 'callback-url' => 'http://example.com/payments/navinopay/callback', ], + + /* + |-------------------------------------------------------------------------- + | TEST gateway + |-------------------------------------------------------------------------- + */ + 'test' => [ + 'active' => env('IRANPAYMENT_TEST_ACTIVE', false), + 'url' => '/iranpayments/test', + // 'callback-url' => 'http://example.com/payments/test/callback', + ], ]; diff --git a/resources/views/pages/status.blade.php b/resources/views/pages/status.blade.php new file mode 100644 index 0000000..39150b5 --- /dev/null +++ b/resources/views/pages/status.blade.php @@ -0,0 +1,29 @@ +@extends('iranpayment::layouts.master') + +@php + if ($status === \Dena\IranPayment\Models\IranPaymentTransaction::T_SUCCEED) { + $title = 'پرداخت با موفقیت انجام شد'; + } else { + $title = 'پرداخت با خطا مواجه شد'; + } +@endphp + +@section('title', $title) + +@section('content') +
+
+

{{ $title }}

+ +

شناسه خرید شما

+

{{ $transaction_code }}

+ @if (isset($image)) +
+ +
+ @endif + + {{ $button_text }} +
+
+@endsection diff --git a/resources/views/pages/test.blade.php b/resources/views/pages/test.blade.php index 01e657a..f5180b8 100644 --- a/resources/views/pages/test.blade.php +++ b/resources/views/pages/test.blade.php @@ -5,17 +5,20 @@ @section('content')
-

شناسه خرید شما

-

{!! $transaction_code !!}

-

شناسه پرداخت شما

-

{!! $reference_number ?? '' !!}

-

پرداخت با موفقیت انجام شد

-

تایید پرداخت

+

شناسه خرید شما

+

{{ $transaction_code }}

+ +

وضعیت مورد نظر را انتخاب کنید:

+
+
+
+ +
+
+ +
+
+
@endsection - -@section('javascript') - -@endsection \ No newline at end of file diff --git a/resources/views/styles/style.blade.php b/resources/views/styles/style.blade.php index ac3c8d9..25a98cc 100644 --- a/resources/views/styles/style.blade.php +++ b/resources/views/styles/style.blade.php @@ -95,7 +95,6 @@ color: #455a64; border: 3px solid #455a64; padding: 1em 1.6em; - margin: auto; border-radius: 5px; letter-spacing: 0.1em; line-height: 1.7em; @@ -106,12 +105,29 @@ border-radius: 5px; } -button.pure-button-default { +button.pure-button-default, +a.pure-button-default { color: white; background: #455a64; - font-size: 150%; + font-size: 150%; +} + +.button-success, +.button-error, +.button-warning, +.button-secondary { + color: white; + border-radius: 4px; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } +.button-success { + background: rgb(28, 184, 65); +} + +.button-error { + background: rgb(202, 60, 60); +} footer { background-color: #263238; @@ -180,4 +196,4 @@ } } - \ No newline at end of file + diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index f98fee1..00ad1c8 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -18,13 +18,7 @@ use Dena\IranPayment\Helpers\Currency; -/** - * @method getName() - * @method purchase() - * @method purchaseUri() - * @method verify() - */ -abstract class AbstractGateway +abstract class AbstractGateway implements GatewayInterface { use UserData, PaymentData, @@ -44,6 +38,9 @@ abstract class AbstractGateway */ protected array $gateway_request_options = []; + abstract public function verify(): void; + abstract public function purchase(): void; + /** * Initialize Gateway function * @@ -299,7 +296,7 @@ protected function postVerify(): void */ public function confirm(IranPaymentTransaction $transaction = null) { - if(isset($transaction)) { + if (isset($transaction)) { $this->setTransaction($transaction); } @@ -321,4 +318,17 @@ public function confirm(IranPaymentTransaction $transaction = null) return $this; } + + public function statusView(array $parameters = []) + { + return response()->view('iranpayment::pages.status', array_merge( + [ + 'status' => $parameters['status'] ?? $this->getTransaction()->status, + 'transaction_code' => $parameters['transaction_code'] ?? $this->getTransactionCode(), + 'button_url' => url('/'), + 'button_text' => 'بازگشت به صفحه‌اصلی', + ], + $parameters + )); + } } diff --git a/src/Gateways/Saman/Saman.php b/src/Gateways/Saman/Saman.php index b9bce8c..9c9e7cc 100644 --- a/src/Gateways/Saman/Saman.php +++ b/src/Gateways/Saman/Saman.php @@ -226,7 +226,7 @@ protected function purchaseViewParams(): array 'method' => 'POST', 'form_data' => [ 'Token' => $this->getToken(), - 'RedirectURL' => $this->getCallbackUrl(), + 'RedirectURL' => $this->preparedCallbackUrl(), ], ]; } diff --git a/src/Gateways/Test/TestException.php b/src/Gateways/Test/TestException.php new file mode 100644 index 0000000..f7c5a4c --- /dev/null +++ b/src/Gateways/Test/TestException.php @@ -0,0 +1,17 @@ + 'تراکنش ناموفق میباشد', + ]; + + public static function error($error_code) + { + return new self(self::$errors[$error_code] ?? self::$errors[-100], $error_code); + } +} diff --git a/src/Gateways/Test/TestGateway.php b/src/Gateways/Test/TestGateway.php index c62b64e..7e70278 100644 --- a/src/Gateways/Test/TestGateway.php +++ b/src/Gateways/Test/TestGateway.php @@ -10,6 +10,8 @@ class TestGateway extends AbstractGateway implements GatewayInterface { + protected ?string $url; + public function getName(): string { return 'test'; @@ -26,6 +28,8 @@ public function initialize(array $parameters = []): self ?? app('config')->get('iranpayment.callback-url') ); + $this->url = $parameters['url'] ?? app('config')->get('iranpayment.test.url'); + return $this; } @@ -33,51 +37,78 @@ protected function prePurchase(): void { parent::prePurchase(); - if ($this->preparedAmount() < 1000 || $this->preparedAmount() > 500000000) { + if ($this->preparedAmount() < 0 || $this->preparedAmount() > 500000000) { throw InvalidDataException::invalidAmount(); } } - - public function preVerify(): void - { - parent::preVerify(); - } - public function verify(): void + public function purchase(): void { - $code = rand(1, 10000); - $this->transactionSucceed(['tracking_code' => $code]); + $this->transactionUpdate([ + 'reference_number' => uniqid(), + ]); } /** - * @throws Exception + * Purchase View Params function + * + * @return array */ - public function redirect() + protected function purchaseViewParams(): array { - $this->addExtra($this->getCallbackUrl(), 'callback_url'); - return view('iranpayment::pages.test')->with([ - 'transaction_code' => $this->getTransactionCode(), - 'reference_number' => $this->getReferenceNumber(), - ]); + return [ + 'title' => 'تست', + 'method' => 'POST', + ]; } - public function purchase(): void + /** + * Pay Link function + * + * @return string + */ + public function purchaseUri(): string { - $this->transactionUpdate([ - 'reference_number' => uniqid(), - ]); + $url = filter_var($this->url, FILTER_VALIDATE_URL) + ? $this->url + : url($this->url); + + $url_parts = parse_url($url); + if (isset($url_parts['query'])) { + parse_str($url_parts['query'], $params); + } else { + $params = []; + } + + $params['reference_number'] = $this->getReferenceNumber(); + + $url_parts['query'] = http_build_query($params); + + return $url_parts['scheme'].'://'.$url_parts['host'] + .(strlen($url_parts['port']) ? ':'.$url_parts['port'] : '') + .$url_parts['path'] + .(strlen($url_parts['query']) ? '?'.$url_parts['query'] : ''); } - public function purchaseView(array $arr = []) + public function verify(): void { - return view('iranpayment::pages.test', [ - 'reference_number' => uniqid(), - 'transaction_code' => $this->getTransactionCode(), - ]); + if ($this->request['status'] === 'error') { + throw TestException::error(-100); + } + + $trackingCode = rand(111111, 999999); + $this->transactionSucceed([ + 'card_number' => rand(1111, 9999).'********'.rand(1111, 9999), + 'tracking_code' => $trackingCode, + 'reference_number' => 'RefNum-'.$trackingCode, + ]); } - public function purchaseUri(): string + public function bankView() { - return route('iranpayment.test.pay', $this->getReferenceNumber()); + return response()->view('iranpayment::pages.test', [ + 'transaction_code' => $this->getTransactionCode(), + 'callback_url' => $this->preparedCallbackUrl(), + ]); } } diff --git a/src/Gateways/Test/TestGatewayController.php b/src/Gateways/Test/TestGatewayController.php index 63e38b9..ddb53a3 100644 --- a/src/Gateways/Test/TestGatewayController.php +++ b/src/Gateways/Test/TestGatewayController.php @@ -9,30 +9,12 @@ class TestGatewayController { - public function paymentView($code) + public function paymentView() { $payment = IranPayment::create('test'); - $transaction = IranPaymentTransaction::where('reference_number', $code)->first(); + $transaction = IranPaymentTransaction::where('reference_number', request()->get('reference_number'))->first(); $payment->setTransaction($transaction); - return $payment->view(); - } - - public function verify(Request $request, $code) - { - $transaction = IranPaymentTransaction::where('code', $code)->first(); - - $queryParams = http_build_query([ - app('config')->get('iranpayment.transaction_query_param') => $code - ]); - - $callback = $transaction->extra['callback_url'];; - - $question_mark = strpos($callback, '?'); - if($question_mark) { - return redirect($callback.'&'.$queryParams); - } - - return redirect($callback.'?'.$queryParams); + return $payment->bankView(); } } diff --git a/src/Gateways/Test/routes.php b/src/Gateways/Test/routes.php index 5421563..ab3d5a8 100644 --- a/src/Gateways/Test/routes.php +++ b/src/Gateways/Test/routes.php @@ -2,10 +2,10 @@ use Illuminate\Support\Facades\Route; -Route::group(['namespace' => 'Dena\IranPayment\Gateways\Test'], function () { - Route::get('/iranpayment/test/{reference}', 'TestGatewayController@paymentView') - ->name('iranpayment.test.pay'); - - Route::get('/iranpayment/test/{code}/verify', 'TestGatewayController@verify') - ->name('iranpayment.test.verify'); -}); +if (app('config')->get('iranpayment.test.active', false) && + app('config')->get('iranpayment.test.url') !== null) { + Route::post( + app('config')->get('iranpayment.test.url'), + 'Dena\IranPayment\Gateways\Test\TestGatewayController@paymentView' + )->name('iranpayment.test.pay'); +} diff --git a/src/IranPayment.php b/src/IranPayment.php index 55184b3..a9bb069 100644 --- a/src/IranPayment.php +++ b/src/IranPayment.php @@ -94,8 +94,10 @@ public function setGateway($gateway): self break; case self::TEST: case TestGateway::class: - if (app('config')->get('app.env', 'production') == 'production') + if (app('config')->get('app.env', 'production') === 'production' || + !app('config')->get('iranpayment.test.active', false)) { throw GatewayNotFoundException::productionUnavailableGateway(); + } $this->gateway = new TestGateway; break; @@ -142,7 +144,8 @@ public function getSupportedGateways(): array self::NOVINOPAY, ]; - if (app('config')->get('app.env', 'production') !== 'production') { + if (app('config')->get('app.env', 'production') !== 'production' && + app('config')->get('iranpayment.test.active', false)) { $gateways[] = self::TEST; } diff --git a/src/Traits/IranPaymentDatabase.php b/src/Traits/IranPaymentDatabase.php index ca0bb7c..20d8cc7 100644 --- a/src/Traits/IranPaymentDatabase.php +++ b/src/Traits/IranPaymentDatabase.php @@ -4,6 +4,13 @@ trait IranPaymentDatabase { + /** + * The table associated with the model. + * + * @var string + */ + protected $table; + /** * IranPayment Table Name variable *