aba-payway 0.2.0 → 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 CHANGED
@@ -1,16 +1,36 @@
1
1
  # aba-payway
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/aba-payway)](https://www.npmjs.com/package/aba-payway)
4
+ [![CI](https://github.com/Joselay/aba-payway/actions/workflows/ci.yml/badge.svg)](https://github.com/Joselay/aba-payway/actions)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![npm downloads](https://img.shields.io/npm/dm/aba-payway)](https://www.npmjs.com/package/aba-payway)
7
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://www.npmjs.com/package/aba-payway)
8
+
3
9
  Type-safe TypeScript SDK for [ABA PayWay](https://www.payway.com.kh/) — Cambodia's #1 payment gateway.
4
10
 
5
11
  > **Unofficial community SDK.** Not affiliated with ABA Bank.
6
12
 
13
+ ## Why aba-payway?
14
+
15
+ ABA PayWay's official SDK is a raw REST API with no official Node.js/TypeScript client. That means you're left dealing with manual HMAC hashing, snake_case field ordering, base64 encoding, and zero type safety. This SDK handles all of that for you.
16
+
17
+ | | `aba-payway` | Rolling your own |
18
+ |---|---|---|
19
+ | Type safety | Full TypeScript with strict types | None — guess the field names |
20
+ | Hash computation | Automatic, correct field ordering | Manual HMAC-SHA512, easy to get wrong |
21
+ | Base64 encoding | Automatic for items, URLs, payout | Do it yourself, hope you didn't miss one |
22
+ | Dependencies | **Zero** — only Node.js built-ins | Probably `axios` + `crypto-js` + glue code |
23
+ | API coverage | 15+ methods | Build each one from scratch |
24
+ | Runtime support | Node.js, Bun, Deno, Cloudflare Workers | Whatever you tested |
25
+
7
26
  ## Features
8
27
 
9
- - Zero runtime dependencies — uses Node.js built-in `crypto` and native `fetch`
10
- - Full TypeScript support with strict types
11
- - Dual ESM + CJS output
12
- - Simple, clean API with camelCase interface
13
- - Works with Node.js, Bun, Next.js, Express, Hono, and any JS runtime with `fetch`
28
+ - **Zero runtime dependencies** — uses Node.js built-in `crypto` and native `fetch`
29
+ - **Full TypeScript support** with strict types and autocomplete
30
+ - **Dual ESM + CJS output** — works everywhere
31
+ - **15+ API methods** — checkout, QR payments, refunds, pre-auth, payouts, and more
32
+ - **Runs anywhere** Node.js, Bun, Deno, Next.js, Express, Hono, Cloudflare Workers
33
+ - **Tested against ABA's sandbox** — not just unit tests, real API integration tests
14
34
 
15
35
  ## Installation
16
36
 
@@ -45,7 +65,7 @@ const params = payway.createTransaction({
45
65
 
46
66
  // Send `params` to your frontend, populate ABA's hidden form,
47
67
  // and call AbaPayway.checkout() to open the payment dialog.
48
- // See examples/server.ts for a complete working example.
68
+ // See examples/ for more snippets and framework integrations.
49
69
  ```
50
70
 
51
71
  ## API Reference
@@ -275,6 +295,18 @@ app.post('/pay', (req, res) => {
275
295
 
276
296
  For the full ABA PayWay API documentation, see [aba-payway-docs](https://github.com/Joselay/aba-payway-docs).
277
297
 
298
+ ## Contributing
299
+
300
+ Found a bug or have a feature request? [Open an issue](https://github.com/Joselay/aba-payway/issues) — all feedback is welcome.
301
+
302
+ Pull requests are also welcome. Please make sure tests pass before submitting:
303
+
304
+ ```bash
305
+ bun run test
306
+ bun run typecheck
307
+ bun run lint
308
+ ```
309
+
278
310
  ## License
279
311
 
280
312
  MIT
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
- options.customFields ?? "",
196
+ customFields,
209
197
  options.returnParams ?? "",
210
198
  payout,
211
199
  options.lifetime?.toString() ?? "",
212
- options.additionalParams ?? "",
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: options.customFields ?? "",
226
+ custom_fields: customFields,
239
227
  payout,
240
228
  lifetime: options.lifetime?.toString() ?? "",
241
- additional_params: options.additionalParams ?? "",
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 !== void 0 && (options.lifetime < 3 || options.lifetime > 43200)) {
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?.toString() ?? "",
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, format = "form") {
455
+ async request(endpoint, params) {
479
456
  const url = `${this.baseUrl}${endpoint}`;
480
- let body;
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
@@ -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?: number;
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
- /** Generate an HMAC-SHA512 hash from concatenated values, returned as a base64 string. */
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?: number;
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
- /** Generate an HMAC-SHA512 hash from concatenated values, returned as a base64 string. */
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
- options.customFields ?? "",
164
+ customFields,
170
165
  options.returnParams ?? "",
171
166
  payout,
172
167
  options.lifetime?.toString() ?? "",
173
- options.additionalParams ?? "",
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: options.customFields ?? "",
194
+ custom_fields: customFields,
200
195
  payout,
201
196
  lifetime: options.lifetime?.toString() ?? "",
202
- additional_params: options.additionalParams ?? "",
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 !== void 0 && (options.lifetime < 3 || options.lifetime > 43200)) {
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?.toString() ?? "",
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, format = "form") {
423
+ async request(endpoint, params) {
440
424
  const url = `${this.baseUrl}${endpoint}`;
441
- let body;
442
- const headers = {};
443
- if (format === "json") {
444
- body = JSON.stringify(filterParams(params));
445
- headers["Content-Type"] = "application/json";
446
- } else {
447
- body = buildFormData(params);
448
- }
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":";AAEO,IAAM,YAAyC;AAAA,EACrD,SAAS;AAAA,EACT,YAAY;AACb;AAEO,IAAM,mBAAmB,UAAU;AACnC,IAAM,sBAAsB,UAAU;AAEtC,IAAM,YAAY;AAAA,EACxB,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,sBACC;AACF;;;ACnBO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACtC,YAAY,SAAiB,SAAwB;AACpD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACb;AACD;AAGO,IAAM,iBAAN,cAA6B,YAAY;AAAA,EAC/B;AAAA,EACA;AAAA,EAEhB,YAAY,SAAiB,YAAoB,cAAwB;AACxE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,eAAe;AAAA,EACrB;AACD;AAGO,IAAM,oBAAN,cAAgC,YAAY;AAAA,EAClD,YAAY,SAAiB;AAC5B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACb;AACD;AAGO,IAAM,kBAAN,cAA8B,YAAY;AAAA,EAChD,YAAY,SAAiB;AAC5B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACb;AACD;;;ACnCA,SAAS,kBAAkB;AAGpB,SAAS,WAAW,QAA2B,QAAwB;AAC7E,QAAM,UAAU,OAAO,KAAK,EAAE;AAC9B,QAAM,OAAO,WAAW,UAAU,MAAM;AACxC,OAAK,OAAO,OAAO;AACnB,SAAO,KAAK,OAAO,QAAQ;AAC5B;;;ACLO,SAAS,kBAAkB,OAAa,oBAAI,KAAK,GAAW;AAClE,QAAM,OAAO,KAAK,eAAe,EAAE,SAAS;AAC5C,QAAM,SAAS,KAAK,YAAY,IAAI,GAAG,SAAS,EAAE,SAAS,GAAG,GAAG;AACjE,QAAM,MAAM,KAAK,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AACxD,QAAM,QAAQ,KAAK,YAAY,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAC3D,QAAM,UAAU,KAAK,cAAc,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAC/D,QAAM,UAAU,KAAK,cAAc,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AAC/D,SAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO;AACzD;AAGO,SAAS,aAAa,QAAiD;AAC7E,QAAM,MAAuC,CAAC;AAC9C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,QAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AAC1D,UAAI,GAAG,IAAI;AAAA,IACZ;AAAA,EACD;AACA,SAAO;AACR;AAcO,SAAS,aACf,QACA,WAAqB,OACZ;AACT,MAAI,aAAa,OAAO;AACvB,WAAO,KAAK,MAAM,MAAM,EAAE,SAAS;AAAA,EACpC;AACA,SAAO,OAAO,QAAQ,CAAC;AACxB;AAGO,SAAS,SAAS,OAAuB;AAC/C,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;AAC5C;;;ACdO,IAAM,SAAN,MAAa;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAY,QAAsB;AACjC,QAAI,CAAC,OAAO,YAAY;AACvB,YAAM,IAAI,kBAAkB,wBAAwB;AAAA,IACrD;AACA,QAAI,CAAC,OAAO,QAAQ;AACnB,YAAM,IAAI,kBAAkB,oBAAoB;AAAA,IACjD;AAEA,SAAK,aAAa,OAAO;AACzB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,WAAW,UAAU,OAAO,eAAe,SAAS;AAC1E,SAAK,UAAU,OAAO,WAAW;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,SAAmD;AACpE,QAAI,CAAC,QAAQ,eAAe;AAC3B,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AACA,QAAI,QAAQ,cAAc,SAAS,IAAI;AACtC,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,QAAI,QAAQ,UAAU,GAAG;AACxB,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC5D;AACA,QACC,QAAQ,aAAa,WACpB,QAAQ,WAAW,KAAK,QAAQ,WAAW,QAC3C;AACD,YAAM,IAAI,kBAAkB,sCAAsC;AAAA,IACnE;AAEA,UAAM,UAAU,kBAAkB;AAClC,UAAM,WAAW,QAAQ,YAAY;AACrC,UAAM,SAAS,aAAa,QAAQ,QAAQ,QAAQ;AACpD,UAAM,OAAO,QAAQ,QAAQ;AAG7B,QAAI;AACJ,QAAI,MAAM,QAAQ,QAAQ,KAAK,GAAG;AACjC,cAAQ,SAAS,KAAK,UAAU,QAAQ,KAAK,CAAC;AAAA,IAC/C,WAAW,QAAQ,OAAO;AACzB,cAAQ,SAAS,QAAQ,KAAK;AAAA,IAC/B,OAAO;AACN,cAAQ;AAAA,IACT;AAGA,UAAM,YAAY,QAAQ,YAAY,SAAS,QAAQ,SAAS,IAAI;AACpE,UAAM,iBAAiB,QAAQ,iBAC5B,SAAS,QAAQ,cAAc,IAC/B;AAGH,UAAM,SAAS,QAAQ,SAAS,SAAS,QAAQ,MAAM,IAAI;AAE3D,UAAM,WACL,QAAQ,aAAa,SAClB,aAAa,QAAQ,UAAU,QAAQ,IACvC;AAGJ,UAAM,eAAe,QAAQ,eAC1B,SAAS,QAAQ,YAAY,IAC7B;AACH,UAAM,mBAAmB,QAAQ,mBAC9B,SAAS,QAAQ,gBAAgB,IACjC;AAGH,UAAM,aAAa;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,aAAa;AAAA,MACrB,QAAQ,YAAY;AAAA,MACpB,QAAQ,SAAS;AAAA,MACjB,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA,QAAQ,iBAAiB;AAAA,MACzB;AAAA,MACA,QAAQ,aAAa;AAAA,MACrB,QAAQ,sBAAsB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,gBAAgB;AAAA,MACxB;AAAA,MACA,QAAQ,UAAU,SAAS,KAAK;AAAA,MAChC;AAAA,MACA,QAAQ,kBAAkB;AAAA,MAC1B,QAAQ,iBAAiB,SAAS,KAAK;AAAA,IACxC;AAEA,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,WAAO;AAAA,MACN,QAAQ,GAAG,KAAK,OAAO,GAAG,UAAU,QAAQ;AAAA,MAC5C;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,QAAQ,aAAa;AAAA,MAChC,UAAU,QAAQ,YAAY;AAAA,MAC9B,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,QAAQ,SAAS;AAAA,MACxB;AAAA,MACA,gBAAgB,QAAQ,iBAAiB;AAAA,MACzC,YAAY;AAAA,MACZ,YAAY,QAAQ,aAAa;AAAA,MACjC,sBAAsB,QAAQ,sBAAsB;AAAA,MACpD,iBAAiB;AAAA,MACjB,eAAe,QAAQ,gBAAgB;AAAA,MACvC;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,MACV,eAAe;AAAA,MACf;AAAA,MACA,UAAU,QAAQ,UAAU,SAAS,KAAK;AAAA,MAC1C,mBAAmB;AAAA,MACnB,kBAAkB,QAAQ,kBAAkB;AAAA,MAC5C,mBAAmB,QAAQ,iBAAiB,SAAS,KAAK;AAAA,MAC1D,WAAW,QAAQ,YAAY;AAAA,MAC/B,cAAc,QAAQ,aAAa,SAAS,KAAK;AAAA,IAClD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACL,eACgD;AAChD,QAAI,CAAC,eAAe;AACnB,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AAEA,UAAM,UAAU,kBAAkB;AAElC,UAAM,aAAa,CAAC,SAAS,KAAK,YAAY,aAAa;AAC3D,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAA4B;AAAA,MACjC;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACL,UAAmC,CAAC,GACA;AACpC,UAAM,UAAU,kBAAkB;AAElC,UAAM,aAAa;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,MACL,QAAQ,YAAY;AAAA,MACpB,QAAQ,UAAU;AAAA,MAClB,QAAQ,YAAY,SAAS,KAAK;AAAA,MAClC,QAAQ,UAAU,SAAS,KAAK;AAAA,MAChC,QAAQ,UAAU;AAAA,MAClB,QAAQ,MAAM,SAAS,KAAK;AAAA,MAC5B,QAAQ,YAAY,SAAS,KAAK;AAAA,IACnC;AACA,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAAiC;AAAA,MACtC;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ,YAAY,SAAS;AAAA,MAC1C,WAAW,QAAQ,UAAU,SAAS;AAAA,MACtC,QAAQ,QAAQ;AAAA,MAChB,MAAM,QAAQ,MAAM,SAAS;AAAA,MAC7B,YAAY,QAAQ,YAAY,SAAS;AAAA,MACzC,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBACL,eACiD;AACjD,QAAI,CAAC,eAAe;AACnB,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AAEA,UAAM,UAAU,kBAAkB;AAClC,UAAM,aAAa,CAAC,SAAS,KAAK,YAAY,aAAa;AAC3D,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAA4B;AAAA,MACjC;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACL,eACoC;AACpC,QAAI,CAAC,eAAe;AACnB,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AAEA,UAAM,UAAU,kBAAkB;AAClC,UAAM,aAAa,CAAC,SAAS,KAAK,YAAY,aAAa;AAC3D,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAA4B;AAAA,MACjC;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAiD;AACtD,UAAM,UAAU,kBAAkB;AAClC,UAAM,aAAa,CAAC,SAAS,KAAK,UAAU;AAC5C,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAA6B;AAAA,MAClC;AAAA,MACA,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK,QAA8B,UAAU,cAAc,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,SAAyD;AACzE,QAAI,CAAC,QAAQ,eAAe;AAC3B,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AACA,QAAI,QAAQ,UAAU,GAAG;AACxB,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC5D;AACA,QAAI,CAAC,QAAQ,eAAe;AAC3B,YAAM,IAAI,kBAAkB,2BAA2B;AAAA,IACxD;AACA,QAAI,CAAC,QAAQ,iBAAiB;AAC7B,YAAM,IAAI,kBAAkB,6BAA6B;AAAA,IAC1D;AACA,QAAI,QAAQ,WAAW,KAAK,QAAQ,WAAW,OAAQ;AACtD,YAAM,IAAI,kBAAkB,sCAAsC;AAAA,IACnE;AAEA,UAAM,UAAU,kBAAkB;AAClC,UAAM,WAAW,QAAQ,YAAY;AACrC,UAAM,SAAS,aAAa,QAAQ,QAAQ,QAAQ;AAGpD,UAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,KAAK,IAAI;AACxD,UAAM,cAAc,QAAQ,cACzB,SAAS,QAAQ,WAAW,IAC5B;AACH,UAAM,iBAAiB,QAAQ,iBAC5B,SAAS,QAAQ,cAAc,IAC/B;AACH,UAAM,eAAe,QAAQ,eAC1B,SAAS,QAAQ,YAAY,IAC7B;AACH,UAAM,SAAS,QAAQ,SAAS,SAAS,QAAQ,MAAM,IAAI;AAG3D,UAAM,aAAa;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,QAAQ,aAAa;AAAA,MACrB,QAAQ,YAAY;AAAA,MACpB,QAAQ,SAAS;AAAA,MACjB,QAAQ,SAAS;AAAA,MACjB,QAAQ,gBAAgB;AAAA,MACxB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,gBAAgB;AAAA,MACxB;AAAA,MACA,QAAQ,SAAS,SAAS;AAAA,MAC1B,QAAQ;AAAA,IACT;AACA,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAA2B;AAAA,MAChC;AAAA,MACA,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,SAAS,QAAQ;AAAA,MACjB,QAAQ,QAAQ;AAAA,MAChB;AAAA,MACA,gBAAgB,QAAQ;AAAA,MACxB,UAAU,QAAQ;AAAA,MAClB,mBAAmB,QAAQ;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,eAAe,QAAQ;AAAA,MACvB,OAAO,SAAS;AAAA,MAChB,cAAc,eAAe;AAAA,MAC7B,iBAAiB,kBAAkB;AAAA,MACnC,eAAe,gBAAgB;AAAA,MAC/B,eAAe,QAAQ;AAAA,MACvB,QAAQ,UAAU;AAAA,IACnB;AAEA,WAAO,KAAK,QAA4B,UAAU,YAAY,MAAM;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBACL,aACwC;AACxC,QAAI,CAAC,aAAa;AACjB,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACtD;AAEA,UAAM,UAAU,kBAAkB;AAClC,UAAM,aAAa,CAAC,SAAS,KAAK,YAAY,WAAW;AACzD,UAAM,OAAO,WAAW,YAAY,KAAK,MAAM;AAE/C,UAAM,SAAqC;AAAA,MAC1C;AAAA,MACA,cAAc;AAAA,MACd,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,QACb,UACA,QACa;AACb,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AACtC,UAAM,OAAO,KAAK,UAAU,aAAa,MAAM,CAAC;AAEhD,QAAI;AACJ,QAAI;AACH,iBAAW,MAAM,MAAM,KAAK;AAAA,QAC3B,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,QAAQ,YAAY,QAAQ,KAAK,OAAO;AAAA,MACzC,CAAC;AAAA,IACF,SAAS,OAAO;AACf,YAAM,IAAI;AAAA,QACT,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACzC,EAAE,OAAO,MAAM;AAAA,MAChB;AAAA,IACD;AAEA,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,eAAwB;AAC5B,UAAI;AACH,uBAAe,KAAK,MAAM,IAAI;AAAA,MAC/B,QAAQ;AAAA,MAER;AACA,YAAM,IAAI;AAAA,QACT,qBAAqB,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QAC3D,SAAS;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC7B;AACD;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aba-payway",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Type-safe TypeScript SDK for ABA PayWay — Cambodia's #1 payment gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -33,11 +33,23 @@
33
33
  "keywords": [
34
34
  "aba",
35
35
  "payway",
36
+ "aba-payway",
36
37
  "cambodia",
37
38
  "payment",
38
39
  "payment-gateway",
39
40
  "typescript",
40
- "sdk"
41
+ "sdk",
42
+ "khqr",
43
+ "qr-payment",
44
+ "checkout",
45
+ "aba-bank",
46
+ "nodejs",
47
+ "fintech",
48
+ "cambodia-payment",
49
+ "bun",
50
+ "deno",
51
+ "esm",
52
+ "cloudflare-workers"
41
53
  ],
42
54
  "engines": {
43
55
  "node": ">=18.0.0"