@laranex/myanmar-payments 0.0.0-stage → 4.0.0-dev.1

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +10 -2
  4. package/dist/cjs/aya-pay/aya-pay.d.ts +122 -0
  5. package/dist/cjs/aya-pay/aya-pay.js +301 -0
  6. package/dist/cjs/aya-pay/index.d.ts +1 -0
  7. package/dist/cjs/aya-pay/index.js +8 -0
  8. package/dist/cjs/core/amount.d.ts +57 -0
  9. package/dist/cjs/core/amount.js +107 -0
  10. package/dist/cjs/core/cache.d.ts +26 -0
  11. package/dist/cjs/core/cache.js +35 -0
  12. package/dist/cjs/core/callback.d.ts +180 -0
  13. package/dist/cjs/core/callback.js +304 -0
  14. package/dist/cjs/core/crypto.d.ts +19 -0
  15. package/dist/cjs/core/crypto.js +50 -0
  16. package/dist/cjs/core/env.d.ts +21 -0
  17. package/dist/cjs/core/env.js +54 -0
  18. package/dist/cjs/core/errors.d.ts +56 -0
  19. package/dist/cjs/core/errors.js +78 -0
  20. package/dist/cjs/core/http.d.ts +81 -0
  21. package/dist/cjs/core/http.js +128 -0
  22. package/dist/cjs/core/index.d.ts +8 -0
  23. package/dist/cjs/core/index.js +30 -0
  24. package/dist/cjs/core/json.d.ts +44 -0
  25. package/dist/cjs/core/json.js +254 -0
  26. package/dist/cjs/core/results.d.ts +122 -0
  27. package/dist/cjs/core/results.js +147 -0
  28. package/dist/cjs/core/status.d.ts +50 -0
  29. package/dist/cjs/core/status.js +60 -0
  30. package/dist/cjs/core/validate.d.ts +46 -0
  31. package/dist/cjs/core/validate.js +148 -0
  32. package/dist/cjs/core/values.d.ts +16 -0
  33. package/dist/cjs/core/values.js +45 -0
  34. package/dist/cjs/cyber-source/cyber-source.d.ts +95 -0
  35. package/dist/cjs/cyber-source/cyber-source.js +188 -0
  36. package/dist/cjs/cyber-source/index.d.ts +1 -0
  37. package/dist/cjs/cyber-source/index.js +7 -0
  38. package/dist/cjs/index.d.ts +7 -0
  39. package/dist/cjs/index.js +25 -0
  40. package/dist/cjs/kbz-pay/index.d.ts +2 -0
  41. package/dist/cjs/kbz-pay/index.js +8 -0
  42. package/dist/cjs/kbz-pay/kbz-pay.d.ts +102 -0
  43. package/dist/cjs/kbz-pay/kbz-pay.js +266 -0
  44. package/dist/cjs/kbz-pay/signer.d.ts +15 -0
  45. package/dist/cjs/kbz-pay/signer.js +36 -0
  46. package/dist/cjs/myanmar-payments.d.ts +50 -0
  47. package/dist/cjs/myanmar-payments.js +73 -0
  48. package/dist/cjs/package.json +3 -0
  49. package/dist/cjs/wave-money/index.d.ts +1 -0
  50. package/dist/cjs/wave-money/index.js +6 -0
  51. package/dist/cjs/wave-money/wave-money.d.ts +111 -0
  52. package/dist/cjs/wave-money/wave-money.js +251 -0
  53. package/dist/cjs/yoma-mmqr/index.d.ts +1 -0
  54. package/dist/cjs/yoma-mmqr/index.js +6 -0
  55. package/dist/cjs/yoma-mmqr/yoma-mmqr.d.ts +105 -0
  56. package/dist/cjs/yoma-mmqr/yoma-mmqr.js +233 -0
  57. package/dist/esm/aya-pay/aya-pay.d.ts +122 -0
  58. package/dist/esm/aya-pay/aya-pay.js +296 -0
  59. package/dist/esm/aya-pay/index.d.ts +1 -0
  60. package/dist/esm/aya-pay/index.js +1 -0
  61. package/dist/esm/core/amount.d.ts +57 -0
  62. package/dist/esm/core/amount.js +103 -0
  63. package/dist/esm/core/cache.d.ts +26 -0
  64. package/dist/esm/core/cache.js +31 -0
  65. package/dist/esm/core/callback.d.ts +180 -0
  66. package/dist/esm/core/callback.js +294 -0
  67. package/dist/esm/core/crypto.d.ts +19 -0
  68. package/dist/esm/core/crypto.js +41 -0
  69. package/dist/esm/core/env.d.ts +21 -0
  70. package/dist/esm/core/env.js +45 -0
  71. package/dist/esm/core/errors.d.ts +56 -0
  72. package/dist/esm/core/errors.js +70 -0
  73. package/dist/esm/core/http.d.ts +81 -0
  74. package/dist/esm/core/http.js +121 -0
  75. package/dist/esm/core/index.d.ts +8 -0
  76. package/dist/esm/core/index.js +7 -0
  77. package/dist/esm/core/json.d.ts +44 -0
  78. package/dist/esm/core/json.js +244 -0
  79. package/dist/esm/core/results.d.ts +122 -0
  80. package/dist/esm/core/results.js +139 -0
  81. package/dist/esm/core/status.d.ts +50 -0
  82. package/dist/esm/core/status.js +56 -0
  83. package/dist/esm/core/validate.d.ts +46 -0
  84. package/dist/esm/core/validate.js +142 -0
  85. package/dist/esm/core/values.d.ts +16 -0
  86. package/dist/esm/core/values.js +38 -0
  87. package/dist/esm/cyber-source/cyber-source.d.ts +95 -0
  88. package/dist/esm/cyber-source/cyber-source.js +184 -0
  89. package/dist/esm/cyber-source/index.d.ts +1 -0
  90. package/dist/esm/cyber-source/index.js +1 -0
  91. package/dist/esm/index.d.ts +7 -0
  92. package/dist/esm/index.js +7 -0
  93. package/dist/esm/kbz-pay/index.d.ts +2 -0
  94. package/dist/esm/kbz-pay/index.js +2 -0
  95. package/dist/esm/kbz-pay/kbz-pay.d.ts +102 -0
  96. package/dist/esm/kbz-pay/kbz-pay.js +262 -0
  97. package/dist/esm/kbz-pay/signer.d.ts +15 -0
  98. package/dist/esm/kbz-pay/signer.js +32 -0
  99. package/dist/esm/myanmar-payments.d.ts +50 -0
  100. package/dist/esm/myanmar-payments.js +69 -0
  101. package/dist/esm/wave-money/index.d.ts +1 -0
  102. package/dist/esm/wave-money/index.js +1 -0
  103. package/dist/esm/wave-money/wave-money.d.ts +111 -0
  104. package/dist/esm/wave-money/wave-money.js +246 -0
  105. package/dist/esm/yoma-mmqr/index.d.ts +1 -0
  106. package/dist/esm/yoma-mmqr/index.js +1 -0
  107. package/dist/esm/yoma-mmqr/yoma-mmqr.d.ts +105 -0
  108. package/dist/esm/yoma-mmqr/yoma-mmqr.js +229 -0
  109. package/package.json +151 -4
  110. package/skills/node-myanmar-payments/SKILL.md +109 -0
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KbzPay = exports.KbzPayConfig = void 0;
4
+ const callback_js_1 = require("../core/callback.js");
5
+ const crypto_js_1 = require("../core/crypto.js");
6
+ const env_js_1 = require("../core/env.js");
7
+ const errors_js_1 = require("../core/errors.js");
8
+ const http_js_1 = require("../core/http.js");
9
+ const json_js_1 = require("../core/json.js");
10
+ const results_js_1 = require("../core/results.js");
11
+ const status_js_1 = require("../core/status.js");
12
+ const validate_js_1 = require("../core/validate.js");
13
+ const values_js_1 = require("../core/values.js");
14
+ const signer_js_1 = require("./signer.js");
15
+ /**
16
+ * KBZ Pay credentials and endpoints. A missing credential throws a `ConfigurationError`.
17
+ */
18
+ class KbzPayConfig {
19
+ static SANDBOX_API_URL = 'http://api-uat.kbzpay.com/payment/gateway/uat';
20
+ static PRODUCTION_API_URL = 'https://api.kbzpay.com/payment/gateway';
21
+ static SANDBOX_PWA_URL = 'https://static.kbzpay.com/pgw/uat/pwa/#/';
22
+ static PRODUCTION_PWA_URL = 'https://wap.kbzpay.com/pgw/pwa/#/';
23
+ appId;
24
+ appKey;
25
+ merchantCode;
26
+ sandbox;
27
+ /** The API base URL in use. */
28
+ apiUrl;
29
+ /** The PWA checkout URL in use, always ending in `/`. */
30
+ pwaUrl;
31
+ constructor(options) {
32
+ this.appId = (0, env_js_1.requireSetting)('kbz_pay', 'app_id', options.appId);
33
+ this.appKey = (0, env_js_1.requireSetting)('kbz_pay', 'app_key', options.appKey);
34
+ this.merchantCode = (0, env_js_1.requireSetting)('kbz_pay', 'merchant_code', options.merchantCode);
35
+ this.sandbox = options.sandbox ?? true;
36
+ this.apiUrl = (0, env_js_1.trimUrl)((0, env_js_1.optionalSetting)(options.apiUrl) ??
37
+ (this.sandbox ? KbzPayConfig.SANDBOX_API_URL : KbzPayConfig.PRODUCTION_API_URL));
38
+ this.pwaUrl = `${(0, env_js_1.trimUrl)((0, env_js_1.optionalSetting)(options.pwaUrl) ??
39
+ (this.sandbox ? KbzPayConfig.SANDBOX_PWA_URL : KbzPayConfig.PRODUCTION_PWA_URL))}/`;
40
+ }
41
+ /**
42
+ * Reads `KBZ_PAY_APP_ID`, `KBZ_PAY_APP_KEY`, `KBZ_PAY_MERCHANT_CODE`, `KBZ_PAY_SANDBOX`,
43
+ * `KBZ_PAY_BASE_URL` and `KBZ_PAY_PWA_BASE_REDIRECT_URL`.
44
+ */
45
+ static fromEnv(env = (0, env_js_1.defaultEnv)()) {
46
+ return new KbzPayConfig({
47
+ appId: (0, env_js_1.envFirst)(env, 'KBZ_PAY_APP_ID'),
48
+ appKey: (0, env_js_1.envFirst)(env, 'KBZ_PAY_APP_KEY'),
49
+ merchantCode: (0, env_js_1.envFirst)(env, 'KBZ_PAY_MERCHANT_CODE'),
50
+ sandbox: (0, env_js_1.envSandbox)(env, 'KBZ_PAY_SANDBOX'),
51
+ apiUrl: (0, env_js_1.envFirst)(env, 'KBZ_PAY_BASE_URL'),
52
+ pwaUrl: (0, env_js_1.envFirst)(env, 'KBZ_PAY_PWA_BASE_REDIRECT_URL'),
53
+ });
54
+ }
55
+ }
56
+ exports.KbzPayConfig = KbzPayConfig;
57
+ const ORDER_ID = /^[A-Za-z0-9_]+$/;
58
+ const STATUSES = {
59
+ PAY_SUCCESS: 'successful',
60
+ WAIT_PAY: 'pending',
61
+ PAYING: 'pending',
62
+ PAY_FAILED: 'failed',
63
+ ORDER_CLOSED: 'cancelled',
64
+ ORDER_EXPIRED: 'expired',
65
+ };
66
+ /**
67
+ * KBZ Pay: PWA (redirect), QR and in-app payments, order status queries and payment
68
+ * notifications.
69
+ */
70
+ class KbzPay {
71
+ /** The configuration in use. */
72
+ config;
73
+ /** KBZ Pay's request signer, for custom calls. */
74
+ signer;
75
+ transport;
76
+ constructor(config, options = {}) {
77
+ this.config = config instanceof KbzPayConfig ? config : new KbzPayConfig(config);
78
+ this.signer = new signer_js_1.KbzPaySigner(this.config.appKey);
79
+ this.transport = new http_js_1.Transport((0, http_js_1.httpClientFrom)(options));
80
+ }
81
+ /** A gateway configured from the `KBZ_PAY_*` environment variables. */
82
+ static fromEnv(env = (0, env_js_1.defaultEnv)(), options = {}) {
83
+ return new KbzPay(KbzPayConfig.fromEnv(env), options);
84
+ }
85
+ /** Checks the order against KBZ's documented limits; throws an `InvalidPaymentDataError`. */
86
+ static validate(data) {
87
+ const callbackUrl = typeof data.callbackUrl === 'string' ? data.callbackUrl : '';
88
+ new validate_js_1.Validator()
89
+ .required('orderId', data.orderId)
90
+ .max('orderId', data.orderId, 40)
91
+ .pattern('orderId', data.orderId, ORDER_ID, 'letters, numbers and underscores')
92
+ .amount('amount', data.amount, { gateway: 'KBZ Pay', maxDecimals: 2 })
93
+ .required('callbackUrl', data.callbackUrl)
94
+ .url('callbackUrl', callbackUrl)
95
+ .max('callbackUrl', callbackUrl, 512)
96
+ .when(callbackUrl.includes('?'), 'callbackUrl', 'The callbackUrl field must not contain a query string.')
97
+ .string('title', data.title)
98
+ .between('timeoutMinutes', data.timeoutMinutes, 1, 120)
99
+ .string('callbackInfo', data.callbackInfo)
100
+ .max('callbackInfo', typeof data.callbackInfo === 'string' ? (0, crypto_js_1.queryEscape)(data.callbackInfo) : undefined, 512)
101
+ .validate();
102
+ }
103
+ /**
104
+ * Creates an order and returns the KBZ Pay PWA checkout URL to redirect the customer to.
105
+ *
106
+ * The redirect only works on a phone with the KBZ Pay app installed, and its Referer must match
107
+ * the URL registered with KBZ.
108
+ */
109
+ async pwa(data, options = {}) {
110
+ const order = await this.precreate(data, 'PWAAPP', options);
111
+ const fields = this.orderInfoFields(order);
112
+ return new results_js_1.RedirectPayment({
113
+ orderId: data.orderId,
114
+ url: `${this.config.pwaUrl}?${this.signer.signString(fields)}&sign=${this.signer.sign(fields)}`,
115
+ gatewayReference: order.prepayId,
116
+ raw: (0, json_js_1.toPlainObject)(order.response),
117
+ });
118
+ }
119
+ /** Creates an order and returns a QR payload for the customer to scan with the KBZ Pay app. */
120
+ async qr(data, options = {}) {
121
+ const order = await this.precreate(data, 'PAY_BY_QRCODE', options);
122
+ const qrCode = (0, values_js_1.get)(order.response, 'qrCode');
123
+ if (qrCode === '') {
124
+ throw new errors_js_1.ApiError('KBZ Pay did not return a QR code.', {
125
+ raw: (0, json_js_1.toPlainObject)(order.response),
126
+ });
127
+ }
128
+ return new results_js_1.QrPayment({
129
+ orderId: data.orderId,
130
+ qrString: qrCode,
131
+ expiresAt: data.timeoutMinutes === undefined
132
+ ? undefined
133
+ : new Date(Date.now() + data.timeoutMinutes * 60_000),
134
+ reference: order.prepayId,
135
+ raw: (0, json_js_1.toPlainObject)(order.response),
136
+ });
137
+ }
138
+ /**
139
+ * Creates an order and returns the signed values your mobile app passes to `KBZPay.startPay()`.
140
+ * The SDK's own result only means the payment screen closed; rely on the callback or `status()`.
141
+ */
142
+ async app(data, options = {}) {
143
+ const order = await this.precreate(data, 'APP', options);
144
+ const fields = this.orderInfoFields(order);
145
+ return new results_js_1.AppPayment({
146
+ orderId: data.orderId,
147
+ orderInfo: this.signer.signString(fields),
148
+ sign: this.signer.sign(fields),
149
+ signType: 'SHA256',
150
+ raw: (0, json_js_1.toPlainObject)(order.response),
151
+ });
152
+ }
153
+ /** Asks KBZ Pay for the current state of an order (`queryorder`). */
154
+ async status(orderId, options = {}) {
155
+ const response = await this.call('queryorder', 'kbz.payment.queryorder', '3.0', {
156
+ appid: this.config.appId,
157
+ merch_code: this.config.merchantCode,
158
+ merch_order_id: orderId,
159
+ }, {}, (0, crypto_js_1.randomHex)(), timestamp(), options.signal);
160
+ const tradeStatus = (0, values_js_1.trimmed)(response, 'trade_status');
161
+ return new callback_js_1.PaymentStatusResult({
162
+ orderId: (0, values_js_1.optional)(response, 'merch_order_id') || orderId,
163
+ status: (0, status_js_1.resolveStatus)(STATUSES, tradeStatus),
164
+ gatewayStatus: tradeStatus,
165
+ gatewayReference: (0, values_js_1.optional)(response, 'mm_order_id'),
166
+ amount: (0, values_js_1.optional)(response, 'total_amount'),
167
+ raw: (0, json_js_1.toPlainObject)(response),
168
+ });
169
+ }
170
+ /**
171
+ * Verifies KBZ Pay's payment notification. Reply with the callback's `acknowledgement` (plain
172
+ * `success`) or KBZ retries.
173
+ */
174
+ handleCallback(request) {
175
+ const input = (0, callback_js_1.losslessBody)(request);
176
+ const fields = (0, values_js_1.object)(input, 'Request') ?? input;
177
+ if (!this.signer.verify(fields)) {
178
+ throw new errors_js_1.SignatureVerificationError('KBZ Pay callback signature verification failed.', (0, json_js_1.toPlainObject)(input));
179
+ }
180
+ const tradeStatus = (0, values_js_1.trimmed)(fields, 'trade_status');
181
+ return new callback_js_1.PaymentCallback({
182
+ orderId: (0, values_js_1.get)(fields, 'merch_order_id'),
183
+ status: (0, status_js_1.resolveStatus)(STATUSES, tradeStatus),
184
+ gatewayStatus: tradeStatus,
185
+ gatewayReference: (0, values_js_1.optional)(fields, 'mm_order_id'),
186
+ amount: (0, values_js_1.optional)(fields, 'total_amount'),
187
+ raw: (0, json_js_1.toPlainObject)(fields),
188
+ acknowledgement: new callback_js_1.Acknowledgement({ body: 'success' }),
189
+ });
190
+ }
191
+ async precreate(data, tradeType, options) {
192
+ KbzPay.validate(data);
193
+ const biz = {
194
+ appid: this.config.appId,
195
+ merch_code: this.config.merchantCode,
196
+ merch_order_id: data.orderId,
197
+ trade_type: tradeType,
198
+ total_amount: String((0, validate_js_1.toAmount)(data.amount)),
199
+ trans_currency: 'MMK',
200
+ };
201
+ if (data.title) {
202
+ biz.title = data.title;
203
+ }
204
+ if (data.timeoutMinutes !== undefined) {
205
+ biz.timeout_express = `${data.timeoutMinutes}m`;
206
+ }
207
+ if (data.callbackInfo) {
208
+ biz.callback_info = (0, crypto_js_1.queryEscape)(data.callbackInfo);
209
+ }
210
+ const nonce = (0, crypto_js_1.randomHex)();
211
+ const time = timestamp();
212
+ const response = await this.call('precreate', 'kbz.payment.precreate', '1.0', biz, { notify_url: data.callbackUrl }, nonce, time, options.signal);
213
+ const prepayId = (0, values_js_1.get)(response, 'prepay_id');
214
+ if (prepayId === '') {
215
+ throw new errors_js_1.ApiError('KBZ Pay did not return a prepay_id.', { raw: (0, json_js_1.toPlainObject)(response) });
216
+ }
217
+ return { prepayId, nonce, timestamp: time, response };
218
+ }
219
+ /** Sends a signed request and returns the `Response` object, throwing when KBZ reports an error. */
220
+ async call(endpoint, method, version, biz, extra, nonce, time, signal) {
221
+ const common = {
222
+ timestamp: time,
223
+ method,
224
+ nonce_str: nonce,
225
+ version,
226
+ ...extra,
227
+ };
228
+ const request = {
229
+ ...common,
230
+ sign_type: 'SHA256',
231
+ sign: this.signer.sign({ ...common, ...biz }),
232
+ biz_content: biz,
233
+ };
234
+ const response = await this.transport.postJson(`${this.config.apiUrl}/${endpoint}`, { Request: request }, {}, signal);
235
+ const body = response.json();
236
+ const result = (0, values_js_1.object)(body, 'Response') ?? {};
237
+ if (!response.successful() ||
238
+ (0, values_js_1.get)(result, 'result') !== 'SUCCESS' ||
239
+ (0, values_js_1.get)(result, 'code') !== '0') {
240
+ const code = (0, values_js_1.optional)(result, 'code');
241
+ const message = (0, values_js_1.optional)(result, 'msg');
242
+ throw new errors_js_1.ApiError(code
243
+ ? `KBZ Pay ${endpoint} failed: [${code}] ${message ?? ''}`.trimEnd()
244
+ : `KBZ Pay ${endpoint} failed with HTTP ${response.status}.`, {
245
+ gatewayCode: code,
246
+ gatewayMessage: message,
247
+ httpStatus: response.status,
248
+ raw: (0, json_js_1.toPlainObject)(body),
249
+ });
250
+ }
251
+ return result;
252
+ }
253
+ orderInfoFields(order) {
254
+ return {
255
+ appid: this.config.appId,
256
+ merch_code: this.config.merchantCode,
257
+ nonce_str: order.nonce,
258
+ prepay_id: order.prepayId,
259
+ timestamp: order.timestamp,
260
+ };
261
+ }
262
+ }
263
+ exports.KbzPay = KbzPay;
264
+ function timestamp() {
265
+ return String(Math.floor(Date.now() / 1000));
266
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * KBZ Pay's signature: every non-empty scalar field except `sign` and `sign_type`, sorted by key,
3
+ * joined as raw `key=value` pairs (not URL-encoded), with `&key=<app key>` appended, hashed with
4
+ * SHA-256 and uppercased.
5
+ */
6
+ export declare class KbzPaySigner {
7
+ private readonly appKey;
8
+ constructor(appKey: string);
9
+ /** The sorted `key=value` string, without the app key. */
10
+ signString(fields: Readonly<Record<string, unknown>>): string;
11
+ /** The uppercase SHA-256 signature of `fields`. */
12
+ sign(fields: Readonly<Record<string, unknown>>): string;
13
+ /** Whether `fields.sign` matches, compared in constant time. */
14
+ verify(fields: Readonly<Record<string, unknown>>): boolean;
15
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KbzPaySigner = void 0;
4
+ const crypto_js_1 = require("../core/crypto.js");
5
+ const values_js_1 = require("../core/values.js");
6
+ /**
7
+ * KBZ Pay's signature: every non-empty scalar field except `sign` and `sign_type`, sorted by key,
8
+ * joined as raw `key=value` pairs (not URL-encoded), with `&key=<app key>` appended, hashed with
9
+ * SHA-256 and uppercased.
10
+ */
11
+ class KbzPaySigner {
12
+ appKey;
13
+ constructor(appKey) {
14
+ this.appKey = appKey;
15
+ }
16
+ /** The sorted `key=value` string, without the app key. */
17
+ signString(fields) {
18
+ return Object.keys(fields)
19
+ .filter((key) => key !== 'sign' && key !== 'sign_type')
20
+ .map((key) => [key, (0, values_js_1.scalarString)(fields[key])])
21
+ .filter((pair) => pair[1] !== undefined && pair[1] !== '')
22
+ .sort(([a], [b]) => (a < b ? -1 : 1))
23
+ .map(([key, value]) => `${key}=${value}`)
24
+ .join('&');
25
+ }
26
+ /** The uppercase SHA-256 signature of `fields`. */
27
+ sign(fields) {
28
+ return (0, crypto_js_1.sha256Hex)(`${this.signString(fields)}&key=${this.appKey}`).toUpperCase();
29
+ }
30
+ /** Whether `fields.sign` matches, compared in constant time. */
31
+ verify(fields) {
32
+ const sign = fields.sign;
33
+ return typeof sign === 'string' && (0, crypto_js_1.safeEqual)(this.sign(fields), sign.toUpperCase());
34
+ }
35
+ }
36
+ exports.KbzPaySigner = KbzPaySigner;
@@ -0,0 +1,50 @@
1
+ import { AyaPay, AyaPayConfig, type AyaPayConfigOptions } from './aya-pay/aya-pay.js';
2
+ import type { TokenCache } from './core/cache.js';
3
+ import { type EnvSource } from './core/env.js';
4
+ import type { GatewayOptions } from './core/http.js';
5
+ import { CyberSource, CyberSourceConfig, type CyberSourceConfigOptions } from './cyber-source/cyber-source.js';
6
+ import { KbzPay, KbzPayConfig, type KbzPayConfigOptions } from './kbz-pay/kbz-pay.js';
7
+ import { WaveMoney, WaveMoneyConfig, type WaveMoneyConfigOptions } from './wave-money/wave-money.js';
8
+ import { YomaMmqr, YomaMmqrConfig, type YomaMmqrConfigOptions } from './yoma-mmqr/yoma-mmqr.js';
9
+ /** The configuration of every gateway; configure only the ones you use. */
10
+ export interface MyanmarPaymentsConfig {
11
+ kbzPay?: KbzPayConfig | KbzPayConfigOptions | undefined;
12
+ waveMoney?: WaveMoneyConfig | WaveMoneyConfigOptions | undefined;
13
+ ayaPay?: AyaPayConfig | AyaPayConfigOptions | undefined;
14
+ yomaMmqr?: YomaMmqrConfig | YomaMmqrConfigOptions | undefined;
15
+ cyberSource?: CyberSourceConfig | CyberSourceConfigOptions | undefined;
16
+ }
17
+ /** Options shared by every gateway the facade builds. */
18
+ export interface MyanmarPaymentsOptions extends GatewayOptions {
19
+ /** Keeps Yoma MMQR's access token; defaults to a {@link MemoryTokenCache}. */
20
+ tokenCache?: TokenCache | undefined;
21
+ }
22
+ /**
23
+ * Builds each gateway from one configuration object (or the environment). Gateways are created
24
+ * on first use and reused, so only the gateways you call need to be configured.
25
+ */
26
+ export declare class MyanmarPayments {
27
+ private kbzPayGateway;
28
+ private waveMoneyGateway;
29
+ private ayaPayGateway;
30
+ private yomaMmqrGateway;
31
+ private cyberSourceGateway;
32
+ private readonly options;
33
+ private readonly sources;
34
+ constructor(config?: MyanmarPaymentsConfig, options?: MyanmarPaymentsOptions);
35
+ /**
36
+ * Reads every gateway's configuration from environment variables (`KBZ_PAY_*`, `WAVE_MONEY_*`,
37
+ * `AYA_PAY_*`, `YOMA_MMQR_*`, `CYBER_SOURCE_*`) when the gateway is first used.
38
+ */
39
+ static fromEnv(env?: EnvSource, options?: MyanmarPaymentsOptions): MyanmarPayments;
40
+ /** The KBZ Pay gateway. Throws a `ConfigurationError` when it is not configured. */
41
+ kbzPay(): KbzPay;
42
+ /** The Wave Money gateway. Throws a `ConfigurationError` when it is not configured. */
43
+ waveMoney(): WaveMoney;
44
+ /** The AYA Payment Gateway. Throws a `ConfigurationError` when it is not configured. */
45
+ ayaPay(): AyaPay;
46
+ /** The Yoma MMQR gateway. Throws a `ConfigurationError` when it is not configured. */
47
+ yomaMmqr(): YomaMmqr;
48
+ /** The CyberSource gateway. Throws a `ConfigurationError` when it is not configured. */
49
+ cyberSource(): CyberSource;
50
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MyanmarPayments = void 0;
4
+ const aya_pay_js_1 = require("./aya-pay/aya-pay.js");
5
+ const cache_js_1 = require("./core/cache.js");
6
+ const env_js_1 = require("./core/env.js");
7
+ const errors_js_1 = require("./core/errors.js");
8
+ const cyber_source_js_1 = require("./cyber-source/cyber-source.js");
9
+ const kbz_pay_js_1 = require("./kbz-pay/kbz-pay.js");
10
+ const wave_money_js_1 = require("./wave-money/wave-money.js");
11
+ const yoma_mmqr_js_1 = require("./yoma-mmqr/yoma-mmqr.js");
12
+ /**
13
+ * Builds each gateway from one configuration object (or the environment). Gateways are created
14
+ * on first use and reused, so only the gateways you call need to be configured.
15
+ */
16
+ class MyanmarPayments {
17
+ kbzPayGateway;
18
+ waveMoneyGateway;
19
+ ayaPayGateway;
20
+ yomaMmqrGateway;
21
+ cyberSourceGateway;
22
+ options;
23
+ sources;
24
+ constructor(config = {}, options = {}) {
25
+ this.options = { ...options, tokenCache: options.tokenCache ?? new cache_js_1.MemoryTokenCache() };
26
+ this.sources = { ...config };
27
+ }
28
+ /**
29
+ * Reads every gateway's configuration from environment variables (`KBZ_PAY_*`, `WAVE_MONEY_*`,
30
+ * `AYA_PAY_*`, `YOMA_MMQR_*`, `CYBER_SOURCE_*`) when the gateway is first used.
31
+ */
32
+ static fromEnv(env = (0, env_js_1.defaultEnv)(), options = {}) {
33
+ const payments = new MyanmarPayments({}, options);
34
+ Object.assign(payments.sources, {
35
+ kbzPay: () => kbz_pay_js_1.KbzPayConfig.fromEnv(env),
36
+ waveMoney: () => wave_money_js_1.WaveMoneyConfig.fromEnv(env),
37
+ ayaPay: () => aya_pay_js_1.AyaPayConfig.fromEnv(env),
38
+ yomaMmqr: () => yoma_mmqr_js_1.YomaMmqrConfig.fromEnv(env),
39
+ cyberSource: () => cyber_source_js_1.CyberSourceConfig.fromEnv(env),
40
+ });
41
+ return payments;
42
+ }
43
+ /** The KBZ Pay gateway. Throws a `ConfigurationError` when it is not configured. */
44
+ kbzPay() {
45
+ return (this.kbzPayGateway ??= new kbz_pay_js_1.KbzPay(resolve(this.sources.kbzPay, kbz_pay_js_1.KbzPayConfig, 'kbz_pay', 'app_id'), this.options));
46
+ }
47
+ /** The Wave Money gateway. Throws a `ConfigurationError` when it is not configured. */
48
+ waveMoney() {
49
+ return (this.waveMoneyGateway ??= new wave_money_js_1.WaveMoney(resolve(this.sources.waveMoney, wave_money_js_1.WaveMoneyConfig, 'wave_money', 'merchant_id'), this.options));
50
+ }
51
+ /** The AYA Payment Gateway. Throws a `ConfigurationError` when it is not configured. */
52
+ ayaPay() {
53
+ return (this.ayaPayGateway ??= new aya_pay_js_1.AyaPay(resolve(this.sources.ayaPay, aya_pay_js_1.AyaPayConfig, 'aya_pay', 'app_key'), this.options));
54
+ }
55
+ /** The Yoma MMQR gateway. Throws a `ConfigurationError` when it is not configured. */
56
+ yomaMmqr() {
57
+ return (this.yomaMmqrGateway ??= new yoma_mmqr_js_1.YomaMmqr(resolve(this.sources.yomaMmqr, yoma_mmqr_js_1.YomaMmqrConfig, 'yoma_mmqr', 'merchant_id'), this.options));
58
+ }
59
+ /** The CyberSource gateway. Throws a `ConfigurationError` when it is not configured. */
60
+ cyberSource() {
61
+ return (this.cyberSourceGateway ??= new cyber_source_js_1.CyberSource(resolve(this.sources.cyberSource, cyber_source_js_1.CyberSourceConfig, 'cyber_source', 'profile_id')));
62
+ }
63
+ }
64
+ exports.MyanmarPayments = MyanmarPayments;
65
+ function resolve(source, type, gateway, firstKey) {
66
+ if (source === undefined || source === null) {
67
+ throw new errors_js_1.ConfigurationError(gateway, firstKey);
68
+ }
69
+ if (typeof source === 'function') {
70
+ return source();
71
+ }
72
+ return source instanceof type ? source : new type(source);
73
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1 @@
1
+ export { WaveMoney, WaveMoneyConfig, type WaveMoneyConfigOptions, type WaveMoneyItem, type WaveMoneyPaymentData, } from './wave-money.js';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaveMoneyConfig = exports.WaveMoney = void 0;
4
+ var wave_money_js_1 = require("./wave-money.js");
5
+ Object.defineProperty(exports, "WaveMoney", { enumerable: true, get: function () { return wave_money_js_1.WaveMoney; } });
6
+ Object.defineProperty(exports, "WaveMoneyConfig", { enumerable: true, get: function () { return wave_money_js_1.WaveMoneyConfig; } });
@@ -0,0 +1,111 @@
1
+ import { Amount, type AmountInput } from '../core/amount.js';
2
+ import { CallbackRequest, PaymentCallback } from '../core/callback.js';
3
+ import { type EnvSource } from '../core/env.js';
4
+ import { type GatewayOptions, type RequestOptions } from '../core/http.js';
5
+ import { RedirectPayment } from '../core/results.js';
6
+ /** The settings of {@link WaveMoneyConfig}. */
7
+ export interface WaveMoneyConfigOptions {
8
+ /** The merchant id Wave issued. */
9
+ merchantId: string;
10
+ /** The hash secret key Wave issued. */
11
+ secretKey: string;
12
+ /** Your business name, shown on Wave's payment page. */
13
+ merchantName: string;
14
+ /** How long the customer has to pay, in seconds (default 300). */
15
+ timeToLiveSeconds?: number | undefined;
16
+ /** Use the test environment (default `true`). */
17
+ sandbox?: boolean | undefined;
18
+ /** Overrides the API base URL. */
19
+ baseUrl?: string | undefined;
20
+ /** Overrides the host the customer is redirected to. Wave serves it without the API port. */
21
+ authenticateUrl?: string | undefined;
22
+ }
23
+ /**
24
+ * Wave Money credentials and endpoints. A missing credential throws a `ConfigurationError`.
25
+ */
26
+ export declare class WaveMoneyConfig {
27
+ static readonly SANDBOX_URL = "https://preprodpayments.wavemoney.io:8107";
28
+ static readonly PRODUCTION_URL = "https://payments.wavemoney.io";
29
+ static readonly SANDBOX_AUTHENTICATE_URL = "https://preprodpayments.wavemoney.io";
30
+ static readonly PRODUCTION_AUTHENTICATE_URL = "https://payments.wavemoney.io";
31
+ static readonly DEFAULT_TIME_TO_LIVE_SECONDS = 300;
32
+ readonly merchantId: string;
33
+ readonly secretKey: string;
34
+ readonly merchantName: string;
35
+ /** Seconds the customer has to pay. */
36
+ readonly timeToLiveSeconds: number;
37
+ readonly sandbox: boolean;
38
+ /** The API base URL in use. */
39
+ readonly baseUrl: string;
40
+ /** The host the customer is redirected to. */
41
+ readonly authenticateUrl: string;
42
+ constructor(options: WaveMoneyConfigOptions);
43
+ /**
44
+ * Reads `WAVE_MONEY_MERCHANT_ID`, `WAVE_MONEY_SECRET_KEY`, `WAVE_MONEY_MERCHANT_NAME` (falling back
45
+ * to `APP_NAME`), `WAVE_MONEY_TIME_TO_LIVE_IN_SECONDS`, `WAVE_MONEY_SANDBOX`, `WAVE_MONEY_BASE_URL`
46
+ * and `WAVE_MONEY_AUTHENTICATE_URL`.
47
+ */
48
+ static fromEnv(env?: EnvSource): WaveMoneyConfig;
49
+ }
50
+ /** A line item shown on Wave's payment page. */
51
+ export interface WaveMoneyItem {
52
+ /** The item name. */
53
+ name: string;
54
+ /** The item amount in whole kyat, e.g. `Amount.kyat(1000)` or `1000`. */
55
+ amount: AmountInput;
56
+ }
57
+ /**
58
+ * A Wave Money payment request. Wave only accepts whole kyat (MMK).
59
+ */
60
+ export interface WaveMoneyPaymentData {
61
+ /** Your order id. One order can have several payment attempts. */
62
+ orderId: string;
63
+ /** The URL Wave posts the result to (`backend_result_url`). */
64
+ callbackUrl: string;
65
+ /** Where Wave sends the customer back (`frontend_result_url`). Not proof of payment. */
66
+ returnUrl: string;
67
+ /** Shown to the customer. */
68
+ description: string;
69
+ /** The line items shown on Wave's page; at least one. */
70
+ items: readonly WaveMoneyItem[];
71
+ /** The total in whole kyat. Leave it unset to charge the sum of the items. */
72
+ amount?: AmountInput | undefined;
73
+ /**
74
+ * The unique id of this attempt; Wave rejects a reused one. `initiate()` fills it with a random
75
+ * id when empty, so store it afterwards: Wave's callback may omit `orderId` but always carries
76
+ * this.
77
+ */
78
+ merchantReferenceId?: string | undefined;
79
+ }
80
+ /**
81
+ * Wave Money (WavePay payment gateway): redirect payments and callbacks. Wave has no status API,
82
+ * so the callback is the only result.
83
+ */
84
+ export declare class WaveMoney {
85
+ /** The configuration in use. */
86
+ readonly config: WaveMoneyConfig;
87
+ private readonly transport;
88
+ constructor(config: WaveMoneyConfig | WaveMoneyConfigOptions, options?: GatewayOptions);
89
+ /** A gateway configured from the `WAVE_MONEY_*` environment variables. */
90
+ static fromEnv(env?: EnvSource, options?: GatewayOptions): WaveMoney;
91
+ /**
92
+ * The total that will be charged: `amount`, or the exact sum of the items when it is unset.
93
+ * `undefined` when an item amount is missing, malformed or has decimals.
94
+ */
95
+ static resolvedAmount(data: Pick<WaveMoneyPaymentData, 'amount' | 'items'>): Amount | undefined;
96
+ /** Checks the request against Wave's documented rules; throws an `InvalidPaymentDataError`. */
97
+ static validate(data: WaveMoneyPaymentData): void;
98
+ /**
99
+ * Creates a payment request and returns Wave's page to redirect the customer to. Once `data`
100
+ * passes validation it fills `data.merchantReferenceId` with a random id when empty, so store it
101
+ * afterwards. Invalid data is left untouched.
102
+ */
103
+ initiate(data: WaveMoneyPaymentData, options?: RequestOptions): Promise<RedirectPayment>;
104
+ /**
105
+ * Verifies Wave's callback. Only `PAYMENT_CONFIRMED` means the customer paid. `orderId` falls
106
+ * back to `merchantReferenceId` when it is missing, null or empty, because Wave marks `orderId` as
107
+ * optional.
108
+ */
109
+ handleCallback(request: CallbackRequest): PaymentCallback;
110
+ private hash;
111
+ }