Skip to content

Commit ad1b1de

Browse files
committed
fix zarinpal
1 parent 1be5ff6 commit ad1b1de

File tree

5 files changed

+134
-59
lines changed

5 files changed

+134
-59
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,23 @@ For example create a POST route in routes folder, web.php like this:
104104
Route::post('payment/callback', 'YourController@handleCallback')->name('payment.callback');
105105
```
106106

107+
`NOTE: SOME GATEWAYS MAY USE GET METHOD FOR CALLBACK (like Zarinpal)`
108+
107109
then set the route name in .env file:
108110

109111
```ini
110112
LARAPAY_PAYMENT_CALLBACK=payment.callback
111113
```
112114

115+
remember to add callback route to except array of validateCsrfToken
116+
117+
add this in `withMiddleware` section in `bootstrap/app.php` :
118+
```php
119+
$middleware->validateCsrfTokens(except: [
120+
'payment/*',
121+
]);
122+
```
123+
113124

114125
## Usage
115126

config/larapay.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
| the gateways list is comma separated
2828
|
2929
*/
30-
'gateways' => env('LARAPAY_GATES', 'Mellat,Saman,Pasargad,Parsian,ZarinPal,Idpay,Payir,Saderat,Zibal,Nextpay'),
30+
'gateways' => env('LARAPAY_GATES', 'Mellat,Saman,Pasargad,Parsian,Zarinpal,Idpay,Payir,Saderat,Zibal,Nextpay'),
3131

3232
/*
3333
|--------------------------------------------------------------------------

src/Adapter/AdapterAbstract.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,30 @@ protected function getEndPoint(): string
217217
}
218218
}
219219

220+
/**
221+
* @return string
222+
*/
223+
protected function getPaymentRequestEndpPoint():string
224+
{
225+
if (config('larapay.mode') === 'production') {
226+
return $this->paymentRequestEndPoint;
227+
} else {
228+
return $this->testPaymentRequestEndPoint;
229+
}
230+
}
231+
232+
/**
233+
* @return string
234+
*/
235+
protected function getPaymentVerifyEndpPoint():string
236+
{
237+
if (config('larapay.mode') === 'production') {
238+
return $this->paymentVerifyEndPoint;
239+
} else {
240+
return $this->testPaymentVerifyEndPoint;
241+
}
242+
}
243+
220244
/**
221245
* @param array $options
222246
*

src/Adapter/Zarinpal.php

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use SoapClient;
77
use SoapFault;
8+
use PhpMonsters\Larapay\Adapter\Zarinpal\Helper;
89
use PhpMonsters\Larapay\Adapter\Zarinpal\Exception;
910
use PhpMonsters\Log\Facades\XLog;
1011

@@ -14,14 +15,18 @@
1415
*/
1516
class Zarinpal extends AdapterAbstract implements AdapterInterface
1617
{
17-
protected $WSDL = 'https://www.zarinpal.com/pg/services/WebGate/wsdl';
18+
protected $paymentRequestEndPoint = "https://payment.zarinpal.com/pg/v4/payment/request.json";
19+
protected $paymentVerifyEndPoint = "https://payment.zarinpal.com/pg/v4/payment/verify.json";
1820

19-
protected $endPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}';
20-
protected $zarinEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/ZarinGate';
21+
22+
protected $endPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}';
23+
protected $zarinEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/ZarinGate';
2124
protected $mobileEndPoint = 'https://www.zarinpal.com/pg/StartPay/{authority}/MobileGate';
2225

23-
protected $testWSDL = 'https://banktest.ir/gateway/zarinpal/ws?wsdl';
24-
protected $testEndPoint = 'https://banktest.ir/gateway/zarinpal/gate/{authority}';
26+
protected $testEndPoint = 'https://sandbox.banktest.ir/zarinpal/www.zarinpal.com/pg/StartPay/{authority}';
27+
protected $testPaymentRequestEndPoint = "https://sandbox.banktest.ir/zarinpal/api.zarinpal.com/pg/v4/payment/request.json";
28+
protected $testPaymentVerifyEndPoint = "https://sandbox.banktest.ir/zarinpal/api.zarinpal.com/pg/v4/payment/verify.json";
29+
2530

2631
public $reverseSupport = false;
2732

@@ -43,42 +48,39 @@ protected function requestToken(): string
4348
]);
4449

4550
$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,
51+
'merchant_id' => $this->merchant_id,
52+
'amount' => intval($this->amount),
53+
'description' => $this->description ? $this->description : '',
54+
"metadata" => [
55+
'mobile' => $this->mobile ? $this->mobile : '',
56+
'email' => $this->email ? $this->email : '',
57+
],
58+
'callback_url' => $this->redirect_url,
5259
];
5360

5461
try {
55-
$soapClient = new SoapClient($this->getWSDL());
56-
5762
XLog::debug('PaymentRequest call', $sendParams);
5863

59-
$response = $soapClient->PaymentRequest($sendParams);
60-
61-
XLog::info('PaymentRequest response', $this->obj2array($response));
62-
64+
$response = Helper::post2https($sendParams, $this->getPaymentRequestEndpPoint());
65+
$result = json_decode($response);
66+
XLog::info('reservation result', $result);
6367

64-
if (isset($response->Status)) {
68+
if (empty($result->errors)) {
69+
if ($result->data->code == 100) {
70+
$this->getTransaction()->setGatewayToken(strval($result->data->authority)); // update transaction reference id
6571

66-
if ($response->Status == 100) {
67-
$this->getTransaction()->setGatewayToken(strval($response->Authority)); // update transaction reference id
68-
69-
return $response->Authority;
72+
return $result->data->authority;
7073
} else {
71-
throw new Exception($response->Status);
74+
throw new Exception('no error provided and not 100');
7275
}
7376
} else {
74-
throw new Exception('larapay::larapay.invalid_response');
77+
throw new Exception('code: ' . $result->errors->code . "\n" . 'message: ' . $result->errors->message);
7578
}
76-
} catch (SoapFault $e) {
77-
throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
79+
} catch (\Exception $e) {
80+
throw new Exception($e->getMessage());
7881
}
7982
}
8083

81-
8284
/**
8385
* @return string
8486
* @throws Exception
@@ -89,9 +91,9 @@ protected function generateForm(): string
8991
$authority = $this->requestToken();
9092

9193
$form = view('larapay::zarinpal-form', [
92-
'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
94+
'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
9395
'submitLabel' => !empty($this->submit_label) ? $this->submit_label : trans("larapay::larapay.goto_gate"),
94-
'autoSubmit' => boolval($this->auto_submit),
96+
'autoSubmit' => boolval($this->auto_submit),
9597
]);
9698

9799
return $form->__toString();
@@ -106,8 +108,8 @@ public function formParams(): array
106108
{
107109
$authority = $this->requestToken();
108110

109-
return [
110-
'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
111+
return [
112+
'endPoint' => strtr($this->getEndPoint(), ['{authority}' => $authority]),
111113
];
112114
}
113115

@@ -128,38 +130,29 @@ protected function verifyTransaction(): bool
128130
]);
129131

130132
$sendParams = [
131-
'MerchantID' => $this->merchant_id,
132-
'Authority' => $this->Authority,
133-
'Amount' => intval($this->transaction->amount),
133+
'merchant_id' => $this->merchant_id,
134+
'authority' => $this->Authority,
135+
'amount' => intval($this->transaction->amount),
134136
];
135137

136-
try {
137-
$soapClient = new SoapClient($this->getWSDL());
138-
139-
XLog::debug('PaymentVerification call', $sendParams);
140-
141-
$response = $soapClient->PaymentVerification($sendParams);
138+
XLog::debug('PaymentVerification call', $sendParams);
142139

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-
}
140+
try {
141+
$response = Helper::post2https($sendParams, $this->getPaymentVerifyEndpPoint());
142+
$result = json_decode($response);
143+
XLog::info('PaymentVerification response', $this->obj2array($result));
144+
145+
if ($result->data->code === 100) {
146+
$this->getTransaction()->setVerified();
147+
$this->getTransaction()->setReferenceId((string) $result->data->ref_id); // update transaction reference id
148+
return true;
149+
} else if ($result->data->code === 101) {
150+
return true;
156151
} else {
157-
throw new Exception('larapay::larapay.invalid_response');
152+
throw new Exception('code: ' . $result->errors->code . "\n" . 'message: ' . $result->errors->message);
158153
}
159-
160-
} catch (SoapFault $e) {
161-
162-
throw new Exception('SoapFault: ' . $e->getMessage() . ' #' . $e->getCode(), $e->getCode());
154+
} catch (\Exception $e) {
155+
throw new Exception("Payment Verify Error: " . $e->getMessage());
163156
}
164157
}
165158

src/Adapter/Zarinpal/Helper.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
namespace PhpMonsters\Larapay\Adapter\Zarinpal;
3+
4+
use PhpMonsters\Log\Facades\XLog;
5+
6+
class Helper
7+
{
8+
/**
9+
* CURL POST TO HTTPS
10+
*
11+
* @param $fields_arr
12+
* @param $url
13+
* @return mixed
14+
*/
15+
public static function post2https($fields_arr, $url)
16+
{
17+
$header = [
18+
'Content-Type: application/json',
19+
];
20+
21+
$ch = curl_init();
22+
//set the url, number of POST vars, POST data
23+
curl_setopt($ch, CURLOPT_URL, $url);
24+
curl_setopt($ch, CURLOPT_USERAGENT, 'ZarinPal Rest Api v4');
25+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
26+
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields_arr));
27+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
28+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
29+
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
30+
31+
//execute post
32+
$res = curl_exec($ch);
33+
34+
// error
35+
$err = curl_error($ch);
36+
37+
//close connection
38+
curl_close($ch);
39+
40+
if ($err) {
41+
throw new Exception("cURL Error #:$err");
42+
}
43+
44+
XLog::debug('Zarinpal call response: ' . $res);
45+
return $res;
46+
}
47+
}

0 commit comments

Comments
 (0)