@laranex/myanmar-payments 4.0.0-dev.3 → 4.0.0-dev.5
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/CHANGELOG.md +10 -3
- package/dist/cjs/aya-pay/aya-pay.d.ts +12 -9
- package/dist/cjs/aya-pay/aya-pay.js +14 -11
- package/dist/cjs/core/amount.d.ts +4 -3
- package/dist/cjs/core/amount.js +13 -4
- package/dist/cjs/core/callback.d.ts +7 -2
- package/dist/cjs/core/callback.js +14 -7
- package/dist/cjs/core/crypto.d.ts +6 -1
- package/dist/cjs/core/crypto.js +17 -3
- package/dist/cjs/core/env.d.ts +5 -5
- package/dist/cjs/core/env.js +21 -12
- package/dist/cjs/core/errors.d.ts +8 -3
- package/dist/cjs/core/errors.js +11 -4
- package/dist/cjs/core/http.d.ts +10 -11
- package/dist/cjs/core/http.js +7 -9
- package/dist/cjs/core/index.d.ts +1 -1
- package/dist/cjs/core/index.js +1 -2
- package/dist/cjs/core/json.d.ts +2 -2
- package/dist/cjs/core/json.js +3 -3
- package/dist/cjs/core/values.d.ts +2 -0
- package/dist/cjs/core/values.js +5 -0
- package/dist/cjs/cyber-source/cyber-source.d.ts +10 -13
- package/dist/cjs/cyber-source/cyber-source.js +13 -14
- package/dist/cjs/kbz-pay/kbz-pay.d.ts +12 -9
- package/dist/cjs/kbz-pay/kbz-pay.js +11 -13
- package/dist/cjs/kbz-pay/signer.d.ts +4 -1
- package/dist/cjs/kbz-pay/signer.js +7 -2
- package/dist/cjs/wave-money/wave-money.d.ts +15 -13
- package/dist/cjs/wave-money/wave-money.js +18 -25
- package/dist/cjs/yoma-mmqr/yoma-mmqr.d.ts +16 -13
- package/dist/cjs/yoma-mmqr/yoma-mmqr.js +21 -19
- package/dist/esm/aya-pay/aya-pay.d.ts +12 -9
- package/dist/esm/aya-pay/aya-pay.js +16 -13
- package/dist/esm/core/amount.d.ts +4 -3
- package/dist/esm/core/amount.js +13 -4
- package/dist/esm/core/callback.d.ts +7 -2
- package/dist/esm/core/callback.js +14 -7
- package/dist/esm/core/crypto.d.ts +6 -1
- package/dist/esm/core/crypto.js +17 -3
- package/dist/esm/core/env.d.ts +5 -5
- package/dist/esm/core/env.js +19 -10
- package/dist/esm/core/errors.d.ts +8 -3
- package/dist/esm/core/errors.js +11 -4
- package/dist/esm/core/http.d.ts +10 -11
- package/dist/esm/core/http.js +6 -8
- package/dist/esm/core/index.d.ts +1 -1
- package/dist/esm/core/index.js +1 -1
- package/dist/esm/core/json.d.ts +2 -2
- package/dist/esm/core/json.js +3 -3
- package/dist/esm/core/values.d.ts +2 -0
- package/dist/esm/core/values.js +4 -0
- package/dist/esm/cyber-source/cyber-source.d.ts +10 -13
- package/dist/esm/cyber-source/cyber-source.js +14 -15
- package/dist/esm/kbz-pay/kbz-pay.d.ts +12 -9
- package/dist/esm/kbz-pay/kbz-pay.js +12 -14
- package/dist/esm/kbz-pay/signer.d.ts +4 -1
- package/dist/esm/kbz-pay/signer.js +8 -3
- package/dist/esm/wave-money/wave-money.d.ts +15 -13
- package/dist/esm/wave-money/wave-money.js +20 -27
- package/dist/esm/yoma-mmqr/yoma-mmqr.d.ts +16 -13
- package/dist/esm/yoma-mmqr/yoma-mmqr.js +23 -21
- package/package.json +1 -1
- package/skills/node-myanmar-payments/SKILL.md +24 -21
|
@@ -11,7 +11,7 @@ metadata:
|
|
|
11
11
|
|
|
12
12
|
## When to use
|
|
13
13
|
|
|
14
|
-
Use this skill when a Node.js or TypeScript app takes payments through KBZ Pay, Wave Money, AYA Payment Gateway, Yoma MMQR or CyberSource. Start payments and verify callbacks with the package's typed API; never build gateway signatures by hand.
|
|
14
|
+
Use this skill when a Node.js or TypeScript app takes payments through KBZ Pay, Wave Money, AYA Payment Gateway, Yoma MMQR or CyberSource. Start payments and verify callbacks with the package's typed API; never build gateway signatures by hand. In NestJS, use `@laranex/nestjs-myanmar-payments` instead; it wraps this package.
|
|
15
15
|
|
|
16
16
|
## Install
|
|
17
17
|
|
|
@@ -19,11 +19,11 @@ Use this skill when a Node.js or TypeScript app takes payments through KBZ Pay,
|
|
|
19
19
|
npm install @laranex/myanmar-payments
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Requires Node.js 20+ and has no runtime dependencies (global `fetch`, `node:crypto`)
|
|
22
|
+
Requires Node.js 20+ and has no runtime dependencies (global `fetch`, `node:crypto`); it ships ESM and CommonJS with types. Import shared types from the root and each gateway from the root or its subpath: `@laranex/myanmar-payments/kbz-pay`, `/wave-money`, `/aya-pay`, `/yoma-mmqr` and `/cyber-source`.
|
|
23
23
|
|
|
24
24
|
## Configure
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
`MyanmarPayments.fromEnv(process.env)` reads `KBZ_PAY_*`, `WAVE_MONEY_*`, `AYA_PAY_*` (or `AYA_PGW_*`), `YOMA_MMQR_*` and `CYBER_SOURCE_*` plus `MYANMAR_PAYMENTS_HTTP_TIMEOUT` (the same variables as the PHP, Go and Python SDKs). Every gateway defaults to its production URLs; to test against UAT, set the URL overrides (`KBZ_PAY_BASE_URL`, `KBZ_PAY_PWA_BASE_REDIRECT_URL`, `WAVE_MONEY_BASE_URL`, `WAVE_MONEY_AUTHENTICATE_URL`, `AYA_PAY_BASE_URL`, `YOMA_MMQR_BASE_URL`, `CYBER_SOURCE_BASE_URL`) to the gateway's UAT URLs. Every other setting is required, with no defaults: credentials, `timeoutSeconds` (seconds, for every gateway except CyberSource), Wave's `merchantName` and `timeToLiveSeconds`, and Yoma's `apiVersion` (e.g. `v1rc`).
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
29
|
import { MyanmarPayments } from '@laranex/myanmar-payments';
|
|
@@ -32,18 +32,21 @@ const payments = MyanmarPayments.fromEnv(process.env); // create once, share acr
|
|
|
32
32
|
const kbz = payments.kbzPay(); // also waveMoney(), ayaPay(), yomaMmqr(), cyberSource()
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
- Or build one gateway: `new KbzPay({ appId, appKey, merchantCode })`, `KbzPay.fromEnv()
|
|
36
|
-
-
|
|
37
|
-
-
|
|
35
|
+
- Or build one gateway: `new KbzPay(new KbzPayConfig({ appId, appKey, merchantCode, timeoutSeconds: 30 }))`, `KbzPay.fromEnv()` or `new KbzPay(KbzPayConfig.fromEnv(process.env))`.
|
|
36
|
+
- Or pass the settings directly: gateways and `new MyanmarPayments({ kbzPay: { appId, appKey, merchantCode, timeoutSeconds } })` take config objects or plain option objects; whole-number settings also take text such as `'30'`.
|
|
37
|
+
- Options (second argument): `{ httpClient, fetch }`. Without `httpClient`, the gateway uses `fetch` with the config's `timeoutSeconds`; a client you pass keeps its own timeout. Yoma and the facade also take `tokenCache` (any `TokenCache`, default `MemoryTokenCache`; back it with Redis when you run several processes).
|
|
38
|
+
- A missing setting throws `ConfigurationError` (`gateway`, `key`); a time setting that is not a whole number greater than 0 throws it too.
|
|
38
39
|
|
|
39
40
|
## Use
|
|
40
41
|
|
|
41
42
|
### Amounts
|
|
42
43
|
|
|
43
|
-
Amounts are `Amount.kyat(1000)`, `Amount.parse('1000.50')
|
|
44
|
+
Amounts are `Amount.kyat(1000)`, `Amount.parse('1000.50')` or a whole `number`/`bigint`; never a float such as `10.5`. Only KBZ Pay (up to 2 decimals) and CyberSource accept decimals; Wave, AYA and Yoma take whole kyat. Invalid data throws `InvalidPaymentDataError` with `errors` per field, before any request is sent. Compare a gateway's amount by value with `amount.equals(callback.amount)`.
|
|
44
45
|
|
|
45
46
|
### Start a payment
|
|
46
47
|
|
|
48
|
+
Each gateway takes a data object (`KbzPayPaymentData`, `WaveMoneyPaymentData` with `WaveMoneyItem`s, `AyaPayPaymentData` with an `AyaPayMethod`, `YomaMmqrPaymentData`, `CyberSourcePaymentData` with a `CyberSourceTransactionType`) and returns a typed result:
|
|
49
|
+
|
|
47
50
|
```ts
|
|
48
51
|
import { Amount } from '@laranex/myanmar-payments';
|
|
49
52
|
|
|
@@ -56,19 +59,22 @@ res.writeHead(302, { Location: payment.url }).end();
|
|
|
56
59
|
```
|
|
57
60
|
|
|
58
61
|
- `RedirectPayment` (`url`) from `kbz.pwa(data)` and `wave.initiate(data)`. Wave fills `data.merchantReferenceId` when empty; store it.
|
|
59
|
-
- `FormPayment` from `aya.initiate(data)` and `cyberSource.initiate(data)` (
|
|
62
|
+
- `FormPayment` from `aya.initiate(data)` and `cyberSource.initiate(data)` (no network call): send `payment.toHtml()` as an auto-submitting page, or render `action`, `fields` and `enctype` yourself.
|
|
60
63
|
- `QrPayment` from `kbz.qr(data)` (encode `qrString`) and `yoma.initiate(data)` (`qrImageDataUri()`, `expiresAt`, `reference`). A Yoma QR lives `YomaMmqr.QR_LIFETIME_SECONDS` (120); renew it with `yoma.renewQr(orderId)`.
|
|
61
|
-
- `AppPayment` from `kbz.app(data)`: `res.json(payment)` sends `orderId`, `orderInfo`, `sign
|
|
62
|
-
|
|
64
|
+
- `AppPayment` from `kbz.app(data)`: `res.json(payment)` sends `orderId`, `orderInfo`, `sign` and `signType` to your mobile app.
|
|
65
|
+
|
|
66
|
+
AYA needs a channel: `await aya.services()` lists `AyaPayService` entries (`key`, `supports(method)`), then `aya.initiate({ orderId: 'ORDER123', amount: 1000, channel: 'kbz_pay', method: AyaPayMethod.Qr })`. Every network method takes `{ signal }` as its last argument.
|
|
63
67
|
|
|
64
|
-
|
|
68
|
+
CyberSource has no payment defaults: pass `currency` (e.g. `'MMK'`), `transactionType` (e.g. `CyberSourceTransactionType.Sale`) and `locale` (e.g. `'en-us'`) on every `cyberSource.initiate(data)`.
|
|
65
69
|
|
|
66
70
|
### Handle the callback
|
|
67
71
|
|
|
72
|
+
Build a `CallbackRequest` from the raw request, verify it, then reply:
|
|
73
|
+
|
|
68
74
|
```ts
|
|
69
75
|
import { CallbackRequest, SignatureVerificationError } from '@laranex/myanmar-payments';
|
|
70
76
|
|
|
71
|
-
const request = await CallbackRequest.fromNodeRequest(req); // or fromWebRequest(request)
|
|
77
|
+
const request = await CallbackRequest.fromNodeRequest(req); // or fromWebRequest(request)
|
|
72
78
|
try {
|
|
73
79
|
const callback = kbz.handleCallback(request);
|
|
74
80
|
if (callback.isSuccessful()) {
|
|
@@ -76,23 +82,20 @@ try {
|
|
|
76
82
|
}
|
|
77
83
|
callback.acknowledgement.send(res); // or return callback.acknowledgement.toResponse()
|
|
78
84
|
} catch (error) {
|
|
79
|
-
if (error instanceof SignatureVerificationError)
|
|
80
|
-
|
|
81
|
-
res.end('invalid signature');
|
|
82
|
-
} else throw error;
|
|
85
|
+
if (!(error instanceof SignatureVerificationError)) throw error;
|
|
86
|
+
res.writeHead(400).end('invalid signature');
|
|
83
87
|
}
|
|
84
88
|
```
|
|
85
89
|
|
|
86
|
-
- Give the
|
|
87
|
-
- Fastify consumes the body before your handler: keep it as a string with a content-type parser (`parseAs: 'string'`) and build `CallbackRequest.from({ body, headers: request.headers, query: request.query })`.
|
|
90
|
+
- Give the package the raw body: in Express use `express.raw({ type: '*/*' })` on the callback route; in Fastify keep the body as a string (`parseAs: 'string'`) and build `CallbackRequest.from({ body, headers, query })`.
|
|
88
91
|
- Check AYA's browser return with `aya.verifyRedirect(request)`.
|
|
89
|
-
- For production, store the verified
|
|
92
|
+
- For production, store the verified callback, acknowledge immediately, then process it once in the background.
|
|
90
93
|
|
|
91
94
|
### Check status and handle errors
|
|
92
95
|
|
|
93
96
|
- `kbz.status(orderId)`, `aya.status(orderId)` and `yoma.status(reference)` return `PaymentStatusResult` with `status` and `isSuccessful()`. Wave Money and CyberSource have no status API.
|
|
94
97
|
- Statuses: `PaymentStatus.Successful`, `Pending`, `Failed`, `Canceled`, `Expired`, `Unknown`; `PaymentStatus.isFinal(status)`.
|
|
95
|
-
- Gateway failures throw `ApiError` (`gatewayCode`, `gatewayMessage`, `httpStatus`, `raw
|
|
98
|
+
- Gateway failures throw `ApiError` (`gatewayCode`, `gatewayMessage`, `httpStatus`, `raw`; network errors and aborts are the `cause`). All errors extend `PaymentError`.
|
|
96
99
|
|
|
97
100
|
## Test your app
|
|
98
101
|
|
|
@@ -105,6 +108,6 @@ try {
|
|
|
105
108
|
- Fulfilling orders from return pages or query strings; fulfill only from a verified callback or a status check.
|
|
106
109
|
- Treating `pending` or `unknown` as paid.
|
|
107
110
|
- Passing floats or `Number(price)` as amounts; use `Amount.parse()`.
|
|
108
|
-
-
|
|
111
|
+
- Building the `CallbackRequest` from `req.body` parsed by `express.json()` instead of the raw body.
|
|
109
112
|
- Reusing a Wave `merchantReferenceId`, or calling Yoma `initiate()` twice for one order (use `renewQr()`).
|
|
110
113
|
- Opening a KBZ Pay PWA link outside a phone with the KBZ Pay app.
|