@mmpay/aya-mmqr 0.0.0-stage → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +251 -2
- package/bun.lock +23 -0
- package/dist/cjs/index.d.ts +78 -0
- package/dist/cjs/index.js +331 -0
- package/dist/cjs/types/index.d.ts +154 -0
- package/dist/cjs/types/index.js +2 -0
- package/dist/esm/index.d.ts +78 -0
- package/dist/esm/index.js +325 -0
- package/dist/esm/types/index.d.ts +154 -0
- package/dist/esm/types/index.js +1 -0
- package/package.json +53 -4
- package/src/index.ts +360 -0
- package/src/types/index.ts +156 -0
- package/test/decrypttest.js +33 -0
- package/test/test.js +65 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Login
|
|
3
|
+
* @Login
|
|
4
|
+
* @Login
|
|
5
|
+
*/
|
|
6
|
+
export interface loginRequest {
|
|
7
|
+
phone: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}
|
|
10
|
+
export interface loginResponse {
|
|
11
|
+
err: number;
|
|
12
|
+
message: string;
|
|
13
|
+
token: {
|
|
14
|
+
token: string;
|
|
15
|
+
expiredAt: string;
|
|
16
|
+
};
|
|
17
|
+
refreshToken: {
|
|
18
|
+
token: string;
|
|
19
|
+
expiredAt: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @Token
|
|
24
|
+
* @Token
|
|
25
|
+
* @Token
|
|
26
|
+
*/
|
|
27
|
+
export interface getTokenRequest {
|
|
28
|
+
grantType: string;
|
|
29
|
+
}
|
|
30
|
+
export interface getTokenResponse {
|
|
31
|
+
accessToken: string;
|
|
32
|
+
scope: string;
|
|
33
|
+
tokenType: string;
|
|
34
|
+
expiresIn: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @PaymentCreate
|
|
38
|
+
* @PaymentCreate
|
|
39
|
+
* @PaymentCreate
|
|
40
|
+
*/
|
|
41
|
+
export interface PaymentCreateRequest {
|
|
42
|
+
amount: number;
|
|
43
|
+
currency: string;
|
|
44
|
+
externalTransactionId: string;
|
|
45
|
+
externalAdditionalData?: string;
|
|
46
|
+
serviceCode: string;
|
|
47
|
+
MMQR: boolean;
|
|
48
|
+
timelimit: number;
|
|
49
|
+
}
|
|
50
|
+
export interface PaymentCreateResponse {
|
|
51
|
+
err: number;
|
|
52
|
+
message: string;
|
|
53
|
+
data: {
|
|
54
|
+
qrdata: string;
|
|
55
|
+
mmqrdata: string;
|
|
56
|
+
merchantId: string;
|
|
57
|
+
externalTransactionId: string;
|
|
58
|
+
referenceNumber: string;
|
|
59
|
+
amount: string;
|
|
60
|
+
fees: {
|
|
61
|
+
debitFee: number;
|
|
62
|
+
creditFee: number;
|
|
63
|
+
};
|
|
64
|
+
currency: string;
|
|
65
|
+
expiredAt: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @PaymentStatus
|
|
70
|
+
* @PaymentStatus
|
|
71
|
+
* @PaymentStatus
|
|
72
|
+
*/
|
|
73
|
+
export interface PaymentStatusRequest {
|
|
74
|
+
referenceNumber: string;
|
|
75
|
+
externalTransactionId: string;
|
|
76
|
+
}
|
|
77
|
+
export interface PaymentStatusResponse {
|
|
78
|
+
err: number;
|
|
79
|
+
message: string;
|
|
80
|
+
status: string;
|
|
81
|
+
transRefId: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @Callback
|
|
85
|
+
* @Callback
|
|
86
|
+
* @Callback
|
|
87
|
+
*/
|
|
88
|
+
export interface CallbackEncoded {
|
|
89
|
+
paymentResult?: string;
|
|
90
|
+
refundResult?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface CallbackDecoded {
|
|
93
|
+
name: string;
|
|
94
|
+
desc: string;
|
|
95
|
+
currency: string;
|
|
96
|
+
fees: {
|
|
97
|
+
debitFee: number;
|
|
98
|
+
creditFee: number;
|
|
99
|
+
};
|
|
100
|
+
status: string;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
transRefId: string;
|
|
103
|
+
code: string;
|
|
104
|
+
extMachId: string;
|
|
105
|
+
externalTransactionId: string;
|
|
106
|
+
referenceNumber: string;
|
|
107
|
+
totalAmount: number;
|
|
108
|
+
amount: number;
|
|
109
|
+
externalAdditionalData: string;
|
|
110
|
+
refFields: {
|
|
111
|
+
ENDTOENDID?: string;
|
|
112
|
+
OFFERID: string;
|
|
113
|
+
SENDERCLIENT: string;
|
|
114
|
+
SENDERID: string;
|
|
115
|
+
CURRENCY: string;
|
|
116
|
+
RECEIVERCLIENT: string;
|
|
117
|
+
TRANSACTIONID: string;
|
|
118
|
+
REFERENCENUMBER: string;
|
|
119
|
+
AMOUNT: number;
|
|
120
|
+
RECEIVERPHONE: string;
|
|
121
|
+
MESSAGE: string;
|
|
122
|
+
VOUCHER: string;
|
|
123
|
+
REQUESTID: string;
|
|
124
|
+
SERVICEID: string;
|
|
125
|
+
SUBUSERCLIENT: string;
|
|
126
|
+
SHOPID: string;
|
|
127
|
+
DEVICEID: string;
|
|
128
|
+
MACHID: string;
|
|
129
|
+
SUBUSERPHONE: string;
|
|
130
|
+
SENDERPHONE: string;
|
|
131
|
+
SENDERUSERID: string;
|
|
132
|
+
RECEIVERUSERID: string;
|
|
133
|
+
thirdpartyData: any;
|
|
134
|
+
TRANSREFID: string;
|
|
135
|
+
IP: string;
|
|
136
|
+
USERID: string;
|
|
137
|
+
CREDITORACCOUNTID?: string;
|
|
138
|
+
INVOICENUMBER?: string;
|
|
139
|
+
DEBITORNAME?: string;
|
|
140
|
+
DEBITORADDRESS?: string;
|
|
141
|
+
CREDITORNAME?: string;
|
|
142
|
+
EXTTRANSID?: string;
|
|
143
|
+
};
|
|
144
|
+
customer: {
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
phone: string;
|
|
148
|
+
};
|
|
149
|
+
merchant: {
|
|
150
|
+
id: string;
|
|
151
|
+
name: string;
|
|
152
|
+
phone: string;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { CallbackDecoded, CallbackEncoded, getTokenResponse, loginResponse, PaymentCreateRequest, PaymentCreateResponse, PaymentStatusRequest, PaymentStatusResponse } from './types';
|
|
2
|
+
export { CallbackDecoded, CallbackEncoded, getTokenResponse, loginResponse, PaymentCreateRequest, PaymentCreateResponse, PaymentStatusRequest, PaymentStatusResponse };
|
|
3
|
+
/**
|
|
4
|
+
* @InstanceOptions
|
|
5
|
+
*/
|
|
6
|
+
export interface InstanceOptions {
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
prefixUrl: string;
|
|
9
|
+
consumerKey: string;
|
|
10
|
+
consumerSecret: string;
|
|
11
|
+
decryptionKey: string;
|
|
12
|
+
phone: string;
|
|
13
|
+
password: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @AYAPayMerchantApi
|
|
17
|
+
* @param {InstanceOptions} options
|
|
18
|
+
* @returns {AYAPayMerchantClass} A status message string.
|
|
19
|
+
*/
|
|
20
|
+
export declare function AYAPayMerchantApi(options: InstanceOptions): AYAPayMerchantClass;
|
|
21
|
+
/**
|
|
22
|
+
* @AYAPayMerchantClass
|
|
23
|
+
*/
|
|
24
|
+
declare class AYAPayMerchantClass {
|
|
25
|
+
#private;
|
|
26
|
+
constructor(options: InstanceOptions);
|
|
27
|
+
/**
|
|
28
|
+
* basicToken
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
private basicToken;
|
|
32
|
+
/**
|
|
33
|
+
* getToken
|
|
34
|
+
* @returns {Promise<getTokenResponse>}
|
|
35
|
+
*/
|
|
36
|
+
private getToken;
|
|
37
|
+
/**
|
|
38
|
+
* login
|
|
39
|
+
* @returns {Promise<loginResponse>}
|
|
40
|
+
*/
|
|
41
|
+
private login;
|
|
42
|
+
/**
|
|
43
|
+
* authenticate
|
|
44
|
+
*/
|
|
45
|
+
authenticate(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* requestQR
|
|
48
|
+
* @param {PaymentCreateRequest} options
|
|
49
|
+
* ...
|
|
50
|
+
* @returns {Promise<PaymentCreateResponse>}
|
|
51
|
+
*/
|
|
52
|
+
requestQR(options: PaymentCreateRequest): Promise<PaymentCreateResponse>;
|
|
53
|
+
/**
|
|
54
|
+
* paymentStatusQR
|
|
55
|
+
* ...
|
|
56
|
+
*/
|
|
57
|
+
paymentStatusQR(options: PaymentStatusRequest): Promise<PaymentStatusResponse>;
|
|
58
|
+
/**
|
|
59
|
+
* requestPush
|
|
60
|
+
* ...
|
|
61
|
+
*/
|
|
62
|
+
requestPush(options: PaymentCreateRequest): Promise<PaymentCreateResponse>;
|
|
63
|
+
/**
|
|
64
|
+
* paymentStatusPush
|
|
65
|
+
* ...
|
|
66
|
+
*/
|
|
67
|
+
paymentStatusPush(options: PaymentStatusRequest): Promise<PaymentStatusResponse>;
|
|
68
|
+
/**
|
|
69
|
+
* verifyCallback
|
|
70
|
+
* ...
|
|
71
|
+
*/
|
|
72
|
+
verifyCallback(options: CallbackEncoded): Promise<CallbackDecoded>;
|
|
73
|
+
/**
|
|
74
|
+
* verifyCallbackRefund
|
|
75
|
+
* ...
|
|
76
|
+
*/
|
|
77
|
+
verifyCallbackRefund(options: CallbackEncoded): Promise<CallbackDecoded>;
|
|
78
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
/**
|
|
4
|
+
* @AYAPayMerchantApi
|
|
5
|
+
* @param {InstanceOptions} options
|
|
6
|
+
* @returns {AYAPayMerchantClass} A status message string.
|
|
7
|
+
*/
|
|
8
|
+
export function AYAPayMerchantApi(options) {
|
|
9
|
+
return new AYAPayMerchantClass({
|
|
10
|
+
baseUrl: options.baseUrl,
|
|
11
|
+
prefixUrl: options.prefixUrl,
|
|
12
|
+
consumerKey: options.consumerKey,
|
|
13
|
+
consumerSecret: options.consumerSecret,
|
|
14
|
+
decryptionKey: options.decryptionKey,
|
|
15
|
+
phone: options.phone,
|
|
16
|
+
password: options.password,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @AYAPayMerchantClass
|
|
21
|
+
*/
|
|
22
|
+
class AYAPayMerchantClass {
|
|
23
|
+
#baseUrl;
|
|
24
|
+
#prefixUrl;
|
|
25
|
+
#consumerKey;
|
|
26
|
+
#consumerSecret;
|
|
27
|
+
#decryptionKey;
|
|
28
|
+
#phone;
|
|
29
|
+
#password;
|
|
30
|
+
#keyToken = '';
|
|
31
|
+
#apiToken = '';
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.#baseUrl = options.baseUrl;
|
|
34
|
+
this.#prefixUrl = options.prefixUrl;
|
|
35
|
+
this.#consumerKey = options.consumerKey;
|
|
36
|
+
this.#consumerSecret = options.consumerSecret;
|
|
37
|
+
this.#decryptionKey = options.decryptionKey;
|
|
38
|
+
this.#phone = options.phone;
|
|
39
|
+
this.#password = options.password;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* basicToken
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
basicToken() {
|
|
46
|
+
const rawString = `${this.#consumerKey}:${this.#consumerSecret}`;
|
|
47
|
+
const buffer = Buffer.from(rawString);
|
|
48
|
+
const base64String = buffer.toString('base64');
|
|
49
|
+
return base64String;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* getToken
|
|
53
|
+
* @returns {Promise<getTokenResponse>}
|
|
54
|
+
*/
|
|
55
|
+
async getToken() {
|
|
56
|
+
try {
|
|
57
|
+
const config = {
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
60
|
+
'Authorization': `Basic ${this.basicToken()}`
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const body = {
|
|
64
|
+
grant_type: 'client_credentials'
|
|
65
|
+
};
|
|
66
|
+
const formBody = new URLSearchParams();
|
|
67
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
68
|
+
if (value !== undefined)
|
|
69
|
+
formBody.append(key, String(value));
|
|
70
|
+
});
|
|
71
|
+
const response = await fetch(`${this.#baseUrl}/token`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: config.headers,
|
|
74
|
+
body: formBody
|
|
75
|
+
});
|
|
76
|
+
const originResponse = (await response.json());
|
|
77
|
+
const modifiedResponse = {
|
|
78
|
+
accessToken: originResponse.access_token,
|
|
79
|
+
scope: originResponse.scope,
|
|
80
|
+
tokenType: originResponse.token_type,
|
|
81
|
+
expiresIn: originResponse.expires_in,
|
|
82
|
+
};
|
|
83
|
+
this.#keyToken = modifiedResponse.accessToken;
|
|
84
|
+
return modifiedResponse;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error(error);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* login
|
|
93
|
+
* @returns {Promise<loginResponse>}
|
|
94
|
+
*/
|
|
95
|
+
async login() {
|
|
96
|
+
try {
|
|
97
|
+
const config = {
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
100
|
+
'Token': `Bearer ${this.#keyToken}`
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const body = {
|
|
104
|
+
phone: this.#phone,
|
|
105
|
+
password: this.#password,
|
|
106
|
+
};
|
|
107
|
+
const formBody = new URLSearchParams();
|
|
108
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
109
|
+
if (value !== undefined)
|
|
110
|
+
formBody.append(key, String(value));
|
|
111
|
+
});
|
|
112
|
+
const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/login`, {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: config.headers,
|
|
115
|
+
body: formBody
|
|
116
|
+
});
|
|
117
|
+
const loginResponse = (await response.json());
|
|
118
|
+
this.#apiToken = loginResponse.token.token;
|
|
119
|
+
return loginResponse;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(error);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* authenticate
|
|
128
|
+
*/
|
|
129
|
+
async authenticate() {
|
|
130
|
+
await this.getToken();
|
|
131
|
+
await this.login();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* requestQR
|
|
135
|
+
* @param {PaymentCreateRequest} options
|
|
136
|
+
* ...
|
|
137
|
+
* @returns {Promise<PaymentCreateResponse>}
|
|
138
|
+
*/
|
|
139
|
+
async requestQR(options) {
|
|
140
|
+
try {
|
|
141
|
+
await this.authenticate();
|
|
142
|
+
const config = {
|
|
143
|
+
headers: {
|
|
144
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
145
|
+
'Token': `Bearer ${this.#keyToken}`,
|
|
146
|
+
'Authorization': `Bearer ${this.#apiToken}`,
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const body = {
|
|
150
|
+
amount: options.amount,
|
|
151
|
+
currency: options.currency,
|
|
152
|
+
externalTransactionId: options.externalTransactionId,
|
|
153
|
+
externalAdditionalData: options.externalAdditionalData,
|
|
154
|
+
serviceCode: options.serviceCode,
|
|
155
|
+
MMQR: options.MMQR,
|
|
156
|
+
timelimit: options.timelimit,
|
|
157
|
+
};
|
|
158
|
+
const formBody = new URLSearchParams();
|
|
159
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
160
|
+
if (value !== undefined)
|
|
161
|
+
formBody.append(key, String(value));
|
|
162
|
+
});
|
|
163
|
+
const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/v2/requestQRPayment`, {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: config.headers,
|
|
166
|
+
body: formBody
|
|
167
|
+
});
|
|
168
|
+
return (await response.json());
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(error);
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* paymentStatusQR
|
|
177
|
+
* ...
|
|
178
|
+
*/
|
|
179
|
+
async paymentStatusQR(options) {
|
|
180
|
+
try {
|
|
181
|
+
await this.authenticate();
|
|
182
|
+
const config = {
|
|
183
|
+
headers: {
|
|
184
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
185
|
+
'Token': `Bearer ${this.#keyToken}`,
|
|
186
|
+
'Authorization': `Bearer ${this.#apiToken}`,
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
const body = {
|
|
190
|
+
externalTransactionId: options.externalTransactionId,
|
|
191
|
+
referenceNumber: options.referenceNumber,
|
|
192
|
+
};
|
|
193
|
+
const formBody = new URLSearchParams();
|
|
194
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
195
|
+
if (value !== undefined)
|
|
196
|
+
formBody.append(key, String(value));
|
|
197
|
+
});
|
|
198
|
+
const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/checkQRPayment`, {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: config.headers,
|
|
201
|
+
body: formBody
|
|
202
|
+
});
|
|
203
|
+
return (await response.json());
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error(error);
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* requestPush
|
|
212
|
+
* ...
|
|
213
|
+
*/
|
|
214
|
+
async requestPush(options) {
|
|
215
|
+
try {
|
|
216
|
+
await this.authenticate();
|
|
217
|
+
const config = {
|
|
218
|
+
headers: {
|
|
219
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
220
|
+
'Token': `Bearer ${this.#keyToken}`,
|
|
221
|
+
'Authorization': `Bearer ${this.#apiToken}`,
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const body = {
|
|
225
|
+
amount: options.amount,
|
|
226
|
+
currency: options.currency,
|
|
227
|
+
externalTransactionId: options.externalTransactionId,
|
|
228
|
+
externalAdditionalData: options.externalAdditionalData,
|
|
229
|
+
serviceCode: options.serviceCode,
|
|
230
|
+
};
|
|
231
|
+
const formBody = new URLSearchParams();
|
|
232
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
233
|
+
if (value !== undefined)
|
|
234
|
+
formBody.append(key, String(value));
|
|
235
|
+
});
|
|
236
|
+
const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/v2/requestPushPayment`, {
|
|
237
|
+
method: 'POST',
|
|
238
|
+
headers: config.headers,
|
|
239
|
+
body: formBody
|
|
240
|
+
});
|
|
241
|
+
return (await response.json());
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
console.error(error);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* paymentStatusPush
|
|
250
|
+
* ...
|
|
251
|
+
*/
|
|
252
|
+
async paymentStatusPush(options) {
|
|
253
|
+
try {
|
|
254
|
+
await this.authenticate();
|
|
255
|
+
const config = {
|
|
256
|
+
headers: {
|
|
257
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
258
|
+
'Token': `Bearer ${this.#keyToken}`,
|
|
259
|
+
'Authorization': `Bearer ${this.#apiToken}`,
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
const body = {
|
|
263
|
+
externalTransactionId: options.externalTransactionId,
|
|
264
|
+
referenceNumber: options.referenceNumber,
|
|
265
|
+
};
|
|
266
|
+
const formBody = new URLSearchParams();
|
|
267
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
268
|
+
if (value !== undefined)
|
|
269
|
+
formBody.append(key, String(value));
|
|
270
|
+
});
|
|
271
|
+
const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/checkRequestPayment`, {
|
|
272
|
+
method: 'POST',
|
|
273
|
+
headers: config.headers,
|
|
274
|
+
body: formBody
|
|
275
|
+
});
|
|
276
|
+
return (await response.json());
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
console.error(error);
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* verifyCallback
|
|
285
|
+
* ...
|
|
286
|
+
*/
|
|
287
|
+
async verifyCallback(options) {
|
|
288
|
+
try {
|
|
289
|
+
if (!options.paymentResult)
|
|
290
|
+
throw new Error("paymentResult is missing or undefined");
|
|
291
|
+
const cipherRaw = Buffer.from(options.paymentResult, 'base64');
|
|
292
|
+
const key = Buffer.from(this.#decryptionKey);
|
|
293
|
+
const decipher = crypto.createDecipheriv('aes-256-ecb', key, null);
|
|
294
|
+
let decrypted = decipher.update(cipherRaw, undefined, 'utf8');
|
|
295
|
+
decrypted += decipher.final('utf8');
|
|
296
|
+
const result = JSON.parse(decrypted);
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
console.error(error);
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* verifyCallbackRefund
|
|
306
|
+
* ...
|
|
307
|
+
*/
|
|
308
|
+
async verifyCallbackRefund(options) {
|
|
309
|
+
try {
|
|
310
|
+
if (!options.refundResult)
|
|
311
|
+
throw new Error("refundResult is missing or undefined");
|
|
312
|
+
const cipherRaw = Buffer.from(options.refundResult, 'base64');
|
|
313
|
+
const key = Buffer.from(this.#decryptionKey);
|
|
314
|
+
const decipher = crypto.createDecipheriv('aes-256-ecb', key, null);
|
|
315
|
+
let decrypted = decipher.update(cipherRaw, undefined, 'utf8');
|
|
316
|
+
decrypted += decipher.final('utf8');
|
|
317
|
+
const result = JSON.parse(decrypted);
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
console.error(error);
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Login
|
|
3
|
+
* @Login
|
|
4
|
+
* @Login
|
|
5
|
+
*/
|
|
6
|
+
export interface loginRequest {
|
|
7
|
+
phone: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}
|
|
10
|
+
export interface loginResponse {
|
|
11
|
+
err: number;
|
|
12
|
+
message: string;
|
|
13
|
+
token: {
|
|
14
|
+
token: string;
|
|
15
|
+
expiredAt: string;
|
|
16
|
+
};
|
|
17
|
+
refreshToken: {
|
|
18
|
+
token: string;
|
|
19
|
+
expiredAt: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @Token
|
|
24
|
+
* @Token
|
|
25
|
+
* @Token
|
|
26
|
+
*/
|
|
27
|
+
export interface getTokenRequest {
|
|
28
|
+
grantType: string;
|
|
29
|
+
}
|
|
30
|
+
export interface getTokenResponse {
|
|
31
|
+
accessToken: string;
|
|
32
|
+
scope: string;
|
|
33
|
+
tokenType: string;
|
|
34
|
+
expiresIn: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @PaymentCreate
|
|
38
|
+
* @PaymentCreate
|
|
39
|
+
* @PaymentCreate
|
|
40
|
+
*/
|
|
41
|
+
export interface PaymentCreateRequest {
|
|
42
|
+
amount: number;
|
|
43
|
+
currency: string;
|
|
44
|
+
externalTransactionId: string;
|
|
45
|
+
externalAdditionalData?: string;
|
|
46
|
+
serviceCode: string;
|
|
47
|
+
MMQR: boolean;
|
|
48
|
+
timelimit: number;
|
|
49
|
+
}
|
|
50
|
+
export interface PaymentCreateResponse {
|
|
51
|
+
err: number;
|
|
52
|
+
message: string;
|
|
53
|
+
data: {
|
|
54
|
+
qrdata: string;
|
|
55
|
+
mmqrdata: string;
|
|
56
|
+
merchantId: string;
|
|
57
|
+
externalTransactionId: string;
|
|
58
|
+
referenceNumber: string;
|
|
59
|
+
amount: string;
|
|
60
|
+
fees: {
|
|
61
|
+
debitFee: number;
|
|
62
|
+
creditFee: number;
|
|
63
|
+
};
|
|
64
|
+
currency: string;
|
|
65
|
+
expiredAt: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @PaymentStatus
|
|
70
|
+
* @PaymentStatus
|
|
71
|
+
* @PaymentStatus
|
|
72
|
+
*/
|
|
73
|
+
export interface PaymentStatusRequest {
|
|
74
|
+
referenceNumber: string;
|
|
75
|
+
externalTransactionId: string;
|
|
76
|
+
}
|
|
77
|
+
export interface PaymentStatusResponse {
|
|
78
|
+
err: number;
|
|
79
|
+
message: string;
|
|
80
|
+
status: string;
|
|
81
|
+
transRefId: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @Callback
|
|
85
|
+
* @Callback
|
|
86
|
+
* @Callback
|
|
87
|
+
*/
|
|
88
|
+
export interface CallbackEncoded {
|
|
89
|
+
paymentResult?: string;
|
|
90
|
+
refundResult?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface CallbackDecoded {
|
|
93
|
+
name: string;
|
|
94
|
+
desc: string;
|
|
95
|
+
currency: string;
|
|
96
|
+
fees: {
|
|
97
|
+
debitFee: number;
|
|
98
|
+
creditFee: number;
|
|
99
|
+
};
|
|
100
|
+
status: string;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
transRefId: string;
|
|
103
|
+
code: string;
|
|
104
|
+
extMachId: string;
|
|
105
|
+
externalTransactionId: string;
|
|
106
|
+
referenceNumber: string;
|
|
107
|
+
totalAmount: number;
|
|
108
|
+
amount: number;
|
|
109
|
+
externalAdditionalData: string;
|
|
110
|
+
refFields: {
|
|
111
|
+
ENDTOENDID?: string;
|
|
112
|
+
OFFERID: string;
|
|
113
|
+
SENDERCLIENT: string;
|
|
114
|
+
SENDERID: string;
|
|
115
|
+
CURRENCY: string;
|
|
116
|
+
RECEIVERCLIENT: string;
|
|
117
|
+
TRANSACTIONID: string;
|
|
118
|
+
REFERENCENUMBER: string;
|
|
119
|
+
AMOUNT: number;
|
|
120
|
+
RECEIVERPHONE: string;
|
|
121
|
+
MESSAGE: string;
|
|
122
|
+
VOUCHER: string;
|
|
123
|
+
REQUESTID: string;
|
|
124
|
+
SERVICEID: string;
|
|
125
|
+
SUBUSERCLIENT: string;
|
|
126
|
+
SHOPID: string;
|
|
127
|
+
DEVICEID: string;
|
|
128
|
+
MACHID: string;
|
|
129
|
+
SUBUSERPHONE: string;
|
|
130
|
+
SENDERPHONE: string;
|
|
131
|
+
SENDERUSERID: string;
|
|
132
|
+
RECEIVERUSERID: string;
|
|
133
|
+
thirdpartyData: any;
|
|
134
|
+
TRANSREFID: string;
|
|
135
|
+
IP: string;
|
|
136
|
+
USERID: string;
|
|
137
|
+
CREDITORACCOUNTID?: string;
|
|
138
|
+
INVOICENUMBER?: string;
|
|
139
|
+
DEBITORNAME?: string;
|
|
140
|
+
DEBITORADDRESS?: string;
|
|
141
|
+
CREDITORNAME?: string;
|
|
142
|
+
EXTTRANSID?: string;
|
|
143
|
+
};
|
|
144
|
+
customer: {
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
phone: string;
|
|
148
|
+
};
|
|
149
|
+
merchant: {
|
|
150
|
+
id: string;
|
|
151
|
+
name: string;
|
|
152
|
+
phone: string;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|