promptpay-qrcode 1.2.0 → 1.2.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.
- package/README.md +9 -1
- package/decode.js +4 -0
- package/package.json +1 -1
- package/promptpay.js +12 -2
package/README.md
CHANGED
|
@@ -65,9 +65,17 @@ generateBillPayment({
|
|
|
65
65
|
dynamic: true, // optional; force POI (true='12', false='11')
|
|
66
66
|
merchantName: 'MY SHOP', // optional (tag 59)
|
|
67
67
|
merchantCity: 'BANGKOK', // optional (tag 60)
|
|
68
|
+
additionalData: '07160000…', // optional raw tag 62 (e.g. terminal label sub-TLV)
|
|
69
|
+
countryCode: 'TH', // optional (tag 58, default 'TH')
|
|
68
70
|
});
|
|
69
71
|
```
|
|
70
72
|
|
|
73
|
+
Tag order matches real Thai bill-payment QRs (`00,01,30,58,53,…,62,63` — note
|
|
74
|
+
`58` before `53`), so a decoded bill-payment QR round-trips **byte-for-byte**:
|
|
75
|
+
`generateBillPayment({ ...account, ...transaction })` from a `detach()` of an
|
|
76
|
+
SCB/Mae Manee QR reproduces the original exactly (including its tag-62 terminal
|
|
77
|
+
label).
|
|
78
|
+
|
|
71
79
|
The Biller ID and references are issued/defined by your bank (for SCB, via the
|
|
72
80
|
Mae Manee / Business QR onboarding). `ref1` is required; `ref2` is optional.
|
|
73
81
|
|
|
@@ -298,7 +306,7 @@ The second `options` argument is passed straight through to `qrcode`
|
|
|
298
306
|
| Function | Returns |
|
|
299
307
|
| --- | --- |
|
|
300
308
|
| `generatePromptPay({ mobile \| nationalId \| ewallet, amount?, dynamic? })` | payload string |
|
|
301
|
-
| `generateBillPayment({ billerId, ref1, ref2?, amount?, dynamic?, merchantName?, merchantCity? })` | payload string |
|
|
309
|
+
| `generateBillPayment({ billerId, ref1, ref2?, amount?, dynamic?, merchantName?, merchantCity?, additionalData?, countryCode? })` | payload string |
|
|
302
310
|
| `generateKShopQR(amount, reference, config)` | payload string |
|
|
303
311
|
| `KSHOP_DEFAULTS` / `REQUIRED_FIELDS` | KShop structural defaults / required field list |
|
|
304
312
|
| `decode(payload)` | structured decode + CRC validation |
|
package/decode.js
CHANGED
|
@@ -291,6 +291,10 @@ function detach(qr) {
|
|
|
291
291
|
if (t30['01'] != null) account.billerId = t30['01'];
|
|
292
292
|
if (f['59'] != null) account.merchantName = f['59'];
|
|
293
293
|
if (f['60'] != null) account.merchantCity = f['60'];
|
|
294
|
+
if (f['58'] != null) account.countryCode = f['58'];
|
|
295
|
+
// Tag 62 (Additional Data) — keep the raw inner string so it round-trips.
|
|
296
|
+
const raw62 = flattenTag62(d.tags);
|
|
297
|
+
if (raw62 != null) account.additionalData = raw62;
|
|
294
298
|
transaction = {
|
|
295
299
|
ref1: t30['02'],
|
|
296
300
|
ref2: t30['03'] != null ? t30['03'] : undefined,
|
package/package.json
CHANGED
package/promptpay.js
CHANGED
|
@@ -115,9 +115,18 @@ function generatePromptPay({ mobile, nationalId, ewallet, amount, dynamic } = {}
|
|
|
115
115
|
* @param {boolean} [opts.dynamic] Force POI: true='12', false='11'. Auto if omitted.
|
|
116
116
|
* @param {string} [opts.merchantName] Merchant name (tag 59).
|
|
117
117
|
* @param {string} [opts.merchantCity] Merchant city (tag 60).
|
|
118
|
+
* @param {string} [opts.additionalData] Raw Additional Data Field (tag 62) value,
|
|
119
|
+
* e.g. terminal label sub-TLV "0716...".
|
|
120
|
+
* @param {string} [opts.countryCode] Country code (tag 58). Default 'TH'.
|
|
118
121
|
* @returns {string} The EMVCo QR payload including CRC.
|
|
122
|
+
*
|
|
123
|
+
* Tag order follows the layout used by real Thai bill-payment QRs (SCB / Mae
|
|
124
|
+
* Manee): `00,01,30,58,53,[54],[59],[60],[62],63` — note `58` precedes `53`.
|
|
125
|
+
* This lets a decoded bill-payment QR round-trip byte-for-byte.
|
|
119
126
|
*/
|
|
120
|
-
function generateBillPayment({
|
|
127
|
+
function generateBillPayment({
|
|
128
|
+
billerId, ref1, ref2, amount, dynamic, merchantName, merchantCity, additionalData, countryCode,
|
|
129
|
+
} = {}) {
|
|
121
130
|
if (!billerId) throw new Error('billerId is required');
|
|
122
131
|
if (!ref1) throw new Error('ref1 is required');
|
|
123
132
|
|
|
@@ -132,13 +141,14 @@ function generateBillPayment({ billerId, ref1, ref2, amount, dynamic, merchantNa
|
|
|
132
141
|
payload += tlv('00', '01'); // payload format indicator
|
|
133
142
|
payload += tlv('01', poiMethod(dynamic, hasAmount)); // dynamic vs static
|
|
134
143
|
payload += tlv('30', merchantAccount); // bill payment merchant account info
|
|
144
|
+
payload += tlv('58', countryCode || COUNTRY_TH); // country (before currency, per Thai QR layout)
|
|
135
145
|
payload += tlv('53', CURRENCY_THB);
|
|
136
146
|
if (hasAmount) {
|
|
137
147
|
payload += tlv('54', Number(amount).toFixed(2));
|
|
138
148
|
}
|
|
139
|
-
payload += tlv('58', COUNTRY_TH);
|
|
140
149
|
if (merchantName) payload += tlv('59', merchantName);
|
|
141
150
|
if (merchantCity) payload += tlv('60', merchantCity);
|
|
151
|
+
if (additionalData) payload += tlv('62', String(additionalData));
|
|
142
152
|
|
|
143
153
|
payload += '6304' + crc16Hex(payload + '6304');
|
|
144
154
|
return payload;
|