@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 CHANGED
@@ -1,3 +1,252 @@
1
- # Temporary Holding Version
1
+ # 📘 AYA Pay Merchant API Integration Documentation (APIM)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An unofficial, personal-use TypeScript API integration package for connecting AYAPay Merchant's MMQR functionalities into Node.js applications.
4
+ It provides a simple class-based wrapper around the AYAPay REST API, handling authentication, token management, dynamic QR generation, status checking, and refunds.
5
+
6
+ > **Disclaimer:** This is an unofficial, community-driven integration package intended for personal reuse. It is not affiliated with, endorsed by, or maintained by AYA Bank.
7
+
8
+ ## 🚀 Installation
9
+
10
+ Install the package via npm:
11
+
12
+ ```bash
13
+ npm install @mmpay/aya-mmqr --save
14
+ ```
15
+
16
+
17
+ ## Implementation IDEA
18
+ ```javascript
19
+ import { AYAPayMerchantApi, SDKOptions } from '@mmpay/aya-mmqr';
20
+
21
+ const options: SDKOptions = {
22
+ baseUrl: 'https://sandboxxxxx.aya-payx.com/api', // <<< Request AYA Team. I cannot disclose here for security reasons
23
+ prefixUrl: 'xxx', // <<< Request AYA Team. I cannot disclose here for security reasons
24
+ consumerKey: 'YOUR_CONSUMER_KEY',
25
+ consumerSecret: 'YOUR_CONSUMER_SECRET',
26
+ decryptionKey: 'YOUR_DECRYPTION_KEY_32_BYTES',
27
+ phone: 'MERCHANT_APP_PHONE_NUMBER',
28
+ password: 'MERCHANT_APP_PASSWORD', // Password Or Pincode
29
+ };
30
+
31
+ const ayaPayClient = AYAPayMerchantApi(options);
32
+
33
+ // DEVELOPMENT QR
34
+ const qrResponse = await ayaPayClient.requestQR({
35
+ amount: 5000,
36
+ currency: 'MMK',
37
+ externalTransactionId: 'ORD-' + new Date().getTime(),
38
+ serviceCode: 'xxx-qr', // << I cannot disclose all of these ENUM for security reasons, Please ask merchant onboarding teams
39
+ // externalAdditionalData: optional
40
+ })
41
+ console.log(qrResponse)
42
+
43
+ const qrStatusResponse = await ayaPayClient.paymentStatusQR({
44
+ referenceNumber: qrResponse.data.referenceNumber,
45
+ externalTransactionId: qrResponse.data.externalTransactionId,
46
+ })
47
+ console.log(qrStatusResponse)
48
+
49
+
50
+ const omResponse = await ayaPayClient.requestPush({
51
+ amount: 5000,
52
+ currency: 'MMK',
53
+ externalTransactionId: 'ORD-' + new Date().getTime(),
54
+ serviceCode: 'xxx-om', // << I cannot disclose all of these ENUM for security reasons, Please ask merchant onboarding teams
55
+ // externalAdditionalData: optional
56
+ })
57
+ console.log(omResponse)
58
+
59
+ const omStatusResponse = await ayaPayClient.paymentStatusPush({
60
+ referenceNumber: omResponse.data.referenceNumber,
61
+ externalTransactionId: omResponse.data.externalTransactionId,
62
+ })
63
+ console.log(omStatusResponse)
64
+
65
+ // Now you can call methods like:
66
+ // await ayaPayClient.getToken({ grantType: 'client_credentials' });
67
+ ```
68
+
69
+ ## 📝 SDK Configuration and Initialization
70
+
71
+ The SDK requires specific credentials and endpoint information for initialization.
72
+
73
+ ### `SDKOptions` Interface
74
+
75
+ This configuration object is passed to the initialization function.
76
+
77
+ | Property | Type | Required | Description |
78
+ | :--- | :--- | :---: | :--- |
79
+ | `baseUrl` | `string` | **Yes** | The base URL for the AYA Pay API (e.g., `https://api.gateway.com`). |
80
+ | `consumerKey` | `string` | **Yes** | Your merchant consumer key used for generating the Basic Token. |
81
+ | `consumerSecret` | `string` | **Yes** | Your merchant consumer secret used for generating the Basic Token. |
82
+ | `decryptionKey` | `string` | **Yes** | The AES-256-ECB secret key for decrypting payment callback data. |
83
+ | `basicKey` | `string` | No | *(Present in interface but currently unused in methods)*. |
84
+
85
+ ### Initialization Example (TypeScript)
86
+
87
+ The `AYAPayMerchantApi` function returns a class instance containing all core methods.
88
+
89
+ ```javascript
90
+ import { AYAPayMerchantApi, SDKOptions } from '@mmpay/aya-mmqr';
91
+
92
+ const options: SDKOptions = {
93
+ baseUrl: 'https://sandbox.ayapay.com/api', // <<< Request HERE I cannot disclose for security reasons
94
+ consumerKey: 'YOUR_CONSUMER_KEY',
95
+ consumerSecret: 'YOUR_CONSUMER_SECRET',
96
+ decryptionKey: 'YOUR_DECRYPTION_KEY_32_BYTES',
97
+ basicKey: '', // Can be an empty string
98
+ };
99
+
100
+ const ayaPayClient = AYAPayMerchantApi(options);
101
+
102
+ // Now you can call methods like:
103
+ // await ayaPayClient.getToken({ grantType: 'client_credentials' });
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 🔑 Authentication and Token Management
109
+
110
+ All merchant API interactions require two tokens: the **Key Token** (for `Token` header) and the **API Token** (for `Authorization` header).
111
+
112
+ ### 1. `getToken()`
113
+
114
+ Requests the primary Key Token using the Client Credentials grant type. This token is stored internally and used in the `Token` header.
115
+
116
+ | Parameter | Type | Description |
117
+ | :--- | :--- | :--- |
118
+ | `options.grantType` | `string` | Must be set to `'client_credentials'`. |
119
+
120
+ #### `getTokenResponse` (Success Response)
121
+
122
+ | Property | Type | Description |
123
+ | :--- | :--- | :--- |
124
+ | `accessToken` | `string` | The Key Token obtained. |
125
+ | `tokenType` | `string` | Token type, e.g., `'Bearer'`. |
126
+ | `expiresIn` | `number` | Token expiry time in seconds. |
127
+
128
+ ### 2. `login(options: loginRequest)`
129
+
130
+ Authenticates the merchant to retrieve the merchant-specific API Token and Refresh Token.
131
+
132
+ #### `loginRequest` (Parameters)
133
+
134
+ | Property | Type | Description |
135
+ | :--- | :--- | :--- |
136
+ | `phone` | `string` | Merchant's registered phone number. |
137
+ | `password` | `string` | Merchant's password. |
138
+
139
+ #### `loginResponse` (Success Response)
140
+
141
+ | Property | Type | Description |
142
+ | :--- | :--- | :--- |
143
+ | `err` | `number` | Error code (0 for success). |
144
+ | `message` | `string` | Status message. |
145
+ | `token.token` | `string` | The API Token, stored internally and used for payment methods. |
146
+ | `refreshToken.token` | `string` | The Refresh Token. |
147
+
148
+ ---
149
+
150
+ ## 💳 Payment Methods
151
+
152
+ ### 1. `requestQR(options: PaymentCreateRequest)`
153
+
154
+ Generates a QR code for a customer to scan and pay.
155
+
156
+ | Parameter | Type | Description |
157
+ | :--- | :--- | :--- |
158
+ | `options` | `PaymentCreateRequest` | Object containing payment details. |
159
+
160
+ ### 2. `requestPush(options: PaymentCreateRequest)`
161
+
162
+ Initiates a payment by sending a push notification request to the customer's payment app.
163
+
164
+ | Parameter | Type | Description |
165
+ | :--- | :--- | :--- |
166
+ | `options` | `PaymentCreateRequest` | Object containing payment details. |
167
+
168
+ #### `PaymentCreateRequest` (Parameters for QR/Push)
169
+
170
+ | Property | Type | Description |
171
+ | :--- | :--- | :--- |
172
+ | `amount` | `number` | Transaction amount. |
173
+ | `currency` | `string` | Currency code (e.g., `'MMK'`). |
174
+ | `externalTransactionId` | `string` | **Unique ID** from the merchant's system. |
175
+ | `serviceCode` | `string` | Merchant's service code. |
176
+ | `externalAdditionalData` | `string` | Optional field for extra merchant data. |
177
+
178
+ #### `PaymentCreateResponse` (Success Response)
179
+
180
+ | Property | Type | Description |
181
+ | :--- | :--- | :--- |
182
+ | `data.qrdata` | `string` | (QR) Raw QR code string. |
183
+ | `data.mmqrdata` | `string` | (QR) Myanmar QR code string. |
184
+ | `data.referenceNumber` | `string` | **Unique** transaction reference number from AYA Pay. |
185
+ | `data.amount` | `string` | Transaction amount confirmed. |
186
+ | `data.expiredAt` | `string` | Timestamp when the payment request expires. |
187
+
188
+ ---
189
+
190
+ ## 🔍 Status Check Methods
191
+
192
+ ### 1. `paymentStatusQR(options: PaymentStatusRequest)`
193
+
194
+ Checks the status of a previously requested QR payment.
195
+
196
+ ### 2. `paymentStatusPush(options: PaymentStatusRequest)`
197
+
198
+ Checks the status of a previously requested Push payment.
199
+
200
+ #### `PaymentStatusRequest` (Parameters for Status Check)
201
+
202
+ | Property | Type | Description |
203
+ | :--- | :--- | :--- |
204
+ | `referenceNumber` | `string` | The AYA Pay unique transaction reference number. |
205
+ | `externalTransactionId` | `string` | The merchant's unique transaction ID. |
206
+
207
+ #### `PaymentStatusResponse` (Success Response)
208
+
209
+ | Property | Type | Description |
210
+ | :--- | :--- | :--- |
211
+ | `status` | `string` | The transaction status (e.g., `'PENDING'`, `'SUCCESS'`, `'FAILED'`). |
212
+ | `transRefId` | `string` | Alias for the AYA Pay transaction ID. |
213
+ | `err` | `number` | Error code (0 for success). |
214
+
215
+ ---
216
+
217
+ ## 🔔 Callback Verification
218
+
219
+ This utility method is used by the merchant's callback endpoint to securely decrypt the transaction result payload sent by the AYA Pay system.
220
+
221
+ ### `verifyCallback(options: CallbackEncoded)`
222
+
223
+ Decrypts the Base64-encoded, encrypted payload using AES-256-ECB with the configured `decryptionKey`.
224
+
225
+ | Parameter | Type | Description |
226
+ | :--- | :--- | :--- |
227
+ | `options.paymentResult` | `string` | The encrypted and Base64-encoded payment payload from the callback body. |
228
+ | `options.refundResult` | `string` | The encrypted refund payload (if applicable). |
229
+ | `options.externalTransactionId` | `string` | The merchant's unique ID for context. |
230
+
231
+ | Returns | Type | Description |
232
+ | :--- | :--- | :--- |
233
+ | `Promise<CallbackDecoded>` | The raw, decrypted JSON string of the transaction result. **Must be parsed** into an object for use. |
234
+
235
+ ### Decryption Example
236
+
237
+ ```javascript
238
+ // Example handler for the merchant's callback endpoint (e.g., /api/payment/callback)
239
+
240
+ async function handleCallback(encodedBody) {
241
+ try {
242
+ const decryptedPayload = await ayaPayClient.verifyCallback(encodedBody);
243
+ // The result is a JSON string, which must be parsed
244
+ const paymentResult = JSON.parse(decryptedPayload as string);
245
+ // Process paymentResult (e.g., update order status)
246
+ console.log('Decrypted Status:', paymentResult.status);
247
+
248
+ } catch (error) {
249
+ console.error('Decryption Failed:', error);
250
+ }
251
+ }
252
+ ```
package/bun.lock ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "lockfileVersion": 2,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "@mmpay/aya-mmqr",
7
+ "devDependencies": {
8
+ "@types/node": "^26.0.0",
9
+ "dotenv": "^17.2.2",
10
+ "typescript": "^5.4.0",
11
+ },
12
+ },
13
+ },
14
+ "packages": {
15
+ "@types/node": ["@types/node@26.6.5", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg=="],
16
+
17
+ "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="],
18
+
19
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
20
+
21
+ "undici-types": ["undici-types@8.9.0", "", {}, "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg=="],
22
+ }
23
+ }
@@ -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,331 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AYAPayMerchantApi = AYAPayMerchantApi;
7
+ const node_buffer_1 = require("node:buffer");
8
+ const node_crypto_1 = __importDefault(require("node:crypto"));
9
+ /**
10
+ * @AYAPayMerchantApi
11
+ * @param {InstanceOptions} options
12
+ * @returns {AYAPayMerchantClass} A status message string.
13
+ */
14
+ function AYAPayMerchantApi(options) {
15
+ return new AYAPayMerchantClass({
16
+ baseUrl: options.baseUrl,
17
+ prefixUrl: options.prefixUrl,
18
+ consumerKey: options.consumerKey,
19
+ consumerSecret: options.consumerSecret,
20
+ decryptionKey: options.decryptionKey,
21
+ phone: options.phone,
22
+ password: options.password,
23
+ });
24
+ }
25
+ /**
26
+ * @AYAPayMerchantClass
27
+ */
28
+ class AYAPayMerchantClass {
29
+ #baseUrl;
30
+ #prefixUrl;
31
+ #consumerKey;
32
+ #consumerSecret;
33
+ #decryptionKey;
34
+ #phone;
35
+ #password;
36
+ #keyToken = '';
37
+ #apiToken = '';
38
+ constructor(options) {
39
+ this.#baseUrl = options.baseUrl;
40
+ this.#prefixUrl = options.prefixUrl;
41
+ this.#consumerKey = options.consumerKey;
42
+ this.#consumerSecret = options.consumerSecret;
43
+ this.#decryptionKey = options.decryptionKey;
44
+ this.#phone = options.phone;
45
+ this.#password = options.password;
46
+ }
47
+ /**
48
+ * basicToken
49
+ * @returns
50
+ */
51
+ basicToken() {
52
+ const rawString = `${this.#consumerKey}:${this.#consumerSecret}`;
53
+ const buffer = node_buffer_1.Buffer.from(rawString);
54
+ const base64String = buffer.toString('base64');
55
+ return base64String;
56
+ }
57
+ /**
58
+ * getToken
59
+ * @returns {Promise<getTokenResponse>}
60
+ */
61
+ async getToken() {
62
+ try {
63
+ const config = {
64
+ headers: {
65
+ 'Content-Type': 'application/x-www-form-urlencoded',
66
+ 'Authorization': `Basic ${this.basicToken()}`
67
+ }
68
+ };
69
+ const body = {
70
+ grant_type: 'client_credentials'
71
+ };
72
+ const formBody = new URLSearchParams();
73
+ Object.entries(body).forEach(([key, value]) => {
74
+ if (value !== undefined)
75
+ formBody.append(key, String(value));
76
+ });
77
+ const response = await fetch(`${this.#baseUrl}/token`, {
78
+ method: 'POST',
79
+ headers: config.headers,
80
+ body: formBody
81
+ });
82
+ const originResponse = (await response.json());
83
+ const modifiedResponse = {
84
+ accessToken: originResponse.access_token,
85
+ scope: originResponse.scope,
86
+ tokenType: originResponse.token_type,
87
+ expiresIn: originResponse.expires_in,
88
+ };
89
+ this.#keyToken = modifiedResponse.accessToken;
90
+ return modifiedResponse;
91
+ }
92
+ catch (error) {
93
+ console.error(error);
94
+ throw error;
95
+ }
96
+ }
97
+ /**
98
+ * login
99
+ * @returns {Promise<loginResponse>}
100
+ */
101
+ async login() {
102
+ try {
103
+ const config = {
104
+ headers: {
105
+ 'Content-Type': 'application/x-www-form-urlencoded',
106
+ 'Token': `Bearer ${this.#keyToken}`
107
+ }
108
+ };
109
+ const body = {
110
+ phone: this.#phone,
111
+ password: this.#password,
112
+ };
113
+ const formBody = new URLSearchParams();
114
+ Object.entries(body).forEach(([key, value]) => {
115
+ if (value !== undefined)
116
+ formBody.append(key, String(value));
117
+ });
118
+ const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/login`, {
119
+ method: 'POST',
120
+ headers: config.headers,
121
+ body: formBody
122
+ });
123
+ const loginResponse = (await response.json());
124
+ this.#apiToken = loginResponse.token.token;
125
+ return loginResponse;
126
+ }
127
+ catch (error) {
128
+ console.error(error);
129
+ throw error;
130
+ }
131
+ }
132
+ /**
133
+ * authenticate
134
+ */
135
+ async authenticate() {
136
+ await this.getToken();
137
+ await this.login();
138
+ }
139
+ /**
140
+ * requestQR
141
+ * @param {PaymentCreateRequest} options
142
+ * ...
143
+ * @returns {Promise<PaymentCreateResponse>}
144
+ */
145
+ async requestQR(options) {
146
+ try {
147
+ await this.authenticate();
148
+ const config = {
149
+ headers: {
150
+ 'Content-Type': 'application/x-www-form-urlencoded',
151
+ 'Token': `Bearer ${this.#keyToken}`,
152
+ 'Authorization': `Bearer ${this.#apiToken}`,
153
+ }
154
+ };
155
+ const body = {
156
+ amount: options.amount,
157
+ currency: options.currency,
158
+ externalTransactionId: options.externalTransactionId,
159
+ externalAdditionalData: options.externalAdditionalData,
160
+ serviceCode: options.serviceCode,
161
+ MMQR: options.MMQR,
162
+ timelimit: options.timelimit,
163
+ };
164
+ const formBody = new URLSearchParams();
165
+ Object.entries(body).forEach(([key, value]) => {
166
+ if (value !== undefined)
167
+ formBody.append(key, String(value));
168
+ });
169
+ const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/v2/requestQRPayment`, {
170
+ method: 'POST',
171
+ headers: config.headers,
172
+ body: formBody
173
+ });
174
+ return (await response.json());
175
+ }
176
+ catch (error) {
177
+ console.error(error);
178
+ throw error;
179
+ }
180
+ }
181
+ /**
182
+ * paymentStatusQR
183
+ * ...
184
+ */
185
+ async paymentStatusQR(options) {
186
+ try {
187
+ await this.authenticate();
188
+ const config = {
189
+ headers: {
190
+ 'Content-Type': 'application/x-www-form-urlencoded',
191
+ 'Token': `Bearer ${this.#keyToken}`,
192
+ 'Authorization': `Bearer ${this.#apiToken}`,
193
+ }
194
+ };
195
+ const body = {
196
+ externalTransactionId: options.externalTransactionId,
197
+ referenceNumber: options.referenceNumber,
198
+ };
199
+ const formBody = new URLSearchParams();
200
+ Object.entries(body).forEach(([key, value]) => {
201
+ if (value !== undefined)
202
+ formBody.append(key, String(value));
203
+ });
204
+ const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/checkQRPayment`, {
205
+ method: 'POST',
206
+ headers: config.headers,
207
+ body: formBody
208
+ });
209
+ return (await response.json());
210
+ }
211
+ catch (error) {
212
+ console.error(error);
213
+ throw error;
214
+ }
215
+ }
216
+ /**
217
+ * requestPush
218
+ * ...
219
+ */
220
+ async requestPush(options) {
221
+ try {
222
+ await this.authenticate();
223
+ const config = {
224
+ headers: {
225
+ 'Content-Type': 'application/x-www-form-urlencoded',
226
+ 'Token': `Bearer ${this.#keyToken}`,
227
+ 'Authorization': `Bearer ${this.#apiToken}`,
228
+ }
229
+ };
230
+ const body = {
231
+ amount: options.amount,
232
+ currency: options.currency,
233
+ externalTransactionId: options.externalTransactionId,
234
+ externalAdditionalData: options.externalAdditionalData,
235
+ serviceCode: options.serviceCode,
236
+ };
237
+ const formBody = new URLSearchParams();
238
+ Object.entries(body).forEach(([key, value]) => {
239
+ if (value !== undefined)
240
+ formBody.append(key, String(value));
241
+ });
242
+ const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/v2/requestPushPayment`, {
243
+ method: 'POST',
244
+ headers: config.headers,
245
+ body: formBody
246
+ });
247
+ return (await response.json());
248
+ }
249
+ catch (error) {
250
+ console.error(error);
251
+ throw error;
252
+ }
253
+ }
254
+ /**
255
+ * paymentStatusPush
256
+ * ...
257
+ */
258
+ async paymentStatusPush(options) {
259
+ try {
260
+ await this.authenticate();
261
+ const config = {
262
+ headers: {
263
+ 'Content-Type': 'application/x-www-form-urlencoded',
264
+ 'Token': `Bearer ${this.#keyToken}`,
265
+ 'Authorization': `Bearer ${this.#apiToken}`,
266
+ }
267
+ };
268
+ const body = {
269
+ externalTransactionId: options.externalTransactionId,
270
+ referenceNumber: options.referenceNumber,
271
+ };
272
+ const formBody = new URLSearchParams();
273
+ Object.entries(body).forEach(([key, value]) => {
274
+ if (value !== undefined)
275
+ formBody.append(key, String(value));
276
+ });
277
+ const response = await fetch(`${this.#baseUrl}/${this.#prefixUrl}/1.0.0/thirdparty/merchant/checkRequestPayment`, {
278
+ method: 'POST',
279
+ headers: config.headers,
280
+ body: formBody
281
+ });
282
+ return (await response.json());
283
+ }
284
+ catch (error) {
285
+ console.error(error);
286
+ throw error;
287
+ }
288
+ }
289
+ /**
290
+ * verifyCallback
291
+ * ...
292
+ */
293
+ async verifyCallback(options) {
294
+ try {
295
+ if (!options.paymentResult)
296
+ throw new Error("paymentResult is missing or undefined");
297
+ const cipherRaw = node_buffer_1.Buffer.from(options.paymentResult, 'base64');
298
+ const key = node_buffer_1.Buffer.from(this.#decryptionKey);
299
+ const decipher = node_crypto_1.default.createDecipheriv('aes-256-ecb', key, null);
300
+ let decrypted = decipher.update(cipherRaw, undefined, 'utf8');
301
+ decrypted += decipher.final('utf8');
302
+ const result = JSON.parse(decrypted);
303
+ return result;
304
+ }
305
+ catch (error) {
306
+ console.error(error);
307
+ throw error;
308
+ }
309
+ }
310
+ /**
311
+ * verifyCallbackRefund
312
+ * ...
313
+ */
314
+ async verifyCallbackRefund(options) {
315
+ try {
316
+ if (!options.refundResult)
317
+ throw new Error("refundResult is missing or undefined");
318
+ const cipherRaw = node_buffer_1.Buffer.from(options.refundResult, 'base64');
319
+ const key = node_buffer_1.Buffer.from(this.#decryptionKey);
320
+ const decipher = node_crypto_1.default.createDecipheriv('aes-256-ecb', key, null);
321
+ let decrypted = decipher.update(cipherRaw, undefined, 'utf8');
322
+ decrypted += decipher.final('utf8');
323
+ const result = JSON.parse(decrypted);
324
+ return result;
325
+ }
326
+ catch (error) {
327
+ console.error(error);
328
+ throw error;
329
+ }
330
+ }
331
+ }