aba-payway 0.1.0 → 0.2.0
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/LICENSE +1 -1
- package/README.md +78 -5
- package/dist/index.cjs +258 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +184 -24
- package/dist/index.d.ts +184 -24
- package/dist/index.js +257 -26
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var BASE_URLS = {
|
|
3
|
+
sandbox: "https://checkout-sandbox.payway.com.kh",
|
|
4
|
+
production: "https://checkout.payway.com.kh"
|
|
5
|
+
};
|
|
6
|
+
var SANDBOX_BASE_URL = BASE_URLS.sandbox;
|
|
7
|
+
var PRODUCTION_BASE_URL = BASE_URLS.production;
|
|
4
8
|
var ENDPOINTS = {
|
|
5
9
|
purchase: "/api/payment-gateway/v1/payments/purchase",
|
|
6
10
|
checkTransaction: "/api/payment-gateway/v1/payments/check-transaction-2",
|
|
7
|
-
transactionList: "/api/payment-gateway/v1/payments/transaction-list-2"
|
|
11
|
+
transactionList: "/api/payment-gateway/v1/payments/transaction-list-2",
|
|
12
|
+
transactionDetail: "/api/payment-gateway/v1/payments/transaction-detail",
|
|
13
|
+
closeTransaction: "/api/payment-gateway/v1/payments/close-transaction",
|
|
14
|
+
exchangeRate: "/api/payment-gateway/v1/exchange-rate",
|
|
15
|
+
generateQR: "/api/payment-gateway/v1/payments/generate-qr",
|
|
16
|
+
getTransactionsByRef: "/api/payment-gateway/v1/payments/get-transactions-by-mc-ref"
|
|
8
17
|
};
|
|
9
18
|
|
|
10
19
|
// src/errors.ts
|
|
11
20
|
var PayWayError = class extends Error {
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message);
|
|
21
|
+
constructor(message, options) {
|
|
22
|
+
super(message, options);
|
|
14
23
|
this.name = "PayWayError";
|
|
15
24
|
}
|
|
16
25
|
};
|
|
@@ -56,17 +65,24 @@ function formatRequestTime(date = /* @__PURE__ */ new Date()) {
|
|
|
56
65
|
const seconds = date.getUTCSeconds().toString().padStart(2, "0");
|
|
57
66
|
return `${year}${month}${day}${hours}${minutes}${seconds}`;
|
|
58
67
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
68
|
+
function filterParams(params) {
|
|
69
|
+
const out = {};
|
|
61
70
|
for (const [key, value] of Object.entries(params)) {
|
|
62
|
-
if (value !== void 0 && value !==
|
|
63
|
-
|
|
71
|
+
if (value !== void 0 && value !== "") {
|
|
72
|
+
out[key] = value;
|
|
64
73
|
}
|
|
65
74
|
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
function buildFormData(params) {
|
|
78
|
+
const formData = new FormData();
|
|
79
|
+
for (const [key, value] of Object.entries(filterParams(params))) {
|
|
80
|
+
formData.append(key, String(value));
|
|
81
|
+
}
|
|
66
82
|
return formData;
|
|
67
83
|
}
|
|
68
84
|
function formatAmount(amount, currency = "USD") {
|
|
69
|
-
if (currency
|
|
85
|
+
if (currency === "KHR") {
|
|
70
86
|
return Math.round(amount).toString();
|
|
71
87
|
}
|
|
72
88
|
return amount.toFixed(2);
|
|
@@ -80,6 +96,11 @@ var PayWay = class {
|
|
|
80
96
|
merchantId;
|
|
81
97
|
apiKey;
|
|
82
98
|
baseUrl;
|
|
99
|
+
timeout;
|
|
100
|
+
/**
|
|
101
|
+
* @param config - Merchant credentials and environment selection.
|
|
102
|
+
* @throws {PayWayConfigError} If `merchantId` or `apiKey` is empty.
|
|
103
|
+
*/
|
|
83
104
|
constructor(config) {
|
|
84
105
|
if (!config.merchantId) {
|
|
85
106
|
throw new PayWayConfigError("merchantId is required");
|
|
@@ -89,13 +110,28 @@ var PayWay = class {
|
|
|
89
110
|
}
|
|
90
111
|
this.merchantId = config.merchantId;
|
|
91
112
|
this.apiKey = config.apiKey;
|
|
92
|
-
this.baseUrl = config.
|
|
113
|
+
this.baseUrl = config.baseUrl ?? BASE_URLS[config.environment ?? "sandbox"];
|
|
114
|
+
this.timeout = config.timeout ?? 3e4;
|
|
93
115
|
}
|
|
94
116
|
/**
|
|
95
117
|
* Generate checkout parameters for a transaction.
|
|
96
118
|
* Returns form params to be submitted from the browser via ABA's checkout JS SDK.
|
|
97
119
|
*/
|
|
98
120
|
createTransaction(options) {
|
|
121
|
+
if (!options.transactionId) {
|
|
122
|
+
throw new PayWayConfigError("transactionId is required");
|
|
123
|
+
}
|
|
124
|
+
if (options.transactionId.length > 20) {
|
|
125
|
+
throw new PayWayConfigError(
|
|
126
|
+
"transactionId must be at most 20 characters"
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
if (options.amount <= 0) {
|
|
130
|
+
throw new PayWayConfigError("amount must be greater than 0");
|
|
131
|
+
}
|
|
132
|
+
if (options.lifetime !== void 0 && (options.lifetime < 3 || options.lifetime > 43200)) {
|
|
133
|
+
throw new PayWayConfigError("lifetime must be between 3 and 43200");
|
|
134
|
+
}
|
|
99
135
|
const reqTime = formatRequestTime();
|
|
100
136
|
const currency = options.currency ?? "USD";
|
|
101
137
|
const amount = formatAmount(options.amount, currency);
|
|
@@ -132,8 +168,6 @@ var PayWay = class {
|
|
|
132
168
|
currency,
|
|
133
169
|
options.customFields ?? "",
|
|
134
170
|
options.returnParams ?? "",
|
|
135
|
-
options.viewType ?? "",
|
|
136
|
-
options.paymentGate?.toString() ?? "",
|
|
137
171
|
payout,
|
|
138
172
|
options.lifetime?.toString() ?? "",
|
|
139
173
|
options.additionalParams ?? "",
|
|
@@ -172,7 +206,15 @@ var PayWay = class {
|
|
|
172
206
|
payment_gate: options.paymentGate?.toString() ?? ""
|
|
173
207
|
};
|
|
174
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Check the status of a transaction.
|
|
211
|
+
* @param transactionId - The unique transaction ID to look up.
|
|
212
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
213
|
+
*/
|
|
175
214
|
async checkTransaction(transactionId) {
|
|
215
|
+
if (!transactionId) {
|
|
216
|
+
throw new PayWayConfigError("transactionId is required");
|
|
217
|
+
}
|
|
176
218
|
const reqTime = formatRequestTime();
|
|
177
219
|
const hashValues = [reqTime, this.merchantId, transactionId];
|
|
178
220
|
const hash = createHash(hashValues, this.apiKey);
|
|
@@ -187,6 +229,11 @@ var PayWay = class {
|
|
|
187
229
|
params
|
|
188
230
|
);
|
|
189
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* List transactions with optional filters. Max 3-day date range.
|
|
234
|
+
* @param options - Filter and pagination options.
|
|
235
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
236
|
+
*/
|
|
190
237
|
async listTransactions(options = {}) {
|
|
191
238
|
const reqTime = formatRequestTime();
|
|
192
239
|
const hashValues = [
|
|
@@ -218,35 +265,219 @@ var PayWay = class {
|
|
|
218
265
|
params
|
|
219
266
|
);
|
|
220
267
|
}
|
|
221
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Get detailed information about a transaction, including its operation history.
|
|
270
|
+
* @param transactionId - The unique transaction ID to look up.
|
|
271
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
272
|
+
*/
|
|
273
|
+
async getTransactionDetails(transactionId) {
|
|
274
|
+
if (!transactionId) {
|
|
275
|
+
throw new PayWayConfigError("transactionId is required");
|
|
276
|
+
}
|
|
277
|
+
const reqTime = formatRequestTime();
|
|
278
|
+
const hashValues = [reqTime, this.merchantId, transactionId];
|
|
279
|
+
const hash = createHash(hashValues, this.apiKey);
|
|
280
|
+
const params = {
|
|
281
|
+
hash,
|
|
282
|
+
tran_id: transactionId,
|
|
283
|
+
req_time: reqTime,
|
|
284
|
+
merchant_id: this.merchantId
|
|
285
|
+
};
|
|
286
|
+
return this.request(
|
|
287
|
+
ENDPOINTS.transactionDetail,
|
|
288
|
+
params,
|
|
289
|
+
"json"
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Close (cancel) a pending transaction.
|
|
294
|
+
* @param transactionId - The transaction ID to close.
|
|
295
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
296
|
+
*/
|
|
297
|
+
async closeTransaction(transactionId) {
|
|
298
|
+
if (!transactionId) {
|
|
299
|
+
throw new PayWayConfigError("transactionId is required");
|
|
300
|
+
}
|
|
301
|
+
const reqTime = formatRequestTime();
|
|
302
|
+
const hashValues = [reqTime, this.merchantId, transactionId];
|
|
303
|
+
const hash = createHash(hashValues, this.apiKey);
|
|
304
|
+
const params = {
|
|
305
|
+
hash,
|
|
306
|
+
tran_id: transactionId,
|
|
307
|
+
req_time: reqTime,
|
|
308
|
+
merchant_id: this.merchantId
|
|
309
|
+
};
|
|
310
|
+
return this.request(
|
|
311
|
+
ENDPOINTS.closeTransaction,
|
|
312
|
+
params,
|
|
313
|
+
"json"
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Fetch the latest exchange rates from ABA Bank.
|
|
318
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
319
|
+
*/
|
|
320
|
+
async getExchangeRate() {
|
|
321
|
+
const reqTime = formatRequestTime();
|
|
322
|
+
const hashValues = [reqTime, this.merchantId];
|
|
323
|
+
const hash = createHash(hashValues, this.apiKey);
|
|
324
|
+
const params = {
|
|
325
|
+
hash,
|
|
326
|
+
req_time: reqTime,
|
|
327
|
+
merchant_id: this.merchantId
|
|
328
|
+
};
|
|
329
|
+
return this.request(
|
|
330
|
+
ENDPOINTS.exchangeRate,
|
|
331
|
+
params,
|
|
332
|
+
"json"
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Generate a QR code for payment via ABA KHQR, WeChat Pay, or Alipay.
|
|
337
|
+
* @param options - QR generation options.
|
|
338
|
+
* @throws {PayWayConfigError} If required options are missing or invalid.
|
|
339
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
340
|
+
*/
|
|
341
|
+
async generateQR(options) {
|
|
342
|
+
if (!options.transactionId) {
|
|
343
|
+
throw new PayWayConfigError("transactionId is required");
|
|
344
|
+
}
|
|
345
|
+
if (options.amount <= 0) {
|
|
346
|
+
throw new PayWayConfigError("amount must be greater than 0");
|
|
347
|
+
}
|
|
348
|
+
if (!options.paymentOption) {
|
|
349
|
+
throw new PayWayConfigError("paymentOption is required");
|
|
350
|
+
}
|
|
351
|
+
if (!options.qrImageTemplate) {
|
|
352
|
+
throw new PayWayConfigError("qrImageTemplate is required");
|
|
353
|
+
}
|
|
354
|
+
if (options.lifetime !== void 0 && (options.lifetime < 3 || options.lifetime > 43200)) {
|
|
355
|
+
throw new PayWayConfigError("lifetime must be between 3 and 43200");
|
|
356
|
+
}
|
|
357
|
+
const reqTime = formatRequestTime();
|
|
358
|
+
const currency = options.currency ?? "USD";
|
|
359
|
+
const amount = formatAmount(options.amount, currency);
|
|
360
|
+
const items = options.items ? toBase64(options.items) : "";
|
|
361
|
+
const callbackUrl = options.callbackUrl ? toBase64(options.callbackUrl) : "";
|
|
362
|
+
const returnDeeplink = options.returnDeeplink ? toBase64(options.returnDeeplink) : "";
|
|
363
|
+
const customFields = options.customFields ? toBase64(options.customFields) : "";
|
|
364
|
+
const payout = options.payout ? toBase64(options.payout) : "";
|
|
365
|
+
const hashValues = [
|
|
366
|
+
reqTime,
|
|
367
|
+
this.merchantId,
|
|
368
|
+
options.transactionId,
|
|
369
|
+
amount,
|
|
370
|
+
items,
|
|
371
|
+
options.firstName ?? "",
|
|
372
|
+
options.lastName ?? "",
|
|
373
|
+
options.email ?? "",
|
|
374
|
+
options.phone ?? "",
|
|
375
|
+
options.purchaseType ?? "",
|
|
376
|
+
options.paymentOption,
|
|
377
|
+
callbackUrl,
|
|
378
|
+
returnDeeplink,
|
|
379
|
+
currency,
|
|
380
|
+
customFields,
|
|
381
|
+
options.returnParams ?? "",
|
|
382
|
+
payout,
|
|
383
|
+
options.lifetime?.toString() ?? "",
|
|
384
|
+
options.qrImageTemplate
|
|
385
|
+
];
|
|
386
|
+
const hash = createHash(hashValues, this.apiKey);
|
|
387
|
+
const params = {
|
|
388
|
+
hash,
|
|
389
|
+
req_time: reqTime,
|
|
390
|
+
merchant_id: this.merchantId,
|
|
391
|
+
tran_id: options.transactionId,
|
|
392
|
+
amount: options.amount,
|
|
393
|
+
currency,
|
|
394
|
+
payment_option: options.paymentOption,
|
|
395
|
+
lifetime: options.lifetime,
|
|
396
|
+
qr_image_template: options.qrImageTemplate,
|
|
397
|
+
first_name: options.firstName,
|
|
398
|
+
last_name: options.lastName,
|
|
399
|
+
email: options.email,
|
|
400
|
+
phone: options.phone,
|
|
401
|
+
purchase_type: options.purchaseType,
|
|
402
|
+
items: items || void 0,
|
|
403
|
+
callback_url: callbackUrl || void 0,
|
|
404
|
+
return_deeplink: returnDeeplink || void 0,
|
|
405
|
+
custom_fields: customFields || void 0,
|
|
406
|
+
return_params: options.returnParams,
|
|
407
|
+
payout: payout || void 0
|
|
408
|
+
};
|
|
409
|
+
return this.request(
|
|
410
|
+
ENDPOINTS.generateQR,
|
|
411
|
+
params,
|
|
412
|
+
"json"
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get transactions by merchant reference. Returns up to the last 50 transactions.
|
|
417
|
+
* @param merchantRef - Your merchant reference number.
|
|
418
|
+
* @throws {PayWayAPIError} If the API returns a non-2xx response.
|
|
419
|
+
*/
|
|
420
|
+
async getTransactionsByRef(merchantRef) {
|
|
421
|
+
if (!merchantRef) {
|
|
422
|
+
throw new PayWayConfigError("merchantRef is required");
|
|
423
|
+
}
|
|
424
|
+
const reqTime = formatRequestTime();
|
|
425
|
+
const hashValues = [reqTime, this.merchantId, merchantRef];
|
|
426
|
+
const hash = createHash(hashValues, this.apiKey);
|
|
427
|
+
const params = {
|
|
428
|
+
hash,
|
|
429
|
+
merchant_ref: merchantRef,
|
|
430
|
+
req_time: reqTime,
|
|
431
|
+
merchant_id: this.merchantId
|
|
432
|
+
};
|
|
433
|
+
return this.request(
|
|
434
|
+
ENDPOINTS.getTransactionsByRef,
|
|
435
|
+
params,
|
|
436
|
+
"json"
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
async request(endpoint, params, format = "form") {
|
|
222
440
|
const url = `${this.baseUrl}${endpoint}`;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
441
|
+
let body;
|
|
442
|
+
const headers = {};
|
|
443
|
+
if (format === "json") {
|
|
444
|
+
body = JSON.stringify(filterParams(params));
|
|
445
|
+
headers["Content-Type"] = "application/json";
|
|
446
|
+
} else {
|
|
447
|
+
body = buildFormData(params);
|
|
448
|
+
}
|
|
449
|
+
let response;
|
|
450
|
+
try {
|
|
451
|
+
response = await fetch(url, {
|
|
452
|
+
method: "POST",
|
|
453
|
+
body,
|
|
454
|
+
headers,
|
|
455
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
456
|
+
});
|
|
457
|
+
} catch (error) {
|
|
458
|
+
throw new PayWayError(
|
|
459
|
+
error instanceof Error ? error.message : "Network request failed",
|
|
460
|
+
{ cause: error }
|
|
461
|
+
);
|
|
228
462
|
}
|
|
229
|
-
const response = await fetch(url, {
|
|
230
|
-
method: "POST",
|
|
231
|
-
body: formData
|
|
232
|
-
});
|
|
233
463
|
if (!response.ok) {
|
|
234
464
|
const text = await response.text();
|
|
235
|
-
let
|
|
465
|
+
let responseBody = text;
|
|
236
466
|
try {
|
|
237
|
-
|
|
467
|
+
responseBody = JSON.parse(text);
|
|
238
468
|
} catch {
|
|
239
469
|
}
|
|
240
470
|
throw new PayWayAPIError(
|
|
241
471
|
`PayWay API error: ${response.status} ${response.statusText}`,
|
|
242
472
|
response.status,
|
|
243
|
-
|
|
473
|
+
responseBody
|
|
244
474
|
);
|
|
245
475
|
}
|
|
246
476
|
return await response.json();
|
|
247
477
|
}
|
|
248
478
|
};
|
|
249
479
|
export {
|
|
480
|
+
BASE_URLS,
|
|
250
481
|
ENDPOINTS,
|
|
251
482
|
PRODUCTION_BASE_URL,
|
|
252
483
|
PayWay,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/hash.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["export const SANDBOX_BASE_URL = \"https://checkout-sandbox.payway.com.kh\";\nexport const PRODUCTION_BASE_URL = \"https://checkout.payway.com.kh\";\n\nexport const ENDPOINTS = {\n\tpurchase: \"/api/payment-gateway/v1/payments/purchase\",\n\tcheckTransaction: \"/api/payment-gateway/v1/payments/check-transaction-2\",\n\ttransactionList: \"/api/payment-gateway/v1/payments/transaction-list-2\",\n} as const;\n","export class PayWayError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayError\";\n\t}\n}\n\nexport class PayWayAPIError extends PayWayError {\n\tpublic readonly statusCode: number;\n\tpublic readonly responseBody: unknown;\n\n\tconstructor(message: string, statusCode: number, responseBody?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayAPIError\";\n\t\tthis.statusCode = statusCode;\n\t\tthis.responseBody = responseBody;\n\t}\n}\n\nexport class PayWayConfigError extends PayWayError {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayConfigError\";\n\t}\n}\n\nexport class PayWayHashError extends PayWayError {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayHashError\";\n\t}\n}\n","import { createHmac } from \"node:crypto\";\n\nexport function createHash(values: string[], apiKey: string): string {\n\tconst message = values.join(\"\");\n\tconst hmac = createHmac(\"sha512\", apiKey);\n\thmac.update(message);\n\treturn hmac.digest(\"base64\");\n}\n","export function formatRequestTime(date: Date = new Date()): string {\n\tconst year = date.getUTCFullYear().toString();\n\tconst month = (date.getUTCMonth() + 1).toString().padStart(2, \"0\");\n\tconst day = date.getUTCDate().toString().padStart(2, \"0\");\n\tconst hours = date.getUTCHours().toString().padStart(2, \"0\");\n\tconst minutes = date.getUTCMinutes().toString().padStart(2, \"0\");\n\tconst seconds = date.getUTCSeconds().toString().padStart(2, \"0\");\n\treturn `${year}${month}${day}${hours}${minutes}${seconds}`;\n}\n\nexport function buildFormData(\n\tparams: Record<string, string | undefined>,\n): FormData {\n\tconst formData = new FormData();\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined && value !== null && value !== \"\") {\n\t\t\tformData.append(key, value);\n\t\t}\n\t}\n\treturn formData;\n}\n\nexport function formatAmount(amount: number, currency = \"USD\"): string {\n\tif (currency.toUpperCase() === \"KHR\") {\n\t\treturn Math.round(amount).toString();\n\t}\n\treturn amount.toFixed(2);\n}\n\nexport function toBase64(value: string): string {\n\treturn Buffer.from(value).toString(\"base64\");\n}\n","import {\n\tENDPOINTS,\n\tPRODUCTION_BASE_URL,\n\tSANDBOX_BASE_URL,\n} from \"./constants.ts\";\nimport { PayWayAPIError, PayWayConfigError } from \"./errors.ts\";\nimport { createHash } from \"./hash.ts\";\nimport type {\n\tCheckoutParams,\n\tCheckTransactionData,\n\tCreateTransactionOptions,\n\tListTransactionsOptions,\n\tListTransactionsResponse,\n\tPayWayConfig,\n\tPayWayResponse,\n} from \"./types.ts\";\nimport { formatAmount, formatRequestTime, toBase64 } from \"./utils.ts\";\n\nexport class PayWay {\n\tprivate readonly merchantId: string;\n\tprivate readonly apiKey: string;\n\tprivate readonly baseUrl: string;\n\n\tconstructor(config: PayWayConfig) {\n\t\tif (!config.merchantId) {\n\t\t\tthrow new PayWayConfigError(\"merchantId is required\");\n\t\t}\n\t\tif (!config.apiKey) {\n\t\t\tthrow new PayWayConfigError(\"apiKey is required\");\n\t\t}\n\n\t\tthis.merchantId = config.merchantId;\n\t\tthis.apiKey = config.apiKey;\n\t\tthis.baseUrl = config.production ? PRODUCTION_BASE_URL : SANDBOX_BASE_URL;\n\t}\n\n\t/**\n\t * Generate checkout parameters for a transaction.\n\t * Returns form params to be submitted from the browser via ABA's checkout JS SDK.\n\t */\n\tcreateTransaction(options: CreateTransactionOptions): CheckoutParams {\n\t\tconst reqTime = formatRequestTime();\n\t\tconst currency = options.currency ?? \"USD\";\n\t\tconst amount = formatAmount(options.amount, currency);\n\t\tconst type = options.type ?? \"purchase\";\n\n\t\t// Items: if array, JSON-stringify and base64-encode; if string, base64-encode as-is\n\t\tlet items: string;\n\t\tif (Array.isArray(options.items)) {\n\t\t\titems = toBase64(JSON.stringify(options.items));\n\t\t} else if (options.items) {\n\t\t\titems = toBase64(options.items);\n\t\t} else {\n\t\t\titems = \"\";\n\t\t}\n\n\t\t// Return URL and return deeplink must be base64-encoded per ABA docs\n\t\tconst returnUrl = options.returnUrl ? toBase64(options.returnUrl) : \"\";\n\t\tconst returnDeeplink = options.returnDeeplink\n\t\t\t? toBase64(options.returnDeeplink)\n\t\t\t: \"\";\n\n\t\t// Payout must be base64-encoded JSON string per ABA docs\n\t\tconst payout = options.payout ? toBase64(options.payout) : \"\";\n\n\t\tconst shipping =\n\t\t\toptions.shipping !== undefined\n\t\t\t\t? formatAmount(options.shipping, currency)\n\t\t\t\t: \"\";\n\n\t\t// Hash field order must match ABA's expected order exactly\n\t\tconst hashValues = [\n\t\t\treqTime,\n\t\t\tthis.merchantId,\n\t\t\toptions.transactionId,\n\t\t\tamount,\n\t\t\titems,\n\t\t\tshipping,\n\t\t\toptions.firstName ?? \"\",\n\t\t\toptions.lastName ?? \"\",\n\t\t\toptions.email ?? \"\",\n\t\t\toptions.phone ?? \"\",\n\t\t\ttype,\n\t\t\toptions.paymentOption ?? \"\",\n\t\t\treturnUrl,\n\t\t\toptions.cancelUrl ?? \"\",\n\t\t\toptions.continueSuccessUrl ?? \"\",\n\t\t\treturnDeeplink,\n\t\t\tcurrency,\n\t\t\toptions.customFields ?? \"\",\n\t\t\toptions.returnParams ?? \"\",\n\t\t\toptions.viewType ?? \"\",\n\t\t\toptions.paymentGate?.toString() ?? \"\",\n\t\t\tpayout,\n\t\t\toptions.lifetime?.toString() ?? \"\",\n\t\t\toptions.additionalParams ?? \"\",\n\t\t\toptions.googlePayToken ?? \"\",\n\t\t\toptions.skipSuccessPage?.toString() ?? \"\",\n\t\t];\n\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\treturn {\n\t\t\taction: `${this.baseUrl}${ENDPOINTS.purchase}`,\n\t\t\thash,\n\t\t\ttran_id: options.transactionId,\n\t\t\tamount,\n\t\t\titems,\n\t\t\tcurrency,\n\t\t\tfirstname: options.firstName ?? \"\",\n\t\t\tlastname: options.lastName ?? \"\",\n\t\t\temail: options.email ?? \"\",\n\t\t\tphone: options.phone ?? \"\",\n\t\t\ttype,\n\t\t\tpayment_option: options.paymentOption ?? \"\",\n\t\t\treturn_url: returnUrl,\n\t\t\tcancel_url: options.cancelUrl ?? \"\",\n\t\t\tcontinue_success_url: options.continueSuccessUrl ?? \"\",\n\t\t\treturn_deeplink: returnDeeplink,\n\t\t\treturn_params: options.returnParams ?? \"\",\n\t\t\tshipping,\n\t\t\tmerchant_id: this.merchantId,\n\t\t\treq_time: reqTime,\n\t\t\tcustom_fields: options.customFields ?? \"\",\n\t\t\tpayout,\n\t\t\tlifetime: options.lifetime?.toString() ?? \"\",\n\t\t\tadditional_params: options.additionalParams ?? \"\",\n\t\t\tgoogle_pay_token: options.googlePayToken ?? \"\",\n\t\t\tskip_success_page: options.skipSuccessPage?.toString() ?? \"\",\n\t\t\tview_type: options.viewType ?? \"\",\n\t\t\tpayment_gate: options.paymentGate?.toString() ?? \"\",\n\t\t};\n\t}\n\n\tasync checkTransaction(\n\t\ttransactionId: string,\n\t): Promise<PayWayResponse<CheckTransactionData>> {\n\t\tconst reqTime = formatRequestTime();\n\n\t\tconst hashValues = [reqTime, this.merchantId, transactionId];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: Record<string, string | undefined> = {\n\t\t\thash,\n\t\t\ttran_id: transactionId,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<PayWayResponse<CheckTransactionData>>(\n\t\t\tENDPOINTS.checkTransaction,\n\t\t\tparams,\n\t\t);\n\t}\n\n\tasync listTransactions(\n\t\toptions: ListTransactionsOptions = {},\n\t): Promise<ListTransactionsResponse> {\n\t\tconst reqTime = formatRequestTime();\n\n\t\tconst hashValues = [\n\t\t\treqTime,\n\t\t\tthis.merchantId,\n\t\t\toptions.fromDate ?? \"\",\n\t\t\toptions.toDate ?? \"\",\n\t\t\toptions.fromAmount?.toString() ?? \"\",\n\t\t\toptions.toAmount?.toString() ?? \"\",\n\t\t\toptions.status ?? \"\",\n\t\t\toptions.page?.toString() ?? \"\",\n\t\t\toptions.pagination?.toString() ?? \"\",\n\t\t];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: Record<string, string | undefined> = {\n\t\t\thash,\n\t\t\tfrom_date: options.fromDate,\n\t\t\tto_date: options.toDate,\n\t\t\tfrom_amount: options.fromAmount?.toString(),\n\t\t\tto_amount: options.toAmount?.toString(),\n\t\t\tstatus: options.status,\n\t\t\tpage: options.page?.toString(),\n\t\t\tpagination: options.pagination?.toString(),\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<ListTransactionsResponse>(\n\t\t\tENDPOINTS.transactionList,\n\t\t\tparams,\n\t\t);\n\t}\n\n\tprivate async request<T>(\n\t\tendpoint: string,\n\t\tparams: Record<string, string | undefined>,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${endpoint}`;\n\t\tconst formData = new FormData();\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (value !== undefined && value !== null && value !== \"\") {\n\t\t\t\tformData.append(key, value);\n\t\t\t}\n\t\t}\n\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: formData,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tlet body: unknown = text;\n\t\t\ttry {\n\t\t\t\tbody = JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\t// keep as text\n\t\t\t}\n\t\t\tthrow new PayWayAPIError(\n\t\t\t\t`PayWay API error: ${response.status} ${response.statusText}`,\n\t\t\t\tresponse.status,\n\t\t\t\tbody,\n\t\t\t);\n\t\t}\n\n\t\treturn (await response.json()) as T;\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/hash.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["import type { Environment } from \"./types.ts\";\n\nexport const BASE_URLS: Record<Environment, string> = {\n\tsandbox: \"https://checkout-sandbox.payway.com.kh\",\n\tproduction: \"https://checkout.payway.com.kh\",\n};\n\nexport const SANDBOX_BASE_URL = BASE_URLS.sandbox;\nexport const PRODUCTION_BASE_URL = BASE_URLS.production;\n\nexport const ENDPOINTS = {\n\tpurchase: \"/api/payment-gateway/v1/payments/purchase\",\n\tcheckTransaction: \"/api/payment-gateway/v1/payments/check-transaction-2\",\n\ttransactionList: \"/api/payment-gateway/v1/payments/transaction-list-2\",\n\ttransactionDetail: \"/api/payment-gateway/v1/payments/transaction-detail\",\n\tcloseTransaction: \"/api/payment-gateway/v1/payments/close-transaction\",\n\texchangeRate: \"/api/payment-gateway/v1/exchange-rate\",\n\tgenerateQR: \"/api/payment-gateway/v1/payments/generate-qr\",\n\tgetTransactionsByRef:\n\t\t\"/api/payment-gateway/v1/payments/get-transactions-by-mc-ref\",\n} as const;\n","/** Base error class for all PayWay SDK errors. */\nexport class PayWayError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"PayWayError\";\n\t}\n}\n\n/** Thrown when the ABA PayWay API returns a non-2xx HTTP response. */\nexport class PayWayAPIError extends PayWayError {\n\tpublic readonly statusCode: number;\n\tpublic readonly responseBody: unknown;\n\n\tconstructor(message: string, statusCode: number, responseBody?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayAPIError\";\n\t\tthis.statusCode = statusCode;\n\t\tthis.responseBody = responseBody;\n\t}\n}\n\n/** Thrown when the SDK is constructed with missing or invalid configuration. */\nexport class PayWayConfigError extends PayWayError {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayConfigError\";\n\t}\n}\n\n/** Thrown when HMAC hash generation fails. */\nexport class PayWayHashError extends PayWayError {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PayWayHashError\";\n\t}\n}\n","import { createHmac } from \"node:crypto\";\n\n/** Generate an HMAC-SHA512 hash from concatenated values, returned as a base64 string. */\nexport function createHash(values: readonly string[], apiKey: string): string {\n\tconst message = values.join(\"\");\n\tconst hmac = createHmac(\"sha512\", apiKey);\n\thmac.update(message);\n\treturn hmac.digest(\"base64\");\n}\n","import type { Currency } from \"./types.ts\";\n\n/** Format a Date as `yyyyMMddHHmmss` in UTC, used for ABA's `req_time` parameter. */\nexport function formatRequestTime(date: Date = new Date()): string {\n\tconst year = date.getUTCFullYear().toString();\n\tconst month = (date.getUTCMonth() + 1).toString().padStart(2, \"0\");\n\tconst day = date.getUTCDate().toString().padStart(2, \"0\");\n\tconst hours = date.getUTCHours().toString().padStart(2, \"0\");\n\tconst minutes = date.getUTCMinutes().toString().padStart(2, \"0\");\n\tconst seconds = date.getUTCSeconds().toString().padStart(2, \"0\");\n\treturn `${year}${month}${day}${hours}${minutes}${seconds}`;\n}\n\n/** Filter out `undefined` and empty string values from a params object. */\nexport function filterParams(params: object): Record<string, string | number> {\n\tconst out: Record<string, string | number> = {};\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined && value !== \"\") {\n\t\t\tout[key] = value as string | number;\n\t\t}\n\t}\n\treturn out;\n}\n\n/** Build a FormData object from a record, skipping `undefined`, `null`, and empty string values. */\nexport function buildFormData(params: object): FormData {\n\tconst formData = new FormData();\n\tfor (const [key, value] of Object.entries(filterParams(params))) {\n\t\tformData.append(key, String(value));\n\t}\n\treturn formData;\n}\n\n/** Format a numeric amount as a string: 2 decimal places for USD, rounded integer for KHR. */\nexport function formatAmount(\n\tamount: number,\n\tcurrency: Currency = \"USD\",\n): string {\n\tif (currency === \"KHR\") {\n\t\treturn Math.round(amount).toString();\n\t}\n\treturn amount.toFixed(2);\n}\n\n/** Base64-encode a string value using Node.js Buffer. */\nexport function toBase64(value: string): string {\n\treturn Buffer.from(value).toString(\"base64\");\n}\n","import { BASE_URLS, ENDPOINTS } from \"./constants.ts\";\nimport { PayWayAPIError, PayWayConfigError, PayWayError } from \"./errors.ts\";\nimport { createHash } from \"./hash.ts\";\nimport type {\n\tCheckoutParams,\n\tCheckTransactionData,\n\tCloseTransactionResponse,\n\tCreateTransactionOptions,\n\tExchangeRateParams,\n\tExchangeRateResponse,\n\tGenerateQROptions,\n\tGenerateQRParams,\n\tGenerateQRResponse,\n\tGetTransactionsByRefParams,\n\tGetTransactionsByRefResponse,\n\tListTransactionsOptions,\n\tListTransactionsParams,\n\tListTransactionsResponse,\n\tPayWayConfig,\n\tPayWayResponse,\n\tRequestParams,\n\tTransactionDetailData,\n\tTransactionParams,\n} from \"./types.ts\";\nimport {\n\tbuildFormData,\n\tfilterParams,\n\tformatAmount,\n\tformatRequestTime,\n\ttoBase64,\n} from \"./utils.ts\";\n\n/**\n * Main SDK client for ABA PayWay.\n * Provides methods for creating transactions, checking status, and listing transactions.\n */\nexport class PayWay {\n\tprivate readonly merchantId: string;\n\tprivate readonly apiKey: string;\n\tprivate readonly baseUrl: string;\n\tprivate readonly timeout: number;\n\n\t/**\n\t * @param config - Merchant credentials and environment selection.\n\t * @throws {PayWayConfigError} If `merchantId` or `apiKey` is empty.\n\t */\n\tconstructor(config: PayWayConfig) {\n\t\tif (!config.merchantId) {\n\t\t\tthrow new PayWayConfigError(\"merchantId is required\");\n\t\t}\n\t\tif (!config.apiKey) {\n\t\t\tthrow new PayWayConfigError(\"apiKey is required\");\n\t\t}\n\n\t\tthis.merchantId = config.merchantId;\n\t\tthis.apiKey = config.apiKey;\n\t\tthis.baseUrl = config.baseUrl ?? BASE_URLS[config.environment ?? \"sandbox\"];\n\t\tthis.timeout = config.timeout ?? 30_000;\n\t}\n\n\t/**\n\t * Generate checkout parameters for a transaction.\n\t * Returns form params to be submitted from the browser via ABA's checkout JS SDK.\n\t */\n\tcreateTransaction(options: CreateTransactionOptions): CheckoutParams {\n\t\tif (!options.transactionId) {\n\t\t\tthrow new PayWayConfigError(\"transactionId is required\");\n\t\t}\n\t\tif (options.transactionId.length > 20) {\n\t\t\tthrow new PayWayConfigError(\n\t\t\t\t\"transactionId must be at most 20 characters\",\n\t\t\t);\n\t\t}\n\t\tif (options.amount <= 0) {\n\t\t\tthrow new PayWayConfigError(\"amount must be greater than 0\");\n\t\t}\n\t\tif (\n\t\t\toptions.lifetime !== undefined &&\n\t\t\t(options.lifetime < 3 || options.lifetime > 43_200)\n\t\t) {\n\t\t\tthrow new PayWayConfigError(\"lifetime must be between 3 and 43200\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\t\tconst currency = options.currency ?? \"USD\";\n\t\tconst amount = formatAmount(options.amount, currency);\n\t\tconst type = options.type ?? \"purchase\";\n\n\t\t// Items: if array, JSON-stringify and base64-encode; if string, base64-encode as-is\n\t\tlet items: string;\n\t\tif (Array.isArray(options.items)) {\n\t\t\titems = toBase64(JSON.stringify(options.items));\n\t\t} else if (options.items) {\n\t\t\titems = toBase64(options.items);\n\t\t} else {\n\t\t\titems = \"\";\n\t\t}\n\n\t\t// Return URL and return deeplink must be base64-encoded per ABA docs\n\t\tconst returnUrl = options.returnUrl ? toBase64(options.returnUrl) : \"\";\n\t\tconst returnDeeplink = options.returnDeeplink\n\t\t\t? toBase64(options.returnDeeplink)\n\t\t\t: \"\";\n\n\t\t// Payout must be base64-encoded JSON string per ABA docs\n\t\tconst payout = options.payout ? toBase64(options.payout) : \"\";\n\n\t\tconst shipping =\n\t\t\toptions.shipping !== undefined\n\t\t\t\t? formatAmount(options.shipping, currency)\n\t\t\t\t: \"\";\n\n\t\t// Hash field order from remote docs (view_type and payment_gate are NOT in hash)\n\t\tconst hashValues = [\n\t\t\treqTime,\n\t\t\tthis.merchantId,\n\t\t\toptions.transactionId,\n\t\t\tamount,\n\t\t\titems,\n\t\t\tshipping,\n\t\t\toptions.firstName ?? \"\",\n\t\t\toptions.lastName ?? \"\",\n\t\t\toptions.email ?? \"\",\n\t\t\toptions.phone ?? \"\",\n\t\t\ttype,\n\t\t\toptions.paymentOption ?? \"\",\n\t\t\treturnUrl,\n\t\t\toptions.cancelUrl ?? \"\",\n\t\t\toptions.continueSuccessUrl ?? \"\",\n\t\t\treturnDeeplink,\n\t\t\tcurrency,\n\t\t\toptions.customFields ?? \"\",\n\t\t\toptions.returnParams ?? \"\",\n\t\t\tpayout,\n\t\t\toptions.lifetime?.toString() ?? \"\",\n\t\t\toptions.additionalParams ?? \"\",\n\t\t\toptions.googlePayToken ?? \"\",\n\t\t\toptions.skipSuccessPage?.toString() ?? \"\",\n\t\t];\n\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\treturn {\n\t\t\taction: `${this.baseUrl}${ENDPOINTS.purchase}`,\n\t\t\thash,\n\t\t\ttran_id: options.transactionId,\n\t\t\tamount,\n\t\t\titems,\n\t\t\tcurrency,\n\t\t\tfirstname: options.firstName ?? \"\",\n\t\t\tlastname: options.lastName ?? \"\",\n\t\t\temail: options.email ?? \"\",\n\t\t\tphone: options.phone ?? \"\",\n\t\t\ttype,\n\t\t\tpayment_option: options.paymentOption ?? \"\",\n\t\t\treturn_url: returnUrl,\n\t\t\tcancel_url: options.cancelUrl ?? \"\",\n\t\t\tcontinue_success_url: options.continueSuccessUrl ?? \"\",\n\t\t\treturn_deeplink: returnDeeplink,\n\t\t\treturn_params: options.returnParams ?? \"\",\n\t\t\tshipping,\n\t\t\tmerchant_id: this.merchantId,\n\t\t\treq_time: reqTime,\n\t\t\tcustom_fields: options.customFields ?? \"\",\n\t\t\tpayout,\n\t\t\tlifetime: options.lifetime?.toString() ?? \"\",\n\t\t\tadditional_params: options.additionalParams ?? \"\",\n\t\t\tgoogle_pay_token: options.googlePayToken ?? \"\",\n\t\t\tskip_success_page: options.skipSuccessPage?.toString() ?? \"\",\n\t\t\tview_type: options.viewType ?? \"\",\n\t\t\tpayment_gate: options.paymentGate?.toString() ?? \"\",\n\t\t};\n\t}\n\n\t/**\n\t * Check the status of a transaction.\n\t * @param transactionId - The unique transaction ID to look up.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync checkTransaction(\n\t\ttransactionId: string,\n\t): Promise<PayWayResponse<CheckTransactionData>> {\n\t\tif (!transactionId) {\n\t\t\tthrow new PayWayConfigError(\"transactionId is required\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\n\t\tconst hashValues = [reqTime, this.merchantId, transactionId];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: TransactionParams = {\n\t\t\thash,\n\t\t\ttran_id: transactionId,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<PayWayResponse<CheckTransactionData>>(\n\t\t\tENDPOINTS.checkTransaction,\n\t\t\tparams,\n\t\t);\n\t}\n\n\t/**\n\t * List transactions with optional filters. Max 3-day date range.\n\t * @param options - Filter and pagination options.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync listTransactions(\n\t\toptions: ListTransactionsOptions = {},\n\t): Promise<ListTransactionsResponse> {\n\t\tconst reqTime = formatRequestTime();\n\n\t\tconst hashValues = [\n\t\t\treqTime,\n\t\t\tthis.merchantId,\n\t\t\toptions.fromDate ?? \"\",\n\t\t\toptions.toDate ?? \"\",\n\t\t\toptions.fromAmount?.toString() ?? \"\",\n\t\t\toptions.toAmount?.toString() ?? \"\",\n\t\t\toptions.status ?? \"\",\n\t\t\toptions.page?.toString() ?? \"\",\n\t\t\toptions.pagination?.toString() ?? \"\",\n\t\t];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: ListTransactionsParams = {\n\t\t\thash,\n\t\t\tfrom_date: options.fromDate,\n\t\t\tto_date: options.toDate,\n\t\t\tfrom_amount: options.fromAmount?.toString(),\n\t\t\tto_amount: options.toAmount?.toString(),\n\t\t\tstatus: options.status,\n\t\t\tpage: options.page?.toString(),\n\t\t\tpagination: options.pagination?.toString(),\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<ListTransactionsResponse>(\n\t\t\tENDPOINTS.transactionList,\n\t\t\tparams,\n\t\t);\n\t}\n\n\t/**\n\t * Get detailed information about a transaction, including its operation history.\n\t * @param transactionId - The unique transaction ID to look up.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync getTransactionDetails(\n\t\ttransactionId: string,\n\t): Promise<PayWayResponse<TransactionDetailData>> {\n\t\tif (!transactionId) {\n\t\t\tthrow new PayWayConfigError(\"transactionId is required\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\t\tconst hashValues = [reqTime, this.merchantId, transactionId];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: TransactionParams = {\n\t\t\thash,\n\t\t\ttran_id: transactionId,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<PayWayResponse<TransactionDetailData>>(\n\t\t\tENDPOINTS.transactionDetail,\n\t\t\tparams,\n\t\t\t\"json\",\n\t\t);\n\t}\n\n\t/**\n\t * Close (cancel) a pending transaction.\n\t * @param transactionId - The transaction ID to close.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync closeTransaction(\n\t\ttransactionId: string,\n\t): Promise<CloseTransactionResponse> {\n\t\tif (!transactionId) {\n\t\t\tthrow new PayWayConfigError(\"transactionId is required\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\t\tconst hashValues = [reqTime, this.merchantId, transactionId];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: TransactionParams = {\n\t\t\thash,\n\t\t\ttran_id: transactionId,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<CloseTransactionResponse>(\n\t\t\tENDPOINTS.closeTransaction,\n\t\t\tparams,\n\t\t\t\"json\",\n\t\t);\n\t}\n\n\t/**\n\t * Fetch the latest exchange rates from ABA Bank.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync getExchangeRate(): Promise<ExchangeRateResponse> {\n\t\tconst reqTime = formatRequestTime();\n\t\tconst hashValues = [reqTime, this.merchantId];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: ExchangeRateParams = {\n\t\t\thash,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<ExchangeRateResponse>(\n\t\t\tENDPOINTS.exchangeRate,\n\t\t\tparams,\n\t\t\t\"json\",\n\t\t);\n\t}\n\n\t/**\n\t * Generate a QR code for payment via ABA KHQR, WeChat Pay, or Alipay.\n\t * @param options - QR generation options.\n\t * @throws {PayWayConfigError} If required options are missing or invalid.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync generateQR(options: GenerateQROptions): Promise<GenerateQRResponse> {\n\t\tif (!options.transactionId) {\n\t\t\tthrow new PayWayConfigError(\"transactionId is required\");\n\t\t}\n\t\tif (options.amount <= 0) {\n\t\t\tthrow new PayWayConfigError(\"amount must be greater than 0\");\n\t\t}\n\t\tif (!options.paymentOption) {\n\t\t\tthrow new PayWayConfigError(\"paymentOption is required\");\n\t\t}\n\t\tif (!options.qrImageTemplate) {\n\t\t\tthrow new PayWayConfigError(\"qrImageTemplate is required\");\n\t\t}\n\t\tif (\n\t\t\toptions.lifetime !== undefined &&\n\t\t\t(options.lifetime < 3 || options.lifetime > 43_200)\n\t\t) {\n\t\t\tthrow new PayWayConfigError(\"lifetime must be between 3 and 43200\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\t\tconst currency = options.currency ?? \"USD\";\n\t\tconst amount = formatAmount(options.amount, currency);\n\n\t\t// Base64-encode fields per ABA docs\n\t\tconst items = options.items ? toBase64(options.items) : \"\";\n\t\tconst callbackUrl = options.callbackUrl\n\t\t\t? toBase64(options.callbackUrl)\n\t\t\t: \"\";\n\t\tconst returnDeeplink = options.returnDeeplink\n\t\t\t? toBase64(options.returnDeeplink)\n\t\t\t: \"\";\n\t\tconst customFields = options.customFields\n\t\t\t? toBase64(options.customFields)\n\t\t\t: \"\";\n\t\tconst payout = options.payout ? toBase64(options.payout) : \"\";\n\n\t\t// Hash field order from remote docs (differs from parameter table order)\n\t\tconst hashValues = [\n\t\t\treqTime,\n\t\t\tthis.merchantId,\n\t\t\toptions.transactionId,\n\t\t\tamount,\n\t\t\titems,\n\t\t\toptions.firstName ?? \"\",\n\t\t\toptions.lastName ?? \"\",\n\t\t\toptions.email ?? \"\",\n\t\t\toptions.phone ?? \"\",\n\t\t\toptions.purchaseType ?? \"\",\n\t\t\toptions.paymentOption,\n\t\t\tcallbackUrl,\n\t\t\treturnDeeplink,\n\t\t\tcurrency,\n\t\t\tcustomFields,\n\t\t\toptions.returnParams ?? \"\",\n\t\t\tpayout,\n\t\t\toptions.lifetime?.toString() ?? \"\",\n\t\t\toptions.qrImageTemplate,\n\t\t];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: GenerateQRParams = {\n\t\t\thash,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t\ttran_id: options.transactionId,\n\t\t\tamount: options.amount,\n\t\t\tcurrency,\n\t\t\tpayment_option: options.paymentOption,\n\t\t\tlifetime: options.lifetime,\n\t\t\tqr_image_template: options.qrImageTemplate,\n\t\t\tfirst_name: options.firstName,\n\t\t\tlast_name: options.lastName,\n\t\t\temail: options.email,\n\t\t\tphone: options.phone,\n\t\t\tpurchase_type: options.purchaseType,\n\t\t\titems: items || undefined,\n\t\t\tcallback_url: callbackUrl || undefined,\n\t\t\treturn_deeplink: returnDeeplink || undefined,\n\t\t\tcustom_fields: customFields || undefined,\n\t\t\treturn_params: options.returnParams,\n\t\t\tpayout: payout || undefined,\n\t\t};\n\n\t\treturn this.request<GenerateQRResponse>(\n\t\t\tENDPOINTS.generateQR,\n\t\t\tparams,\n\t\t\t\"json\",\n\t\t);\n\t}\n\n\t/**\n\t * Get transactions by merchant reference. Returns up to the last 50 transactions.\n\t * @param merchantRef - Your merchant reference number.\n\t * @throws {PayWayAPIError} If the API returns a non-2xx response.\n\t */\n\tasync getTransactionsByRef(\n\t\tmerchantRef: string,\n\t): Promise<GetTransactionsByRefResponse> {\n\t\tif (!merchantRef) {\n\t\t\tthrow new PayWayConfigError(\"merchantRef is required\");\n\t\t}\n\n\t\tconst reqTime = formatRequestTime();\n\t\tconst hashValues = [reqTime, this.merchantId, merchantRef];\n\t\tconst hash = createHash(hashValues, this.apiKey);\n\n\t\tconst params: GetTransactionsByRefParams = {\n\t\t\thash,\n\t\t\tmerchant_ref: merchantRef,\n\t\t\treq_time: reqTime,\n\t\t\tmerchant_id: this.merchantId,\n\t\t};\n\n\t\treturn this.request<GetTransactionsByRefResponse>(\n\t\t\tENDPOINTS.getTransactionsByRef,\n\t\t\tparams,\n\t\t\t\"json\",\n\t\t);\n\t}\n\n\tprivate async request<T>(\n\t\tendpoint: (typeof ENDPOINTS)[keyof typeof ENDPOINTS],\n\t\tparams: RequestParams,\n\t\tformat: \"form\" | \"json\" = \"form\",\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${endpoint}`;\n\n\t\tlet body: FormData | string;\n\t\tconst headers: Record<string, string> = {};\n\n\t\tif (format === \"json\") {\n\t\t\tbody = JSON.stringify(filterParams(params));\n\t\t\theaders[\"Content-Type\"] = \"application/json\";\n\t\t} else {\n\t\t\tbody = buildFormData(params);\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody,\n\t\t\t\theaders,\n\t\t\t\tsignal: AbortSignal.timeout(this.timeout),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new PayWayError(\n\t\t\t\terror instanceof Error ? error.message : \"Network request failed\",\n\t\t\t\t{ cause: error },\n\t\t\t);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tlet responseBody: unknown = text;\n\t\t\ttry {\n\t\t\t\tresponseBody = JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\t// keep as text\n\t\t\t}\n\t\t\tthrow new PayWayAPIError(\n\t\t\t\t`PayWay API error: ${response.status} ${response.statusText}`,\n\t\t\t\tresponse.status,\n\t\t\t\tresponseBody,\n\t\t\t);\n\t\t}\n\n\t\treturn (await response.json()) as T;\n\t}\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aba-payway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Type-safe TypeScript SDK for ABA PayWay — Cambodia's #1 payment gateway",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"typescript",
|
|
40
40
|
"sdk"
|
|
41
41
|
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"sideEffects": false,
|
|
42
46
|
"license": "MIT",
|
|
43
47
|
"author": "Joselay",
|
|
44
48
|
"repository": {
|