aba-payway 0.1.0 → 0.2.0

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