This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 GatewayClients\DataInterface; |
||
11 | |||
12 | use yii\base\NotSupportedException; |
||
13 | |||
14 | use yiiviet\payment\BasePaymentGateway; |
||
15 | |||
16 | use vxm\gatewayclients\RequestEvent; |
||
17 | |||
18 | /** |
||
19 | * Lớp PaymentGateway hổ trợ việc kết nối đến Ngân Lượng. |
||
20 | * Hiện tại nó hỗ trợ 100% tính năng của Ngân Lượng v3.1, v3.2 |
||
21 | * |
||
22 | * @method ResponseData purchase(array $data, $clientId = null) |
||
23 | * @method ResponseData queryDR(array $data, $clientId = null) |
||
24 | * @method VerifiedData verifyRequestPurchaseSuccess(\yii\web\Request $request = null, $clientId = null) |
||
25 | * @method PaymentClient getClient($id = null) |
||
26 | * @method PaymentClient getDefaultClient() |
||
27 | * |
||
28 | * @property PaymentClient $client |
||
29 | * @property PaymentClient $defaultClient |
||
30 | * @property bool $seamless |
||
31 | * |
||
32 | * @author Vuong Minh <[email protected]> |
||
33 | * @since 1.0 |
||
34 | */ |
||
35 | class PaymentGateway extends BasePaymentGateway |
||
36 | { |
||
37 | /** |
||
38 | * 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. |
||
39 | * Nó được sử dụng ở version 3.2 phương thức seamless checkout. |
||
40 | */ |
||
41 | const RC_AUTHENTICATE = 'authenticate'; |
||
42 | |||
43 | /** |
||
44 | * @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. |
||
45 | */ |
||
46 | const EVENT_BEFORE_AUTHENTICATE = 'beforeAuthenticate'; |
||
47 | |||
48 | /** |
||
49 | * @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. |
||
50 | */ |
||
51 | const EVENT_AFTER_AUTHENTICATE = 'afterAuthenticate'; |
||
52 | |||
53 | /** |
||
54 | * 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, |
||
55 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
56 | */ |
||
57 | const PAYMENT_METHOD_NL = 'NL'; |
||
58 | |||
59 | /** |
||
60 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là QR Code, |
||
61 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
62 | */ |
||
63 | const PAYMENT_METHOD_QR_CODE = 'QRCODE'; |
||
64 | |||
65 | /** |
||
66 | * 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, |
||
67 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
68 | */ |
||
69 | const PAYMENT_METHOD_BANK_OFFLINE = 'NH_OFFLINE'; |
||
70 | |||
71 | /** |
||
72 | * 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, |
||
73 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
74 | */ |
||
75 | const PAYMENT_METHOD_CREDIT_CARD_PREPAID = 'CREDIT_CARD_PREPAID'; |
||
76 | |||
77 | /** |
||
78 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là thẻ VISA, |
||
79 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
80 | */ |
||
81 | const PAYMENT_METHOD_VISA = 'VISA'; |
||
82 | |||
83 | /** |
||
84 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là ATM Online, |
||
85 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
86 | */ |
||
87 | const PAYMENT_METHOD_ATM_ONLINE = 'ATM_ONLINE'; |
||
88 | |||
89 | /** |
||
90 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là ATM Offline, |
||
91 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
92 | */ |
||
93 | const PAYMENT_METHOD_ATM_OFFLINE = 'ATM_OFFLINE'; |
||
94 | |||
95 | /** |
||
96 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là Internet Banking, |
||
97 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
98 | */ |
||
99 | const PAYMENT_METHOD_INTERNET_BANKING = 'IB_ONLINE'; |
||
100 | |||
101 | /** |
||
102 | * Hằng khai báo giúp Ngân Lượng xác định phương thức thanh toán là thanh toán tại shop, |
||
103 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
104 | * @since 1.0.3 |
||
105 | */ |
||
106 | const PAYMENT_METHOD_CASH_IN_SHOP = 'CASH_IN_SHOP'; |
||
107 | |||
108 | /** |
||
109 | * 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), |
||
110 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
111 | */ |
||
112 | const PAYMENT_TYPE_REDIRECT = 1; |
||
113 | /** |
||
114 | * 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), |
||
115 | * khi khởi tạo lệnh [[RC_PURCHASE]] tại phương thức [[request()]]. |
||
116 | */ |
||
117 | const PAYMENT_TYPE_SAFE = 2; |
||
118 | |||
119 | /** |
||
120 | * Hằng khai báo giúp bạn xác định trạng thái giao dịch thành công, |
||
121 | * 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()]]. |
||
122 | */ |
||
123 | const TRANSACTION_STATUS_SUCCESS = '00'; |
||
124 | |||
125 | /** |
||
126 | * 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ữ, |
||
127 | * 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()]]. |
||
128 | */ |
||
129 | const TRANSACTION_STATUS_PENDING = '01'; |
||
130 | |||
131 | /** |
||
132 | * 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, |
||
133 | * 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()]]. |
||
134 | */ |
||
135 | const TRANSACTION_STATUS_ERROR = '02'; |
||
136 | |||
137 | /** |
||
138 | * 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 |
||
139 | * phương thức [[authenticate()]]. |
||
140 | */ |
||
141 | const AUTH_NL = 'NL'; |
||
142 | |||
143 | /** |
||
144 | * 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 |
||
145 | * ngân hàng, bạn phải `redirect` khách đến trang `auth_url` để xác minh `OTP`. |
||
146 | */ |
||
147 | const AUTH_BANK = 'BANK'; |
||
148 | |||
149 | /** |
||
150 | * Hằng cho biết gateway ở version 3.1 |
||
151 | */ |
||
152 | const VERSION_3_1 = '3.1'; |
||
153 | |||
154 | /** |
||
155 | * Hằng cho biết gateway ở version 3.2 |
||
156 | */ |
||
157 | const VERSION_3_2 = '3.2'; |
||
158 | |||
159 | /** |
||
160 | * @inheritdoc |
||
161 | */ |
||
162 | public $clientConfig = ['class' => PaymentClient::class]; |
||
163 | |||
164 | /** |
||
165 | * @inheritdoc |
||
166 | */ |
||
167 | public $requestDataConfig = ['class' => RequestData::class]; |
||
168 | |||
169 | /** |
||
170 | * @inheritdoc |
||
171 | */ |
||
172 | public $responseDataConfig = ['class' => ResponseData::class]; |
||
173 | |||
174 | /** |
||
175 | * @inheritdoc |
||
176 | */ |
||
177 | public $verifiedDataConfig = ['class' => VerifiedData::class]; |
||
178 | |||
179 | /** |
||
180 | * @inheritdoc |
||
181 | */ |
||
182 | 4 | public function getBaseUrl(): string |
|
183 | { |
||
184 | 4 | return ($this->sandbox ? 'https://sandbox.nganluong.vn:8088/nl30' : 'https://www.nganluong.vn') . '/checkout.api.nganluong.post.php'; |
|
185 | } |
||
186 | |||
187 | /** |
||
188 | * @inheritdoc |
||
189 | * @since 1.0.3 |
||
190 | */ |
||
191 | 4 | public function requestCommands(): array |
|
192 | { |
||
193 | 4 | return [self::RC_PURCHASE, self::RC_QUERY_DR, self::RC_AUTHENTICATE]; |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * @inheritdoc |
||
198 | */ |
||
199 | 2 | public function getSupportedVersions(): array |
|
200 | { |
||
201 | 2 | return [self::VERSION_3_1, self::VERSION_3_2]; |
|
202 | } |
||
203 | |||
204 | /** |
||
205 | * Phương thức yêu cầu Ngân Lượng xác minh OTP. |
||
206 | * Đâ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. |
||
207 | * |
||
208 | * @param array $data Dữ liệu yêu cầu xác minh. |
||
209 | * @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. |
||
210 | * @return ResponseData|DataInterface Trả về [[ResponseData]] là dữ liệu từ Ngân Lượng phản hồi. |
||
211 | * @throws \yii\base\InvalidConfigException|NotSupportedException|\ReflectionException |
||
212 | */ |
||
213 | 1 | public function authenticate(array $data, $clientId = null) |
|
214 | { |
||
215 | 1 | return $this->request(self::RC_AUTHENTICATE, $data, $clientId); |
|
216 | } |
||
217 | |||
218 | /** |
||
219 | * Phương thức dùng để nhận biết gateway có phải đang sử dụng chế độ `seamless checkout` hay không (version 3.2). |
||
220 | * |
||
221 | * @return bool Return TRUE if current mode is seamless. |
||
222 | */ |
||
223 | 4 | public function getSeamless(): bool |
|
224 | { |
||
225 | 4 | return $this->getVersion() === self::VERSION_3_2; |
|
226 | } |
||
227 | |||
228 | /** |
||
229 | * Phương thức dùng để thiết lập `seamless checkout` (version 3.2). |
||
230 | * |
||
231 | * @param bool $seamless Mode seamless or not. |
||
232 | * @return bool Return TRUE if seamless mode is turn on. |
||
233 | * @throws NotSupportedException |
||
234 | */ |
||
235 | public function setSeamless(bool $seamless): bool |
||
236 | { |
||
237 | return $this->setVersion($seamless ? self::VERSION_3_2 : self::VERSION_3_1); |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * @inheritdoc |
||
242 | * @throws NotSupportedException |
||
243 | */ |
||
244 | 4 | public function request($command, array $data, $clientId = null): DataInterface |
|
245 | { |
||
246 | 4 | View Code Duplication | if ($command === self::RC_AUTHENTICATE && !$this->getSeamless()) { |
0 ignored issues
–
show
|
|||
247 | throw new NotSupportedException('Authenticate command only support in `seamless` mode!'); |
||
248 | } else { |
||
249 | 4 | return parent::request($command, $data, $clientId); |
|
250 | } |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * @inheritdoc |
||
255 | * @throws NotSupportedException |
||
256 | */ |
||
257 | 1 | public function verifyRequest($command, \yii\web\Request $request = null, $clientId = null) |
|
258 | { |
||
259 | 1 | View Code Duplication | if ($command === self::VRC_IPN) { |
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
260 | throw new NotSupportedException('IPN is not supported in Ngan Luong gateway!'); |
||
261 | } else { |
||
262 | 1 | return parent::verifyRequest($command, $request, $clientId); |
|
263 | } |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * @inheritdoc |
||
268 | */ |
||
269 | 2 | protected function defaultVersion(): string |
|
270 | { |
||
271 | 2 | return self::VERSION_3_1; |
|
272 | } |
||
273 | |||
274 | /** |
||
275 | * @inheritdoc |
||
276 | * @throws \yii\base\InvalidConfigException |
||
277 | */ |
||
278 | 9 | protected function initSandboxEnvironment() |
|
279 | { |
||
280 | 9 | $clientConfig = require(__DIR__ . '/sandbox-client.php'); |
|
281 | 9 | $this->setClient($clientConfig); |
|
282 | 9 | } |
|
283 | |||
284 | /** |
||
285 | * @inheritdoc |
||
286 | */ |
||
287 | 4 | public function beforeRequest(RequestEvent $event) |
|
288 | { |
||
289 | 4 | if ($event->command === self::RC_AUTHENTICATE) { |
|
290 | 1 | $this->trigger(self::EVENT_BEFORE_AUTHENTICATE, $event); |
|
291 | } |
||
292 | |||
293 | 4 | parent::beforeRequest($event); |
|
294 | 4 | } |
|
295 | |||
296 | /** |
||
297 | * @inheritdoc |
||
298 | */ |
||
299 | 3 | public function afterRequest(RequestEvent $event) |
|
300 | { |
||
301 | 3 | if ($event->command === self::RC_AUTHENTICATE) { |
|
302 | 1 | $this->trigger(self::EVENT_AFTER_AUTHENTICATE, $event); |
|
303 | } |
||
304 | |||
305 | 3 | parent::afterRequest($event); |
|
306 | 3 | } |
|
307 | |||
308 | /** |
||
309 | * @inheritdoc |
||
310 | * @throws \yii\base\InvalidConfigException|\yii\httpclient\Exception |
||
311 | */ |
||
312 | 4 | protected function requestInternal(\vxm\gatewayclients\RequestData $requestData, \yii\httpclient\Client $httpClient): array |
|
313 | { |
||
314 | 4 | $data = $requestData->get(); |
|
315 | |||
316 | 3 | return $httpClient->post('', $data)->send()->getData(); |
|
317 | } |
||
318 | |||
319 | /** |
||
320 | * @inheritdoc |
||
321 | */ |
||
322 | 1 | protected function getVerifyRequestData($command, \yii\web\Request $request): array |
|
323 | { |
||
324 | return [ |
||
325 | 1 | 'token' => $request->get('token') |
|
326 | ]; |
||
327 | } |
||
328 | |||
329 | } |
||
330 |
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.