Completed
Push — master ( 8181ea...3209e5 )
by Vuong
01:33
created

PaymentGateway::verifyRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 3
cts 4
cp 0.75
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
crap 2.0625
1
<?php
2
/**
3
 * @link https://github.com/yiiviet/yii2-payment
4
 * @copyright Copyright (c) 2017 Yii Viet
5
 * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php)
6
 */
7
8
namespace yiiviet\payment\nganluong;
9
10
use yii\base\NotSupportedException;
11
12
use yiiviet\payment\BasePaymentGateway;
13
14
use vxm\gatewayclients\RequestEvent;
15
16
/**
17
 * Lớp PaymentGateway hổ trợ việc kết nối đến Ngân Lượng.
18
 * Hiện tại nó hỗ trợ 100% tính năng của Ngân Lượng v3.1
19
 *
20
 * @method ResponseData purchase(array $data, $clientId = null)
21
 * @method ResponseData queryDR(array $data, $clientId = null)
22
 * @method VerifiedData verifyRequestPurchaseSuccess(\yii\web\Request $request = null, $clientId = null)
23
 * @method PaymentClient getClient($id = null)
24
 * @method PaymentClient getDefaultClient()
25
 *
26
 * @property PaymentClient $client
27
 * @property PaymentClient $defaultClient
28
 * @property bool $seamless
29
 *
30
 * @author Vuong Minh <[email protected]>
31
 * @since 1.0
32
 */
33
class PaymentGateway extends BasePaymentGateway
34
{
35
    /**
36
     * Lệnh `authenticate` yêu cầu Ngân Lượng xác minh OTP của khách có hợp lệ hay không.
37
     * Nó được sử dụng ở version 3.2 phương thức seamless checkout.
38
     */
39
    const RC_AUTHENTICATE = 'authenticate';
40
41
    /**
42
     * @event RequestEvent được gọi trước khi thực hiện yêu cầu Ngân Lượng xác minh OTP của khách.
43
     */
44
    const EVENT_BEFORE_AUTHENTICATE = 'beforeAuthenticate';
45
46
    /**
47
     * @event RequestEvent được gọi sau khi thực hiện yêu cầu Ngân Lượng xác minh OTP của khách.
48
     */
49
    const EVENT_AFTER_AUTHENTICATE = 'afterAuthenticate';
50
51
    /**
52
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là Ngân Lượng,
53
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
54
     */
55
    const PAYMENT_METHOD_NL = 'NL';
56
57
    /**
58
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là QR Code,
59
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
60
     */
61
    const PAYMENT_METHOD_QR_CODE = 'QRCODE';
62
63
    /**
64
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là tại ngân hàng,
65
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
66
     */
67
    const PAYMENT_METHOD_BANK_OFFLINE = 'NH_OFFLINE';
68
69
    /**
70
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là thẻ tín dụng trả trước,
71
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
72
     */
73
    const PAYMENT_METHOD_CREDIT_CARD_PREPAID = 'CREDIT_CARD_PREPAID';
74
75
    /**
76
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là thẻ VISA,
77
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
78
     */
79
    const PAYMENT_METHOD_VISA = 'VISA';
80
81
    /**
82
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là ATM Online,
83
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
84
     */
85
    const PAYMENT_METHOD_ATM_ONLINE = 'ATM_ONLINE';
86
87
    /**
88
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là ATM Offline,
89
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
90
     */
91
    const PAYMENT_METHOD_ATM_OFFLINE = 'ATM_ONLINE';
92
93
    /**
94
     * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là Internet Banking,
95
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
96
     */
97
    const PAYMENT_METHOD_INTERNET_BANKING = 'IB_ONLINE';
98
99
    /**
100
     * Hằng khai báo giúp Ngân Lượng xác định phương thức giao dịch là trực tiếp (trực tiếp nhận tiền),
101
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
102
     */
103
    const PAYMENT_TYPE_REDIRECT = 1;
104
    /**
105
     * Hằng khai báo giúp Ngân Lượng xác định phương thức giao dịch là tạm giữ (tạm giữ tiền),
106
     * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]].
107
     */
108
    const PAYMENT_TYPE_SAFE = 2;
109
110
    /**
111
     * Hằng khai báo giúp bạn xác định trạng thái giao dịch thành công,
112
     * khi khởi tạo lệnh [[VRC_PURCHASE_SUCCESS]] hoặc [[RC_QUERY_DR]] tại phương thức [[request()]] hoặc [[verifyRequest()]].
113
     */
114
    const TRANSACTION_STATUS_SUCCESS = '00';
115
116
    /**
117
     * Hằng khai báo giúp bạn xác định trạng thái giao dịch thàng công nhưng Ngân Lượng tạm giữ,
118
     * khi khởi tạo lệnh [[VRC_PURCHASE_SUCCESS]] hoặc [[RC_QUERY_DR]] tại phương thức [[request()]] hoặc [[verifyRequest()]].
119
     */
120
    const TRANSACTION_STATUS_PENDING = '01';
121
122
    /**
123
     * Hằng khai báo giúp bạn xác định trạng thái giao dịch thất bại khách hàng không thanh toán hoặc lỗi,
124
     * khi khởi tạo lệnh [[VRC_PURCHASE_SUCCESS]] hoặc [[RC_QUERY_DR]] tại phương thức [[request()]] hoặc [[verifyRequest()]].
125
     */
126
    const TRANSACTION_STATUS_ERROR = '02';
127
128
    /**
129
     * Hằng khai báo giúp xác nhận thuộc tính `auth_site` trong kết quả nhận được từ `purchase` version 3.2 là xác nhận OTP thông qua
130
     * phương thức [[authenticate()]].
131
     */
132
    const AUTH_NL = 'NL';
133
134
    /**
135
     * Hằng khai báo giúp xác nhận thuộc tính `auth_site` trong kết quả nhận được từ `purchase` version 3.2 là xác nhận OTP thông qua
136
     * ngân hàng, bạn phải `redirect` khách đến trang `auth_url` để xác minh `OTP`.
137
     */
138
    const AUTH_BANK = 'BANK';
139
140
    /**
141
     * Hằng cho biết gateway ở version 3.1
142
     */
143
    const VERSION_3_1 = '3.1';
144
145
    /**
146
     * Hằng cho biết gateway ở version 3.2
147
     */
148
    const VERSION_3_2 = '3.2';
149
150
    /**
151
     * @inheritdoc
152
     */
153
    public $clientConfig = ['class' => PaymentClient::class];
154
155
    /**
156
     * @inheritdoc
157
     */
158
    public $requestDataConfig = ['class' => RequestData::class];
159
160
    /**
161
     * @inheritdoc
162
     */
163
    public $responseDataConfig = ['class' => ResponseData::class];
164
165
    /**
166
     * @inheritdoc
167
     */
168
    public $verifiedDataConfig = ['class' => VerifiedData::class];
169
170
    /**
171
     * @inheritdoc
172
     */
173 4
    public function getBaseUrl(): string
174
    {
175 4
        return ($this->sandbox ? 'https://sandbox.nganluong.vn:8088/nl30' : 'https://www.nganluong.vn') . '/checkout.api.nganluong.post.php';
176
    }
177
178
    /**
179
     * @inheritdoc
180
     */
181 2
    public function getSupportedVersions(): array
182
    {
183 2
        return [self::VERSION_3_1, self::VERSION_3_2];
184
    }
185
186
    /**
187
     * Phương thức yêu cầu Ngân Lượng xác minh OTP.
188
     * Đây là phương thức ánh xạ của [[request()]] sử dụng lệnh [[RC_AUTHENTICATE]]. Nó chỉ được hổ trợ ở version 3.2.
189
     *
190
     * @param array $data Dữ liệu yêu cầu xác minh.
191
     * @param null $clientId Client id sử dụng để tạo yêu. Nếu không thiết lập [[getDefaultClient()]] sẽ được gọi để xác định client.
192
     * @return ResponseData|\vxm\gatewayclients\DataInterface Trả về [[ResponseData]] là dữ liệu từ Ngân Lượng phản hồi.
193
     * @throws \yii\base\InvalidConfigException|\ReflectionException
194
     */
195 1
    public function authenticate(array $data, $clientId = null)
196
    {
197 1
        return $this->request(self::RC_AUTHENTICATE, $data, $clientId);
198
    }
199
200
    /**
201
     * This method checking gateway mode is seamless or not.
202
     *
203
     * @return bool Return TRUE if current mode is seamless.
204
     */
205 4
    public function getSeamless(): bool
206
    {
207 4
        return $this->getVersion() === self::VERSION_3_2;
208
    }
209
210
    /**
211
     * This method is an alias of `setVersion` to detect gateway mode is seamless or origin.
212
     *
213
     * @param bool $seamless Mode seamless or not.
214
     * @return bool Return TRUE if seamless mode is turn on.
215
     * @throws NotSupportedException
216
     */
217
    public function setSeamless(bool $seamless): bool
218
    {
219
        return $this->setVersion($seamless ? self::VERSION_3_2 : self::VERSION_3_1);
220
    }
221
222
    /**
223
     * @inheritdoc
224
     * @throws NotSupportedException
225
     */
226 1
    public function verifyRequest($command, \yii\web\Request $request = null, $clientId = null)
227
    {
228 1
        if ($command === self::VRC_IPN) {
229
            throw new NotSupportedException('IPN is not supported in Ngan Luong gateway!');
230
        } else {
231 1
            return parent::verifyRequest($command, $request, $clientId);
232
        }
233
    }
234
235
    /**
236
     * @inheritdoc
237
     */
238 2
    protected function defaultVersion(): string
239
    {
240 2
        return self::VERSION_3_1;
241
    }
242
243
    /**
244
     * @inheritdoc
245
     * @throws \yii\base\InvalidConfigException
246
     */
247 6
    protected function initSandboxEnvironment()
248
    {
249 6
        $clientConfig = require(__DIR__ . '/sandbox-client.php');
250 6
        $this->setClient($clientConfig);
251 6
    }
252
253
    /**
254
     * @inheritdoc
255
     */
256 4 View Code Duplication
    protected function getHttpClientConfig(): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
257
    {
258
        return [
259 4
            'transport' => 'yii\httpclient\CurlTransport',
260
            'requestConfig' => [
261
                'options' => [
262 4
                    CURLOPT_SSL_VERIFYPEER => false,
263 4
                    CURLOPT_SSL_VERIFYHOST => false
264
                ]
265
            ]
266
        ];
267
    }
268
269
    /**
270
     * @inheritdoc
271
     */
272 4
    public function beforeRequest(RequestEvent $event)
273
    {
274 4
        if ($event->command === self::RC_AUTHENTICATE) {
275 1
            $this->trigger(self::EVENT_BEFORE_AUTHENTICATE, $event);
276
        }
277
278 4
        parent::beforeRequest($event);
279 4
    }
280
281
    /**
282
     * @inheritdoc
283
     */
284 3
    public function afterRequest(RequestEvent $event)
285
    {
286 3
        if ($event->command === self::RC_AUTHENTICATE) {
287 1
            $this->trigger(self::EVENT_AFTER_AUTHENTICATE, $event);
288
        }
289
290 3
        parent::afterRequest($event);
291 3
    }
292
293
    /**
294
     * @inheritdoc
295
     * @throws \yii\base\InvalidConfigException
296
     */
297 4
    protected function requestInternal(\vxm\gatewayclients\RequestData $requestData, \yii\httpclient\Client $httpClient): array
298
    {
299 4
        $data = $requestData->get();
300
301 3
        return $httpClient->post('', $data)->send()->getData();
302
    }
303
304
    /**
305
     * @inheritdoc
306
     */
307 1
    protected function getVerifyRequestData($command, \yii\web\Request $request): array
308
    {
309
        return [
310 1
            'token' => $request->get('token')
311
        ];
312
    }
313
314
}
315