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\onepay; |
9
|
|
|
|
10
|
|
|
use Yii; |
11
|
|
|
|
12
|
|
|
use yii\helpers\Url; |
13
|
|
|
|
14
|
|
|
use vxm\gatewayclients\RequestData as BaseRequestData; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Lớp RequestData cung cấp dữ liệu để giao tiếp với OnePay như truy vấn giao dịch, yêu cầu thanh toán. |
18
|
|
|
* |
19
|
|
|
* @method PaymentClient getClient() đối tượng client đã dùng để thực thi request. |
20
|
|
|
* |
21
|
|
|
* @property PaymentClient $client đối tượng client đã dùng để thực thi request. |
22
|
|
|
* |
23
|
|
|
* @author Vuong Minh <[email protected]> |
24
|
|
|
* @since 1.0 |
25
|
|
|
*/ |
26
|
|
|
class RequestData extends BaseRequestData |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* Mảng hằng tập hợp các attributes cần thêm prefix `avs_` |
30
|
|
|
*/ |
31
|
|
|
const AVS_ATTRIBUTES = ['Street01', 'City', 'StateProv', 'PostCode', 'Country']; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Mảng hằng tập hợp các attributes cần thêm prefix `vpc_` |
35
|
|
|
*/ |
36
|
|
|
const VPC_ATTRIBUTES = [ |
37
|
|
|
'Amount', 'Locale', 'TicketNo', 'MerchTxnRef', 'ReturnURL', 'Currency', 'OrderInfo', |
38
|
|
|
'SHIP_Street01', 'SHIP_Provice', 'SHIP_City', 'SHIP_Country', 'Customer_Phone', 'Customer_Email', |
39
|
|
|
'Customer_Id', |
40
|
|
|
]; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @inheritdoc |
44
|
|
|
*/ |
45
|
4 |
|
public function rules() |
46
|
|
|
{ |
47
|
|
|
$rules = [ |
48
|
4 |
|
[['vpc_Version', 'vpc_Command', 'vpc_AccessCode', 'vpc_Merchant', 'vpc_MerchTxnRef'], 'required', 'on' => [ |
49
|
|
|
PaymentGateway::RC_PURCHASE, PaymentGateway::RC_QUERY_DR |
50
|
|
|
]], |
51
|
|
|
[[ |
52
|
|
|
'vpc_Locale', 'vpc_ReturnURL', 'vpc_OrderInfo', 'vpc_Amount', |
53
|
|
|
'vpc_TicketNo', 'AgainLink', 'Title', 'vpc_SecureHash' |
54
|
|
|
], 'required', 'on' => PaymentGateway::RC_PURCHASE] |
55
|
|
|
]; |
56
|
|
|
|
57
|
4 |
|
if (!$this->getClient()->getGateway()->international) { |
58
|
2 |
|
return array_merge($rules, [ |
59
|
2 |
|
[['vpc_Currency'], 'required', 'on' => [PaymentGateway::RC_PURCHASE]] |
60
|
|
|
]); |
61
|
|
|
} else { |
62
|
2 |
|
return $rules; |
63
|
|
|
} |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @inheritdoc |
68
|
|
|
* @throws \yii\base\NotSupportedException |
69
|
|
|
*/ |
70
|
4 |
|
protected function ensureAttributes(array &$attributes) |
71
|
|
|
{ |
72
|
4 |
|
$client = $this->getClient(); |
73
|
4 |
|
$command = $this->getCommand(); |
74
|
4 |
|
$attributesEnsured = []; |
75
|
|
|
|
76
|
4 |
|
foreach ($attributes as $attribute => $value) { |
77
|
4 |
|
if (in_array($attribute, self::AVS_ATTRIBUTES, true)) { |
78
|
|
|
$attributesEnsured['AVS_' . $attribute] = $value; |
79
|
4 |
|
} elseif (in_array($attribute, self::VPC_ATTRIBUTES, true)) { |
80
|
4 |
|
$attributesEnsured['vpc_' . $attribute] = $value; |
81
|
|
|
} else { |
82
|
4 |
|
$attributesEnsured[$attribute] = $value; |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
4 |
|
$attributesEnsured['vpc_Merchant'] = $client->merchantId; |
87
|
4 |
|
$attributesEnsured['vpc_AccessCode'] = $client->accessCode; |
88
|
4 |
|
$attributesEnsured['vpc_Version'] = $client->getGateway()->getVersion(); |
89
|
|
|
|
90
|
4 |
|
if (!$client->getGateway()->international && $command === PaymentGateway::RC_PURCHASE) { |
91
|
1 |
|
$attributesEnsured['vpc_Currency'] = $attributesEnsured['vpc_Currency'] ?? 'VND'; |
92
|
|
|
} |
93
|
|
|
|
94
|
4 |
|
if ($command === PaymentGateway::RC_QUERY_DR) { |
95
|
2 |
|
$attributesEnsured['vpc_Command'] = 'queryDR'; |
96
|
2 |
|
$attributesEnsured['vpc_User'] = 'op01'; |
97
|
2 |
|
$attributesEnsured['vpc_Password'] = 'op123456'; |
98
|
|
|
} else { |
99
|
2 |
|
$attributesEnsured['vpc_Command'] = 'pay'; |
100
|
2 |
|
$attributesEnsured['vpc_Locale'] = $attributesEnsured['vpc_Locale'] ?? 'vn'; |
101
|
2 |
|
$attributesEnsured['vpc_SecureHash'] = $this->signature($attributesEnsured); |
102
|
|
|
|
103
|
2 |
|
if (Yii::$app instanceof \yii\web\Application) { |
104
|
2 |
|
$attributesEnsured['vpc_TicketNo'] = $attributesEnsured['vpc_TicketNo'] ?? Yii::$app->getRequest()->getUserIP(); |
105
|
2 |
|
$attributesEnsured['AgainLink'] = $attributesEnsured['AgainLink'] ?? Url::current(); |
106
|
2 |
|
$attributesEnsured['Title'] = $attributesEnsured['Title'] ?? (string)Yii::$app->getView()->title; |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
4 |
|
$attributes = $attributesEnsured; |
111
|
4 |
|
parent::ensureAttributes($attributes); |
112
|
4 |
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Phương thức tạo chữ ký dữ liệu |
116
|
|
|
* |
117
|
|
|
* @param array $data Dữ liệu cần tạo chữ ký |
118
|
|
|
* @return string Trả về chuỗi chữ ký của dữ liệu |
119
|
|
|
* @throws \yii\base\NotSupportedException |
120
|
|
|
*/ |
121
|
2 |
|
private function signature(array $data): string |
122
|
|
|
{ |
123
|
2 |
|
unset($data['vpc_SecureHash']); |
124
|
2 |
|
ksort($data); |
125
|
2 |
|
$dataSign = []; |
126
|
|
|
|
127
|
2 |
|
foreach ($data as $attribute => $value) { |
128
|
2 |
|
if (strpos($attribute, 'vpc_') === 0) { |
129
|
2 |
|
$dataSign[$attribute] = $value; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** @var PaymentClient $client */ |
134
|
2 |
|
$client = $this->getClient(); |
135
|
2 |
|
$dataSign = urldecode(http_build_query($dataSign)); |
136
|
2 |
|
return strtoupper($client->signature($dataSign)); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
} |
140
|
|
|
|