├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── config
└── larapay.php
├── database
└── migrations
│ └── create_larapay_transaction_table.php.stub
├── src
├── Adapter
│ ├── AdapterAbstract.php
│ ├── AdapterInterface.php
│ ├── Exception.php
│ ├── Idpay.php
│ ├── Idpay
│ │ └── Exception.php
│ ├── Mellat.php
│ ├── Mellat
│ │ └── Exception.php
│ ├── Nextpay.php
│ ├── Nextpay
│ │ ├── Exception.php
│ │ └── Helper.php
│ ├── Parsian.php
│ ├── Parsian
│ │ └── Exception.php
│ ├── Pasargad.php
│ ├── Pasargad
│ │ ├── Helper.php
│ │ ├── PasargadResult.php
│ │ ├── RSA.php
│ │ ├── RSAProcessor.php
│ │ └── certificate.xml
│ ├── PayIr
│ │ ├── Exception.php
│ │ └── Helper.php
│ ├── Payir.php
│ ├── Saderat.php
│ ├── Saderat
│ │ ├── Exception.php
│ │ └── Helper.php
│ ├── Saman.php
│ ├── Saman
│ │ └── Exception.php
│ ├── Zarinpal.php
│ ├── Zarinpal
│ │ └── Exception.php
│ ├── Zibal.php
│ └── Zibal
│ │ ├── Exception.php
│ │ └── Helper.php
├── Contracts
│ └── LarapayTransaction.php
├── Exception.php
├── Exceptions
│ ├── EmptyAmountException.php
│ ├── FailedReverseTransactionException.php
│ ├── FailedTransactionException.php
│ └── TransactionNotFoundException.php
├── Facades
│ └── Larapay.php
├── Factory.php
├── LarapayServiceProvider.php
├── Models
│ ├── Enum
│ │ ├── Bank.php
│ │ └── Sharing.php
│ ├── LarapayTransaction.php
│ └── Traits
│ │ └── OnlineTransactionTrait.php
├── Payable.php
└── Transaction
│ └── TransactionInterface.php
├── translations
├── en
│ └── larapay.php
└── fa
│ └── larapay.php
└── views
├── idpay-form.blade.php
├── mellat-form.blade.php
├── nextpay-form.blade.php
├── parsian-form.blade.php
├── pasargad-form.blade.php
├── payir-form.blade.php
├── sadad-form.blade.php
├── saderat-form.blade.php
├── saman-form.blade.php
├── zarinpal-form.blade.php
└── zibal-form.blade.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | /vendor
3 | composer.lock
4 | phpunit.xml
5 |
6 | *.DS_Store
7 | .DS_Store
8 | # Thumbnails
9 | ._*
10 |
11 | # Files that might appear in the root of a volume
12 | .DocumentRevisions-V100
13 | .fseventsd
14 | .Spotlight-V100
15 | .TemporaryItems
16 | .Trashes
17 | .VolumeIcon.icns
18 | .com.apple.timemachine.donotpresent
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | # Laravel Online Payment Module v1.0.0 for Laravel 5
2 |
3 | ## Laravel
4 |
5 |
6 | The MIT License (MIT)
7 |
8 | Copyright (c) 2016 Aboozar Ghaffari
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Iranian Online Payment Component
2 | Online Payment Module handler for Laravel 5+ known as LaraPay component completely compatible with [BankTest](http://banktest.ir) sandbox.
3 | Larapay integrated all Iranian payment gateways into one component.
4 |
5 | Here are a few short examples of what you can do:
6 | * create new transaction form your order model and generate bank form
7 | ```php
8 | $transaction = $order->createTransaction(Bank::MELLAT);
9 | $form = $transaction->generateForm();
10 | ```
11 | * handle gateway callback (verify/settle/...)
12 | ```php
13 | $transaction = Larapay::verifyTransaction($request);
14 | //if the gateway supports reverse method
15 | $transaction->reverseTransaction();
16 | $order = $transaction->model;
17 | ```
18 | * get order transaction information
19 | ```php
20 | $allTransactions = $order->transations;
21 | $accomplishedTransactions = $order->accomplishedTransactions;
22 | $isPaid = $order->isPaid();
23 | $paidAmount = $order->paidAmount();
24 | ```
25 |
26 | ## Currenctly supports:
27 |
28 | - Mellat Bank Gateway - درگاه بانک ملت لاراول
29 | - Saman Bank Gateway - درگاه بانک سامان لاراول
30 | - Saderat/Sepehr Pay Bank Gateway - درگاه بانک صادرات / سپهر
31 | - Pasargad Bank Gateway - درگاه بانک پاسارگاد لاراول
32 | - Parsian Bank Gateway - درگاه بانک پارسیان لاراول
33 | - Melli/Sadad Bank Gateway (Sadad) - درگاه بانک ملی / سداد لاراول
34 | - Pay.ir Gateway / درگاه پرداخت پی
35 | - Zarinpal Gateway / درگاه پرداخت زرین پال
36 | - IDPay Gateway / درگاه آیدی پی
37 | - Zibal Gateway / درگاه زیبال
38 | - nextpay Gateway / درگاه نکست پی
39 |
40 | - ...
41 | - Other gateways, coming soon... لطفا شما هم در تکمیل پکیج مشارکت کنید
42 |
43 | #### But what is Banktest sandbox?
44 | - [BankTest](http://banktest.ir) is a sandbox service for all Iranian online payment gateways
45 | - [بانک تست](http://banktest.ir) یک سرویس شبیه ساز درگاه های پرداخت آنلاین ایرانی برای اهداف توسعه و تست نرم افزار می باشد
46 |
47 |
48 | ## Requirements
49 | Larapay Version 6+ required PHP 7+
50 |
51 | ## Installation
52 | 1. Installing via composer
53 |
54 | ```bash
55 | composer require php-monsters/laravel-online-payment
56 | ```
57 | 2. Add package service provider to your app service providers (only for Laravel < 5.5):
58 |
59 | ```php
60 | PhpMonsters\Larapay\LarapayServiceProvider::class,
61 | PhpMonsters\Log\XLogServiceProvider::class,
62 | ```
63 | 3. Add package alias to your app aliases (only for Laravel < 5.5):
64 |
65 | ```php
66 | 'Larapay' => PhpMonsters\Larapay\Facades\Larapay::class,
67 | 'XLog' => PhpMonsters\Log\Facades\XLog::class,
68 | ```
69 | 4. Publish package assets and configs
70 |
71 | ```bash
72 | php artisan vendor:publish --provider="PhpMonsters\Larapay\LarapayServiceProvider"
73 | ```
74 |
75 | 5. Run migration
76 | ```bash
77 | php artisan migrate
78 | ```
79 |
80 | ## Configuration
81 | If you complete installation step correctly, you can find Larapay config file as larapay.php in you project config file.
82 |
83 | For sandbox (banktest) you should set ```LARAPAY_MODE=development``` in your .env file otherwise set ```LARAPAY_MODE=production```
84 |
85 | If you choose development mode, Larapay use banktest.ir as it's payment gateway.
86 |
87 | Set your gateway(s) configs in your .env file. Here are some example:
88 | ```ini
89 | LARAPAY_MODE=development
90 |
91 | SAMAN_MERCHANT_ID=bmcf****
92 | SAMAN_MERCHANT_PASS=98221***
93 |
94 | MELLAT_USERNAME=user***
95 | MELLAT_PASSWORD=80714***
96 | MELLAT_TERMINAL_ID=747
97 | ```
98 |
99 | ### Setup callback route
100 | you should create a route for handling callback from bank and set your route name in .env
101 |
102 | For example create a POST route in routes folder, web.php like this:
103 | ```php
104 | Route::post('payment/callback', 'YourController@handleCallback')->name('payment.callback');
105 | ```
106 |
107 | then set the route name in .env file:
108 |
109 | ```ini
110 | LARAPAY_PAYMENT_CALLBACK=payment.callback
111 | ```
112 |
113 |
114 | ## Usage
115 |
116 | ### Prepare payable model
117 |
118 | Use `Payable` trait in your order model or any other model like user which will get payment feature and implement it.
119 |
120 | You can impalement getAmount() method to return `Iranian Rail` amount of your model.
121 | ```php
122 | use PhpMonsters\Larapay\Payable;
123 |
124 | class Order extends Model
125 | {
126 | use Payable;
127 |
128 | public function getAmount(){
129 | return intval($this->amount) * 10;
130 | }
131 |
132 | }
133 | ```
134 |
135 | Now you just have 3 steps to complete your payment:
136 |
137 | ### 1- create transaction
138 |
139 | In your bank controller create a transaction for your order and generate bank for to transfer user to payment gateway.
140 | ```php
141 | use PhpMonsters\Larapay\Models\Enum\Bank;
142 |
143 | class BankController extends Controller
144 | {
145 | public function index()
146 | {
147 | //your logic and prepare your order
148 | // ...
149 |
150 | //if you implement getAmount() method you can set amount to null
151 | $amount = 1200000; //Rial at least 1000
152 | //order or user description
153 | $description = 'I pay my order with Larapay <3';
154 | //some additional data that you need store on transaction
155 | $additionalData = [];
156 | //create transaction
157 | $transaction = $order->createTransaction(Bank::MELLAT, $amount, $description, $additionalData);
158 |
159 | //auto submit bank form and transfer user to gateway
160 | $autoSubmit = true;
161 | //callback route name. if you set it on your .env file you can set this to null
162 | $callbackRouteName = 'payment.callback';
163 | //adapter config
164 | $adapterConfig = [];
165 | //generate bank form
166 | $form = $transaction->generateForm($autoSubmit, $callbackRouteName, $adapterConfig);
167 |
168 | return view('go-to-bank',[
169 | 'form' => $form,
170 | ]);
171 | }
172 | }
173 | ```
174 |
175 | ### 2- show bank transfer form
176 |
177 | Now you can show you `$form` in your `go-to-bank` view file:
178 | ```php
179 |
180 | {!! $form !!}
181 |
182 | ```
183 |
184 | You can modify bank forms in:
185 | ```
186 | resources/views/vendor/larapy
187 | ```
188 |
189 | ### 3- handle callback
190 |
191 | After payment, bank call you callback route
192 |
193 | ```php
194 | use Illuminate\Http\Request;
195 | use PhpMonsters\Larapay\Facades\Larapay;
196 |
197 | class YourController extends Controller
198 | {
199 | public function handleCallback(Request $request)
200 | {
201 | try{
202 | $adapterConfig = [];
203 | $transaction = Larapay::verifyTransaction($request, $adapterConfig);
204 | $order = $transaction->model;
205 | //transaction done. payment is successful
206 | } catch (\Exception $e){
207 | // transaction not complete!!!
208 | // show error to your user
209 | }
210 | }
211 | }
212 | ```
213 |
214 | If you want to revers transaction and your bank support it, you can do this way:
215 | ```php
216 | $transaction->reverseTransaction();
217 | ```
218 |
219 | ## Methods
220 |
221 | ### Methods available in `Paybel` trait and your order model:
222 |
223 | * `$order->transactions` : get all transactions of this model
224 | * `$order->accomplishedTransactions`: get all accomplished transactions
225 | * `$order->isPaid()`: return true if this model has at least one accomplished transaction
226 | * `$order->paidAmount()`: return sum of accomplished transactions amount in Rial
227 | * `$order->createTransaction(
228 | $paymentGateway,
229 | $amount = null,
230 | $description = null,
231 | array $additionalData = []
232 | )`: create a transaction.
233 |
234 |
235 | ### Methods available in `LarapayTransaction` model:
236 |
237 | * `$transaction->model`: return the model that create this transaction. for example `$order`
238 | * `$transaction->reverseTransaction()`: reverse transaction and get back money to user. (if bank support reverse transaction)
239 | * `$transaction->generateForm($autoSubmit = false, $callback = null)`: generate bank transfer form
240 | * `$transaction->gatewayHandler()`: get gatewayHandler for advance use.
241 |
242 | ### Fields available in `LarapayTransaction` model:
243 | * `id`
244 | * `created_at`
245 | * `updated_at`
246 |
247 | Status in boolean:
248 | * `accomplished`
249 | * `verified`
250 | * `after_verified`
251 | * `reversed`
252 | * `submitted`
253 | * `approved`
254 | * `rejected`
255 |
256 | Gate information:
257 | * `payment_method`
258 | * `bank_order_id`
259 | * `gate_name`
260 | * `gate_refid`
261 | * `gate_status`
262 | * `extra_params`
263 | * `additional_data`
264 |
265 | Order information:
266 | * `amount`
267 | * `description`
268 | * `paid_at`
269 |
270 |
271 | ## LarapayTransaction
272 |
273 | You can use `LarapayTransaction` model to find your transaction:
274 |
275 | ```php
276 | use PhpMonsters\Larapay\Models\LarapayTransaction;
277 |
278 | public function getTransaction($transactionId){
279 |
280 | //find single transaction by transaction id
281 | $transaction = LarapayTransaction::find($transactionId);
282 |
283 | //get all accomplished transaction
284 | $accomplishedTransactions = LarapayTransaction::where('accomplished',true)->get();
285 |
286 | //get all reversed transaction
287 | $reversedTransactions = LarapayTransaction::where('reversed',true)->get();
288 | }
289 | ```
290 |
291 | This class use SoftDeletes. you can call delete() on your transaction model to softDelete it or forceDelete() to truly remove it from your database.
292 |
293 | ## Security
294 |
295 | If you discover any security related issues, please email a6oozar@gmail.com or milad.kian@gmail.com instead of using the issue tracker.
296 |
297 | ## Team
298 |
299 | This component is developed by the following person(s) and a bunch of [awesome contributors](https://github.com/php-monsters/laravel-online-payment/graphs/contributors).
300 |
301 | [](https://github.com/samuraee) | [](https://github.com/miladkian) | [](https://github.com/sinamiandashti) | [](https://github.com/xshaan)
302 | | --- | --- | --- | --- |
303 | [Aboozar Ghaffari](https://github.com/samuraee) | [Milad Kianmehr](https://github.com/miladkian) | [Sina Miandashti](https://github.com/sinamiandashti) | [XShaan](https://github.com/xshaan)
304 |
305 |
306 | ## Support This Project
307 |
308 | Please contribute in package completion. This is the best support.
309 |
310 | ## License
311 |
312 | The Laravel Online Payment Module is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
313 |
314 |
315 |
316 |
317 |
318 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-monsters/laravel-online-payment",
3 | "description": "Iranian payment gateways handler for laravel applications",
4 | "keywords": ["payment","shetab", "bank", "online payment", "gateway", "iran"],
5 | "type": "library",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Aboozar Ghaffari ",
10 | "email": "aboozar.ghf@gmail.com"
11 | },
12 | {
13 | "name": "Milad Kianmehr",
14 | "email": "milad.kian@gmail.com"
15 | }
16 | ],
17 | "require": {
18 | "php": ">=7.4",
19 | "ext-soap" : "*",
20 | "ext-json": "*",
21 | "ext-bcmath": "*",
22 | "ext-simplexml": "*",
23 | "illuminate/contracts": ">=7.0",
24 | "illuminate/database": ">=7.0",
25 | "illuminate/http": ">=7.0",
26 | "illuminate/routing": ">=7.0",
27 | "illuminate/support": ">=7.0",
28 | "illuminate/view": ">=7.0",
29 | "php-monsters/laravel-xlog": "^1.3.0"
30 | },
31 | "require-dev": {
32 | "mockery/mockery": "^1.0",
33 | "orchestra/testbench": "^3.8|^4.0|^5.0",
34 | "phpunit/phpunit": "^7.5|^8.0"
35 | },
36 | "autoload": {
37 | "psr-4": {
38 | "PhpMonsters\\Larapay\\": "src/"
39 | }
40 | },
41 | "extra": {
42 | "laravel": {
43 | "providers": [
44 | "PhpMonsters\\Larapay\\LarapayServiceProvider"
45 | ],
46 | "aliases": {
47 | "Larapay": "PhpMonsters\\Larapay\\Facades\\Larapay"
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/config/larapay.php:
--------------------------------------------------------------------------------
1 | env('LARAPAY_MODE', 'production'),
18 |
19 | /*
20 | |--------------------------------------------------------------------------
21 | | ready to serve gateways
22 | |--------------------------------------------------------------------------
23 | |
24 | | specifies ready to serve gateways.
25 | | gateway characters are case sensitive and should be exactly same as their folder name.
26 | | eg, "Asanpay" is correct not "AsanPay" or "asanpay"
27 | | the gateways list is comma separated
28 | |
29 | */
30 | 'gateways' => env('LARAPAY_GATES', 'Mellat,Saman,Pasargad,Parsian,ZarinPal,Idpay,Payir,Saderat,Zibal,Nextpay'),
31 |
32 | /*
33 | |--------------------------------------------------------------------------
34 | | Mellat gateway configuration
35 | |--------------------------------------------------------------------------
36 | */
37 | 'mellat' => [
38 | 'username' => env('MELLAT_USERNAME', ''),
39 | 'password' => env('MELLAT_PASSWORD', ''),
40 | 'terminal_id' => env('MELLAT_TERMINAL_ID', ''),
41 | ],
42 |
43 | /*
44 | |--------------------------------------------------------------------------
45 | | Parsian gateway configuration
46 | |--------------------------------------------------------------------------
47 | */
48 | 'parsian' => [
49 | 'pin' => env('PARSIAN_PIN', ''),
50 | 'timeout' => env('PARSIAN_TIMEOUT', 15),
51 |
52 | ],
53 | /*
54 | |--------------------------------------------------------------------------
55 | | Pasargad gateway configuration
56 | |--------------------------------------------------------------------------
57 | */
58 | 'pasargad' => [
59 | 'terminalId' => env('PASARGAD_TERMINAL_ID', ''),
60 | 'merchantId' => env('PASARGAD_MERCHANT_ID', ''),
61 | 'certificate_path' => storage_path(env('PASARGAD_CERT_PATH', 'payment/pasargad/certificate.xml')),
62 | ],
63 |
64 | /*
65 | |--------------------------------------------------------------------------
66 | | Sadad gateway configuration
67 | |--------------------------------------------------------------------------
68 | */
69 | 'sadad' => [
70 | 'merchant' => env('SADAD_MERCHANT', ''),
71 | 'transaction_key' => env('SADAD_TRANS_KEY', ''),
72 | 'terminal_id' => env('SADAD_TERMINAL_ID', ''),
73 | ],
74 |
75 | /*
76 | |--------------------------------------------------------------------------
77 | | Saderat - Sepehr Pay gateway configuration
78 | |--------------------------------------------------------------------------
79 | */
80 | 'saderat' => [
81 | 'terminalId' => env('SADERAT_TERMINAL_ID', ''),
82 | 'callbackUrl' => env('SADERAT_CALLBACK_URL', ''),
83 | 'description' => env('SADERAT_DESCRIPTION', 'powered-by-Larapay saderat(sepehr)'),
84 | ],
85 |
86 | /*
87 | |--------------------------------------------------------------------------
88 | | Saman gateway configuration
89 | |--------------------------------------------------------------------------
90 | */
91 | 'saman' => [
92 | 'merchant_id' => env('SAMAN_MERCHANT_ID', ''),
93 | 'merchant_pass' => env('SAMAN_MERCHANT_PASS', ''),
94 | 'with_token' => 1,
95 | ],
96 |
97 | /*
98 | |--------------------------------------------------------------------------
99 | | Zarinpal gateway configuration
100 | |--------------------------------------------------------------------------
101 | |
102 | | types: acceptable values --- zarin-gate or normal
103 | | server: acceptable values --- germany or iran or test
104 | |
105 | */
106 | 'zarinpal' => [
107 | 'merchant_id' => env('ZARINPAL_MERCHANT_ID', ''),
108 | 'type' => env('ZARINPAL_TYPE', 'zarin-gate'),
109 | 'callback_url' => env('ZARINPAL_CALLBACK_URL', ''),
110 | 'server' => env('ZARINPAL_SERVER', 'germany'),
111 | 'email' => env('ZARINPAL_EMAIL', ''),
112 | 'mobile' => env('ZARINPAL_MOBILE', '09xxxxxxxxx'),
113 | 'description' => env('ZARINPAL_DESCRIPTION', 'powered-by-Larapay'),
114 | ],
115 |
116 | /*
117 | |--------------------------------------------------------------------------
118 | | Pay.ir gateway configuration
119 | |--------------------------------------------------------------------------
120 | |
121 | | api: For the sandbox gateway, set API to 'test'
122 | |
123 | */
124 | 'payir' => [
125 | 'api' => env('PAY_IR_API_KEY', ''),
126 | ],
127 |
128 | /*
129 | |--------------------------------------------------------------------------
130 | | Idpay gateway configuration
131 | |--------------------------------------------------------------------------
132 | |
133 | | types: acceptable values --- normal
134 | |
135 | */
136 | 'idpay' => [
137 | 'merchant_id' => env('IDPAY_MERCHANT_ID', ''),
138 | 'type' => env('IDPAY_TYPE', 'normal'),
139 | 'callback_url' => env('IDPAY_CALLBACK_URL', ''),
140 | 'email' => env('IDPAY_EMAIL', ''),
141 | 'mobile' => env('IDPAY_MOBILE', '09xxxxxxxxx'),
142 | 'description' => env('IDPAY_DESCRIPTION', 'powered-by-Larapay'),
143 | ],
144 |
145 | /*
146 | |--------------------------------------------------------------------------
147 | | Zibal gateway configuration
148 | |--------------------------------------------------------------------------
149 | |
150 | | merchant_id: For the sandbox gateway, set merchant_id to 'zibal'
151 | |
152 | */
153 | 'zibal' => [
154 | 'merchant_id' => env('ZIBAL_MERCHANT_ID', ''),
155 | 'type' => env('ZIBAL_TYPE', 'normal'),
156 | 'callback_url' => env('ZIBAL_CALLBACK_URL', ''),
157 | 'email' => env('ZIBAL_EMAIL', ''),
158 | 'mobile' => env('ZIBAL_MOBILE', '09xxxxxxxxx'),
159 | 'description' => env('ZIBAL_DESCRIPTION', 'powered-by-Larapay'),
160 | ],
161 |
162 | /*
163 | |--------------------------------------------------------------------------
164 | | Nextpay gateway configuration
165 | |--------------------------------------------------------------------------
166 | |
167 | */
168 | 'nextpay' => [
169 | 'api_key' => env('NEXTPAY_MERCHANT_ID', ''),
170 | 'type' => env('NEXTPAY_TYPE', 'normal'),
171 | 'callback_url' => env('NEXTPAY_CALLBACK_URL', ''),
172 | 'email' => env('NEXTPAY_EMAIL', ''),
173 | 'mobile' => env('NEXTPAY_MOBILE', '09xxxxxxxxx'),
174 | 'description' => env('NEXTPAY_DESCRIPTION', 'powered-by-Larapay'),
175 | ],
176 |
177 | /*
178 | |--------------------------------------------------------------------------
179 | | SoapClient Options
180 | |--------------------------------------------------------------------------
181 | |
182 | | useOptions: true/false
183 | | options: soapClient Options
184 | |
185 | */
186 | 'soap' => [
187 | 'useOptions' => env('SOAP_HAS_OPTIONS', false),
188 | 'options' => [
189 | 'proxy_host' => env('SOAP_PROXY_HOST', ''),
190 | 'proxy_port' => env('SOAP_PROXY_PORT', ''),
191 | 'stream_context' => stream_context_create(
192 | [
193 | 'ssl' => [
194 | 'verify_peer' => false,
195 | 'verify_peer_name' => false,
196 | ],
197 | ]
198 | ),
199 | ],
200 | ],
201 | /*
202 | |--------------------------------------------------------------------------
203 | | Route name for handle payment callback
204 | |--------------------------------------------------------------------------
205 | */
206 |
207 | 'payment_callback' => env('LARAPAY_PAYMENT_CALLBACK' , '')
208 | ];
209 |
--------------------------------------------------------------------------------
/database/migrations/create_larapay_transaction_table.php.stub:
--------------------------------------------------------------------------------
1 | increments('id');
19 |
20 | //morph to model like order or user
21 | $table->morphs('model');
22 |
23 | //status
24 | $table->boolean('accomplished')->default(false);
25 | $table->boolean('verified')->default(false);
26 | $table->boolean('after_verified')->default(false);
27 | $table->boolean('reversed')->default(false);
28 | $table->boolean('submitted')->default(false);
29 | $table->boolean('approved')->default(false);
30 | $table->boolean('rejected')->default(false);
31 |
32 | $table->string('payment_method', 255)->default('ONLINE');
33 |
34 | $table->string('bank_order_id', 20)->nullable(); // gateway order ID
35 |
36 | $table->string('gate_name', 20)->nullable();
37 | $table->string('gate_refid', 50)->nullable();
38 | $table->string('gate_status')->nullable();
39 |
40 | $table->text('description')->nullable();
41 | $table->bigInteger('amount')->default(0);
42 |
43 | if (env('DB_CONNECTION') == 'pgsql') { // for POSTGRESQL
44 | $table->jsonb('extra_params')->nullable()->default('{}');
45 | $table->jsonb('additional_data')->nullable()->default('{}');
46 | $table->jsonb('sharing')->nullable()->default('{}');
47 | } else { // for MYSQL
48 | $table->jsonb('extra_params')->nullable();
49 | $table->jsonb('additional_data')->nullable();
50 | $table->jsonb('sharing')->nullable();
51 | }
52 |
53 | $table->dateTime('paid_at')->nullable();
54 | $table->timestamps();
55 | $table->softDeletes();
56 | });
57 | }
58 |
59 | /**
60 | * Reverse the migrations.
61 | */
62 | public function down()
63 | {
64 | Schema::dropIfExists('larapay_transactions');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Adapter/AdapterAbstract.php:
--------------------------------------------------------------------------------
1 | transaction = $transaction;
67 |
68 | $this->setParameters($configs);
69 | $this->init();
70 | }
71 |
72 | /**
73 | * Adapter`s init method that called after construct method
74 | */
75 | public function init() { }
76 |
77 | /**
78 | * @param string $key
79 | * @param mixed $val
80 | */
81 | public function __set($key, $val)
82 | {
83 | $key = strtolower($key);
84 | $this->parameters[$key] = trim($val);
85 | }
86 |
87 | /**
88 | * @param string $key
89 | *
90 | * @return mixed|null
91 | */
92 | public function __get($key)
93 | {
94 | $key = strtolower($key);
95 | return isset($this->parameters[$key]) ? trim($this->parameters[$key]) : null;
96 | }
97 |
98 |
99 | /**
100 | * @return TransactionInterface
101 | */
102 | public function getTransaction(): TransactionInterface
103 | {
104 | return $this->transaction;
105 | }
106 |
107 | /**
108 | * @param array $parameters
109 | *
110 | * @return $this
111 | */
112 | public function setParameters(array $parameters = []): AdapterInterface
113 | {
114 | foreach ($parameters as $key => $value) {
115 | if($key === 'customer_card_number'){
116 | continue;
117 | }
118 | $key = strtolower($key);
119 | $this->parameters[$key] = is_array($value) ? $value : trim($value);
120 | }
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * @param string $key
127 | *
128 | * @return mixed|null
129 | */
130 | public function getParameter($key)
131 | {
132 | $key = strtolower($key);
133 | return isset($this->parameters[$key]) ? trim($this->parameters[$key]) : null;
134 | }
135 |
136 | /**
137 | * @return array
138 | */
139 | public function getParameters(): array
140 | {
141 | return $this->parameters;
142 | }
143 |
144 | /**
145 | * @return string
146 | */
147 | public function form(): string
148 | {
149 | return $this->generateForm();
150 | }
151 |
152 | /**
153 | * @return true
154 | */
155 | public function verify(): bool
156 | {
157 | return $this->verifyTransaction();
158 | }
159 |
160 | /**
161 | * @return bool
162 | */
163 | public function afterVerify(): bool
164 | {
165 | $this->getTransaction()->setAfterVerified(); // عملیات پیش فرض در صورت عدم نیاز
166 |
167 | return true;
168 | }
169 |
170 | /**
171 | * @return bool
172 | */
173 | public function reverse(): bool
174 | {
175 | return $this->reverseTransaction();
176 | }
177 |
178 | /**
179 | * check for required parameters
180 | *
181 | * @param array $parameters
182 | *
183 | * @throws Exception
184 | */
185 | protected function checkRequiredParameters(array $parameters)
186 | {
187 | foreach ($parameters as $parameter) {
188 | $parameter = strtolower($parameter);
189 |
190 | if (!array_key_exists($parameter, $this->parameters) || trim($this->parameters[$parameter]) == "") {
191 | throw new Exception("Parameters array must have a not null value for key: '$parameter'");
192 | }
193 | }
194 | }
195 |
196 | /**
197 | * @return string
198 | */
199 | protected function getWSDL(): string
200 | {
201 | if (config('larapay.mode') === 'production') {
202 | return $this->WSDL;
203 | } else {
204 | return $this->testWSDL;
205 | }
206 | }
207 |
208 | /**
209 | * @return string
210 | */
211 | protected function getEndPoint(): string
212 | {
213 | if (config('larapay.mode') === 'production') {
214 | return $this->endPoint;
215 | } else {
216 | return $this->testEndPoint;
217 | }
218 | }
219 |
220 | /**
221 | * @param array $options
222 | *
223 | * @deprecated
224 | *
225 | * 'login' => config('api.basic.username'),
226 | * 'password' => config('api.basic.password'),
227 | * 'proxy_host' => 'localhost',
228 | * 'proxy_port' => '8080'
229 | *
230 | */
231 | public function setSoapOptions(array $options = [])
232 | {
233 | XLog::debug('soap options set', $options);
234 | $this->soapOptions = $options;
235 | }
236 |
237 | /**
238 | * @return array
239 | */
240 | protected function getSoapOptions(): array
241 | {
242 | return $this->soapOptions;
243 | }
244 |
245 |
246 | /**
247 | * @return SoapClient
248 | * @throws \SoapFault
249 | */
250 | protected function getSoapClient(): SoapClient
251 | {
252 | return new SoapClient($this->getWSDL(), $this->getSoapOptions());
253 | }
254 |
255 | /**
256 | * @return mixed
257 | * @throws Exception
258 | */
259 | public function getGatewayReferenceId(): string
260 | {
261 | throw new Exception(__METHOD__ . ' not implemented');
262 | }
263 |
264 | /**
265 | * @return bool
266 | */
267 | public function reverseSupport(): bool
268 | {
269 | return $this->reverseSupport;
270 | }
271 |
272 | /**
273 | * @return bool
274 | */
275 | public function canContinueWithCallbackParameters(): bool
276 | {
277 | return true;
278 | }
279 |
280 | /**
281 | * @param $obj
282 | *
283 | * @return array
284 | */
285 | protected function obj2array($obj): array
286 | {
287 | $out = [];
288 | foreach ($obj as $key => $val) {
289 | switch (true) {
290 | case is_object($val):
291 | $out[$key] = $this->obj2array($val);
292 | break;
293 | case is_array($val):
294 | $out[$key] = $this->obj2array($val);
295 | break;
296 | default:
297 | $out[$key] = $val;
298 | }
299 | }
300 |
301 | return $out;
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/src/Adapter/AdapterInterface.php:
--------------------------------------------------------------------------------
1 | adapter );
27 | $gate = end($gate);
28 | $gate = strtolower($gate);
29 |
30 | switch ($message)
31 | {
32 | case is_numeric($message): {
33 | $code = $message;
34 | $message = 'larapay::larapay.'.$gate.'.errors.error_' . str_replace('-', '_', strval($message)); // fetch message from translation file
35 | break;
36 | }
37 |
38 | case preg_match('/^larapay::/', $message) == 1 : {
39 | $code = static::UNHANDLED_ERR;
40 | $message = trans(strval($message)); // fetch message from translation file
41 | break;
42 | }
43 | }
44 |
45 | parent::__construct($message, $code, $previous);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Adapter/Idpay.php:
--------------------------------------------------------------------------------
1 | requestToken();
32 |
33 | return [
34 | 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
35 | ];
36 | }
37 |
38 | /**
39 | * @return bool
40 | */
41 | public function canContinueWithCallbackParameters(): bool
42 | {
43 | if (!empty($this->transaction['gate_refid'])) {
44 | return true;
45 | }
46 |
47 | return false;
48 | }
49 |
50 | public function getGatewayReferenceId(): string
51 | {
52 | $this->checkRequiredParameters([
53 | 'merchant_id',
54 | ]);
55 |
56 | return strval($this->transaction['gate_refid']);
57 | }
58 |
59 | /**
60 | * @return string
61 | * @throws Exception
62 | * @throws \PhpMonsters\Larapay\Adapter\Exception
63 | */
64 | protected function generateForm(): string
65 | {
66 | $authority = $this->requestToken();
67 |
68 | $form = view('larapay::idpay-form', [
69 | 'endPoint' => strtr($this->getEndPoint(), ['{order-id}' => $authority]),
70 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
71 | 'autoSubmit' => boolval($this->auto_submit),
72 | ]);
73 |
74 | return $form->__toString();
75 | }
76 |
77 | /**
78 | * @return string
79 | * @throws Exception
80 | * @throws \PhpMonsters\Larapay\Adapter\Exception
81 | */
82 | protected function requestToken(): string
83 | {
84 | if ($this->getTransaction()->checkForRequestToken() === false) {
85 | throw new Exception('larapay::larapay.could_not_request_payment');
86 | }
87 |
88 | $this->checkRequiredParameters([
89 | 'order_id',
90 | 'amount',
91 | 'redirect_url',
92 | ]);
93 |
94 | $sendParams = [
95 | 'order_id' => $this->getTransaction()->bank_order_id,
96 | 'amount' => intval($this->amount),
97 | 'desc' => $this->description ? $this->description : '',
98 | 'mail' => $this->email ? $this->email : '',
99 | 'phone' => $this->mobile ? $this->mobile : '',
100 | 'callback' => $this->redirect_url,
101 | ];
102 |
103 | $header = [
104 | 'Content-Type: application/json',
105 | 'X-API-KEY:'.$this->merchant_id,
106 | 'X-SANDBOX:'.$this->getSandbox()
107 | ];
108 | try {
109 | XLog::debug('PaymentRequest call', $sendParams);
110 | $ch = curl_init();
111 | curl_setopt($ch, CURLOPT_URL, $this->WSDL);
112 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($sendParams));
113 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
114 | curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
115 | $response = curl_exec($ch);
116 | $ch_error = curl_error($ch);
117 | curl_close($ch);
118 | $result = json_decode($response);
119 |
120 | if (isset($result->error_code)) {
121 | throw new Exception($result->error_code);
122 | }
123 |
124 | XLog::info('PaymentRequest response', $this->obj2array($result));
125 | $this->getTransaction()->setGatewayToken(strval($result->id)); // update transaction reference id
126 | return $result->id;
127 | } catch (\Exception $e) {
128 | throw new Exception($e->getMessage());
129 | };
130 | }
131 |
132 | public function getSandbox(): string
133 | {
134 | if (config('larapay.mode') === 'production') {
135 | return "0";
136 | } else {
137 | return "1";
138 | }
139 | }
140 |
141 | /**
142 | * @return bool
143 | * @throws Exception
144 | * @throws \PhpMonsters\Larapay\Adapter\Exception
145 | */
146 | protected function verifyTransaction(): bool
147 | {
148 | if ($this->getTransaction()->checkForVerify() === false) {
149 | throw new Exception('larapay::larapay.could_not_verify_payment');
150 | }
151 |
152 | $this->checkRequiredParameters([
153 | 'merchant_id',
154 | ]);
155 |
156 | $sendParams = [
157 | 'id' => $this->getTransaction()->gate_refid,
158 | 'order_id' => $this->getTransaction()->bank_order_id,
159 | ];
160 |
161 | $header = [
162 | 'Content-Type: application/json',
163 | 'X-API-KEY:'.$this->merchant_id,
164 | 'X-SANDBOX:'.$this->getSandbox()
165 | ];
166 |
167 | try {
168 | $ch = curl_init();
169 | curl_setopt($ch, CURLOPT_URL, $this->endPointVerify);
170 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($sendParams));
171 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
172 | curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
173 | $response = curl_exec($ch);
174 | $ch_error = curl_error($ch);
175 | curl_close($ch);
176 | XLog::debug('PaymentVerification call', $sendParams);
177 | $result = json_decode($response);
178 | XLog::info('PaymentVerification response', $this->obj2array($result));
179 |
180 | if (isset($result->status)) {
181 | if ($result->status == 100 || $result->status == 101) {
182 | $this->getTransaction()->setVerified();
183 | $this->getTransaction()->setReferenceId((string) $result->id);
184 | return true;
185 | } else {
186 | throw new Exception($result->status);
187 | }
188 | } else {
189 | throw new Exception($result->error_code);
190 | }
191 | } catch (\Exception $e) {
192 | throw new Exception($e->getMessage());
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/src/Adapter/Idpay/Exception.php:
--------------------------------------------------------------------------------
1 | getTransaction()->checkForRequestToken() === false) {
32 | throw new Exception('larapay::larapay.could_not_request_payment');
33 | }
34 |
35 | $this->checkRequiredParameters([
36 | 'terminal_id',
37 | 'username',
38 | 'password',
39 | 'order_id',
40 | 'amount',
41 | 'redirect_url',
42 | ]);
43 |
44 | $sendParams = [
45 | 'terminalId' => intval($this->terminal_id),
46 | 'userName' => $this->username,
47 | 'userPassword' => $this->password,
48 | 'orderId' => intval($this->order_id),
49 | 'amount' => intval($this->amount),
50 | 'localDate' => $this->local_date ? $this->local_date : date('Ymd'),
51 | 'localTime' => $this->local_time ? $this->local_time : date('His'),
52 | 'additionalData' => $this->additional_data ? $this->additional_data : '',
53 | 'callBackUrl' => $this->redirect_url,
54 | 'payerId' => intval($this->payer_id),
55 | ];
56 |
57 | try {
58 | $soapClient = $this->getSoapClient();
59 |
60 | XLog::debug('bpPayRequest call', $sendParams);
61 |
62 | $response = $soapClient->bpPayRequest($sendParams);
63 |
64 | if (isset($response->return)) {
65 | XLog::info('bpPayRequest response', ['return' => $response->return]);
66 |
67 | $response = explode(',', $response->return);
68 |
69 | if ($response[0] == 0) {
70 | $this->getTransaction()->setGatewayToken(strval($response[1])); // update transaction reference id
71 |
72 | return $response[1];
73 | } else {
74 | throw new Exception($response[0]);
75 | }
76 | } else {
77 | throw new Exception('larapay::larapay.invalid_response');
78 | }
79 | } catch (SoapFault $e) {
80 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
81 | }
82 | }
83 |
84 | /**
85 | * @return string
86 | * @throws Exception
87 | */
88 | protected function generateForm(): string
89 | {
90 | $refId = $this->requestToken();
91 |
92 | $form = view('larapay::mellat-form', [
93 | 'endPoint' => $this->getEndPoint(),
94 | 'refId' => $refId,
95 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
96 | 'autoSubmit' => boolval($this->auto_submit),
97 | ]);
98 |
99 | return $form->__toString();
100 | }
101 |
102 | /**
103 | * @return array
104 | * @throws Exception
105 | */
106 | public function formParams(): array
107 | {
108 | $refId = $this->requestToken();
109 |
110 | return [
111 | 'endPoint' => $this->getEndPoint(),
112 | 'refId' => $refId,
113 | ];
114 | }
115 |
116 | /**
117 | * @return bool
118 | * @throws Exception
119 | * @throws \PhpMonsters\Larapay\Adapter\Exception
120 | */
121 | protected function verifyTransaction()
122 | {
123 | if ($this->getTransaction()->checkForVerify() === false) {
124 | throw new Exception('larapay::larapay.could_not_verify_payment');
125 | }
126 |
127 | $this->checkRequiredParameters([
128 | 'terminal_id',
129 | 'username',
130 | 'password',
131 | 'RefId',
132 | 'ResCode',
133 | 'SaleOrderId',
134 | 'SaleReferenceId',
135 | 'CardHolderInfo',
136 | 'CardHolderPan',
137 | ]);
138 |
139 | $sendParams = [
140 | 'terminalId' => intval($this->terminal_id),
141 | 'userName' => $this->username,
142 | 'userPassword' => $this->password,
143 | 'orderId' => intval($this->SaleOrderId), // same as SaleOrderId
144 | 'saleOrderId' => intval($this->SaleOrderId),
145 | 'saleReferenceId' => intval($this->SaleReferenceId),
146 | ];
147 |
148 | $this->getTransaction()->setCardNumber(strval($this->CardHolderInfo));
149 |
150 | try {
151 | $soapClient = $this->getSoapClient();
152 |
153 | XLog::debug('bpVerifyRequest call', $sendParams);
154 |
155 | //$response = $soapClient->__soapCall('bpVerifyRequest', $sendParams);
156 | $response = $soapClient->bpVerifyRequest($sendParams);
157 |
158 | if (isset($response->return)) {
159 | XLog::info('bpVerifyRequest response', ['return' => $response->return]);
160 |
161 | if ($response->return != '0') {
162 | throw new Exception($response->return);
163 | } else {
164 | $this->getTransaction()->setVerified();
165 |
166 | return true;
167 | }
168 | } else {
169 | throw new Exception('larapay::larapay.invalid_response');
170 | }
171 |
172 | } catch (SoapFault $e) {
173 |
174 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
175 | }
176 | }
177 |
178 | /**
179 | * @return bool
180 | * @throws Exception
181 | * @throws \PhpMonsters\Larapay\Adapter\Exception
182 | */
183 | public function inquiryTransaction()
184 | {
185 | if ($this->getTransaction()->checkForInquiry() === false) {
186 | throw new Exception('larapay::larapay.could_not_inquiry_payment');
187 | }
188 |
189 | $this->checkRequiredParameters([
190 | 'terminal_id',
191 | 'terminal_user',
192 | 'terminal_pass',
193 | 'RefId',
194 | 'ResCode',
195 | 'SaleOrderId',
196 | 'SaleReferenceId',
197 | 'CardHolderInfo',
198 | ]);
199 |
200 | $sendParams = [
201 | 'terminalId' => intval($this->terminal_id),
202 | 'userName' => $this->username,
203 | 'userPassword' => $this->password,
204 | 'orderId' => intval($this->SaleOrderId), // same as SaleOrderId
205 | 'saleOrderId' => intval($this->SaleOrderId),
206 | 'saleReferenceId' => intval($this->SaleReferenceId),
207 | ];
208 |
209 | $this->getTransaction()->setCardNumber(strval($this->CardHolderInfo));
210 |
211 | try {
212 | $soapClient = $this->getSoapClient();
213 |
214 | XLog::debug('bpInquiryRequest call', $sendParams);
215 | //$response = $soapClient->__soapCall('bpInquiryRequest', $sendParams);
216 | $response = $soapClient->bpInquiryRequest($sendParams);
217 |
218 | if (isset($response->return)) {
219 | XLog::info('bpInquiryRequest response', ['return' => $response->return]);
220 | if ($response->return != '0') {
221 | throw new Exception($response->return);
222 | } else {
223 | $this->getTransaction()->setVerified();
224 |
225 | return true;
226 | }
227 | } else {
228 | throw new Exception('larapay::larapay.invalid_response');
229 | }
230 |
231 | } catch (SoapFault $e) {
232 |
233 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
234 | }
235 | }
236 |
237 | /**
238 | * Send settle request
239 | *
240 | * @return bool
241 | *
242 | * @throws Exception
243 | * @throws \PhpMonsters\Larapay\Adapter\Exception
244 | */
245 | protected function settleTransaction()
246 | {
247 | if ($this->getTransaction()->checkForAfterVerify() === false) {
248 | throw new Exception('larapay::larapay.could_not_settle_payment');
249 | }
250 |
251 | $this->checkRequiredParameters([
252 | 'terminal_id',
253 | 'username',
254 | 'password',
255 | 'RefId',
256 | 'ResCode',
257 | 'SaleOrderId',
258 | 'SaleReferenceId',
259 | 'CardHolderInfo',
260 | ]);
261 |
262 | $sendParams = [
263 | 'terminalId' => intval($this->terminal_id),
264 | 'userName' => $this->username,
265 | 'userPassword' => $this->password,
266 | 'orderId' => intval($this->SaleOrderId), // same as orderId
267 | 'saleOrderId' => intval($this->SaleOrderId),
268 | 'saleReferenceId' => intval($this->SaleReferenceId),
269 | ];
270 |
271 | try {
272 | $soapClient = $this->getSoapClient();
273 |
274 | XLog::debug('bpSettleRequest call', $sendParams);
275 | //$response = $soapClient->__soapCall('bpSettleRequest', $sendParams);
276 | $response = $soapClient->bpSettleRequest($sendParams);
277 |
278 | if (isset($response->return)) {
279 | XLog::info('bpSettleRequest response', ['return' => $response->return]);
280 |
281 | if ($response->return == '0' || $response->return == '45') {
282 | $this->getTransaction()->setAfterVerified();
283 |
284 | return true;
285 | } else {
286 | throw new Exception($response->return);
287 | }
288 | } else {
289 | throw new Exception('larapay::larapay.invalid_response');
290 | }
291 |
292 | } catch (\SoapFault $e) {
293 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
294 | }
295 |
296 | }
297 |
298 | /**
299 | * @return bool
300 | * @throws Exception
301 | * @throws \PhpMonsters\Larapay\Adapter\Exception
302 | */
303 | protected function reverseTransaction(): bool
304 | {
305 | if ($this->reverseSupport === false || $this->getTransaction()->checkForReverse() === false) {
306 | throw new Exception('larapay::larapay.could_not_reverse_payment');
307 | }
308 |
309 | $this->checkRequiredParameters([
310 | 'terminal_id',
311 | 'username',
312 | 'password',
313 | 'RefId',
314 | 'ResCode',
315 | 'SaleOrderId',
316 | 'SaleReferenceId',
317 | 'CardHolderInfo',
318 | ]);
319 |
320 | $sendParams = [
321 | 'terminalId' => intval($this->terminal_id),
322 | 'userName' => $this->username,
323 | 'userPassword' => $this->password,
324 | 'orderId' => intval($this->SaleOrderId), // same as orderId
325 | 'saleOrderId' => intval($this->SaleOrderId),
326 | 'saleReferenceId' => intval($this->SaleReferenceId),
327 | ];
328 |
329 | try {
330 | $soapClient = $this->getSoapClient();
331 |
332 | XLog::debug('bpReversalRequest call', $sendParams);
333 | //$response = $soapClient->__soapCall('bpReversalRequest', $sendParams);
334 | $response = $soapClient->bpReversalRequest($sendParams);
335 |
336 | XLog::info('bpReversalRequest response', ['return' => $response->return]);
337 |
338 | if (isset($response->return)) {
339 | if ($response->return == '0' || $response->return == '45') {
340 | $this->getTransaction()->setRefunded();
341 |
342 | return true;
343 | } else {
344 | throw new Exception($response->return);
345 | }
346 | } else {
347 | throw new Exception('larapay::larapay.invalid_response');
348 | }
349 |
350 | } catch (SoapFault $e) {
351 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
352 | }
353 | }
354 |
355 |
356 | /**
357 | * @return bool
358 | */
359 | public function canContinueWithCallbackParameters(): bool
360 | {
361 | if ($this->ResCode === "0" || $this->ResCode === 0) {
362 | return true;
363 | }
364 |
365 | return false;
366 | }
367 |
368 | public function getGatewayReferenceId(): string
369 | {
370 | $this->checkRequiredParameters([
371 | 'RefId',
372 | ]);
373 |
374 | return strval($this->RefId);
375 | }
376 |
377 | public function afterVerify(): bool
378 | {
379 | return $this->settleTransaction();
380 | }
381 | }
382 |
--------------------------------------------------------------------------------
/src/Adapter/Mellat/Exception.php:
--------------------------------------------------------------------------------
1 | requestToken();
32 |
33 | return [
34 | 'endPoint' => strtr($this->endPointForm, ['{trans_id}' => $authority]),
35 | ];
36 | }
37 |
38 | /**
39 | * @return bool
40 | */
41 | public function canContinueWithCallbackParameters(): bool
42 | {
43 | if (!empty($this->parameters['trans_id'])) {
44 | return true;
45 | }
46 |
47 | return false;
48 | }
49 |
50 | /**
51 | * @return string
52 | * @throws \PhpMonsters\Larapay\Adapter\Exception
53 | */
54 | public function getGatewayReferenceId(): string
55 | {
56 | $this->checkRequiredParameters([
57 | 'trans_id',
58 | ]);
59 |
60 | return strval($this->trans_id);
61 | }
62 |
63 | /**
64 | * @return string
65 | * @throws Exception
66 | * @throws \PhpMonsters\Larapay\Adapter\Exception
67 | */
68 | protected function generateForm(): string
69 | {
70 | $authority = $this->requestToken();
71 |
72 | $form = view('larapay::nextpay-form', [
73 | 'endPoint' => strtr($this->endPointForm, ['{trans_id}' => $authority]),
74 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
75 | 'autoSubmit' => true,
76 | ]);
77 | return $form->__toString();
78 | }
79 |
80 | /**
81 | * @return string
82 | * @throws Exception
83 | * @throws \PhpMonsters\Larapay\Adapter\Exception
84 | */
85 | protected function requestToken(): string
86 | {
87 | if ($this->getTransaction()->checkForRequestToken() === false) {
88 | throw new Exception('larapay::larapay.could_not_request_payment');
89 | }
90 |
91 | $this->checkRequiredParameters([
92 | 'api_key',
93 | 'amount',
94 | 'redirect_url',
95 | 'order_id',
96 | ]);
97 |
98 | $sendParams = [
99 | 'api_key' => $this->api_key,
100 | 'amount' => intval($this->amount),
101 | 'order_id' => ($this->order_id),
102 | 'payer_desc' => $this->description ? $this->description : '',
103 | 'customer_phone' => $this->mobile ? $this->mobile : '',
104 | 'callback_uri' => $this->redirect_url,
105 | ];
106 |
107 | try {
108 | XLog::debug('PaymentRequest call', $sendParams);
109 | $result = Helper::post2https($sendParams, $this->endPoint);
110 | $resultObj = json_decode($result);
111 |
112 | XLog::info('PaymentRequest response', $this->obj2array($resultObj));
113 |
114 | if (isset($resultObj->code)) {
115 | if ($resultObj->code == -1) {
116 | $this->getTransaction()->setGatewayToken(strval($resultObj->trans_id)); // update transaction reference id
117 | return $resultObj->trans_id;
118 | } else {
119 | throw new Exception('larapay::larapay.nextpay.errors.error_'.$resultObj->code);
120 | }
121 | } else {
122 | throw new Exception('larapay::larapay.invalid_response');
123 | }
124 | } catch (\Exception $e) {
125 | throw new Exception('Nextpay Fault: '.$e->getMessage().' #'.$e->getCode(), $e->getCode());
126 | }
127 | }
128 |
129 | /**
130 | * @return bool
131 | * @throws Exception
132 | * @throws \PhpMonsters\Larapay\Adapter\Exception
133 | */
134 | protected function verifyTransaction(): bool
135 | {
136 | if ($this->getTransaction()->checkForVerify() === false) {
137 | throw new Exception('larapay::larapay.could_not_verify_payment');
138 | }
139 |
140 | $this->checkRequiredParameters([
141 | 'api_key',
142 | 'trans_id',
143 | 'amount'
144 | ]);
145 |
146 | $sendParams = [
147 | 'api_key' => $this->api_key,
148 | 'trans_id' => $this->trans_id,
149 | 'amount' => $this->amount,
150 | ];
151 |
152 | try {
153 | XLog::debug('PaymentVerification call', $sendParams);
154 | $result = Helper::post2https($sendParams, $this->endPointVerify);
155 | $response = json_decode($result);
156 | XLog::info('PaymentVerification response', $this->obj2array($response));
157 | if (isset($response->code, $response->Shaparak_Ref_Id)) {
158 | if ($response->code == 0) {
159 | $this->getTransaction()->setVerified();
160 | $this->getTransaction()->setReferenceId(strval($response->Shaparak_Ref_Id)); // update transaction reference id
161 | return true;
162 | } else {
163 | throw new Exception('larapay::larapay.nextpay.errors.error_'.$response->code);
164 | }
165 | } else {
166 | throw new Exception('larapay::larapay.invalid_response');
167 | }
168 | } catch (\Exception $e) {
169 | throw new Exception('Nextpay Fault: '.$e->getMessage().' #'.$e->getCode(), $e->getCode());
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/src/Adapter/Nextpay/Exception.php:
--------------------------------------------------------------------------------
1 | 'SOAP_1_1',
38 | 'cache_wsdl' => WSDL_CACHE_BOTH,
39 | 'encoding' => 'UTF-8',
40 | );
41 |
42 |
43 | public function init()
44 | {
45 | ini_set("default_socket_timeout", strval(config('larapay.parsian.timeout')));
46 | }
47 |
48 | /**
49 | * @return array
50 | * @throws Exception
51 | * @throws \PhpMonsters\Larapay\Adapter\Exception
52 | */
53 | protected function requestToken()
54 | {
55 | if ($this->getTransaction()->checkForRequestToken() == false) {
56 | throw new Exception('larapay::larapay.could_not_request_payment');
57 | }
58 |
59 |
60 | $this->checkRequiredParameters([
61 | 'pin',
62 | 'order_id',
63 | 'amount',
64 | 'redirect_url',
65 | ]);
66 |
67 |
68 | $sendParams = [
69 | 'LoginAccount' => $this->pin,
70 | 'Amount' => intval($this->amount),
71 | 'OrderId' => intval($this->order_id),
72 | 'CallBackUrl' => $this->redirect_url,
73 | 'AdditionalData' => $this->additional_data ?? '',
74 | 'Originator' => $this->originator ?? '',
75 | ];
76 |
77 |
78 | if (!empty($this->sharing) && is_array($this->sharing)) {
79 | return $this->requestTokenWithSharing($sendParams);
80 | } else {
81 | return $this->requestTokenWithoutSharing($sendParams);
82 | }
83 | }
84 |
85 | /**
86 | * @param array $sendParams
87 | *
88 | * @return mixed
89 | * @throws Exception
90 | */
91 | private function requestTokenWithoutSharing($sendParams)
92 | {
93 | for ($i = 1; $i <= 3; $i++) {
94 | try {
95 |
96 | $this->requestType = 'request';
97 | $soapClient = $this->getSoapClient();
98 |
99 | XLog::debug('SalePaymentRequest call', $sendParams);
100 |
101 | $response = $soapClient->SalePaymentRequest(array("requestData" => $sendParams));
102 |
103 | XLog::debug('SalePaymentRequest response', $this->obj2array($response));
104 |
105 | if (isset($response->SalePaymentRequestResult->Status, $response->SalePaymentRequestResult->Token)) {
106 | if ($response->SalePaymentRequestResult->Status == 0) {
107 | $this->getTransaction()->setGatewayToken(strval($response->SalePaymentRequestResult->Token)); // update transaction reference id
108 |
109 | return $response->SalePaymentRequestResult->Token;
110 | } else {
111 | if ($i == 3) {
112 | throw new Exception($response->SalePaymentRequestResult->Status);
113 | }
114 | usleep(500);
115 | }
116 | } else {
117 | if ($i == 3) {
118 | throw new Exception('larapay::parsian.errors.invalid_response');
119 | }
120 | usleep(500);
121 | }
122 |
123 | } catch (SoapFault $e) {
124 | if ($i == 3) {
125 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
126 | }
127 | usleep(500);
128 | }
129 | }
130 | }
131 |
132 | /**
133 | * @param array $sendParams
134 | *
135 | * @return mixed
136 | * @throws Exception
137 | */
138 | private function requestTokenWithSharing($sendParams)
139 | {
140 | if (!isset($this->sharing['type']) || !isset($this->sharing['data'])) {
141 | throw new Exception('larapay::larapay.invalid_sharing_data');
142 | }
143 |
144 |
145 | if ($this->sharing['type'] == Sharing::DYNAMIC) {
146 | // dynamic sharing
147 | $method = 'MultiplexedSaleWithIBANPaymentRequest';
148 | $respo = 'MultiplexedSaleWithIBANPaymentResult';
149 | foreach ($this->sharing['data'] as $item) {
150 | $sendParams['MultiplexedAccounts']['Account'][] = [
151 | 'Amount' => $item->share,
152 | 'PayId' => $item->pay_id ?? '',
153 | 'IBAN' => $item->iban,
154 | ];
155 | }
156 | } else {
157 | // fix sharing
158 | $method = 'MultiplexedSalePaymentRequest';
159 | $respo = 'MultiplexedSalePaymentResult';
160 | foreach ($this->sharing['data'] as $item) {
161 | $sendParams['MultiplexedAccounts']['Account'][] = [
162 | 'Amount' => $item->share,
163 | 'PayId' => $item->pay_id ?? '',
164 | ];
165 | }
166 | }
167 |
168 | try {
169 | $this->requestType = 'multiplex';
170 | $soapClient = $this->getSoapClient();
171 |
172 | XLog::debug("{$method} call", $sendParams);
173 |
174 | $response = $soapClient->$method(array("requestData" => $sendParams));
175 |
176 | XLog::debug("{$method} response", $this->obj2array($response));
177 |
178 | if (isset($response->$respo->Status, $response->$respo->Token)) {
179 | if ($response->$respo->Status == 0) {
180 | $this->getTransaction()->setGatewayToken(strval($response->$respo->Token)); // update transaction reference id
181 |
182 | return $response->$respo->Token;
183 | } else {
184 | throw new Exception($response->$respo->Status);
185 | }
186 | } else {
187 | throw new Exception('larapay::parsian.errors.invalid_response');
188 | }
189 | } catch (SoapFault $e) {
190 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
191 | }
192 | }
193 |
194 | /**
195 | * @return string
196 | * @throws Exception
197 | * @throws \PhpMonsters\Larapay\Adapter\Exception
198 | */
199 | protected function generateForm(): string
200 | {
201 | $authority = $this->requestToken();
202 |
203 | $form = view('larapay::parsian-form', [
204 | 'endPoint' => $this->getEndPoint(),
205 | 'refId' => $authority,
206 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
207 | 'autoSubmit' => boolval($this->auto_submit),
208 | ]);
209 |
210 | return $form->__toString();
211 | }
212 |
213 | /**
214 | * @return array
215 | * @throws Exception
216 | * @throws \PhpMonsters\Larapay\Adapter\Exception
217 | */
218 | public function formParams(): array
219 | {
220 | $authority = $this->requestToken();
221 |
222 | return [
223 | 'endPoint' => $this->getEndPoint(),
224 | 'refId' => $authority,
225 | ];
226 | }
227 |
228 | /**
229 | * @return bool
230 | * @throws Exception
231 | * @throws \PhpMonsters\Larapay\Adapter\Exception
232 | */
233 | protected function verifyTransaction(): bool
234 | {
235 | if ($this->getTransaction()->checkForVerify() == false) {
236 | throw new Exception('larapay::larapay.could_not_verify_payment');
237 | }
238 | $this->requestType = 'confirm';
239 |
240 | $this->checkRequiredParameters([
241 | 'Token',
242 | ]);
243 |
244 | if ($this->status !== '0') {
245 | throw new Exception('larapay::parsian.errors.could_not_continue_with_non0_rs');
246 | }
247 |
248 | $sendParams = [
249 | 'LoginAccount' => $this->pin,
250 | 'Token' => $this->Token,
251 | ];
252 |
253 |
254 | try {
255 | $soapClient = $this->getSoapClient();
256 |
257 |
258 | XLog::debug('ConfirmPayment call', $sendParams);
259 |
260 | $response = $soapClient->ConfirmPayment(array("requestData" => $sendParams));
261 |
262 | XLog::debug('ConfirmPayment response', $this->obj2array($response));
263 |
264 | if (isset($response->ConfirmPaymentResult)) {
265 | if ($response->ConfirmPaymentResult->Status == 0) {
266 | $this->getTransaction()->setVerified();
267 |
268 | return true;
269 | } else {
270 | throw new Exception($response->ConfirmPaymentResult->Status);
271 | }
272 | } else {
273 | throw new Exception('larapay::parsian.errors.invalid_response');
274 | }
275 |
276 | } catch (SoapFault $e) {
277 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
278 | }
279 | }
280 |
281 |
282 | /**
283 | * @return bool
284 | * @throws Exception
285 | * @throws \PhpMonsters\Larapay\Adapter\Exception
286 | */
287 | protected function reverseTransaction(): bool
288 | {
289 | if ($this->reverseSupport == false || $this->getTransaction()->checkForReverse() == false) {
290 | throw new Exception('larapay::larapay.could_not_reverse_payment');
291 | }
292 |
293 | $this->requestType = 'reversal';
294 |
295 |
296 | $this->checkRequiredParameters([
297 | 'Token',
298 | ]);
299 |
300 | $sendParams = [
301 | 'LoginAccount' => $this->pin,
302 | 'Token' => $this->Token,
303 | ];
304 |
305 | try {
306 | $soapClient = $this->getSoapClient();
307 | XLog::debug('ReversalRequest call', $sendParams);
308 |
309 | $response = $soapClient->ReversalRequest(array("requestData" => $sendParams));
310 |
311 | XLog::debug('ReversalRequest response', $this->obj2array($response));
312 |
313 | if (isset($response->ReversalRequestResult->Status)) {
314 | if ($response->ReversalRequestResult->Status == 0) {
315 | $this->getTransaction()->setRefunded();
316 |
317 | return true;
318 | } else {
319 | throw new Exception($response->ReversalRequestResult->Status);
320 | }
321 | } else {
322 | throw new Exception('larapay::parsian.errors.invalid_response');
323 | }
324 | } catch (SoapFault $e) {
325 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
326 | }
327 | }
328 |
329 | public function getGatewayReferenceId(): string
330 | {
331 | $this->checkRequiredParameters([
332 | 'Token',
333 | ]);
334 |
335 | return strval($this->Token);
336 | }
337 |
338 |
339 | protected function getWSDL(): string
340 | {
341 |
342 | $type = $this->requestType;
343 |
344 | switch ($type) {
345 | case 'request':
346 | if (config('larapay.mode') == 'production') {
347 | return $this->WSDLSale;
348 | } else {
349 | return $this->testWSDLSale;
350 | }
351 | break;
352 | case 'confirm':
353 | if (config('larapay.mode') == 'production') {
354 | return $this->WSDLConfirm;
355 | } else {
356 | return $this->testWSDLConfirm;
357 | }
358 | break;
359 | case 'reversal':
360 | if (config('larapay.mode') == 'production') {
361 | return $this->WSDLReversal;
362 | } else {
363 | return $this->testWSDLReversal;
364 | }
365 | break;
366 | case 'multiplex':
367 | if (config('larapay.mode') == 'production') {
368 | return $this->WSDLMultiplex;
369 | } else {
370 | return $this->testWSDLMultiplex;
371 | }
372 | break;
373 | }
374 | }
375 | }
376 |
--------------------------------------------------------------------------------
/src/Adapter/Parsian/Exception.php:
--------------------------------------------------------------------------------
1 | checkRequiredParameters([
37 | 'amount',
38 | 'order_id',
39 | 'redirect_url'
40 | ]);
41 |
42 | $processor = new RSAProcessor(config('larapay.pasargad.certificate_path'), RSAKeyType::XMLFile);
43 |
44 | $url = $this->getEndPoint();
45 | $redirectUrl = $this->redirect_url;
46 | $invoiceNumber = $this->order_id;
47 | $amount = $this->amount;
48 | $terminalCode = config('larapay.pasargad.terminalId');
49 | $merchantCode = config('larapay.pasargad.merchantId');
50 | $timeStamp = date("Y/m/d H:i:s");
51 | $invoiceDate = date("Y/m/d H:i:s");
52 | $action = 1003; // sell code
53 | $submitLabel = !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate");
54 | $autoSubmit = boolval($this->auto_submit);
55 |
56 | $data = "#" . $merchantCode . "#" . $terminalCode . "#" . $invoiceNumber . "#" . $invoiceDate . "#" . $amount . "#" . $redirectUrl . "#" . $action . "#" . $timeStamp . "#";
57 | $data = sha1($data, true);
58 | $data = $processor->sign($data); // امضاي ديجيتال
59 | $sign = base64_encode($data); // base64_encode
60 |
61 | $form = view('larapay::pasargad-form')->with(compact(
62 | 'url',
63 | 'redirectUrl',
64 | 'invoiceNumber',
65 | 'invoiceDate',
66 | 'amount',
67 | 'terminalCode',
68 | 'merchantCode',
69 | 'timeStamp',
70 | 'action',
71 | 'sign',
72 | 'submitLabel',
73 | 'autoSubmit'
74 | ));
75 |
76 | return $form->__toString();
77 | }
78 |
79 | /**
80 | * @return array
81 | * @throws Exception
82 | */
83 | public function formParams(): array
84 | {
85 | $this->checkRequiredParameters([
86 | 'amount',
87 | 'order_id',
88 | 'redirect_url'
89 | ]);
90 |
91 | $processor = new RSAProcessor(config('larapay.pasargad.certificate_path'), RSAKeyType::XMLFile);
92 |
93 | $url = $this->getEndPoint();
94 | $redirectUrl = $this->redirect_url;
95 | $invoiceNumber = $this->order_id;
96 | $amount = $this->amount;
97 | $terminalCode = config('larapay.pasargad.terminalId');
98 | $merchantCode = config('larapay.pasargad.merchantId');
99 | $timeStamp = date("Y/m/d H:i:s");
100 | $invoiceDate = date("Y/m/d H:i:s");
101 | $action = 1003; // sell code
102 |
103 | $data = "#" . $merchantCode . "#" . $terminalCode . "#" . $invoiceNumber . "#" . $invoiceDate . "#" . $amount . "#" . $redirectUrl . "#" . $action . "#" . $timeStamp . "#";
104 | $data = sha1($data, true);
105 | $data = $processor->sign($data); // امضاي ديجيتال
106 | $sign = base64_encode($data); // base64_encode
107 |
108 | return [
109 | 'url' => $url,
110 | 'redirectUrl' => $redirectUrl,
111 | 'invoiceNumber' => $invoiceNumber,
112 | 'invoiceDate' => $invoiceDate,
113 | 'amount' => $amount,
114 | 'terminalCode' => $terminalCode,
115 | 'merchantCode' => $merchantCode,
116 | 'timeStamp' => $timeStamp,
117 | 'action' => $action,
118 | 'sign' => $sign,
119 | ];
120 | }
121 |
122 | // public function inquiryTransaction ()
123 | // {
124 | //
125 | // }
126 |
127 | /**
128 | * @return bool
129 | * @throws Exception
130 | */
131 | protected function verifyTransaction(): bool
132 | {
133 | $this->checkRequiredParameters([
134 | 'iN',
135 | 'iD',
136 | 'tref',
137 | ]);
138 |
139 | // update transaction reference number
140 | if (!empty($this->tref)) {
141 | $this->setInvoiceReferenceId($this->tref); // update transaction reference id
142 | }
143 |
144 | $processor = new RSAProcessor(config('larapay.pasargad.certificate_path'), RSAKeyType::XMLFile);
145 |
146 | $terminalCode = config('larapay.pasargad.terminalId');
147 | $merchantCode = config('larapay.pasargad.merchantId');
148 | $invoiceNumber = $this->iN;
149 | $invoiceDate = $this->iD;
150 | $amount = $this->getTransaction()->getPayableAmount();
151 | $timeStamp = date("Y/m/d H:i:s");
152 |
153 | $data = "#" . $merchantCode . "#" . $terminalCode . "#" . $invoiceNumber . "#" . $invoiceDate . "#" . $amount . "#" . $timeStamp . "#";
154 | XLog::debug('pasargad generated sign string: ' . $data);
155 | $data = sha1($data, true);
156 | $data = $processor->sign($data); // امضاي ديجيتال
157 | $sign = base64_encode($data); // base64_encode
158 | XLog::debug('pasargad generated hash: ' . $sign);
159 |
160 | $parameters = compact(
161 | 'terminalCode',
162 | 'merchantCode',
163 | 'invoiceNumber',
164 | 'invoiceDate',
165 | 'amount',
166 | 'timeStamp',
167 | 'sign'
168 | );
169 |
170 | $result = Helper::post2https($parameters , $this->getVerifyUrl());
171 |
172 | $array = Helper::parseXML($result, [
173 | 'invoiceNumber' => $this->iN,
174 | 'invoiceDate' => $this->iD
175 | ]);
176 |
177 | XLog::debug('pasargad verify parseXML result', $array);
178 |
179 | if ($array['actionResult']['result'] != "True") {
180 | throw new Exception('larapay::larapay.verification_failed');
181 | } else {
182 | $this->getTransaction()->setVerified();
183 | return true;
184 | }
185 | }
186 |
187 | /**
188 | * @return bool
189 | * @throws Exception
190 | */
191 | protected function reverseTransaction(): bool
192 | {
193 | $this->checkRequiredParameters([
194 | 'iN',
195 | 'iD',
196 | 'tref',
197 | ]);
198 |
199 | // update transaction reference number
200 | if (!empty($this->tref)) {
201 | $this->setInvoiceReferenceId($this->tref); // update transaction reference id
202 | }
203 |
204 | $processor = new RSAProcessor(config('larapay.pasargad.certificate_path'), RSAKeyType::XMLFile);
205 |
206 | $terminalCode = config('larapay.pasargad.terminalId');
207 | $merchantCode = config('larapay.pasargad.merchantId');
208 | $invoiceNumber = $this->iN;
209 | $invoiceDate = $this->iD;
210 | $amount = $this->getTransaction()->getPayableAmount();
211 | $timeStamp = date("Y/m/d H:i:s");
212 | $action = 1004; // reverse code
213 |
214 | $data = "#" . $merchantCode . "#" . $terminalCode . "#" . $invoiceNumber . "#" . $invoiceDate . "#" . $amount . "#" . $action . "#" . $timeStamp . "#";
215 | $data = sha1($data, true);
216 | $data = $processor->sign($data); // امضاي ديجيتال
217 | $sign = base64_encode($data); // base64_encode
218 |
219 | $parameters = compact(
220 | 'terminalCode',
221 | 'merchantCode',
222 | 'invoiceNumber',
223 | 'invoiceDate',
224 | 'amount',
225 | 'timeStamp',
226 | 'action',
227 | 'sign'
228 | );
229 |
230 | $result = Helper::post2https($parameters , $this->getRefundUrl());
231 | $array = Helper::parseXML($result, [
232 | 'invoiceNumber' => $this->iN,
233 | 'invoiceDate' => $this->iD
234 | ]);
235 |
236 | XLog::debug('pasargad refund parseXML result', $array);
237 |
238 | if ($array['actionResult']['result'] != "True") {
239 | throw new Exception('larapay::larapay.reversed_failed');
240 | } else {
241 | $this->getTransaction()->setRefunded();
242 | return true;
243 | }
244 | }
245 |
246 | /**
247 | * @return string
248 | */
249 | protected function getVerifyUrl(): string
250 | {
251 | if (config('larapay.mode') == 'production') {
252 | return $this->verifyUrl;
253 | } else {
254 | return $this->testVerifyUrl;
255 | }
256 | }
257 |
258 | /**
259 | * @return string
260 | */
261 | protected function getRefundUrl(): string
262 | {
263 | if (config('larapay.mode') == 'production') {
264 | return $this->refundUrl;
265 | } else {
266 | return $this->testRefundUrl;
267 | }
268 | }
269 |
270 | /**
271 | * @return string
272 | */
273 | protected function getInquiryUrl(): string
274 | {
275 | if (config('larapay.mode') == 'production') {
276 | return $this->checkTransactionUrl;
277 | } else {
278 | return $this->testCheckTransactionUrl;
279 | }
280 | }
281 |
282 | /**
283 | * @return bool
284 | */
285 | public function canContinueWithCallbackParameters(): bool
286 | {
287 | if (!empty($this->getParameter('tref'))) {
288 | return true;
289 | }
290 | return false;
291 | }
292 |
293 |
294 | public function getGatewayReferenceId(): string
295 | {
296 | $this->checkRequiredParameters([
297 | 'tref',
298 | ]);
299 |
300 | return strval($this->tref);
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/src/Adapter/Pasargad/Helper.php:
--------------------------------------------------------------------------------
1 | $val) {
27 | switch ($val['type']) {
28 | case 'open':
29 | array_push($hash_stack, $val['tag']);
30 | break;
31 | case 'close':
32 | array_pop($hash_stack);
33 | break;
34 | case 'complete':
35 | array_push($hash_stack, $val['tag']);
36 | if(!isset($val['value'])){
37 | $val['value'] = $temp[$val['tag']];
38 | }
39 |
40 | @eval("\$ret['" . implode($hash_stack, "']['") . "'] = '{$val['value']}';");
41 | array_pop($hash_stack);
42 | break;
43 | }
44 | }
45 |
46 | return $ret;
47 | }
48 |
49 |
50 | /**
51 | * CURL POST TO HTTPS
52 | *
53 | * @param $fields_arr
54 | * @param $url
55 | * @return mixed
56 | */
57 | public static function post2https($fields_arr, $url)
58 | {
59 | $fields_string = '';
60 | //url-ify the data for the POST
61 | foreach ($fields_arr as $key => $value) {
62 | $fields_string .= $key . '=' . $value . '&';
63 | }
64 | $fields_string = substr($fields_string, 0, -1);
65 |
66 | //open connection
67 | $ch = curl_init();
68 |
69 | //set the url, number of POST vars, POST data
70 | curl_setopt($ch, CURLOPT_URL, $url);
71 | curl_setopt($ch, CURLOPT_POST, count($fields_arr));
72 | curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
73 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
74 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
75 |
76 |
77 | //execute post
78 | $res = curl_exec($ch);
79 |
80 | //close connection
81 | curl_close($ch);
82 |
83 | XLog::debug('pasargad call result: '. $res);
84 | return $res;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Adapter/Pasargad/PasargadResult.php:
--------------------------------------------------------------------------------
1 | = 0; $i--) {
133 | $digit = ord($data[$i]);
134 | $part_res = bcmul($digit, $radix);
135 | $result = bcadd($result, $part_res);
136 | $radix = bcmul($radix, $base);
137 | }
138 |
139 | return $result;
140 | }
141 |
142 | public static function number_to_binary($number, $blocksize)
143 | {
144 | $base = "256";
145 | $result = "";
146 | $div = $number;
147 | while ($div > 0) {
148 | $mod = bcmod($div, $base);
149 | $div = bcdiv($div, $base);
150 | $result = chr($mod) . $result;
151 | }
152 |
153 | return str_pad($result, $blocksize, "\x00", STR_PAD_LEFT);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Adapter/Pasargad/RSAProcessor.php:
--------------------------------------------------------------------------------
1 | modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
39 | $this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
40 | $this->private_key = RSA::binary_to_number(base64_decode($xmlObj->D));
41 | $this->key_length = strlen(base64_decode($xmlObj->Modulus)) * 8;
42 | }
43 |
44 | public function getPublicKey ()
45 | {
46 | return $this->public_key;
47 | }
48 |
49 | public function getPrivateKey ()
50 | {
51 | return $this->private_key;
52 | }
53 |
54 | public function getKeyLength (): int
55 | {
56 | return $this->key_length;
57 | }
58 |
59 | public function getModulus ()
60 | {
61 | return $this->modulus;
62 | }
63 |
64 | public function encrypt ($data)
65 | {
66 | return base64_encode(RSA::rsa_encrypt($data, $this->public_key, $this->modulus, $this->key_length));
67 | }
68 |
69 | public function decrypt ($data)
70 | {
71 | return RSA::rsa_decrypt($data, $this->private_key, $this->modulus, $this->key_length);
72 | }
73 |
74 | public function sign ($data)
75 | {
76 | return RSA::rsa_sign($data, $this->private_key, $this->modulus, $this->key_length);
77 | }
78 |
79 | public function verify ($data)
80 | {
81 | return RSA::rsa_verify($data, $this->public_key, $this->modulus, $this->key_length);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Adapter/Pasargad/certificate.xml:
--------------------------------------------------------------------------------
1 | tCZiqDS5BVQQZDBUYbyeoP4rENN4mX5FZJjjMNfGbyzfzH45RY2/YsMaY0yI1jMCOpukvkUyl153tcn0LXhMCDdsEhhZPoKbPUGMniKtFGjs18rv/b5FFUUW1utgwoL8+WJqjOqhQGgvbja63X9+WMFP0nM3d8yudn9C/X55KyM=AQAB5HXvmU4IfqUG2jFLSqi/BMEQ3x1NsUDvx3zN5O1p9yLLspJ4sqAt4RUkxzcGodYgBSdXsR9IGcPwjQfbx3a7nQ==
yd2hDCF/5Zqtz9DXjY1NRYGvBjTS4AQn83ERR46Y5eBSnLjpVjv6gPfARuhsUP44nikrQPvwPnjxQcOhJaOlvw==
ztuqUplBP8qU5cN0dOlN7DQT3rFdw30Unv/2Pa5qIAc1gT72YmZ+pCrM3kSIkMicvY3d7NZyJkIv8MKI0ZZEUQ==QFLJ5YarLWubZPQEK4vSCornTY/5ff51CIKH4ghTOjS/vkbBu4PDL+NCNpYLJcfMHMG7kap2BEIfhjgjGk5KGw==WE6TqpcexQJwt9Mnp1FbeLtarBcFkXVdBauouFKHcbHCfQjA3IjUrGTxgSO74O/4QSKqaF2gnlL6GI7gKuGbzQ==czYtWDfHsFGv3fNOs+cGaB3E+xDTiw7HYGuquJz2qjk/s69x/zqFEKuIH8Ndq+eZYFQUCx+EGGxxENDkmYPa0z8wbfFI6JEHpxaLmQfpkkbSL1BJIp9Z5BNM2gy6jJqgbWwQPcN/4jpiMefHZWAqhMKqenUu1KIq1ZX6Bz5xKYk=
--------------------------------------------------------------------------------
/src/Adapter/PayIr/Exception.php:
--------------------------------------------------------------------------------
1 | requestToken();
32 |
33 | return [
34 | 'endPoint' => $this->endPointForm.$authority,
35 | ];
36 | }
37 |
38 | /**
39 | * @return bool
40 | */
41 | public function canContinueWithCallbackParameters(): bool
42 | {
43 | if (!empty($this->parameters['token'])) {
44 | return true;
45 | }
46 |
47 | return false;
48 | }
49 |
50 | /**
51 | * @return string
52 | * @throws \PhpMonsters\Larapay\Adapter\Exception
53 | */
54 | public function getGatewayReferenceId(): string
55 | {
56 | $this->checkRequiredParameters([
57 | 'token',
58 | ]);
59 |
60 | return strval($this->transId);
61 | }
62 |
63 | /**
64 | * @return string
65 | * @throws Exception
66 | * @throws \PhpMonsters\Larapay\Adapter\Exception
67 | */
68 | protected function generateForm(): string
69 | {
70 | $authority = $this->requestToken();
71 |
72 | $form = view('larapay::payir-form', [
73 | 'endPoint' => $this->endPointForm.$authority,
74 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
75 | 'autoSubmit' => true,
76 | ]);
77 | return $form->__toString();
78 | }
79 |
80 | /**
81 | * @return string
82 | * @throws Exception
83 | * @throws \PhpMonsters\Larapay\Adapter\Exception
84 | */
85 | protected function requestToken(): string
86 | {
87 | if ($this->getTransaction()->checkForRequestToken() === false) {
88 | throw new Exception('larapay::larapay.could_not_request_payment');
89 | }
90 |
91 | $this->checkRequiredParameters([
92 | 'api',
93 | 'amount',
94 | 'redirect_url',
95 | 'order_id',
96 | ]);
97 |
98 | $sendParams = [
99 | 'api' => $this->api,
100 | 'amount' => intval($this->amount),
101 | 'orderId' => ($this->order_id),
102 | 'description' => $this->description ? $this->description : '',
103 | 'mobile' => $this->mobile ? $this->mobile : '',
104 | 'redirect' => $this->redirect_url,
105 | ];
106 |
107 | try {
108 | XLog::debug('PaymentRequest call', $sendParams);
109 | $result = Helper::post2https($sendParams, $this->endPoint);
110 |
111 | $resultObj = json_decode($result);
112 |
113 | XLog::info('PaymentRequest response', $this->obj2array($resultObj));
114 |
115 |
116 | if (isset($resultObj->status)) {
117 | if ($resultObj->status == 1) {
118 | $this->getTransaction()->setGatewayToken(strval($resultObj->token)); // update transaction reference id
119 |
120 | return $resultObj->token;
121 | } else {
122 | throw new Exception($resultObj->status);
123 | }
124 | } else {
125 | throw new Exception('larapay::larapay.invalid_response');
126 | }
127 | } catch (\Exception $e) {
128 | throw new Exception('PayIr Fault: '.$e->getMessage().' #'.$e->getCode(), $e->getCode());
129 | }
130 | }
131 |
132 | /**
133 | * @return bool
134 | * @throws Exception
135 | * @throws \PhpMonsters\Larapay\Adapter\Exception
136 | */
137 | protected function verifyTransaction(): bool
138 | {
139 | if ($this->getTransaction()->checkForVerify() === false) {
140 | throw new Exception('larapay::larapay.could_not_verify_payment');
141 | }
142 |
143 | $this->checkRequiredParameters([
144 | 'api',
145 | 'token',
146 | ]);
147 |
148 | $sendParams = [
149 | 'api' => $this->api,
150 | 'token' => $this->token,
151 | ];
152 |
153 | try {
154 | XLog::debug('PaymentVerification call', $sendParams);
155 | $result = Helper::post2https($sendParams, $this->endPointVerify);
156 | $response = json_decode($result);
157 | XLog::info('PaymentVerification response', $this->obj2array($response));
158 |
159 | if (isset($response->status, $response->amount)) {
160 | if ($response->status == 1) {
161 | $this->getTransaction()->setVerified();
162 | $this->getTransaction()->setReferenceId(strval($this->token)); // update transaction reference id
163 | return true;
164 | } else {
165 | throw new Exception($response->status);
166 | }
167 | } else {
168 | throw new Exception($response->status);
169 | }
170 | } catch (\Exception $e) {
171 | throw new Exception('Payir Fault: '.$e->getMessage().' #'.$e->getCode(), $e->getCode());
172 | }
173 | }
174 | }
--------------------------------------------------------------------------------
/src/Adapter/Saderat.php:
--------------------------------------------------------------------------------
1 | getTransaction()->checkForRequestToken() === false) {
34 | throw new Exception('larapay::larapay.could_not_request_payment');
35 | }
36 |
37 | $this->checkRequiredParameters([
38 | 'terminalid',
39 | 'amount',
40 | 'order_id',
41 | 'redirect_url',
42 | ]);
43 |
44 | $sendParams = [
45 | "Amount" => $this->amount,
46 | "callbackURL" => $this->redirect_url,
47 | "invoiceID" => $this->order_id,
48 | "terminalID" => $this->terminalid,
49 | ];
50 |
51 | try {
52 | XLog::debug('reservation call', $sendParams);
53 |
54 | $result = Helper::post2https($sendParams, $this->getWSDL());
55 | $response = json_decode($result);
56 |
57 | XLog::info('reservation response', $response);
58 |
59 | if (isset($response->Accesstoken)) {
60 |
61 | if ($response->Status == 0) {
62 | $this->getTransaction()->setGatewayToken(strval($response->Accesstoken)); // update transaction reference id
63 | return $response->Accesstoken;
64 | } else {
65 | throw new Exception($response->Status);
66 | }
67 | } else {
68 | throw new Exception('larapay::larapay.invalid_response');
69 | }
70 | } catch (\Exception $e) {
71 | throw new Exception('Saderat(Sepehr) Fault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
72 | }
73 | }
74 |
75 | /**
76 | * @return string
77 | * @throws Exception
78 | */
79 | protected function generateForm(): string
80 | {
81 | $token = $this->requestToken();
82 | $form = view('larapay::saderat-form', [
83 | 'endPoint' => $this->getEndPoint(),
84 | 'token' => $token,
85 | 'terminalID' => $this->terminalID,
86 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
87 | 'autoSubmit' => boolval($this->auto_submit)
88 | ]);
89 |
90 | return $form->__toString();
91 | }
92 |
93 | /**
94 | * @return array
95 | * @throws Exception
96 | */
97 | public function formParams(): array
98 | {
99 | $token = $this->requestToken();
100 |
101 | return [
102 | 'endPoint' => $this->getEndPoint() . $token,
103 | ];
104 | }
105 |
106 | /**
107 | * @return bool
108 | * @throws Exception
109 | * @throws \PhpMonsters\Larapay\Adapter\Exception
110 | */
111 | protected function verifyTransaction(): bool
112 | {
113 | if ($this->getTransaction()->checkForVerify() === false) {
114 | throw new Exception('larapay::larapay.could_not_verify_payment');
115 | }
116 |
117 |
118 | $this->checkRequiredParameters([
119 | 'rrn',
120 | 'tracenumber',
121 | 'digitalreceipt',
122 | 'respcode',
123 | 'amount',
124 | ]);
125 |
126 | $sendParams = [
127 | "digitalreceipt" => $this->digitalreceipt,
128 | "Tid" => $this->terminalid,
129 | ];
130 |
131 | try {
132 | XLog::debug('PaymentVerification call', $sendParams);
133 | $result = Helper::post2https($sendParams, $this->getVerifyWSDL());
134 | $response = json_decode($result);
135 | XLog::info('PaymentVerification response', $this->obj2array($response));
136 |
137 | if (isset($response->Status)) {
138 | if ($response->Status == "Ok" and $response->ReturnId == $this->getTransaction()->getPayableAmount()) {
139 | $this->getTransaction()->setReferenceId(strval($this->rrn)); // update transaction reference id
140 | $this->getTransaction()->setVerified();
141 | return true;
142 | } else {
143 | throw new Exception($response->Message);
144 | }
145 | } else {
146 | throw new Exception($response->Message);
147 | }
148 | } catch (\Exception $e) {
149 | throw new Exception('Saderat Fault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
150 | }
151 | }
152 |
153 |
154 | /**
155 | * @return string
156 | */
157 | private function getVerifyWSDL(): string
158 | {
159 | if (config('larapay.mode') == 'production') {
160 | return $this->verifyWSDL;
161 | } else {
162 | return $this->testVerifyWSDL;
163 | }
164 | }
165 |
166 | /**
167 | * @return bool
168 | */
169 | public function canContinueWithCallbackParameters(): bool
170 | {
171 | if ($this->respcode == "0") {
172 | return true;
173 | }
174 |
175 | return false;
176 | }
177 |
178 | public function getGatewayReferenceId(): string
179 | {
180 | $this->checkRequiredParameters([
181 | 'digitalreceipt',
182 | ]);
183 |
184 | return strval($this->digitalreceipt);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/Adapter/Saderat/Exception.php:
--------------------------------------------------------------------------------
1 | getTransaction()->checkForRequestToken() == false) {
37 | throw new Exception('larapay::larapay.could_not_request_payment');
38 | }
39 |
40 | $this->checkRequiredParameters([
41 | 'merchant_id',
42 | 'order_id',
43 | 'amount',
44 | 'redirect_url',
45 | ]);
46 |
47 | $sendParams = [
48 | 'TermID' => $this->merchant_id,
49 | 'ResNum' => $this->order_id,
50 | 'TotalAmount' => intval($this->amount),
51 | ];
52 |
53 | try {
54 | $soapClient = $this->getSoapClient('token');
55 |
56 | XLog::debug('RequestToken call', $sendParams);
57 |
58 | $response = $soapClient->__soapCall('RequestToken', $sendParams);
59 |
60 | if (!empty($response)) {
61 | XLog::info('RequestToken response', ['response' => $response]);
62 |
63 | if (strlen($response) > 10) { // got string token
64 | $this->getTransaction()->setGatewayToken(strval($response)); // update transaction reference id
65 |
66 | return $response;
67 | } else {
68 | throw new Exception($response); // negative integer as error
69 | }
70 | } else {
71 | throw new Exception('larapay::larapay.invalid_response');
72 | }
73 |
74 | } catch (SoapFault $e) {
75 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
76 | }
77 | }
78 |
79 | public function generateForm(): string
80 | {
81 | XLog::debug(__METHOD__);
82 |
83 | if ($this->with_token) {
84 | return $this->generateFormWithToken()->__toString();
85 | } else {
86 | return $this->generateFormWithoutToken()->__toString(); // default
87 | }
88 | }
89 |
90 | public function formParams(): array
91 | {
92 | if ($this->with_token) {
93 | return $this->formParamsWithToken();
94 | } else {
95 | return $this->formParamsWithoutToken(); // default
96 | }
97 | }
98 |
99 | protected function generateFormWithoutToken(): \Illuminate\View\View
100 | {
101 | XLog::debug(__METHOD__, $this->getParameters());
102 |
103 | $this->checkRequiredParameters([
104 | 'merchant_id',
105 | 'amount',
106 | 'order_id',
107 | 'redirect_url',
108 | ]);
109 |
110 | return view('larapay::saman-form', [
111 | 'endPoint' => $this->getEndPoint(),
112 | 'amount' => intval($this->amount),
113 | 'merchantId' => $this->merchant_id,
114 | 'orderId' => $this->order_id,
115 | 'redirectUrl' => $this->redirect_url,
116 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
117 | 'autoSubmit' => boolval($this->auto_submit),
118 | ]);
119 | }
120 |
121 | protected function formParamsWithoutToken(): array
122 | {
123 | XLog::debug(__METHOD__, $this->getParameters());
124 |
125 | $this->checkRequiredParameters([
126 | 'merchant_id',
127 | 'amount',
128 | 'order_id',
129 | 'redirect_url',
130 | ]);
131 |
132 | return [
133 | 'endPoint' => $this->getEndPoint(),
134 | 'amount' => intval($this->amount),
135 | 'merchantId' => $this->merchant_id,
136 | 'orderId' => $this->order_id,
137 | 'redirectUrl' => $this->redirect_url,
138 | ];
139 | }
140 |
141 | protected function generateFormWithToken(): \Illuminate\View\View
142 | {
143 | XLog::debug(__METHOD__, $this->getParameters());
144 | $this->checkRequiredParameters([
145 | 'merchant_id',
146 | 'order_id',
147 | 'amount',
148 | 'redirect_url',
149 | ]);
150 |
151 | $token = $this->requestToken();
152 |
153 | XLog::info(__METHOD__, ['fetchedToken' => $token]);
154 |
155 | return view('larapay::saman-form', [
156 | 'endPoint' => $this->getEndPoint(),
157 | 'amount' => '',// just because of view
158 | 'merchantId' => '', // just because of view
159 | 'orderId' => '', // just because of view
160 | 'token' => $token,
161 | 'redirectUrl' => $this->redirect_url,
162 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
163 | 'autoSubmit' => boolval($this->auto_submit),
164 | ]);
165 | }
166 |
167 | protected function formParamsWithToken(): array
168 | {
169 | XLog::debug(__METHOD__, $this->getParameters());
170 | $this->checkRequiredParameters([
171 | 'merchant_id',
172 | 'order_id',
173 | 'amount',
174 | 'redirect_url',
175 | ]);
176 |
177 | $token = $this->requestToken();
178 |
179 | XLog::info(__METHOD__, ['fetchedToken' => $token]);
180 |
181 | return [
182 | 'endPoint' => $this->getEndPoint(),
183 | 'amount' => '',// just because of view
184 | 'merchantId' => '', // just because of view
185 | 'orderId' => '', // just because of view
186 | 'token' => $token,
187 | 'redirectUrl' => $this->redirect_url,
188 | ];
189 | }
190 |
191 | /**
192 | * @return bool
193 | * @throws Exception
194 | * @throws \PhpMonsters\Larapay\Adapter\Exception
195 | */
196 | protected function verifyTransaction(): bool
197 | {
198 | if ($this->getTransaction()->checkForVerify() == false) {
199 | throw new Exception('larapay::larapay.could_not_verify_payment');
200 | }
201 |
202 | $this->checkRequiredParameters([
203 | 'State',
204 | 'RefNum',
205 | 'ResNum',
206 | 'merchant_id',
207 | 'TraceNo',
208 | 'SecurePan'
209 | ]);
210 |
211 | if ($this->State != 'OK') {
212 | throw new Exception('Error: ' . $this->State);
213 | }
214 |
215 | try {
216 | $soapClient = $this->getSoapClient();
217 |
218 | XLog::info('VerifyTransaction call', [$this->RefNum, $this->merchant_id]);
219 | $response = $soapClient->VerifyTransaction($this->RefNum, $this->merchant_id);
220 |
221 | if (isset($response)) {
222 | XLog::info('VerifyTransaction response', ['response' => $response]);
223 |
224 | if ($response == $this->getTransaction()->getPayableAmount()) {
225 | // double check the amount by transaction amount
226 | $this->getTransaction()->setCardNumber(strval($this->SecurePan), false); // no save()
227 | $this->getTransaction()->setVerified(); // with save()
228 |
229 | return true;
230 | } else {
231 | throw new Exception($response);
232 | }
233 | } else {
234 | throw new Exception('larapay::larapay.invalid_response');
235 | }
236 |
237 | } catch (SoapFault $e) {
238 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
239 | }
240 | }
241 |
242 | /**
243 | * @return bool
244 | * @throws Exception
245 | * @throws \PhpMonsters\Larapay\Adapter\Exception
246 | */
247 | protected function reverseTransaction(): bool
248 | {
249 | if ($this->reverseSupport == false || $this->getTransaction()->checkForReverse() == false) {
250 | throw new Exception('larapay::larapay.could_not_reverse_payment');
251 | }
252 |
253 | $this->checkRequiredParameters([
254 | 'RefNum',
255 | 'merchant_id',
256 | 'merchant_pass',
257 | 'amount',
258 | ]);
259 |
260 | try {
261 | $soapClient = $this->getSoapClient();
262 |
263 | XLog::info('reverseTransaction call', [$this->RefNum, $this->merchant_id]);
264 | $response = $soapClient->reverseTransaction1(
265 | $this->RefNum,
266 | $this->merchant_id,
267 | $this->merchant_pass,
268 | $this->amount
269 | );
270 |
271 | if (isset($response)) {
272 | XLog::info('reverseTransaction response', ['response' => $response]);
273 |
274 | if ($response == 1) { // check by transaction amount
275 | $this->getTransaction()->setRefunded(true);
276 |
277 | return true;
278 | } else {
279 | throw new Exception($response);
280 | }
281 | } else {
282 | throw new Exception('larapay::larapay.invalid_response');
283 | }
284 |
285 | } catch (SoapFault $e) {
286 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
287 | }
288 | }
289 |
290 | /**
291 | * @return bool
292 | */
293 | public function canContinueWithCallbackParameters(): bool
294 | {
295 | try {
296 | $this->checkRequiredParameters([
297 | 'RefNum',
298 | 'State',
299 | ]);
300 | } catch (\Exception $e) {
301 | return false;
302 | }
303 |
304 | if ($this->State == 'OK') {
305 | return true;
306 | }
307 |
308 | return false;
309 | }
310 |
311 | /**
312 | * @return string
313 | * @throws \PhpMonsters\Larapay\Adapter\Exception
314 | */
315 | public function getGatewayReferenceId(): string
316 | {
317 | $this->checkRequiredParameters([
318 | 'RefNum',
319 | ]);
320 |
321 | return strval($this->RefNum);
322 | }
323 |
324 | /**
325 | * @param string $type
326 | *
327 | * @return string
328 | */
329 | protected function getWSDL($type = null): string
330 | {
331 |
332 | $type = $type !== null ? strtoupper($type) : null;
333 | if (config('larapay.mode') == 'production') {
334 | switch ($type) {
335 | case 'TOKEN':
336 | return $this->tokenWSDL;
337 | break;
338 | default:
339 | return $this->WSDL;
340 | break;
341 | }
342 | } else {
343 | switch ($type) {
344 | case 'TOKEN':
345 | return $this->testTokenWSDL;
346 | break;
347 | default:
348 | return $this->testWSDL;
349 | break;
350 | }
351 | }
352 | }
353 |
354 | /**
355 | * @param string type
356 | *
357 | * @return SoapClient
358 | * @throws SoapFault
359 | */
360 | protected function getSoapClient($type = null): SoapClient
361 | {
362 | return new SoapClient($this->getWSDL($type), $this->getSoapOptions());
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/src/Adapter/Saman/Exception.php:
--------------------------------------------------------------------------------
1 | getTransaction()->checkForRequestToken() === false) {
36 | throw new Exception('larapay::larapay.could_not_request_payment');
37 | }
38 |
39 | $this->checkRequiredParameters([
40 | 'merchant_id',
41 | 'amount',
42 | 'redirect_url',
43 | ]);
44 |
45 | $sendParams = [
46 | 'MerchantID' => $this->merchant_id,
47 | 'Amount' => intval($this->amount),
48 | 'Description' => $this->description ? $this->description : '',
49 | 'Email' => $this->email ? $this->email : '',
50 | 'Mobile' => $this->mobile ? $this->mobile : '',
51 | 'CallbackURL' => $this->redirect_url,
52 | ];
53 |
54 | try {
55 | $soapClient = new SoapClient($this->getWSDL());
56 |
57 | XLog::debug('PaymentRequest call', $sendParams);
58 |
59 | $response = $soapClient->PaymentRequest($sendParams);
60 |
61 | XLog::info('PaymentRequest response', $this->obj2array($response));
62 |
63 |
64 | if (isset($response->Status)) {
65 |
66 | if ($response->Status == 100) {
67 | $this->getTransaction()->setGatewayToken(strval($response->Authority)); // update transaction reference id
68 |
69 | return $response->Authority;
70 | } else {
71 | throw new Exception($response->Status);
72 | }
73 | } else {
74 | throw new Exception('larapay::larapay.invalid_response');
75 | }
76 | } catch (SoapFault $e) {
77 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
78 | }
79 | }
80 |
81 |
82 | /**
83 | * @return string
84 | * @throws Exception
85 | * @throws \PhpMonsters\Larapay\Adapter\Exception
86 | */
87 | protected function generateForm(): string
88 | {
89 | $authority = $this->requestToken();
90 |
91 | $form = view('larapay::zarinpal-form', [
92 | 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
93 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
94 | 'autoSubmit' => boolval($this->auto_submit),
95 | ]);
96 |
97 | return $form->__toString();
98 | }
99 |
100 | /**
101 | * @return array
102 | * @throws Exception
103 | * @throws \PhpMonsters\Larapay\Adapter\Exception
104 | */
105 | public function formParams(): array
106 | {
107 | $authority = $this->requestToken();
108 |
109 | return [
110 | 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
111 | ];
112 | }
113 |
114 | /**
115 | * @return bool
116 | * @throws Exception
117 | * @throws \PhpMonsters\Larapay\Adapter\Exception
118 | */
119 | protected function verifyTransaction(): bool
120 | {
121 | if ($this->getTransaction()->checkForVerify() == false) {
122 | throw new Exception('larapay::larapay.could_not_verify_payment');
123 | }
124 |
125 | $this->checkRequiredParameters([
126 | 'merchant_id',
127 | 'Authority',
128 | ]);
129 |
130 | $sendParams = [
131 | 'MerchantID' => $this->merchant_id,
132 | 'Authority' => $this->Authority,
133 | 'Amount' => intval($this->transaction->amount),
134 | ];
135 |
136 | try {
137 | $soapClient = new SoapClient($this->getWSDL());
138 |
139 | XLog::debug('PaymentVerification call', $sendParams);
140 |
141 | $response = $soapClient->PaymentVerification($sendParams);
142 |
143 | XLog::info('PaymentVerification response', $this->obj2array($response));
144 |
145 |
146 | if (isset($response->Status, $response->RefID)) {
147 |
148 | if ($response->Status == 100) {
149 | $this->getTransaction()->setVerified();
150 | $this->getTransaction()->setReferenceId((string)$response->RefID); // update transaction reference id
151 |
152 | return true;
153 | } else {
154 | throw new Exception($response->Status);
155 | }
156 | } else {
157 | throw new Exception('larapay::larapay.invalid_response');
158 | }
159 |
160 | } catch (SoapFault $e) {
161 |
162 | throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
163 | }
164 | }
165 |
166 | /**
167 | * @return bool
168 | */
169 | public function canContinueWithCallbackParameters(): bool
170 | {
171 | if ($this->Status == "OK") {
172 | return true;
173 | }
174 |
175 | return false;
176 | }
177 |
178 | public function getGatewayReferenceId(): string
179 | {
180 | $this->checkRequiredParameters([
181 | 'Authority',
182 | ]);
183 |
184 | return strval($this->Authority);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/Adapter/Zarinpal/Exception.php:
--------------------------------------------------------------------------------
1 | requestToken();
33 |
34 | return [
35 | 'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
36 | ];
37 | }
38 |
39 | /**
40 | * @return bool
41 | */
42 | public function canContinueWithCallbackParameters(): bool
43 | {
44 | if ($this->success == 1) {
45 | return true;
46 | }
47 |
48 | return false;
49 | }
50 |
51 | public function getGatewayReferenceId(): string
52 | {
53 | $this->checkRequiredParameters([
54 | 'trackid',
55 | ]);
56 | return strval($this->trackid);
57 | }
58 |
59 | /**
60 | * @return string
61 | * @throws Exception
62 | * @throws \PhpMonsters\Larapay\Adapter\Exception
63 | */
64 | protected function generateForm(): string
65 | {
66 | $authority = $this->requestToken();
67 |
68 | $form = view('larapay::zibal-form', [
69 | 'endPoint' => strtr($this->getEndPoint(), ['{trackId}' => $authority]),
70 | 'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
71 | 'autoSubmit' => boolval($this->auto_submit),
72 | ]);
73 |
74 | return $form->__toString();
75 | }
76 |
77 | /**
78 | * @return string
79 | * @throws Exception
80 | * @throws \PhpMonsters\Larapay\Adapter\Exception
81 | */
82 | protected function requestToken(): string
83 | {
84 | if ($this->getTransaction()->checkForRequestToken() === false) {
85 | throw new Exception('larapay::larapay.could_not_request_payment');
86 | }
87 |
88 | $this->checkRequiredParameters([
89 | 'merchant_id',
90 | 'amount',
91 | 'redirect_url',
92 | ]);
93 |
94 | $sendParams = [
95 | 'merchant' => $this->getSandbox(),
96 | 'orderId' => $this->getTransaction()->bank_order_id,
97 | 'amount' => intval($this->amount),
98 | 'description' => $this->description ? $this->description : '',
99 | 'mobile' => $this->mobile ? $this->mobile : '',
100 | 'callbackUrl' => $this->redirect_url,
101 | ];
102 |
103 | try {
104 | XLog::debug('PaymentRequest call', $sendParams);
105 | $result = Helper::post2https($sendParams, $this->WSDL);
106 | $resultObj = json_decode($result);
107 |
108 | XLog::info('PaymentRequest response', $this->obj2array($resultObj));
109 |
110 | if (isset($resultObj->result)) {
111 | if ($resultObj->result == 100) {
112 | $this->getTransaction()->setGatewayToken(strval($resultObj->trackId)); // update transaction reference id
113 | return strval($resultObj->trackId);
114 | } else {
115 | throw new Exception($resultObj->result);
116 | }
117 | } else {
118 | throw new Exception('larapay::larapay.invalid_response');
119 | }
120 | } catch (\Exception $e) {
121 | throw new Exception($e->getMessage());
122 | }
123 | }
124 |
125 | public function getSandbox(): string
126 | {
127 | if (config('larapay.mode') == 'production') {
128 | return $this->merchant_id;
129 | } else {
130 | return "zibal";
131 | }
132 | }
133 |
134 | /**
135 | * @return bool
136 | * @throws Exception
137 | * @throws \PhpMonsters\Larapay\Adapter\Exception
138 | */
139 | protected function verifyTransaction(): bool
140 | {
141 | if ($this->getTransaction()->checkForVerify() === false) {
142 | throw new Exception('larapay::larapay.could_not_verify_payment');
143 | }
144 |
145 | $this->checkRequiredParameters([
146 | 'status',
147 | 'trackid',
148 | ]);
149 |
150 | $sendParams = [
151 | 'merchant' => $this->getSandbox(),
152 | 'trackId' => $this->trackid,
153 | ];
154 |
155 |
156 | try {
157 | XLog::debug('PaymentRequest call', $sendParams);
158 | $result = Helper::post2https($sendParams, $this->endPointVerify);
159 | $resultObj = json_decode($result);
160 |
161 | XLog::info('PaymentRequest response', $this->obj2array($resultObj));
162 | if (isset($resultObj->result)) {
163 | if ($resultObj->result == 100 || $resultObj->result == 201) {
164 | $this->getTransaction()->setVerified();
165 | $this->getTransaction()->setReferenceId((string) $this->trackId);
166 | return true;
167 | } else {
168 | throw new Exception($resultObj->result);
169 | }
170 | } else {
171 | throw new Exception('larapay::larapay.invalid_response');
172 | }
173 | } catch (\Exception $e) {
174 | throw new Exception($e->getMessage());
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/Adapter/Zibal/Exception.php:
--------------------------------------------------------------------------------
1 | setSoapOptions(config('larapay.soap.options'));
65 | }
66 |
67 | $this->gateway = $bankAdapter;
68 |
69 | return $this;
70 | }
71 |
72 | public function verifyTransaction(Request $request, array $adapterConfig = [])
73 | {
74 | //get gateway and transaction id from request
75 | $gateway = $request->gateway;
76 | $transactionId = $request->transaction_id;
77 |
78 | $parameters = $request->all();
79 | $parameters ['routes'] = $request->route()->parameters();
80 | //log all incoming data for debug request
81 | XLog::debug('request: ', $parameters);
82 |
83 |
84 | $referenceId = '';
85 | $paidTime = '';
86 | $amount = '';
87 |
88 | //validate incoming request parameters
89 | $validator = Validator::make([
90 | 'transactionId' => $transactionId,
91 | 'gateway' => $gateway,
92 | ], [
93 | 'transactionId' => [
94 | 'required',
95 | 'numeric',
96 | ],
97 | 'gateway' => [
98 | 'required',
99 | ],
100 | ]);
101 |
102 | // validate required route parameters
103 | if ($validator->fails()) {
104 | throw new FailedTransactionException(trans('larapay::larapay.invalid_response'));
105 | }
106 | // find the transaction by token
107 | $transaction = LarapayTransaction::find($transactionId);
108 | //transaction not found in our database
109 | if (!$transaction) {
110 | throw new TransactionNotFoundException(trans('larapay::larapay.transaction_not_found'), 2);
111 | }
112 | //transaction gateway conflict
113 | if ($transaction->gate_name != $gateway) {
114 | throw new TransactionNotFoundException(trans('larapay::larapay.transaction_not_found'), 3);
115 | }
116 |
117 | try {
118 | // update transaction`s callback parameter
119 | $transaction->setCallBackParameters($request->all(), true);
120 |
121 | //read gateway property from transaction and make payment gateway handler
122 | $paymentGatewayHandler = $this->make($gateway, $transaction, $adapterConfig);
123 |
124 | //check that it's correct data and we can continue with this parameters
125 | if ($paymentGatewayHandler->canContinueWithCallbackParameters($request->all()) !== true) {
126 | throw new FailedTransactionException(trans('larapay::larapay.invalid_response'));
127 | }
128 |
129 | //get reference id from callback data
130 | $referenceId = $paymentGatewayHandler->getGatewayReferenceId();
131 |
132 | //search or transaction to detect double spending
133 | $doubleInvoice = LarapayTransaction::where('gate_refid', $referenceId)
134 | ->where('verified', true)//قبلا وریفای شده
135 | ->where('gate_name', $transaction->gate_name)
136 | ->first();
137 |
138 | //found double transaction
139 | if (!empty($doubleInvoice)) {
140 | // log double spending details
141 | XLog::emergency('referenceId double spending detected', [
142 | 'tag' => $referenceId,
143 | 'order_id' => $transaction->gateway_order_id,
144 | 'ips' => $request->ips(),
145 | 'gateway' => $gateway,
146 | ]);
147 |
148 | //update transaction and log double spending
149 | if (!preg_match('/DOUBLE_SPENDING/i', $transaction->description)) {
150 | $transaction->description = "#DOUBLE_SPENDING_BY_{$doubleInvoice->id}#\n" . $transaction->description;
151 | $transaction->save();
152 | }
153 | //throw new exception and stop verify transaction
154 | throw new FailedTransactionException(trans('larapay::larapay.could_not_verify_transaction'));
155 | }
156 |
157 | //set reference id on transaction
158 | $transaction->setReferenceId($referenceId);
159 |
160 | // verify start ----------------------------------------------------------------------------------------
161 | $verified = false;
162 | // try 3 times for verify transaction
163 | for ($i = 1; $i <= 3; $i++) {
164 | try {
165 | XLog::info('trying to verify payment',
166 | ['try' => $i, 'tag' => $referenceId, 'gateway' => $gateway]);
167 |
168 | $verifyResult = $paymentGatewayHandler->verify();
169 | if ($verifyResult) {
170 | $verified = true;
171 | }
172 | XLog::info('verify result',
173 | ['result' => $verifyResult, 'try' => $i, 'tag' => $referenceId, 'gateway' => $gateway]);
174 | break;
175 | } catch (Exception $e) {
176 | XLog::error('Exception: ' . $e->getMessage(),
177 | ['try' => $i, 'tag' => $referenceId, 'gateway' => $gateway]);
178 | usleep(500);
179 | continue;
180 | }
181 | }
182 |
183 | //check if transaction verified
184 | if ($verified !== true) {
185 | XLog::error('transaction verification failed', ['tag' => $referenceId, 'gateway' => $gateway]);
186 | throw new FailedTransactionException(trans('larapay::larapay.verification_failed'));
187 | } else {
188 | XLog::info('invoice verified successfully', ['tag' => $referenceId, 'gateway' => $gateway]);
189 | }
190 | // verify end ------------------------------------------------------------------------------------------
191 |
192 | // after verify start ----------------------------------------------------------------------------------
193 | $afterVerified = false;
194 | // try 3 times for after verify transaction
195 | for ($i = 1; $i <= 3; $i++) {
196 | try {
197 | XLog::info('trying to after verify payment',
198 | ['try' => $i, 'tag' => $referenceId, 'gateway' => $gateway]);
199 |
200 | $afterVerifyResult = $paymentGatewayHandler->afterVerify();
201 | if ($afterVerifyResult) {
202 | $afterVerified = true;
203 | }
204 | XLog::info('after verify result', [
205 | 'result' => $afterVerifyResult,
206 | 'try' => $i,
207 | 'tag' => $referenceId,
208 | 'gateway' => $gateway,
209 | ]);
210 | break;
211 | } catch (Exception $e) {
212 | XLog::error('Exception: ' . $e->getMessage(),
213 | ['try' => $i, 'tag' => $referenceId, 'gateway' => $gateway]);
214 | usleep(500);
215 | continue;
216 | }
217 | }
218 |
219 | if ($afterVerified !== true) {
220 | XLog::error('transaction after verification failed',
221 | ['tag' => $referenceId, 'gateway' => $gateway]);
222 | throw new FailedTransactionException(trans('larapay::larapay.after_verification_failed'));
223 | } else {
224 | XLog::info('invoice after verified successfully', ['tag' => $referenceId, 'gateway' => $gateway]);
225 | }
226 |
227 | // after verify end ------------------------------------------------------------------------------------
228 | } catch (Exception $e) {
229 | XLog::emergency($e->getMessage() . ' code:' . $e->getCode() . ' ' . $e->getFile() . ':' . $e->getLine());
230 | throw new FailedTransactionException($e->getMessage(), $e->getCode(), $e);
231 | }
232 |
233 | //transaction done successfully
234 | XLog::info('invoice completed successfully', ['tag' => $referenceId, 'gateway' => $gateway]);
235 | //set transaction date time
236 | $transaction->setPaidAt('now');
237 | //set accomplished true on transaction and save it.
238 | $transaction->setAccomplished(true);
239 | //return transaction
240 | return $transaction;
241 | }
242 |
243 | /**
244 | * @param $name
245 | * @param $arguments
246 | *
247 | * @return mixed
248 | * @throws Exception
249 | */
250 | public function __call($name, $arguments)
251 | {
252 | if (empty($this->gateway)) {
253 | throw new Exception("Gateway not defined before! please use make method to initialize gateway");
254 | }
255 |
256 | XLog::info($name, $arguments);
257 |
258 | // چو ن همیشه متد ها با یک پارامتر کلی بصورت آرایه فراخوانی میشوند. مثلا:
259 | // $paymentGatewayHandler->generateForm($ArrayOfExtraPaymentParams)
260 | if (count($arguments) > 0) {
261 | $this->gateway->setParameters($arguments[0]); // set parameters
262 | }
263 |
264 | try {
265 | return call_user_func_array([$this->gateway, $name], $arguments); // call desire method
266 | } catch (Exception $e) {
267 | XLog::error($e->getMessage() . ' Code:' . $e->getCode() . ' File:' . $e->getFile() . ':' . $e->getLine());
268 | throw $e;
269 | }
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/src/LarapayServiceProvider.php:
--------------------------------------------------------------------------------
1 | registerResources();
22 | $this->registerPublishing();
23 | $this->registerModelBindings();
24 | }
25 |
26 | /**
27 | * Get the services provided by the provider.
28 | *
29 | * @return array
30 | */
31 | public function register()
32 | {
33 | $this->app->singleton('larapay', function ($app) {
34 | return new Factory;
35 | });
36 | }
37 |
38 | protected function registerResources()
39 | {
40 | $this->loadViewsFrom(__DIR__ . '/../views/', 'larapay');
41 |
42 | $this->publishes([
43 | __DIR__ . '/../translations/' => resource_path('lang/vendor/larapay'),
44 | ], 'translations');
45 |
46 | $this->loadTranslationsFrom(__DIR__ . '/../translations', 'larapay');
47 | }
48 |
49 | protected function registerPublishing()
50 | {
51 | $this->publishes([
52 | __DIR__ . '/../config/larapay.php' => config_path('larapay.php')
53 | ], 'config');
54 |
55 | $this->publishes([
56 | __DIR__ . '/../views/' => resource_path('/views/vendor/larapay'),
57 | ], 'views');
58 |
59 |
60 | $this->publishes([
61 | __DIR__ . '/../database/migrations/create_larapay_transaction_table.php.stub' => database_path('migrations/' . date('Y_m_d_His',
62 | time()) . '_create_larapay_transaction_table.php'),
63 | ], 'migrations');
64 | }
65 |
66 |
67 | protected function registerModelBindings()
68 | {
69 | $this->app->bind(LarapayTransactionContract::class, LarapayTransaction::class);
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/Models/Enum/Bank.php:
--------------------------------------------------------------------------------
1 | morphTo();
53 | }
54 |
55 | public function reverseTransaction()
56 | {
57 | //make payment gateway handler
58 | $gatewayProperties = json_decode($this->extra_params, true);
59 | $paymentGatewayHandler = Larapay::make($this->gate_name, $this, $gatewayProperties);
60 | //$paymentGatewayHandler->setParameters($gatewayProperties);
61 | //get reference id
62 | $referenceId = $paymentGatewayHandler->getGatewayReferenceId();
63 | //try 3 times to reverse transaction
64 | $reversed = false;
65 | for ($i = 1; $i <= 3; $i++) {
66 | try {
67 | $reverseResult = $paymentGatewayHandler->reverse();
68 | if ($reverseResult) {
69 | $reversed = true;
70 | }
71 |
72 | break;
73 | } catch (Exception $e) {
74 | XLog::error('Exception: ' . $e->getMessage(), ['try' => $i, 'tag' => $referenceId]);
75 | usleep(500);
76 | continue;
77 | }
78 | }
79 | //throw exception when 3 times failed
80 | if ($reversed !== true) {
81 | XLog::error('invoice reverse failed', ['tag' => $referenceId]);
82 | throw new FailedReverseTransactionException(trans('larapay::larapay.reversed_failed'));
83 | }
84 |
85 | //set reversed flag
86 | $this->reversed = true;
87 | $this->save();
88 | //log true result
89 | XLog::info('invoice reversed successfully', ['tag' => $referenceId]);
90 |
91 | return true;
92 | }
93 |
94 | public function generateForm($autoSubmit = false, $callback = null, $adapterConfig = [])
95 | {
96 | $paymentGatewayHandler = $this->gatewayHandler($adapterConfig);
97 |
98 | $callbackRoute = route(config("larapay.payment_callback"), [
99 | 'gateway' => $this->gate_name,
100 | 'transaction_id' => $this->id,
101 | ]);
102 |
103 | if ($callback != null) {
104 | $callbackRoute = route($callback, [
105 | 'gateway' => $this->gate_name,
106 | 'transaction_id' => $this->id,
107 | ]);
108 | }
109 |
110 | $paymentParams = [
111 | 'order_id' => $this->getBankOrderId(),
112 | 'redirect_url' => $callbackRoute,
113 | 'amount' => $this->amount,
114 | 'sharing' => json_decode($this->sharing, true),
115 | 'submit_label' => trans('larapay::larapay.goto_gate'),
116 | ];
117 |
118 | try {
119 | if ($autoSubmit) {
120 | $paymentParams['auto_submit'] = true;
121 | }
122 |
123 | $form = $paymentGatewayHandler->form($paymentParams);
124 |
125 | return $form;
126 | } catch (Exception $e) {
127 | XLog::emergency($this->gate_name . ' #' . $e->getCode() . '-' . $e->getMessage());
128 |
129 | throw $e;
130 | }
131 | }
132 |
133 | public function formParams($callback = null, $adapterConfig = []): array
134 | {
135 |
136 | $paymentGatewayHandler = $this->gatewayHandler($adapterConfig);
137 |
138 | $callbackRoute = route(config("larapay.payment_callback"), [
139 | 'gateway' => $this->gate_name,
140 | 'transaction_id' => $this->id,
141 | ]);
142 |
143 | if ($callback != null) {
144 | $callbackRoute = route($callback, [
145 | 'gateway' => $this->gate_name,
146 | 'transaction_id' => $this->id,
147 | ]);
148 | }
149 |
150 | $paymentParams = [
151 | 'order_id' => $this->getBankOrderId(),
152 | 'redirect_url' => $callbackRoute,
153 | 'amount' => $this->amount,
154 | 'sharing' => json_decode($this->sharing, true),
155 | 'submit_label' => trans('larapay::larapay.goto_gate'),
156 | ];
157 |
158 | try {
159 | return $paymentGatewayHandler->formParams($paymentParams);
160 | } catch (Exception $e) {
161 | XLog::emergency($this->gate_name . ' #' . $e->getCode() . '-' . $e->getMessage());
162 |
163 | return [];
164 | }
165 | }
166 |
167 | public function gatewayHandler($adapterConfig = [])
168 | {
169 | return Larapay::make($this->gate_name, $this, $adapterConfig);
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/Models/Traits/OnlineTransactionTrait.php:
--------------------------------------------------------------------------------
1 | gate_refid = $referenceId;
11 | if ($save) {
12 | return $this->save();
13 | }
14 |
15 | return true;
16 | }
17 |
18 | public function checkForRequestToken(): bool
19 | {
20 | return $this->veified != true;
21 | }
22 |
23 | public function checkForVerify(): bool
24 | {
25 | return $this->veified != true;
26 | }
27 |
28 | public function checkForInquiry(): bool
29 | {
30 | return true;
31 | }
32 |
33 | public function checkForAfterVerify(): bool
34 | {
35 | return $this->after_verified != true;
36 | }
37 |
38 | public function checkForReverse(): bool
39 | {
40 | return $this->after_verified == true && $this->reversed != true;
41 | }
42 |
43 | public function setCardNumber(string $cardNumber, bool $save = true): bool
44 | {
45 | return $this->setExtra('customer_card_number', $cardNumber, $save);
46 | }
47 |
48 | public function setVerified(bool $save = true): bool
49 | {
50 | $this->verified = true;
51 |
52 | if ($save) {
53 | return $this->save();
54 | }
55 |
56 | return true;
57 | }
58 |
59 | public function setAfterVerified(bool $save = true): bool
60 | {
61 | $this->after_verified = true;
62 |
63 | if ($save) {
64 | return $this->save();
65 | }
66 |
67 | return true;
68 | }
69 |
70 | public function setSuccessful($flag, $save = true): bool
71 | {
72 | $this->accomplished = boolval($flag);
73 |
74 | if ($save) {
75 | return $this->save();
76 | }
77 |
78 | return true;
79 | }
80 |
81 | public function setReversed($save = true): bool
82 | {
83 | $this->reversed = true;
84 | $this->accomplished = false;
85 |
86 | if ($save) {
87 | return $this->save();
88 | }
89 |
90 | return true;
91 | }
92 |
93 | public function getAmount()
94 | {
95 | return abs($this->amount);
96 | }
97 |
98 | public function getBankOrderId()
99 | {
100 | return $this->bank_order_id;
101 | }
102 |
103 | public function setPaidAt($time = 'now', $save = false)
104 | {
105 | $this->paid_at = date('Y-m-d H:i:s', strtotime($time));
106 |
107 | if ($save) {
108 | return $this->save();
109 | }
110 |
111 | return true;
112 | }
113 |
114 |
115 | public function getPayableAmount(): int
116 | {
117 | return $this->getAmount();
118 | }
119 |
120 | public function setRefunded(bool $save = true): bool
121 | {
122 | $this->reversed = true;
123 | $this->accomplished = false;
124 |
125 | if ($save) {
126 | return $this->save();
127 | }
128 |
129 | return true;
130 | }
131 |
132 | public function setAccomplished(bool $save = true): bool
133 | {
134 |
135 | $this->accomplished = true;
136 |
137 | if ($save) {
138 | return $this->save();
139 | }
140 |
141 | return true;
142 | }
143 |
144 | public function setCallBackParameters(array $parameters, bool $save = true): bool
145 | {
146 | $this->extra_params = json_encode($parameters, JSON_UNESCAPED_UNICODE);
147 |
148 | if ($save) {
149 | $this->save();
150 | }
151 |
152 | return true;
153 | }
154 |
155 | public function setGatewayToken(string $token, bool $save = true): bool
156 | {
157 | $this->gate_refid = $token;
158 | if ($save) {
159 | $this->save();
160 | }
161 |
162 | return true;
163 | }
164 |
165 | public function setExtra(string $key, $value, bool $save = true): bool
166 | {
167 | $value = (array)$value;
168 |
169 | $extra = json_decode($this->extra_params, true);
170 |
171 | if (isset($extra[$key])) {
172 | $oldKey = $key . '_' . time();
173 | $extra[$oldKey] = $extra[$key];
174 | }
175 |
176 | $extra[$key] = $value;
177 | $this->extra_params = json_encode($extra, JSON_UNESCAPED_UNICODE);
178 |
179 | if ($save) {
180 | $this->save();
181 | }
182 |
183 | return true;
184 | }
185 |
186 | }
187 |
--------------------------------------------------------------------------------
/src/Payable.php:
--------------------------------------------------------------------------------
1 | morphMany(app(LarapayTransactionContract::class), 'model');
16 | }
17 |
18 | public function accomplishedTransactions()
19 | {
20 | return $this->morphMany(app(LarapayTransactionContract::class), 'model')->where('accomplished', true);
21 | }
22 |
23 | public function isPaid()
24 | {
25 | $accomplishedTransactions = $this->accomplishedTransactions;
26 | if ($accomplishedTransactions->count() != 0) {
27 | return true;
28 | }
29 |
30 | return false;
31 | }
32 |
33 | public function paidAmount()
34 | {
35 | $accomplishedTransactions = $this->accomplishedTransactions;
36 | $amount = 0;
37 | foreach ($accomplishedTransactions as $accomplishedTransaction) {
38 | $amount += $accomplishedTransaction->amount;
39 | }
40 |
41 | return $amount;
42 | }
43 |
44 | public function createTransaction(
45 | $paymentGateway,
46 | $amount = null,
47 | $description = null,
48 | array $additionalData = [],
49 | array $sharing = []
50 | ) {
51 |
52 | $transactionData = [];
53 |
54 | $transactionData['amount'] = $amount;
55 | if ($amount == null) {
56 | $transactionData['amount'] = $this->getAmount();
57 | }
58 |
59 | if ($transactionData['amount'] == null || $transactionData['amount'] == 0) {
60 | throw new EmptyAmountException();
61 | }
62 |
63 | $paymentGateway = ucfirst(strtolower($paymentGateway));
64 |
65 | $transactionData['description'] = $description;
66 | $transactionData['gate_name'] = $paymentGateway;
67 | $transactionData['submitted'] = true;
68 | $transactionData['bank_order_id'] = $this->generateBankOrderId($paymentGateway);
69 | $transactionData['payment_method'] = 'ONLINE';
70 | $transactionData['additional_data'] = empty($additionalData) ? '{}' : json_encode($additionalData, JSON_UNESCAPED_UNICODE);
71 | $transactionData['sharing'] = empty($sharing) ? '{}' : json_encode($sharing, JSON_UNESCAPED_UNICODE);
72 |
73 | return $this->transactions()->create($transactionData);
74 | }
75 |
76 | public function getAmount()
77 | {
78 | return intval($this->amount) * 10;
79 | }
80 |
81 | public function generateBankOrderId(string $bank = null): int
82 | {
83 | // handle each gateway exception
84 | switch ($bank) {
85 | default:
86 | {
87 | return time() . mt_rand(10, 99);
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Transaction/TransactionInterface.php:
--------------------------------------------------------------------------------
1 | 'خطای هندل نشده!', // unofficial error code --- added by PhpMonsters
5 |
6 | 'canceled_by_user' => 'تراکنش بانکی توسط کاربر لغو شد',
7 | 'could_not_request_payment' => 'امکان درخواست توکن برای این تراکنش وجود ندارد',
8 | 'could_not_verify_transaction' => 'امکان تایید این تراکنش وجود ندارد',
9 | 'could_not_inquiry_payment' => 'امکان استعلام این تراکنش وجود ندارد',
10 | 'could_not_settle_payment' => 'امکان درخواست واریز وجه برای این تراکنش وجود ندارد',
11 | 'could_not_reverse_payment' => 'انمان بازگشت این تراکنش وجود ندارد',
12 | 'gate_not_ready' => 'درگاه پرداختی یا وجود ندارد یا آماده سرویس دهی نمی باشد',
13 | 'gate_not_implemented_larapay' => 'دروازه پرداخت :name از PhpMonsters\\Larapay\\Adapter\\AdapterInterface پیروی نمی کند',
14 | 'goto_gate' => 'اتصال به درگاه پرداخت',
15 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
16 | 'reversed_failed' => 'بازگشت تراکنش با موفقیت انجام نشد!',
17 | 'verification_failed' => 'تایید تراکنش با موفقیت انجام نشد!',
18 | 'after_verification_failed' => 'تایید بعد از تراکنش با موفقیت انجام نشد!',
19 | 'invalid_sharing_data' => 'اطلاعات تسهیم معتبر نیست',
20 | 'transaction_not_found' => 'تراکنش پیدا نشد',
21 |
22 | 'mellat' => [
23 | 'errors' => [
24 | 'error_11' => 'شماره کارت نامعتبر است',
25 | 'error_12' => 'موجودی کافی نیست',
26 | 'error_13' => 'رمز نادرست است',
27 | 'error_14' => 'تعداد دفعات وارد کردن رمز بیش از حد مجاز است',
28 | 'error_15' => 'کارت نامعتبر است',
29 | 'error_16' => 'دفعات برداشت وجه بیش از حد مجاز است',
30 | 'error_17' => 'کاربر از انجام تراکنش منصرف شده است',
31 | 'error_18' => 'تاریخ انقضای کارت گذشته است',
32 | 'error_19' => 'مبلغ برداشت وجه بیش از حد مجاز است',
33 | 'error_21' => 'پذیرنده نامعتبر است',
34 | 'error_23' => 'خطای امنیتی رخ داده است',
35 | 'error_24' => 'اطلاعات کاربری پذیرنده نامعتبر است',
36 | 'error_25' => 'مبلغ نامعتبر است',
37 | 'error_31' => 'پاسخ نامعتبر است',
38 | 'error_32' => 'فرمت اطلاعات وارد شده صحیح نمیباشد',
39 | 'error_33' => 'حساب نامعتبر است',
40 | 'error_34' => 'خطای سیستمی',
41 | 'error_35' => 'تاریخ نامعتبر است',
42 | 'error_41' => 'شماره درخواست تکراری است',
43 | 'error_42' => 'تراکنش Sale یافت نشد',
44 | 'error_43' => 'قبلا درخواست Verfiy داده شده است',
45 | 'error_44' => 'درخواست Verfiy یافت نشد',
46 | 'error_45' => 'تراکنش Settle شده است',
47 | 'error_46' => 'تراکنش Settle نشده است',
48 | 'error_47' => 'تراکنش Settle یافت نشد',
49 | 'error_48' => 'تراکنش Reverse شده است',
50 | 'error_49' => 'تراکنش Refund یافت نشد.',
51 | 'error_51' => 'تراکنش تکراری است',
52 | 'error_54' => 'تراکنش مرجع موجود نیست',
53 | 'error_55' => 'تراکنش نامعتبر است',
54 | 'error_61' => 'خطا در واریز',
55 | 'error_111' => 'صادر کننده کارت نامعتبر است',
56 | 'error_112' => 'خطای سوییچ صادر کننده کارت',
57 | 'error_113' => 'پاسخی از صادر کننده کارت دریافت نشد',
58 | 'error_114' => 'دارنده این کارت مجاز به انجام این تراکنش نیست',
59 | 'error_412' => 'شناسه قبض نادرست است',
60 | 'error_413' => 'شناسه پرداخت نادرست است',
61 | 'error_414' => 'سازمان صادر کننده قبض نامعتبر است',
62 | 'error_415' => 'زمان جلسه کاری به پایان رسیده است',
63 | 'error_416' => 'خطا در ثبت اطلاعات',
64 | 'error_417' => 'شناسه پرداخت کننده نامعتبر است',
65 | 'error_418' => 'اشکال در تعریف اطلاعات مشتری',
66 | 'error_419' => 'تعداد دفعات ورود اطلاعات از حد مجاز گذشته است',
67 | 'error_421' => 'IP نامعتبر است',
68 |
69 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
70 | ]
71 | ],
72 | 'parsian' => [
73 | 'errors' => [
74 | 'error_20' => 'پین فروشنده درست نمی باشد',
75 | 'error_22' => 'پین فروشنده درست نمی باشد',
76 | 'error_30' => 'عملیات قبلا با موفقیت انجام شده است',
77 | 'error_34' => 'شماره تراکنش فرونشده درست نمی باشد',
78 |
79 | 'could_not_continue_with_non0_rs' => 'امکان تایید این تراکنش از سمت درگاه پرداخت وجود ندارد',
80 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
81 | ]
82 | ],
83 | 'pasargad' => [
84 | 'errors' => [
85 |
86 | ]
87 | ],
88 | 'saderat' => [
89 | 'errors' => [
90 | 'error_1' => 'وجود خطا در فرمت اطلاعات ارسالی',
91 | 'error_2' => 'عدم وجود پذیرنده و ترمینال مورد درخواست در سیستم',
92 | 'error_3' => 'رد درخواست به علت دریافت درخواست توسط آدرس آی پی نامعتبر',
93 | 'error_4' => 'پذیرنده مورد نظر امکان استفاده از سیستم را ندارد',
94 | 'error_5' => 'برخورد با مشکل در انجام درخواست مورد نظر',
95 | 'error_6' => 'خطا در پردازش درخواست',
96 | 'error_7' => 'بروز خطا در تشخیص اصالت اطلاعات (امضای دیجیتالی نامعتبر است)',
97 | 'error_8' => 'شماره خرید ارائه شده توسط پذیرنده (CRN) تکراری است',
98 | 'error_9' => 'سیستم در حال حاضر قادر به سرویس دهی نمی باشد (این پیام هنگام بروزرسانی سرور برگردانده می شود)',
99 | 'error_102' => 'تراکنش مورد نظر برگشت خورده است',
100 | 'error_103' => 'تایید انجام نشد',
101 | 'error_106' => 'پیامی از سوییچ پرداخت دریافت نشد',
102 | 'error_107' => 'تراکنش درخواستی موجود نیست',
103 | 'error_111' => 'مشکل در ارتباط با سوییچ',
104 | 'error_112' => 'مقادیر ارسالی در درخواست معتبر نیستند',
105 | 'error_113' => 'خطای سمت سرور (مربوط به واحد فنی PSP)',
106 | 'error_200' => 'تراکنش بانکی توسط کاربر لغو شد',
107 | 'error__1' => 'امضای دیجیتال مشکل دارد و با اطلاعات ارسالی همخوانی ندارد',
108 | 'error__2' => 'دسترسی از IP غیر مجاز است',
109 |
110 | 'making_openssl_sign_error' => 'ایجاد امضای دیجیتال با استفاده از openssl موفقیت آمیز نبود',
111 | 'invalid_verify_result' => 'اطلاعات دریافتی از درگاه پرداخت معتبر نمی باشد',
112 | 'invalid_transaction' => 'تراکنش شما معتبر نیست',
113 | 'public_key_file_not_found' => 'فایل public key در مسیر مورد نظر وجود ندارد',
114 | 'private_key_file_not_found' => 'فایل private key در مسیر مورد نظر وجود ندارد',
115 | ]
116 | ],
117 | 'zarinpal' => [
118 | 'errors' => [
119 | 'error_101' => 'عملیات پرداخت موفق بوده و قبلا PaymentVerification تراکنش انجام شده است',
120 |
121 | 'error__1' => 'اطلاعات ارسال شده ناقص است', //-1
122 | 'error__2' => 'IP و یا مرچنت کد پذیرنده صحیح نیست', //-1
123 | 'error__3' => 'با توجه به محدودیتهای شاپرک امکان پرداخت با رقم درخواست شده میسر نمی باشد',
124 | 'error__4' => 'سطح تایید پذیرنده پایین تز از سطح نقره است',
125 | 'error__11' => 'درخواست مورد نظر یافت نشد',
126 | 'error__12 '=> 'امکان ویرایش درخواست میسر نمی باشد',
127 | 'error__21 '=> 'هیچ نوع عملیات مالی برای این تراکنش یافت نشد',
128 | 'error__22 '=> 'تراکنش ناموفق می باشد',
129 | 'error__33 '=> 'رقم تراکنش با رقم پرداخت شده مطابقت ندارد',
130 | 'error__34 '=> 'سقف تقیسم تراکنش از لحاظ تعداد یا رقم عبور نموده است',
131 | 'error__40 '=> 'اجازه دسترسی به متد مربوطه وجود ندارد',
132 | 'error__41 '=> 'اطلاعات ارسال شده به AdditionalData غیر معتبر می باشد',
133 | 'error__42 '=> 'مدت زمان معتبر طول عمر شناسه پرداخت باید بین ۳۰ دقیقه تا ۴۵ روز باشد',
134 | 'error__54 '=> 'درخواست مورد نظر آرشیو شده است',
135 | ]
136 | ],
137 | 'idpay' => [
138 | 'errors' => [
139 | "error_1" => "پرداخت انجام نشده است.",
140 | "error_2" => "پرداخت ناموفق بوده است.",
141 | "error_3" => "خطا رخ داده است.",
142 | "error_4" => "بلوکه شده.",
143 | "error_5" => "برگشت به پرداخت کننده.",
144 | "error_6" => "برگشت خورده سیستمی.",
145 | "error_10" => "در انتظار تایید پرداخت.",
146 | "error_100" => "پرداخت تایید شده است.",
147 | "error_101" => "پرداخت قبلا تایید شده است.",
148 | "error_200" => "به دریافت کننده واریز شد.",
149 | "error_11" => "کاربر مسدود شده است.",
150 | "error_12" => "API Key یافت نشد.",
151 | "error_13" => "درخواست شما از {ip} ارسال شده است. این IP با IP های ثبت شده در وب سرویس همخوانی ندارد.",
152 | "error_14" => "وب سرویس تایید نشده است.",
153 | "error_21" => "حساب بانکی متصل به وب سرویس تایید نشده است.",
154 | "error_31" => "کد تراکنش id نباید خالی باشد.",
155 | "error_32" => "شماره سفارش order_id نباید خالی باشد.",
156 | "error_33" => "مبلغ amount نباید خالی باشد.",
157 | "error_34" => "مبلغ amount باید بیشتر از {min-amount} ریال باشد.",
158 | "error_35" => "مبلغ amount باید کمتر از {max-amount} ریال باشد.",
159 | "error_36" => "مبلغ amount بیشتر از حد مجاز است.",
160 | "error_37" => "آدرس بازگشت callback نباید خالی باشد.",
161 | "error_38" => "درخواست شما از آدرس {domain} ارسال شده است. دامنه آدرس بازگشت callback با آدرس ثبت شده در وب سرویس همخوانی ندارد.",
162 | "error_51" => "تراکنش ایجاد نشد.",
163 | "error_52" => "استعلام نتیجه ای نداشت.",
164 | "error_53" => "تایید پرداخت امکان پذیر نیست.",
165 | "error_54" => "مدت زمان تایید پرداخت سپری شده است.",
166 | ]
167 | ],
168 | 'zibal' => [
169 | 'errors' => [
170 | "error_-1" => "در انتظار پردخت.",
171 | "error_-2" => "خطای داخلی.",
172 | "error_1" => "پرداخت شده - تاییدشده.",
173 | "error_2" => "پرداخت شده - تاییدنشده.",
174 | "error_3" => "لغوشده توسط کاربر.",
175 | "error_4" => "شماره کارت نامعتبر میباشد.",
176 | "error_5" => "موجودی حساب کافی نمیباشد.",
177 | "error_6" => "رمز واردشده اشتباه میباشد.",
178 | "error_8" => "تعداد درخواستها بیش از حد مجاز میباشد.",
179 | "error_9" => "مبلغ پرداخت اینترنتی روزانه بیش از حد مجاز میباشد.",
180 | "error_10" => "صادرکنندهی کارت نامعتبر میباشد.",
181 | "error_11" => "خطای سوییچ",
182 | "error_12" => "کارت قابل دسترسی نمیباشد.",
183 | "error_102" => "merchant یافت نشد.",
184 | "error_104" => "merchant نامعتبر",
185 | "error_103" => "merchant غیرفعال",
186 | "error_201" => "پرداخت قبلا تایید شده است.",
187 | "error_202" => "سفارش پرداخت نشده یا ناموفق بوده است. جهت اطلاعات بیشتر جدول وضعیتها را مطالعه کنید.",
188 | "error_203" => "trackId نامعتبر میباشد.",
189 | ]
190 | ],
191 | 'payir' => [
192 | 'errors' => [
193 | 'error_0' => 'درحال حاضر درگاه بانکی قطع شده و مشکل بزودی برطرف می شود',
194 | 'error_-1' => 'API Key ارسال نمی شود',
195 | 'error_-2' => 'Token ارسال نمی شود',
196 | 'error_-3' => 'API Key ارسال شده اشتباه است',
197 | 'error_-4' => 'امکان انجام تراکنش برای این پذیرنده وجود ندارد',
198 | 'error_-5' => 'تراکنش با خطا مواجه شده است',
199 | 'error_-6' => 'تراکنش تکراریست یا قبلا انجام شده',
200 | 'error_-7' => 'مقدار Token ارسالی اشتباه است',
201 | 'error_-8' => 'شماره تراکنش ارسالی اشتباه است',
202 | 'error_-9' => 'زمان مجاز برای انجام تراکنش تمام شده',
203 | 'error_-10' => 'مبلغ تراکنش ارسال نمی شود',
204 | 'error_-11' => 'مبلغ تراکنش باید به صورت عددی و با کاراکترهای لاتین باشد',
205 | 'error_-12' => 'مبلغ تراکنش می بایست عددی بین 10,000 و 500,000,000 ریال باشد',
206 | 'error_-13' => 'مقدار آدرس بازگشتی ارسال نمی شود',
207 | 'error_-14' => 'آدرس بازگشتی ارسالی با آدرس درگاه ثبت شده در شبکه پرداخت پی یکسان نیست',
208 | 'error_-15' => 'امکان وریفای وجود ندارد. این تراکنش پرداخت نشده است',
209 | 'error_-16' => 'یک یا چند شماره موبایل از اطلاعات پذیرندگان ارسال شده اشتباه است',
210 | 'error_-17' => 'میزان سهم ارسالی باید بصورت عددی و بین 1 تا 100 باشد',
211 | 'error_-18' => 'فرمت پذیرندگان صحیح نمی باشد',
212 | 'error_-19' => 'هر پذیرنده فقط یک سهم میتواند داشته باشد',
213 | 'error_-20' => 'مجموع سهم پذیرنده ها باید 100 درصد باشد',
214 | 'error_-21' => 'Reseller ID ارسالی اشتباه است',
215 | 'error_-22' => 'فرمت یا طول مقادیر ارسالی به درگاه اشتباه است',
216 | 'error_-23' => 'سوییچ PSP ( درگاه بانک ) قادر به پردازش درخواست نیست. لطفا لحظاتی بعد مجددا تلاش کنید',
217 | 'error_-24' => 'شماره کارت باید بصورت 16 رقمی، لاتین و چسبیده بهم باشد',
218 | 'error_-25' => 'امکان استفاده از سرویس در کشور مبدا شما وجود نداره',
219 | 'error_-26' => 'امکان انجام تراکنش برای این درگاه وجود ندارد',
220 | 'error_-27' => 'در انتظار تایید درگاه توسط شاپرک',
221 | 'error_-28' => 'امکان تسهیم تراکنش برای این درگاه وجود ندارد',
222 | ]
223 | ],
224 | 'nextpay' => [
225 | 'errors' => [
226 | 'error_0' => "تراکنش تکمیل و موفق است",
227 | 'error_-1' => "حالت پیش فرض تراکنش",
228 | 'error_-2' => "خطای بانکی یا انصراف از پرداخت",
229 | 'error_-3' => "در انتظار پرداخت بانکی",
230 | 'error_-4' => "انصراف در درگاه بانک",
231 | 'error_-20' => "کلید مجوزدهی ارسال نشده است",
232 | 'error_-21' => "شماره تراکنش ارسال نشده است",
233 | 'error_-22' => "مبلغ ارسال نشده است",
234 | 'error_-23' => "مسیر بازگشت ارسال نشده است",
235 | 'error_-24' => "مبلغ اشتباه است",
236 | 'error_-25' => "شماره تراکنش تکراریست و قادر به ادامه کار نیستید",
237 | 'error_-26' => "توکن ارسال نشده است",
238 | 'error_-30' => "مقدار مبلغ کمتر از ۱۰۰ تومان است",
239 | 'error_-32' => "مسیر بازگشت خطا دارد",
240 | 'error_-33' => "ساختار کلید مجوز دهی صحیح نیست",
241 | 'error_-34' => "شماره تراکنش صحیح نیست",
242 | 'error_-35' => "نوع کلید مجوز دهی صحیح نیست",
243 | 'error_-36' => "شماره سفارش ارسال نشده است",
244 | 'error_-37' => "تراکنش یافت نشد",
245 | 'error_-38' => "توکن یافت نشد",
246 | 'error_-39' => "کلید مجوز دهی یافت نشد",
247 | 'error_-40' => "کلید مجوز دهی مسدود شده است",
248 | 'error_-41' => "پارامتر های ارسالی از بانک مورد تایید نیست",
249 | 'error_-42' => "سیستم پرداخت دچار مشکل شده است",
250 | 'error_-43' => "درگاهی برای پرداخت یافت نشد",
251 | 'error_-44' => "پاسخ بانک صحیح نیست",
252 | 'error_-45' => "سیستم پرداخت غیر فعال شده است",
253 | 'error_-46' => "درخواست اشتباه",
254 | 'error_-48' => "نرخ کمیسیون تعیین نشده است",
255 | 'error_-49' => "تراکنش تکراریست",
256 | 'error_-50' => "حساب کاربری یافت نشد",
257 | 'error_-51' => "کاربر یافت نشد",
258 | 'error_-60' => "ایمیل صحیح نیست",
259 | 'error_-61' => "کد ملی صحیح نیست",
260 | 'error_-62' => "کد پستی صحیح نیست",
261 | 'error_-63' => "آدرس پستی صحیح نیست",
262 | 'error_-64' => "توضیحات صحیح نیست",
263 | 'error_-65' => "نام و نام خانوادگی صحیح نیست",
264 | 'error_-66' => "شماره تلفن صحیح نیست",
265 | 'error_-67' => "نام کاربری صحیح نیست",
266 | 'error_-68' => "نام محصول صحیح نیست",
267 | 'error_-69' => "مسیر بازگشت برای حالت موفق صحیح نیست",
268 | 'error_-70' => "مسیر بازگشت برای حالت ناموفق صحیح نیست",
269 | 'error_-71' => "شماره موبایل صحیح نیست",
270 | 'error_-72' => "بانک عامل پاسخ گو نیست"
271 | ]
272 | ]
273 |
274 | ];
275 |
--------------------------------------------------------------------------------
/translations/fa/larapay.php:
--------------------------------------------------------------------------------
1 | 'خطای هندل نشده!', // unofficial error code --- added by PhpMonsters
5 |
6 | 'canceled_by_user' => 'تراکنش بانکی توسط کاربر لغو شد',
7 | 'could_not_request_payment' => 'امکان درخواست توکن برای این تراکنش وجود ندارد',
8 | 'could_not_verify_transaction' => 'امکان تایید این تراکنش وجود ندارد',
9 | 'could_not_inquiry_payment' => 'امکان استعلام این تراکنش وجود ندارد',
10 | 'could_not_settle_payment' => 'امکان درخواست واریز وجه برای این تراکنش وجود ندارد',
11 | 'could_not_reverse_payment' => 'انمان بازگشت این تراکنش وجود ندارد',
12 | 'gate_not_ready' => 'درگاه پرداختی یا وجود ندارد یا آماده سرویس دهی نمی باشد',
13 | 'gate_not_implemented_larapay' => 'دروازه پرداخت :name از PhpMonsters\\Larapay\\Adapter\\AdapterInterface پیروی نمی کند',
14 | 'goto_gate' => 'اتصال به درگاه پرداخت',
15 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
16 | 'reversed_failed' => 'بازگشت تراکنش با موفقیت انجام نشد!',
17 | 'verification_failed' => 'تایید تراکنش با موفقیت انجام نشد!',
18 | 'after_verification_failed' => 'تایید بعد از تراکنش با موفقیت انجام نشد!',
19 | 'invalid_sharing_data' => 'اطلاعات تسهیم معتبر نیست',
20 | 'transaction_not_found' => 'تراکنش پیدا نشد',
21 |
22 | 'mellat' => [
23 | 'errors' => [
24 | 'error_11' => 'شماره کارت نامعتبر است',
25 | 'error_12' => 'موجودی کافی نیست',
26 | 'error_13' => 'رمز نادرست است',
27 | 'error_14' => 'تعداد دفعات وارد کردن رمز بیش از حد مجاز است',
28 | 'error_15' => 'کارت نامعتبر است',
29 | 'error_16' => 'دفعات برداشت وجه بیش از حد مجاز است',
30 | 'error_17' => 'کاربر از انجام تراکنش منصرف شده است',
31 | 'error_18' => 'تاریخ انقضای کارت گذشته است',
32 | 'error_19' => 'مبلغ برداشت وجه بیش از حد مجاز است',
33 | 'error_21' => 'پذیرنده نامعتبر است',
34 | 'error_23' => 'خطای امنیتی رخ داده است',
35 | 'error_24' => 'اطلاعات کاربری پذیرنده نامعتبر است',
36 | 'error_25' => 'مبلغ نامعتبر است',
37 | 'error_31' => 'پاسخ نامعتبر است',
38 | 'error_32' => 'فرمت اطلاعات وارد شده صحیح نمیباشد',
39 | 'error_33' => 'حساب نامعتبر است',
40 | 'error_34' => 'خطای سیستمی',
41 | 'error_35' => 'تاریخ نامعتبر است',
42 | 'error_41' => 'شماره درخواست تکراری است',
43 | 'error_42' => 'تراکنش Sale یافت نشد',
44 | 'error_43' => 'قبلا درخواست Verfiy داده شده است',
45 | 'error_44' => 'درخواست Verfiy یافت نشد',
46 | 'error_45' => 'تراکنش Settle شده است',
47 | 'error_46' => 'تراکنش Settle نشده است',
48 | 'error_47' => 'تراکنش Settle یافت نشد',
49 | 'error_48' => 'تراکنش Reverse شده است',
50 | 'error_49' => 'تراکنش Refund یافت نشد.',
51 | 'error_51' => 'تراکنش تکراری است',
52 | 'error_54' => 'تراکنش مرجع موجود نیست',
53 | 'error_55' => 'تراکنش نامعتبر است',
54 | 'error_61' => 'خطا در واریز',
55 | 'error_111' => 'صادر کننده کارت نامعتبر است',
56 | 'error_112' => 'خطای سوییچ صادر کننده کارت',
57 | 'error_113' => 'پاسخی از صادر کننده کارت دریافت نشد',
58 | 'error_114' => 'دارنده این کارت مجاز به انجام این تراکنش نیست',
59 | 'error_412' => 'شناسه قبض نادرست است',
60 | 'error_413' => 'شناسه پرداخت نادرست است',
61 | 'error_414' => 'سازمان صادر کننده قبض نامعتبر است',
62 | 'error_415' => 'زمان جلسه کاری به پایان رسیده است',
63 | 'error_416' => 'خطا در ثبت اطلاعات',
64 | 'error_417' => 'شناسه پرداخت کننده نامعتبر است',
65 | 'error_418' => 'اشکال در تعریف اطلاعات مشتری',
66 | 'error_419' => 'تعداد دفعات ورود اطلاعات از حد مجاز گذشته است',
67 | 'error_421' => 'IP نامعتبر است',
68 |
69 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
70 | ]
71 | ],
72 | 'parsian' => [
73 | 'errors' => [
74 | 'error_20' => 'پین فروشنده درست نمی باشد',
75 | 'error_22' => 'پین فروشنده درست نمی باشد',
76 | 'error_30' => 'عملیات قبلا با موفقیت انجام شده است',
77 | 'error_34' => 'شماره تراکنش فرونشده درست نمی باشد',
78 |
79 | 'could_not_continue_with_non0_rs' => 'امکان تایید این تراکنش از سمت درگاه پرداخت وجود ندارد',
80 | 'invalid_response' => 'پاسخ معتبر از سرور درگاه پرداخت دریافت نشد!',
81 | ]
82 | ],
83 | 'pasargad' => [
84 | 'errors' => [
85 |
86 | ]
87 | ],
88 | 'saderat' => [
89 | 'errors' => [
90 | 'error_1' => 'وجود خطا در فرمت اطلاعات ارسالی',
91 | 'error_2' => 'عدم وجود پذیرنده و ترمینال مورد درخواست در سیستم',
92 | 'error_3' => 'رد درخواست به علت دریافت درخواست توسط آدرس آی پی نامعتبر',
93 | 'error_4' => 'پذیرنده مورد نظر امکان استفاده از سیستم را ندارد',
94 | 'error_5' => 'برخورد با مشکل در انجام درخواست مورد نظر',
95 | 'error_6' => 'خطا در پردازش درخواست',
96 | 'error_7' => 'بروز خطا در تشخیص اصالت اطلاعات (امضای دیجیتالی نامعتبر است)',
97 | 'error_8' => 'شماره خرید ارائه شده توسط پذیرنده (CRN) تکراری است',
98 | 'error_9' => 'سیستم در حال حاضر قادر به سرویس دهی نمی باشد (این پیام هنگام بروزرسانی سرور برگردانده می شود)',
99 | 'error_102' => 'تراکنش مورد نظر برگشت خورده است',
100 | 'error_103' => 'تایید انجام نشد',
101 | 'error_106' => 'پیامی از سوییچ پرداخت دریافت نشد',
102 | 'error_107' => 'تراکنش درخواستی موجود نیست',
103 | 'error_111' => 'مشکل در ارتباط با سوییچ',
104 | 'error_112' => 'مقادیر ارسالی در درخواست معتبر نیستند',
105 | 'error_113' => 'خطای سمت سرور (مربوط به واحد فنی PSP)',
106 | 'error_200' => 'تراکنش بانکی توسط کاربر لغو شد',
107 | 'error__1' => 'امضای دیجیتال مشکل دارد و با اطلاعات ارسالی همخوانی ندارد',
108 | 'error__2' => 'دسترسی از IP غیر مجاز است',
109 |
110 | 'making_openssl_sign_error' => 'ایجاد امضای دیجیتال با استفاده از openssl موفقیت آمیز نبود',
111 | 'invalid_verify_result' => 'اطلاعات دریافتی از درگاه پرداخت معتبر نمی باشد',
112 | 'invalid_transaction' => 'تراکنش شما معتبر نیست',
113 | 'public_key_file_not_found' => 'فایل public key در مسیر مورد نظر وجود ندارد',
114 | 'private_key_file_not_found' => 'فایل private key در مسیر مورد نظر وجود ندارد',
115 | ]
116 | ],
117 | 'zarinpal' => [
118 | 'errors' => [
119 | 'error_101' => 'عملیات پرداخت موفق بوده و قبلا PaymentVerification تراکنش انجام شده است',
120 |
121 | 'error__1' => 'اطلاعات ارسال شده ناقص است', //-1
122 | 'error__2' => 'IP و یا مرچنت کد پذیرنده صحیح نیست', //-1
123 | 'error__3' => 'با توجه به محدودیتهای شاپرک امکان پرداخت با رقم درخواست شده میسر نمی باشد',
124 | 'error__4' => 'سطح تایید پذیرنده پایین تز از سطح نقره است',
125 | 'error__11' => 'درخواست مورد نظر یافت نشد',
126 | 'error__12 '=> 'امکان ویرایش درخواست میسر نمی باشد',
127 | 'error__21 '=> 'هیچ نوع عملیات مالی برای این تراکنش یافت نشد',
128 | 'error__22 '=> 'تراکنش ناموفق می باشد',
129 | 'error__33 '=> 'رقم تراکنش با رقم پرداخت شده مطابقت ندارد',
130 | 'error__34 '=> 'سقف تقیسم تراکنش از لحاظ تعداد یا رقم عبور نموده است',
131 | 'error__40 '=> 'اجازه دسترسی به متد مربوطه وجود ندارد',
132 | 'error__41 '=> 'اطلاعات ارسال شده به AdditionalData غیر معتبر می باشد',
133 | 'error__42 '=> 'مدت زمان معتبر طول عمر شناسه پرداخت باید بین ۳۰ دقیقه تا ۴۵ روز باشد',
134 | 'error__54 '=> 'درخواست مورد نظر آرشیو شده است',
135 | ]
136 | ],
137 | 'idpay' => [
138 | 'errors' => [
139 | "error_1" => "پرداخت انجام نشده است.",
140 | "error_2" => "پرداخت ناموفق بوده است.",
141 | "error_3" => "خطا رخ داده است.",
142 | "error_4" => "بلوکه شده.",
143 | "error_5" => "برگشت به پرداخت کننده.",
144 | "error_6" => "برگشت خورده سیستمی.",
145 | "error_10" => "در انتظار تایید پرداخت.",
146 | "error_100" => "پرداخت تایید شده است.",
147 | "error_101" => "پرداخت قبلا تایید شده است.",
148 | "error_200" => "به دریافت کننده واریز شد.",
149 | "error_11" => "کاربر مسدود شده است.",
150 | "error_12" => "API Key یافت نشد.",
151 | "error_13" => "درخواست شما از {ip} ارسال شده است. این IP با IP های ثبت شده در وب سرویس همخوانی ندارد.",
152 | "error_14" => "وب سرویس تایید نشده است.",
153 | "error_21" => "حساب بانکی متصل به وب سرویس تایید نشده است.",
154 | "error_31" => "کد تراکنش id نباید خالی باشد.",
155 | "error_32" => "شماره سفارش order_id نباید خالی باشد.",
156 | "error_33" => "مبلغ amount نباید خالی باشد.",
157 | "error_34" => "مبلغ amount باید بیشتر از {min-amount} ریال باشد.",
158 | "error_35" => "مبلغ amount باید کمتر از {max-amount} ریال باشد.",
159 | "error_36" => "مبلغ amount بیشتر از حد مجاز است.",
160 | "error_37" => "آدرس بازگشت callback نباید خالی باشد.",
161 | "error_38" => "درخواست شما از آدرس {domain} ارسال شده است. دامنه آدرس بازگشت callback با آدرس ثبت شده در وب سرویس همخوانی ندارد.",
162 | "error_51" => "تراکنش ایجاد نشد.",
163 | "error_52" => "استعلام نتیجه ای نداشت.",
164 | "error_53" => "تایید پرداخت امکان پذیر نیست.",
165 | "error_54" => "مدت زمان تایید پرداخت سپری شده است.",
166 | ]
167 | ],
168 | 'zibal' => [
169 | 'errors' => [
170 | "error_-1" => "در انتظار پردخت.",
171 | "error_-2" => "خطای داخلی.",
172 | "error_1" => "پرداخت شده - تاییدشده.",
173 | "error_2" => "پرداخت شده - تاییدنشده.",
174 | "error_3" => "لغوشده توسط کاربر.",
175 | "error_4" => "شماره کارت نامعتبر میباشد.",
176 | "error_5" => "موجودی حساب کافی نمیباشد.",
177 | "error_6" => "رمز واردشده اشتباه میباشد.",
178 | "error_8" => "تعداد درخواستها بیش از حد مجاز میباشد.",
179 | "error_9" => "مبلغ پرداخت اینترنتی روزانه بیش از حد مجاز میباشد.",
180 | "error_10" => "صادرکنندهی کارت نامعتبر میباشد.",
181 | "error_11" => "خطای سوییچ",
182 | "error_12" => "کارت قابل دسترسی نمیباشد.",
183 | "error_102" => "merchant یافت نشد.",
184 | "error_104" => "merchant نامعتبر",
185 | "error_103" => "merchant غیرفعال",
186 | "error_201" => "پرداخت قبلا تایید شده است.",
187 | "error_202" => "سفارش پرداخت نشده یا ناموفق بوده است. جهت اطلاعات بیشتر جدول وضعیتها را مطالعه کنید.",
188 | "error_203" => "trackId نامعتبر میباشد.",
189 | ]
190 | ],
191 | 'payir' => [
192 | 'errors' => [
193 | 'error_0' => 'درحال حاضر درگاه بانکی قطع شده و مشکل بزودی برطرف می شود',
194 | 'error_-1' => 'API Key ارسال نمی شود',
195 | 'error_-2' => 'Token ارسال نمی شود',
196 | 'error_-3' => 'API Key ارسال شده اشتباه است',
197 | 'error_-4' => 'امکان انجام تراکنش برای این پذیرنده وجود ندارد',
198 | 'error_-5' => 'تراکنش با خطا مواجه شده است',
199 | 'error_-6' => 'تراکنش تکراریست یا قبلا انجام شده',
200 | 'error_-7' => 'مقدار Token ارسالی اشتباه است',
201 | 'error_-8' => 'شماره تراکنش ارسالی اشتباه است',
202 | 'error_-9' => 'زمان مجاز برای انجام تراکنش تمام شده',
203 | 'error_-10' => 'مبلغ تراکنش ارسال نمی شود',
204 | 'error_-11' => 'مبلغ تراکنش باید به صورت عددی و با کاراکترهای لاتین باشد',
205 | 'error_-12' => 'مبلغ تراکنش می بایست عددی بین 10,000 و 500,000,000 ریال باشد',
206 | 'error_-13' => 'مقدار آدرس بازگشتی ارسال نمی شود',
207 | 'error_-14' => 'آدرس بازگشتی ارسالی با آدرس درگاه ثبت شده در شبکه پرداخت پی یکسان نیست',
208 | 'error_-15' => 'امکان وریفای وجود ندارد. این تراکنش پرداخت نشده است',
209 | 'error_-16' => 'یک یا چند شماره موبایل از اطلاعات پذیرندگان ارسال شده اشتباه است',
210 | 'error_-17' => 'میزان سهم ارسالی باید بصورت عددی و بین 1 تا 100 باشد',
211 | 'error_-18' => 'فرمت پذیرندگان صحیح نمی باشد',
212 | 'error_-19' => 'هر پذیرنده فقط یک سهم میتواند داشته باشد',
213 | 'error_-20' => 'مجموع سهم پذیرنده ها باید 100 درصد باشد',
214 | 'error_-21' => 'Reseller ID ارسالی اشتباه است',
215 | 'error_-22' => 'فرمت یا طول مقادیر ارسالی به درگاه اشتباه است',
216 | 'error_-23' => 'سوییچ PSP ( درگاه بانک ) قادر به پردازش درخواست نیست. لطفا لحظاتی بعد مجددا تلاش کنید',
217 | 'error_-24' => 'شماره کارت باید بصورت 16 رقمی، لاتین و چسبیده بهم باشد',
218 | 'error_-25' => 'امکان استفاده از سرویس در کشور مبدا شما وجود نداره',
219 | 'error_-26' => 'امکان انجام تراکنش برای این درگاه وجود ندارد',
220 | 'error_-27' => 'در انتظار تایید درگاه توسط شاپرک',
221 | 'error_-28' => 'امکان تسهیم تراکنش برای این درگاه وجود ندارد',
222 | ]
223 | ],
224 | 'nextpay' => [
225 | 'errors' => [
226 | 'error_0' => "تراکنش تکمیل و موفق است",
227 | 'error_-1' => "حالت پیش فرض تراکنش",
228 | 'error_-2' => "خطای بانکی یا انصراف از پرداخت",
229 | 'error_-3' => "در انتظار پرداخت بانکی",
230 | 'error_-4' => "انصراف در درگاه بانک",
231 | 'error_-20' => "کلید مجوزدهی ارسال نشده است",
232 | 'error_-21' => "شماره تراکنش ارسال نشده است",
233 | 'error_-22' => "مبلغ ارسال نشده است",
234 | 'error_-23' => "مسیر بازگشت ارسال نشده است",
235 | 'error_-24' => "مبلغ اشتباه است",
236 | 'error_-25' => "شماره تراکنش تکراریست و قادر به ادامه کار نیستید",
237 | 'error_-26' => "توکن ارسال نشده است",
238 | 'error_-30' => "مقدار مبلغ کمتر از ۱۰۰ تومان است",
239 | 'error_-32' => "مسیر بازگشت خطا دارد",
240 | 'error_-33' => "ساختار کلید مجوز دهی صحیح نیست",
241 | 'error_-34' => "شماره تراکنش صحیح نیست",
242 | 'error_-35' => "نوع کلید مجوز دهی صحیح نیست",
243 | 'error_-36' => "شماره سفارش ارسال نشده است",
244 | 'error_-37' => "تراکنش یافت نشد",
245 | 'error_-38' => "توکن یافت نشد",
246 | 'error_-39' => "کلید مجوز دهی یافت نشد",
247 | 'error_-40' => "کلید مجوز دهی مسدود شده است",
248 | 'error_-41' => "پارامتر های ارسالی از بانک مورد تایید نیست",
249 | 'error_-42' => "سیستم پرداخت دچار مشکل شده است",
250 | 'error_-43' => "درگاهی برای پرداخت یافت نشد",
251 | 'error_-44' => "پاسخ بانک صحیح نیست",
252 | 'error_-45' => "سیستم پرداخت غیر فعال شده است",
253 | 'error_-46' => "درخواست اشتباه",
254 | 'error_-48' => "نرخ کمیسیون تعیین نشده است",
255 | 'error_-49' => "تراکنش تکراریست",
256 | 'error_-50' => "حساب کاربری یافت نشد",
257 | 'error_-51' => "کاربر یافت نشد",
258 | 'error_-60' => "ایمیل صحیح نیست",
259 | 'error_-61' => "کد ملی صحیح نیست",
260 | 'error_-62' => "کد پستی صحیح نیست",
261 | 'error_-63' => "آدرس پستی صحیح نیست",
262 | 'error_-64' => "توضیحات صحیح نیست",
263 | 'error_-65' => "نام و نام خانوادگی صحیح نیست",
264 | 'error_-66' => "شماره تلفن صحیح نیست",
265 | 'error_-67' => "نام کاربری صحیح نیست",
266 | 'error_-68' => "نام محصول صحیح نیست",
267 | 'error_-69' => "مسیر بازگشت برای حالت موفق صحیح نیست",
268 | 'error_-70' => "مسیر بازگشت برای حالت ناموفق صحیح نیست",
269 | 'error_-71' => "شماره موبایل صحیح نیست",
270 | 'error_-72' => "بانک عامل پاسخ گو نیست"
271 | ]
272 | ]
273 |
274 | ];
275 |
--------------------------------------------------------------------------------
/views/idpay-form.blade.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | @if($autoSubmit === true)
10 |
14 | @endif
15 |
--------------------------------------------------------------------------------
/views/mellat-form.blade.php:
--------------------------------------------------------------------------------
1 |
9 |
10 | @if($autoSubmit === true)
11 |
15 | @endif
--------------------------------------------------------------------------------
/views/nextpay-form.blade.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | @if($autoSubmit === true)
10 |
14 | @endif
15 |
--------------------------------------------------------------------------------
/views/parsian-form.blade.php:
--------------------------------------------------------------------------------
1 |
9 |
10 | @if($autoSubmit === true)
11 |
15 | @endif
16 |
17 |
18 |
--------------------------------------------------------------------------------
/views/pasargad-form.blade.php:
--------------------------------------------------------------------------------
1 |
17 |
18 | @if($autoSubmit === true)
19 |
23 | @endif
24 |
--------------------------------------------------------------------------------
/views/payir-form.blade.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | @if($autoSubmit === true)
10 |
14 | @endif
--------------------------------------------------------------------------------
/views/sadad-form.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | {!! $form !!}
4 |
5 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/views/saderat-form.blade.php:
--------------------------------------------------------------------------------
1 |
9 |
10 | @if($autoSubmit === true)
11 |
15 | @endif
--------------------------------------------------------------------------------
/views/saman-form.blade.php:
--------------------------------------------------------------------------------
1 |
16 |
17 | @if($autoSubmit === true)
18 |
22 | @endif
23 |
24 |
25 |
--------------------------------------------------------------------------------
/views/zarinpal-form.blade.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | @if($autoSubmit === true)
10 |
14 | @endif
--------------------------------------------------------------------------------
/views/zibal-form.blade.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | @if($autoSubmit === true)
10 |
14 | @endif
15 |
--------------------------------------------------------------------------------