aba-payway 0.2.1 → 0.2.2
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 +1 -1
- package/dist/index.cjs +19 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -18
- package/dist/index.d.ts +5 -18
- package/dist/index.js +18 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ const params = payway.createTransaction({
|
|
|
65
65
|
|
|
66
66
|
// Send `params` to your frontend, populate ABA's hidden form,
|
|
67
67
|
// and call AbaPayway.checkout() to open the payment dialog.
|
|
68
|
-
// See examples/
|
|
68
|
+
// See examples/ for more snippets and framework integrations.
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
## API Reference
|
package/dist/index.cjs
CHANGED
|
@@ -22,18 +22,11 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
BASE_URLS: () => BASE_URLS,
|
|
24
24
|
ENDPOINTS: () => ENDPOINTS,
|
|
25
|
-
PRODUCTION_BASE_URL: () => PRODUCTION_BASE_URL,
|
|
26
25
|
PayWay: () => PayWay,
|
|
27
26
|
PayWayAPIError: () => PayWayAPIError,
|
|
28
27
|
PayWayConfigError: () => PayWayConfigError,
|
|
29
28
|
PayWayError: () => PayWayError,
|
|
30
|
-
PayWayHashError: () => PayWayHashError
|
|
31
|
-
SANDBOX_BASE_URL: () => SANDBOX_BASE_URL,
|
|
32
|
-
buildFormData: () => buildFormData,
|
|
33
|
-
createHash: () => createHash,
|
|
34
|
-
formatAmount: () => formatAmount,
|
|
35
|
-
formatRequestTime: () => formatRequestTime,
|
|
36
|
-
toBase64: () => toBase64
|
|
29
|
+
PayWayHashError: () => PayWayHashError
|
|
37
30
|
});
|
|
38
31
|
module.exports = __toCommonJS(index_exports);
|
|
39
32
|
|
|
@@ -107,19 +100,12 @@ function formatRequestTime(date = /* @__PURE__ */ new Date()) {
|
|
|
107
100
|
function filterParams(params) {
|
|
108
101
|
const out = {};
|
|
109
102
|
for (const [key, value] of Object.entries(params)) {
|
|
110
|
-
if (value !== void 0 && value !== "") {
|
|
103
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
111
104
|
out[key] = value;
|
|
112
105
|
}
|
|
113
106
|
}
|
|
114
107
|
return out;
|
|
115
108
|
}
|
|
116
|
-
function buildFormData(params) {
|
|
117
|
-
const formData = new FormData();
|
|
118
|
-
for (const [key, value] of Object.entries(filterParams(params))) {
|
|
119
|
-
formData.append(key, String(value));
|
|
120
|
-
}
|
|
121
|
-
return formData;
|
|
122
|
-
}
|
|
123
109
|
function formatAmount(amount, currency = "USD") {
|
|
124
110
|
if (currency === "KHR") {
|
|
125
111
|
return Math.round(amount).toString();
|
|
@@ -187,6 +173,8 @@ var PayWay = class {
|
|
|
187
173
|
const returnDeeplink = options.returnDeeplink ? toBase64(options.returnDeeplink) : "";
|
|
188
174
|
const payout = options.payout ? toBase64(options.payout) : "";
|
|
189
175
|
const shipping = options.shipping !== void 0 ? formatAmount(options.shipping, currency) : "";
|
|
176
|
+
const customFields = options.customFields ? toBase64(options.customFields) : "";
|
|
177
|
+
const additionalParams = options.additionalParams ? toBase64(options.additionalParams) : "";
|
|
190
178
|
const hashValues = [
|
|
191
179
|
reqTime,
|
|
192
180
|
this.merchantId,
|
|
@@ -205,11 +193,11 @@ var PayWay = class {
|
|
|
205
193
|
options.continueSuccessUrl ?? "",
|
|
206
194
|
returnDeeplink,
|
|
207
195
|
currency,
|
|
208
|
-
|
|
196
|
+
customFields,
|
|
209
197
|
options.returnParams ?? "",
|
|
210
198
|
payout,
|
|
211
199
|
options.lifetime?.toString() ?? "",
|
|
212
|
-
|
|
200
|
+
additionalParams,
|
|
213
201
|
options.googlePayToken ?? "",
|
|
214
202
|
options.skipSuccessPage?.toString() ?? ""
|
|
215
203
|
];
|
|
@@ -235,10 +223,10 @@ var PayWay = class {
|
|
|
235
223
|
shipping,
|
|
236
224
|
merchant_id: this.merchantId,
|
|
237
225
|
req_time: reqTime,
|
|
238
|
-
custom_fields:
|
|
226
|
+
custom_fields: customFields,
|
|
239
227
|
payout,
|
|
240
228
|
lifetime: options.lifetime?.toString() ?? "",
|
|
241
|
-
additional_params:
|
|
229
|
+
additional_params: additionalParams,
|
|
242
230
|
google_pay_token: options.googlePayToken ?? "",
|
|
243
231
|
skip_success_page: options.skipSuccessPage?.toString() ?? "",
|
|
244
232
|
view_type: options.viewType ?? "",
|
|
@@ -324,8 +312,7 @@ var PayWay = class {
|
|
|
324
312
|
};
|
|
325
313
|
return this.request(
|
|
326
314
|
ENDPOINTS.transactionDetail,
|
|
327
|
-
params
|
|
328
|
-
"json"
|
|
315
|
+
params
|
|
329
316
|
);
|
|
330
317
|
}
|
|
331
318
|
/**
|
|
@@ -348,8 +335,7 @@ var PayWay = class {
|
|
|
348
335
|
};
|
|
349
336
|
return this.request(
|
|
350
337
|
ENDPOINTS.closeTransaction,
|
|
351
|
-
params
|
|
352
|
-
"json"
|
|
338
|
+
params
|
|
353
339
|
);
|
|
354
340
|
}
|
|
355
341
|
/**
|
|
@@ -365,11 +351,7 @@ var PayWay = class {
|
|
|
365
351
|
req_time: reqTime,
|
|
366
352
|
merchant_id: this.merchantId
|
|
367
353
|
};
|
|
368
|
-
return this.request(
|
|
369
|
-
ENDPOINTS.exchangeRate,
|
|
370
|
-
params,
|
|
371
|
-
"json"
|
|
372
|
-
);
|
|
354
|
+
return this.request(ENDPOINTS.exchangeRate, params);
|
|
373
355
|
}
|
|
374
356
|
/**
|
|
375
357
|
* Generate a QR code for payment via ABA KHQR, WeChat Pay, or Alipay.
|
|
@@ -390,7 +372,7 @@ var PayWay = class {
|
|
|
390
372
|
if (!options.qrImageTemplate) {
|
|
391
373
|
throw new PayWayConfigError("qrImageTemplate is required");
|
|
392
374
|
}
|
|
393
|
-
if (options.lifetime
|
|
375
|
+
if (options.lifetime < 3 || options.lifetime > 43200) {
|
|
394
376
|
throw new PayWayConfigError("lifetime must be between 3 and 43200");
|
|
395
377
|
}
|
|
396
378
|
const reqTime = formatRequestTime();
|
|
@@ -419,7 +401,7 @@ var PayWay = class {
|
|
|
419
401
|
customFields,
|
|
420
402
|
options.returnParams ?? "",
|
|
421
403
|
payout,
|
|
422
|
-
options.lifetime
|
|
404
|
+
options.lifetime.toString(),
|
|
423
405
|
options.qrImageTemplate
|
|
424
406
|
];
|
|
425
407
|
const hash = createHash(hashValues, this.apiKey);
|
|
@@ -445,11 +427,7 @@ var PayWay = class {
|
|
|
445
427
|
return_params: options.returnParams,
|
|
446
428
|
payout: payout || void 0
|
|
447
429
|
};
|
|
448
|
-
return this.request(
|
|
449
|
-
ENDPOINTS.generateQR,
|
|
450
|
-
params,
|
|
451
|
-
"json"
|
|
452
|
-
);
|
|
430
|
+
return this.request(ENDPOINTS.generateQR, params);
|
|
453
431
|
}
|
|
454
432
|
/**
|
|
455
433
|
* Get transactions by merchant reference. Returns up to the last 50 transactions.
|
|
@@ -471,26 +449,18 @@ var PayWay = class {
|
|
|
471
449
|
};
|
|
472
450
|
return this.request(
|
|
473
451
|
ENDPOINTS.getTransactionsByRef,
|
|
474
|
-
params
|
|
475
|
-
"json"
|
|
452
|
+
params
|
|
476
453
|
);
|
|
477
454
|
}
|
|
478
|
-
async request(endpoint, params
|
|
455
|
+
async request(endpoint, params) {
|
|
479
456
|
const url = `${this.baseUrl}${endpoint}`;
|
|
480
|
-
|
|
481
|
-
const headers = {};
|
|
482
|
-
if (format === "json") {
|
|
483
|
-
body = JSON.stringify(filterParams(params));
|
|
484
|
-
headers["Content-Type"] = "application/json";
|
|
485
|
-
} else {
|
|
486
|
-
body = buildFormData(params);
|
|
487
|
-
}
|
|
457
|
+
const body = JSON.stringify(filterParams(params));
|
|
488
458
|
let response;
|
|
489
459
|
try {
|
|
490
460
|
response = await fetch(url, {
|
|
491
461
|
method: "POST",
|
|
492
462
|
body,
|
|
493
|
-
headers,
|
|
463
|
+
headers: { "Content-Type": "application/json" },
|
|
494
464
|
signal: AbortSignal.timeout(this.timeout)
|
|
495
465
|
});
|
|
496
466
|
} catch (error) {
|
|
@@ -519,17 +489,10 @@ var PayWay = class {
|
|
|
519
489
|
0 && (module.exports = {
|
|
520
490
|
BASE_URLS,
|
|
521
491
|
ENDPOINTS,
|
|
522
|
-
PRODUCTION_BASE_URL,
|
|
523
492
|
PayWay,
|
|
524
493
|
PayWayAPIError,
|
|
525
494
|
PayWayConfigError,
|
|
526
495
|
PayWayError,
|
|
527
|
-
PayWayHashError
|
|
528
|
-
SANDBOX_BASE_URL,
|
|
529
|
-
buildFormData,
|
|
530
|
-
createHash,
|
|
531
|
-
formatAmount,
|
|
532
|
-
formatRequestTime,
|
|
533
|
-
toBase64
|
|
496
|
+
PayWayHashError
|
|
534
497
|
});
|
|
535
498
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/errors.ts","../src/hash.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["export { PayWay } from \"./client.ts\";\nexport {\n\tBASE_URLS,\n\tENDPOINTS,\n\tPRODUCTION_BASE_URL,\n\tSANDBOX_BASE_URL,\n} from \"./constants.ts\";\nexport {\n\tPayWayAPIError,\n\tPayWayConfigError,\n\tPayWayError,\n\tPayWayHashError,\n} from \"./errors.ts\";\nexport { createHash } from \"./hash.ts\";\nexport type {\n\tCheckoutParams,\n\tCheckTransactionData,\n\tCloseTransactionResponse,\n\tCreateTransactionOptions,\n\tCurrency,\n\tEnvironment,\n\tExchangeRate,\n\tExchangeRateCurrency,\n\tExchangeRateResponse,\n\tGenerateQROptions,\n\tGenerateQRResponse,\n\tGetTransactionsByRefResponse,\n\tItemEntry,\n\tListTransactionsOptions,\n\tListTransactionsResponse,\n\tPaymentOption,\n\tPayWayConfig,\n\tPayWayResponse,\n\tPayWayResponseStatus,\n\tQRPaymentOption,\n\tTransactionByRefItem,\n\tTransactionDetailData,\n\tTransactionListItem,\n\tTransactionOperation,\n\tTransactionStatus,\n\tTransactionType,\n} from \"./types.ts\";\nexport {\n\tbuildFormData,\n\tformatAmount,\n\tformatRequestTime,\n\ttoBase64,\n} from \"./utils.ts\";\n","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":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/errors.ts","../src/hash.ts","../src/utils.ts","../src/client.ts"],"sourcesContent":["export { PayWay } from \"./client.ts\";\nexport { BASE_URLS, ENDPOINTS } from \"./constants.ts\";\nexport {\n\tPayWayAPIError,\n\tPayWayConfigError,\n\tPayWayError,\n\tPayWayHashError,\n} from \"./errors.ts\";\nexport type {\n\tCheckoutParams,\n\tCheckTransactionData,\n\tCloseTransactionResponse,\n\tCreateTransactionOptions,\n\tCurrency,\n\tEnvironment,\n\tExchangeRate,\n\tExchangeRateCurrency,\n\tExchangeRateResponse,\n\tGenerateQROptions,\n\tGenerateQRResponse,\n\tGetTransactionsByRefResponse,\n\tItemEntry,\n\tListTransactionsOptions,\n\tListTransactionsResponse,\n\tPaymentOption,\n\tPayWayConfig,\n\tPayWayResponse,\n\tPayWayResponseStatus,\n\tQRPaymentOption,\n\tTransactionByRefItem,\n\tTransactionDetailData,\n\tTransactionListItem,\n\tTransactionOperation,\n\tTransactionStatus,\n\tTransactionType,\n} from \"./types.ts\";\n","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`, `null`, 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 !== null && 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(params)) {\n\t\tif (value !== undefined && value !== null && value !== \"\") {\n\t\t\tformData.append(key, String(value));\n\t\t}\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\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// Base64-encode custom_fields and additional_params per ABA docs\n\t\tconst customFields = options.customFields\n\t\t\t? toBase64(options.customFields)\n\t\t\t: \"\";\n\t\tconst additionalParams = options.additionalParams\n\t\t\t? toBase64(options.additionalParams)\n\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\tcustomFields,\n\t\t\toptions.returnParams ?? \"\",\n\t\t\tpayout,\n\t\t\toptions.lifetime?.toString() ?? \"\",\n\t\t\tadditionalParams,\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: customFields,\n\t\t\tpayout,\n\t\t\tlifetime: options.lifetime?.toString() ?? \"\",\n\t\t\tadditional_params: 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);\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);\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>(ENDPOINTS.exchangeRate, params);\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 (options.lifetime < 3 || options.lifetime > 43_200) {\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>(ENDPOINTS.generateQR, params);\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);\n\t}\n\n\tprivate async request<T>(\n\t\tendpoint: (typeof ENDPOINTS)[keyof typeof ENDPOINTS],\n\t\tparams: RequestParams,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${endpoint}`;\n\t\tconst body = JSON.stringify(filterParams(params));\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: { \"Content-Type\": \"application/json\" },\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/dist/index.d.cts
CHANGED
|
@@ -95,6 +95,7 @@ interface PayWayResponseStatus {
|
|
|
95
95
|
code: string;
|
|
96
96
|
message?: string;
|
|
97
97
|
tran_id?: string;
|
|
98
|
+
merchant_ref?: string;
|
|
98
99
|
}
|
|
99
100
|
interface CheckTransactionData {
|
|
100
101
|
payment_status_code: number;
|
|
@@ -103,7 +104,7 @@ interface CheckTransactionData {
|
|
|
103
104
|
refund_amount: number;
|
|
104
105
|
discount_amount: number;
|
|
105
106
|
payment_amount: number;
|
|
106
|
-
payment_currency: Currency;
|
|
107
|
+
payment_currency: Currency | "";
|
|
107
108
|
apv: string;
|
|
108
109
|
payment_status: TransactionStatus;
|
|
109
110
|
transaction_date: string;
|
|
@@ -120,7 +121,7 @@ interface TransactionListItem {
|
|
|
120
121
|
discount_amount: number;
|
|
121
122
|
refund_amount: number;
|
|
122
123
|
payment_amount: number;
|
|
123
|
-
payment_currency: Currency;
|
|
124
|
+
payment_currency: Currency | "";
|
|
124
125
|
first_name: string;
|
|
125
126
|
last_name: string;
|
|
126
127
|
email: string;
|
|
@@ -185,7 +186,7 @@ interface GenerateQROptions {
|
|
|
185
186
|
amount: number;
|
|
186
187
|
currency?: Currency;
|
|
187
188
|
paymentOption: QRPaymentOption;
|
|
188
|
-
lifetime
|
|
189
|
+
lifetime: number;
|
|
189
190
|
qrImageTemplate: string;
|
|
190
191
|
firstName?: string;
|
|
191
192
|
lastName?: string;
|
|
@@ -300,8 +301,6 @@ declare class PayWay {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
declare const BASE_URLS: Record<Environment, string>;
|
|
303
|
-
declare const SANDBOX_BASE_URL: string;
|
|
304
|
-
declare const PRODUCTION_BASE_URL: string;
|
|
305
304
|
declare const ENDPOINTS: {
|
|
306
305
|
readonly purchase: "/api/payment-gateway/v1/payments/purchase";
|
|
307
306
|
readonly checkTransaction: "/api/payment-gateway/v1/payments/check-transaction-2";
|
|
@@ -332,16 +331,4 @@ declare class PayWayHashError extends PayWayError {
|
|
|
332
331
|
constructor(message: string);
|
|
333
332
|
}
|
|
334
333
|
|
|
335
|
-
|
|
336
|
-
declare function createHash(values: readonly string[], apiKey: string): string;
|
|
337
|
-
|
|
338
|
-
/** Format a Date as `yyyyMMddHHmmss` in UTC, used for ABA's `req_time` parameter. */
|
|
339
|
-
declare function formatRequestTime(date?: Date): string;
|
|
340
|
-
/** Build a FormData object from a record, skipping `undefined`, `null`, and empty string values. */
|
|
341
|
-
declare function buildFormData(params: object): FormData;
|
|
342
|
-
/** Format a numeric amount as a string: 2 decimal places for USD, rounded integer for KHR. */
|
|
343
|
-
declare function formatAmount(amount: number, currency?: Currency): string;
|
|
344
|
-
/** Base64-encode a string value using Node.js Buffer. */
|
|
345
|
-
declare function toBase64(value: string): string;
|
|
346
|
-
|
|
347
|
-
export { BASE_URLS, type CheckTransactionData, type CheckoutParams, type CloseTransactionResponse, type CreateTransactionOptions, type Currency, ENDPOINTS, type Environment, type ExchangeRate, type ExchangeRateCurrency, type ExchangeRateResponse, type GenerateQROptions, type GenerateQRResponse, type GetTransactionsByRefResponse, type ItemEntry, type ListTransactionsOptions, type ListTransactionsResponse, PRODUCTION_BASE_URL, PayWay, PayWayAPIError, type PayWayConfig, PayWayConfigError, PayWayError, PayWayHashError, type PayWayResponse, type PayWayResponseStatus, type PaymentOption, type QRPaymentOption, SANDBOX_BASE_URL, type TransactionByRefItem, type TransactionDetailData, type TransactionListItem, type TransactionOperation, type TransactionStatus, type TransactionType, buildFormData, createHash, formatAmount, formatRequestTime, toBase64 };
|
|
334
|
+
export { BASE_URLS, type CheckTransactionData, type CheckoutParams, type CloseTransactionResponse, type CreateTransactionOptions, type Currency, ENDPOINTS, type Environment, type ExchangeRate, type ExchangeRateCurrency, type ExchangeRateResponse, type GenerateQROptions, type GenerateQRResponse, type GetTransactionsByRefResponse, type ItemEntry, type ListTransactionsOptions, type ListTransactionsResponse, PayWay, PayWayAPIError, type PayWayConfig, PayWayConfigError, PayWayError, PayWayHashError, type PayWayResponse, type PayWayResponseStatus, type PaymentOption, type QRPaymentOption, type TransactionByRefItem, type TransactionDetailData, type TransactionListItem, type TransactionOperation, type TransactionStatus, type TransactionType };
|
package/dist/index.d.ts
CHANGED
|
@@ -95,6 +95,7 @@ interface PayWayResponseStatus {
|
|
|
95
95
|
code: string;
|
|
96
96
|
message?: string;
|
|
97
97
|
tran_id?: string;
|
|
98
|
+
merchant_ref?: string;
|
|
98
99
|
}
|
|
99
100
|
interface CheckTransactionData {
|
|
100
101
|
payment_status_code: number;
|
|
@@ -103,7 +104,7 @@ interface CheckTransactionData {
|
|
|
103
104
|
refund_amount: number;
|
|
104
105
|
discount_amount: number;
|
|
105
106
|
payment_amount: number;
|
|
106
|
-
payment_currency: Currency;
|
|
107
|
+
payment_currency: Currency | "";
|
|
107
108
|
apv: string;
|
|
108
109
|
payment_status: TransactionStatus;
|
|
109
110
|
transaction_date: string;
|
|
@@ -120,7 +121,7 @@ interface TransactionListItem {
|
|
|
120
121
|
discount_amount: number;
|
|
121
122
|
refund_amount: number;
|
|
122
123
|
payment_amount: number;
|
|
123
|
-
payment_currency: Currency;
|
|
124
|
+
payment_currency: Currency | "";
|
|
124
125
|
first_name: string;
|
|
125
126
|
last_name: string;
|
|
126
127
|
email: string;
|
|
@@ -185,7 +186,7 @@ interface GenerateQROptions {
|
|
|
185
186
|
amount: number;
|
|
186
187
|
currency?: Currency;
|
|
187
188
|
paymentOption: QRPaymentOption;
|
|
188
|
-
lifetime
|
|
189
|
+
lifetime: number;
|
|
189
190
|
qrImageTemplate: string;
|
|
190
191
|
firstName?: string;
|
|
191
192
|
lastName?: string;
|
|
@@ -300,8 +301,6 @@ declare class PayWay {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
declare const BASE_URLS: Record<Environment, string>;
|
|
303
|
-
declare const SANDBOX_BASE_URL: string;
|
|
304
|
-
declare const PRODUCTION_BASE_URL: string;
|
|
305
304
|
declare const ENDPOINTS: {
|
|
306
305
|
readonly purchase: "/api/payment-gateway/v1/payments/purchase";
|
|
307
306
|
readonly checkTransaction: "/api/payment-gateway/v1/payments/check-transaction-2";
|
|
@@ -332,16 +331,4 @@ declare class PayWayHashError extends PayWayError {
|
|
|
332
331
|
constructor(message: string);
|
|
333
332
|
}
|
|
334
333
|
|
|
335
|
-
|
|
336
|
-
declare function createHash(values: readonly string[], apiKey: string): string;
|
|
337
|
-
|
|
338
|
-
/** Format a Date as `yyyyMMddHHmmss` in UTC, used for ABA's `req_time` parameter. */
|
|
339
|
-
declare function formatRequestTime(date?: Date): string;
|
|
340
|
-
/** Build a FormData object from a record, skipping `undefined`, `null`, and empty string values. */
|
|
341
|
-
declare function buildFormData(params: object): FormData;
|
|
342
|
-
/** Format a numeric amount as a string: 2 decimal places for USD, rounded integer for KHR. */
|
|
343
|
-
declare function formatAmount(amount: number, currency?: Currency): string;
|
|
344
|
-
/** Base64-encode a string value using Node.js Buffer. */
|
|
345
|
-
declare function toBase64(value: string): string;
|
|
346
|
-
|
|
347
|
-
export { BASE_URLS, type CheckTransactionData, type CheckoutParams, type CloseTransactionResponse, type CreateTransactionOptions, type Currency, ENDPOINTS, type Environment, type ExchangeRate, type ExchangeRateCurrency, type ExchangeRateResponse, type GenerateQROptions, type GenerateQRResponse, type GetTransactionsByRefResponse, type ItemEntry, type ListTransactionsOptions, type ListTransactionsResponse, PRODUCTION_BASE_URL, PayWay, PayWayAPIError, type PayWayConfig, PayWayConfigError, PayWayError, PayWayHashError, type PayWayResponse, type PayWayResponseStatus, type PaymentOption, type QRPaymentOption, SANDBOX_BASE_URL, type TransactionByRefItem, type TransactionDetailData, type TransactionListItem, type TransactionOperation, type TransactionStatus, type TransactionType, buildFormData, createHash, formatAmount, formatRequestTime, toBase64 };
|
|
334
|
+
export { BASE_URLS, type CheckTransactionData, type CheckoutParams, type CloseTransactionResponse, type CreateTransactionOptions, type Currency, ENDPOINTS, type Environment, type ExchangeRate, type ExchangeRateCurrency, type ExchangeRateResponse, type GenerateQROptions, type GenerateQRResponse, type GetTransactionsByRefResponse, type ItemEntry, type ListTransactionsOptions, type ListTransactionsResponse, PayWay, PayWayAPIError, type PayWayConfig, PayWayConfigError, PayWayError, PayWayHashError, type PayWayResponse, type PayWayResponseStatus, type PaymentOption, type QRPaymentOption, type TransactionByRefItem, type TransactionDetailData, type TransactionListItem, type TransactionOperation, type TransactionStatus, type TransactionType };
|
package/dist/index.js
CHANGED
|
@@ -68,19 +68,12 @@ function formatRequestTime(date = /* @__PURE__ */ new Date()) {
|
|
|
68
68
|
function filterParams(params) {
|
|
69
69
|
const out = {};
|
|
70
70
|
for (const [key, value] of Object.entries(params)) {
|
|
71
|
-
if (value !== void 0 && value !== "") {
|
|
71
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
72
72
|
out[key] = value;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
return out;
|
|
76
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
|
-
}
|
|
82
|
-
return formData;
|
|
83
|
-
}
|
|
84
77
|
function formatAmount(amount, currency = "USD") {
|
|
85
78
|
if (currency === "KHR") {
|
|
86
79
|
return Math.round(amount).toString();
|
|
@@ -148,6 +141,8 @@ var PayWay = class {
|
|
|
148
141
|
const returnDeeplink = options.returnDeeplink ? toBase64(options.returnDeeplink) : "";
|
|
149
142
|
const payout = options.payout ? toBase64(options.payout) : "";
|
|
150
143
|
const shipping = options.shipping !== void 0 ? formatAmount(options.shipping, currency) : "";
|
|
144
|
+
const customFields = options.customFields ? toBase64(options.customFields) : "";
|
|
145
|
+
const additionalParams = options.additionalParams ? toBase64(options.additionalParams) : "";
|
|
151
146
|
const hashValues = [
|
|
152
147
|
reqTime,
|
|
153
148
|
this.merchantId,
|
|
@@ -166,11 +161,11 @@ var PayWay = class {
|
|
|
166
161
|
options.continueSuccessUrl ?? "",
|
|
167
162
|
returnDeeplink,
|
|
168
163
|
currency,
|
|
169
|
-
|
|
164
|
+
customFields,
|
|
170
165
|
options.returnParams ?? "",
|
|
171
166
|
payout,
|
|
172
167
|
options.lifetime?.toString() ?? "",
|
|
173
|
-
|
|
168
|
+
additionalParams,
|
|
174
169
|
options.googlePayToken ?? "",
|
|
175
170
|
options.skipSuccessPage?.toString() ?? ""
|
|
176
171
|
];
|
|
@@ -196,10 +191,10 @@ var PayWay = class {
|
|
|
196
191
|
shipping,
|
|
197
192
|
merchant_id: this.merchantId,
|
|
198
193
|
req_time: reqTime,
|
|
199
|
-
custom_fields:
|
|
194
|
+
custom_fields: customFields,
|
|
200
195
|
payout,
|
|
201
196
|
lifetime: options.lifetime?.toString() ?? "",
|
|
202
|
-
additional_params:
|
|
197
|
+
additional_params: additionalParams,
|
|
203
198
|
google_pay_token: options.googlePayToken ?? "",
|
|
204
199
|
skip_success_page: options.skipSuccessPage?.toString() ?? "",
|
|
205
200
|
view_type: options.viewType ?? "",
|
|
@@ -285,8 +280,7 @@ var PayWay = class {
|
|
|
285
280
|
};
|
|
286
281
|
return this.request(
|
|
287
282
|
ENDPOINTS.transactionDetail,
|
|
288
|
-
params
|
|
289
|
-
"json"
|
|
283
|
+
params
|
|
290
284
|
);
|
|
291
285
|
}
|
|
292
286
|
/**
|
|
@@ -309,8 +303,7 @@ var PayWay = class {
|
|
|
309
303
|
};
|
|
310
304
|
return this.request(
|
|
311
305
|
ENDPOINTS.closeTransaction,
|
|
312
|
-
params
|
|
313
|
-
"json"
|
|
306
|
+
params
|
|
314
307
|
);
|
|
315
308
|
}
|
|
316
309
|
/**
|
|
@@ -326,11 +319,7 @@ var PayWay = class {
|
|
|
326
319
|
req_time: reqTime,
|
|
327
320
|
merchant_id: this.merchantId
|
|
328
321
|
};
|
|
329
|
-
return this.request(
|
|
330
|
-
ENDPOINTS.exchangeRate,
|
|
331
|
-
params,
|
|
332
|
-
"json"
|
|
333
|
-
);
|
|
322
|
+
return this.request(ENDPOINTS.exchangeRate, params);
|
|
334
323
|
}
|
|
335
324
|
/**
|
|
336
325
|
* Generate a QR code for payment via ABA KHQR, WeChat Pay, or Alipay.
|
|
@@ -351,7 +340,7 @@ var PayWay = class {
|
|
|
351
340
|
if (!options.qrImageTemplate) {
|
|
352
341
|
throw new PayWayConfigError("qrImageTemplate is required");
|
|
353
342
|
}
|
|
354
|
-
if (options.lifetime
|
|
343
|
+
if (options.lifetime < 3 || options.lifetime > 43200) {
|
|
355
344
|
throw new PayWayConfigError("lifetime must be between 3 and 43200");
|
|
356
345
|
}
|
|
357
346
|
const reqTime = formatRequestTime();
|
|
@@ -380,7 +369,7 @@ var PayWay = class {
|
|
|
380
369
|
customFields,
|
|
381
370
|
options.returnParams ?? "",
|
|
382
371
|
payout,
|
|
383
|
-
options.lifetime
|
|
372
|
+
options.lifetime.toString(),
|
|
384
373
|
options.qrImageTemplate
|
|
385
374
|
];
|
|
386
375
|
const hash = createHash(hashValues, this.apiKey);
|
|
@@ -406,11 +395,7 @@ var PayWay = class {
|
|
|
406
395
|
return_params: options.returnParams,
|
|
407
396
|
payout: payout || void 0
|
|
408
397
|
};
|
|
409
|
-
return this.request(
|
|
410
|
-
ENDPOINTS.generateQR,
|
|
411
|
-
params,
|
|
412
|
-
"json"
|
|
413
|
-
);
|
|
398
|
+
return this.request(ENDPOINTS.generateQR, params);
|
|
414
399
|
}
|
|
415
400
|
/**
|
|
416
401
|
* Get transactions by merchant reference. Returns up to the last 50 transactions.
|
|
@@ -432,26 +417,18 @@ var PayWay = class {
|
|
|
432
417
|
};
|
|
433
418
|
return this.request(
|
|
434
419
|
ENDPOINTS.getTransactionsByRef,
|
|
435
|
-
params
|
|
436
|
-
"json"
|
|
420
|
+
params
|
|
437
421
|
);
|
|
438
422
|
}
|
|
439
|
-
async request(endpoint, params
|
|
423
|
+
async request(endpoint, params) {
|
|
440
424
|
const url = `${this.baseUrl}${endpoint}`;
|
|
441
|
-
|
|
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
|
-
}
|
|
425
|
+
const body = JSON.stringify(filterParams(params));
|
|
449
426
|
let response;
|
|
450
427
|
try {
|
|
451
428
|
response = await fetch(url, {
|
|
452
429
|
method: "POST",
|
|
453
430
|
body,
|
|
454
|
-
headers,
|
|
431
|
+
headers: { "Content-Type": "application/json" },
|
|
455
432
|
signal: AbortSignal.timeout(this.timeout)
|
|
456
433
|
});
|
|
457
434
|
} catch (error) {
|
|
@@ -479,17 +456,10 @@ var PayWay = class {
|
|
|
479
456
|
export {
|
|
480
457
|
BASE_URLS,
|
|
481
458
|
ENDPOINTS,
|
|
482
|
-
PRODUCTION_BASE_URL,
|
|
483
459
|
PayWay,
|
|
484
460
|
PayWayAPIError,
|
|
485
461
|
PayWayConfigError,
|
|
486
462
|
PayWayError,
|
|
487
|
-
PayWayHashError
|
|
488
|
-
SANDBOX_BASE_URL,
|
|
489
|
-
buildFormData,
|
|
490
|
-
createHash,
|
|
491
|
-
formatAmount,
|
|
492
|
-
formatRequestTime,
|
|
493
|
-
toBase64
|
|
463
|
+
PayWayHashError
|
|
494
464
|
};
|
|
495
465
|
//# sourceMappingURL=index.js.map
|
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":["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":[]}
|
|
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`, `null`, 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 !== null && 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(params)) {\n\t\tif (value !== undefined && value !== null && value !== \"\") {\n\t\t\tformData.append(key, String(value));\n\t\t}\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\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// Base64-encode custom_fields and additional_params per ABA docs\n\t\tconst customFields = options.customFields\n\t\t\t? toBase64(options.customFields)\n\t\t\t: \"\";\n\t\tconst additionalParams = options.additionalParams\n\t\t\t? toBase64(options.additionalParams)\n\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\tcustomFields,\n\t\t\toptions.returnParams ?? \"\",\n\t\t\tpayout,\n\t\t\toptions.lifetime?.toString() ?? \"\",\n\t\t\tadditionalParams,\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: customFields,\n\t\t\tpayout,\n\t\t\tlifetime: options.lifetime?.toString() ?? \"\",\n\t\t\tadditional_params: 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);\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);\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>(ENDPOINTS.exchangeRate, params);\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 (options.lifetime < 3 || options.lifetime > 43_200) {\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>(ENDPOINTS.generateQR, params);\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);\n\t}\n\n\tprivate async request<T>(\n\t\tendpoint: (typeof ENDPOINTS)[keyof typeof ENDPOINTS],\n\t\tparams: RequestParams,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${endpoint}`;\n\t\tconst body = JSON.stringify(filterParams(params));\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: { \"Content-Type\": \"application/json\" },\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":[]}
|