@bayarkit/testing 0.0.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.
Files changed (138) hide show
  1. package/README.md +26 -1
  2. package/dist/cli/2c2p.d.ts +4 -0
  3. package/dist/cli/2c2p.d.ts.map +1 -0
  4. package/dist/cli/2c2p.js +7 -0
  5. package/dist/cli/2c2p.js.map +1 -0
  6. package/dist/cli/bayarcash.d.ts +4 -0
  7. package/dist/cli/bayarcash.d.ts.map +1 -0
  8. package/dist/cli/bayarcash.js +11 -0
  9. package/dist/cli/bayarcash.js.map +1 -0
  10. package/dist/cli/billplz.d.ts +4 -0
  11. package/dist/cli/billplz.d.ts.map +1 -0
  12. package/dist/cli/billplz.js +11 -0
  13. package/dist/cli/billplz.js.map +1 -0
  14. package/dist/cli/chip.d.ts +4 -0
  15. package/dist/cli/chip.d.ts.map +1 -0
  16. package/dist/cli/chip.js +7 -0
  17. package/dist/cli/chip.js.map +1 -0
  18. package/dist/cli/curlec.d.ts +4 -0
  19. package/dist/cli/curlec.d.ts.map +1 -0
  20. package/dist/cli/curlec.js +11 -0
  21. package/dist/cli/curlec.js.map +1 -0
  22. package/dist/cli/eghl.d.ts +4 -0
  23. package/dist/cli/eghl.d.ts.map +1 -0
  24. package/dist/cli/eghl.js +7 -0
  25. package/dist/cli/eghl.js.map +1 -0
  26. package/dist/cli/fiuu.d.ts +4 -0
  27. package/dist/cli/fiuu.d.ts.map +1 -0
  28. package/dist/cli/fiuu.js +17 -0
  29. package/dist/cli/fiuu.js.map +1 -0
  30. package/dist/cli/gkash.d.ts +4 -0
  31. package/dist/cli/gkash.d.ts.map +1 -0
  32. package/dist/cli/gkash.js +7 -0
  33. package/dist/cli/gkash.js.map +1 -0
  34. package/dist/cli/hitpay.d.ts +4 -0
  35. package/dist/cli/hitpay.d.ts.map +1 -0
  36. package/dist/cli/hitpay.js +7 -0
  37. package/dist/cli/hitpay.js.map +1 -0
  38. package/dist/cli/ipay88.d.ts +4 -0
  39. package/dist/cli/ipay88.d.ts.map +1 -0
  40. package/dist/cli/ipay88.js +7 -0
  41. package/dist/cli/ipay88.js.map +1 -0
  42. package/dist/cli/senangpay.d.ts +4 -0
  43. package/dist/cli/senangpay.d.ts.map +1 -0
  44. package/dist/cli/senangpay.js +17 -0
  45. package/dist/cli/senangpay.js.map +1 -0
  46. package/dist/cli/stripe.d.ts +4 -0
  47. package/dist/cli/stripe.d.ts.map +1 -0
  48. package/dist/cli/stripe.js +7 -0
  49. package/dist/cli/stripe.js.map +1 -0
  50. package/dist/cli/toyyibpay.d.ts +4 -0
  51. package/dist/cli/toyyibpay.d.ts.map +1 -0
  52. package/dist/cli/toyyibpay.js +7 -0
  53. package/dist/cli/toyyibpay.js.map +1 -0
  54. package/dist/cli/types.d.ts +7 -0
  55. package/dist/cli/types.d.ts.map +1 -0
  56. package/dist/cli/types.js +2 -0
  57. package/dist/cli/types.js.map +1 -0
  58. package/dist/cli/xendit.d.ts +4 -0
  59. package/dist/cli/xendit.d.ts.map +1 -0
  60. package/dist/cli/xendit.js +7 -0
  61. package/dist/cli/xendit.js.map +1 -0
  62. package/dist/cli.d.ts +3 -0
  63. package/dist/cli.d.ts.map +1 -0
  64. package/dist/cli.js +46 -0
  65. package/dist/cli.js.map +1 -0
  66. package/dist/conformance.d.ts +13 -0
  67. package/dist/conformance.d.ts.map +1 -0
  68. package/dist/conformance.js +166 -0
  69. package/dist/conformance.js.map +1 -0
  70. package/dist/control.d.ts +6 -0
  71. package/dist/control.d.ts.map +1 -0
  72. package/dist/control.js +46 -0
  73. package/dist/control.js.map +1 -0
  74. package/dist/fakes/2c2p.d.ts +21 -0
  75. package/dist/fakes/2c2p.d.ts.map +1 -0
  76. package/dist/fakes/2c2p.js +287 -0
  77. package/dist/fakes/2c2p.js.map +1 -0
  78. package/dist/fakes/bayarcash.d.ts +17 -0
  79. package/dist/fakes/bayarcash.d.ts.map +1 -0
  80. package/dist/fakes/bayarcash.js +183 -0
  81. package/dist/fakes/bayarcash.js.map +1 -0
  82. package/dist/fakes/billplz.d.ts +20 -0
  83. package/dist/fakes/billplz.d.ts.map +1 -0
  84. package/dist/fakes/billplz.js +233 -0
  85. package/dist/fakes/billplz.js.map +1 -0
  86. package/dist/fakes/chip.d.ts +18 -0
  87. package/dist/fakes/chip.d.ts.map +1 -0
  88. package/dist/fakes/chip.js +227 -0
  89. package/dist/fakes/chip.js.map +1 -0
  90. package/dist/fakes/curlec.d.ts +30 -0
  91. package/dist/fakes/curlec.d.ts.map +1 -0
  92. package/dist/fakes/curlec.js +396 -0
  93. package/dist/fakes/curlec.js.map +1 -0
  94. package/dist/fakes/eghl.d.ts +36 -0
  95. package/dist/fakes/eghl.d.ts.map +1 -0
  96. package/dist/fakes/eghl.js +267 -0
  97. package/dist/fakes/eghl.js.map +1 -0
  98. package/dist/fakes/fiuu.d.ts +27 -0
  99. package/dist/fakes/fiuu.d.ts.map +1 -0
  100. package/dist/fakes/fiuu.js +230 -0
  101. package/dist/fakes/fiuu.js.map +1 -0
  102. package/dist/fakes/gkash.d.ts +18 -0
  103. package/dist/fakes/gkash.d.ts.map +1 -0
  104. package/dist/fakes/gkash.js +193 -0
  105. package/dist/fakes/gkash.js.map +1 -0
  106. package/dist/fakes/hitpay.d.ts +36 -0
  107. package/dist/fakes/hitpay.d.ts.map +1 -0
  108. package/dist/fakes/hitpay.js +233 -0
  109. package/dist/fakes/hitpay.js.map +1 -0
  110. package/dist/fakes/ipay88.d.ts +16 -0
  111. package/dist/fakes/ipay88.d.ts.map +1 -0
  112. package/dist/fakes/ipay88.js +195 -0
  113. package/dist/fakes/ipay88.js.map +1 -0
  114. package/dist/fakes/senangpay.d.ts +51 -0
  115. package/dist/fakes/senangpay.d.ts.map +1 -0
  116. package/dist/fakes/senangpay.js +255 -0
  117. package/dist/fakes/senangpay.js.map +1 -0
  118. package/dist/fakes/stripe.d.ts +26 -0
  119. package/dist/fakes/stripe.d.ts.map +1 -0
  120. package/dist/fakes/stripe.js +243 -0
  121. package/dist/fakes/stripe.js.map +1 -0
  122. package/dist/fakes/toyyibpay.d.ts +14 -0
  123. package/dist/fakes/toyyibpay.d.ts.map +1 -0
  124. package/dist/fakes/toyyibpay.js +130 -0
  125. package/dist/fakes/toyyibpay.js.map +1 -0
  126. package/dist/fakes/types.d.ts +19 -0
  127. package/dist/fakes/types.d.ts.map +1 -0
  128. package/dist/fakes/types.js +3 -0
  129. package/dist/fakes/types.js.map +1 -0
  130. package/dist/fakes/xendit.d.ts +36 -0
  131. package/dist/fakes/xendit.d.ts.map +1 -0
  132. package/dist/fakes/xendit.js +300 -0
  133. package/dist/fakes/xendit.js.map +1 -0
  134. package/dist/index.d.ts +18 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +18 -0
  137. package/dist/index.js.map +1 -0
  138. package/package.json +66 -2
@@ -0,0 +1,267 @@
1
+ /**
2
+ * A fake eGHL (ADAPTIS e-Commerce) `payment.aspx`, built from the official PUBLIC code only (gateways/eghl/spec.md):
3
+ * the eGHL_HASH class, merchant-api (QUERY), the Omnipay driver (response fields, test vector), paramvalidator (field
4
+ * limits) and the WooCommerce plugin (GET redirect). eGHL publishes no API guide and this fake is NOT measured against
5
+ * the test host (pay.e-ghl.com): when someone does, change this file first so it answers like the real thing, then the
6
+ * adapter.
7
+ *
8
+ * What it does, with the spec section in brackets:
9
+ * - ONE endpoint, `/IPGSG/payment.aspx` (path matched case-insensitively, C7), GET query or POST form; the
10
+ * `TransactionType` field picks the operation [§1];
11
+ * - `SALE`: checks the paramvalidator required fields and limits (PaymentID ≤ 20, OrderNumber ≤ 40, CustIP ≤ 45,
12
+ * CustName ≤ 50, CustEmail ≤ 60, CustPhone ≤ 25, PageTimeout ≤ 4 digits), Amount = ringgit with exactly two decimals
13
+ * and no comma, and HashValue = sha256(password + ServiceID + PaymentID + MerchantReturnURL + MerchantApprovalURL +
14
+ * MerchantUnApprovalURL + MerchantCallBackURL + Amount + CurrencyCode + CustIP + PageTimeout + CardNo + Token) [§2,
15
+ * §4]. Accepted = 200 with an HTML payment page. ASSUMED (no public source): a refused SALE is HTTP 400 with a
16
+ * plain-text reason, and a reused PaymentID is refused (reuse behaviour is UNCONFIRMED, §6);
17
+ * - `QUERY`: PymtMethod, ServiceID, PaymentID, Amount, CurrencyCode, HashValue (sha256(password + ServiceID +
18
+ * PaymentID + Amount + CurrencyCode)) [§3, §4]. The answer is a URL-encoded `key=value&…` body [§3] signed with the
19
+ * 7-field response HashValue that merchant-api checks [§3, C2]; HashValue2 is NOT included (C2: UNCONFIRMED whether
20
+ * QUERY carries it). A query that does not match an existing payment in PaymentID, Amount, CurrencyCode AND
21
+ * PymtMethod answers `TxnExists=1&TxnStatus=-1` (merchant-api README: "matches all parameters sent in Query
22
+ * request"). ASSUMED: the PymtMethod that matches is the one the buyer PAID with (`DD`, the callback's value) once
23
+ * paid, and the one sent in the SALE (`ANY`) before; `queryMethod: 'sent'` makes it always the SALE's;
24
+ * - unpaid payments answer TxnStatus `2` (pending) — ASSUMED: no public source says what QUERY returns for a page that
25
+ * was opened but not paid;
26
+ * - callbacks: the Omnipay response field set, form-encoded, signed with HashValue (legacy, 7 fields) and HashValue2
27
+ * (10 fields: TxnID, ServiceID, PaymentID, TxnStatus, Amount, CurrencyCode, AuthCode, OrderNumber, Param6, Param7),
28
+ * TxnID = ServiceID + PaymentID like the official test vector [§4].
29
+ *
30
+ * A payment whose page the customer never opened (the conformance suite never opens one) is opened by `markPaid` /
31
+ * `callbackFor` the way the customer's browser would deliver `created.url`: PaymentID and amount come from the adapter's
32
+ * id `<PaymentID>.<amount in sen>`, and OrderNumber = PaymentID (the adapter sends the reference as both). A SALE that
33
+ * did arrive (a test that fetched `created.url`) is used as received.
34
+ */
35
+ import { createHash } from 'node:crypto';
36
+ import { createServer } from 'node:http';
37
+ import { flip } from './types.js';
38
+ /** The eGHL hash, written independently of the adapter: lowercase hex SHA-256 of password + values, no separator. */
39
+ const eghlSha = (password, values) => createHash('sha256')
40
+ .update(password + values.map((v) => v ?? '').join(''), 'utf8')
41
+ .digest('hex');
42
+ const SALE_FIELDS = [
43
+ 'ServiceID',
44
+ 'PaymentID',
45
+ 'MerchantReturnURL',
46
+ 'MerchantApprovalURL',
47
+ 'MerchantUnApprovalURL',
48
+ 'MerchantCallBackURL',
49
+ 'Amount',
50
+ 'CurrencyCode',
51
+ 'CustIP',
52
+ 'PageTimeout',
53
+ 'CardNo',
54
+ 'Token',
55
+ ];
56
+ const QUERY_FIELDS = ['ServiceID', 'PaymentID', 'Amount', 'CurrencyCode'];
57
+ const RESPONSE_FIELDS = ['TxnID', 'ServiceID', 'PaymentID', 'TxnStatus', 'Amount', 'CurrencyCode', 'AuthCode'];
58
+ const RESPONSE2_FIELDS = [...RESPONSE_FIELDS, 'OrderNumber', 'Param6', 'Param7'];
59
+ /** paramvalidator `PaymentRequest` limits for the fields this fake checks, and which are required. */
60
+ const SALE_LIMITS = {
61
+ TransactionType: [7, true],
62
+ PymtMethod: [3, true],
63
+ ServiceID: [3, true],
64
+ PaymentID: [20, true],
65
+ OrderNumber: [40, true],
66
+ PaymentDesc: [100, true],
67
+ MerchantReturnURL: [255, true],
68
+ Amount: [15, true],
69
+ CurrencyCode: [3, true],
70
+ HashValue: [64, true],
71
+ CustIP: [45, true],
72
+ CustName: [50, true],
73
+ CustEmail: [60, true],
74
+ CustPhone: [25, true],
75
+ MerchantApprovalURL: [255, false],
76
+ MerchantUnApprovalURL: [255, false],
77
+ MerchantCallBackURL: [255, false],
78
+ PageTimeout: [4, false],
79
+ Param6: [50, false],
80
+ Param7: [50, false],
81
+ };
82
+ export async function startFakeEghl(opts) {
83
+ const payments = new Map();
84
+ const requests = [];
85
+ let auth = 0;
86
+ const server = createServer((req, res) => {
87
+ let raw = '';
88
+ req.on('data', (d) => {
89
+ raw += d;
90
+ });
91
+ req.on('end', () => {
92
+ const url = new URL(req.url ?? '/', 'http://fake');
93
+ const fields = Object.fromEntries(url.searchParams);
94
+ if (req.method === 'POST')
95
+ Object.assign(fields, Object.fromEntries(new URLSearchParams(raw)));
96
+ requests.push({ method: req.method ?? '', path: url.pathname, fields });
97
+ const text = (status, body, type = 'text/plain') => {
98
+ res.writeHead(status, { 'content-type': `${type}; charset=utf-8` });
99
+ res.end(body);
100
+ };
101
+ if (url.pathname.toLowerCase() !== '/ipgsg/payment.aspx')
102
+ return text(404, 'Not Found');
103
+ const f = (k) => fields[k] ?? '';
104
+ switch (f('TransactionType').toUpperCase()) {
105
+ case 'SALE': {
106
+ for (const [k, [max, required]] of Object.entries(SALE_LIMITS)) {
107
+ if (required && !f(k))
108
+ return text(400, `Param '${k}' is required`);
109
+ if ([...f(k)].length > max)
110
+ return text(400, `Param '${k}' exceeds maxlength i.e. ${max}`);
111
+ }
112
+ if (!/^\d+\.\d{2}$/.test(f('Amount')))
113
+ return text(400, `Amount [${f('Amount')}] is invalid`);
114
+ if (f('PageTimeout') && !/^\d+$/.test(f('PageTimeout')))
115
+ return text(400, 'PageTimeout is invalid');
116
+ if (f('ServiceID') !== opts.serviceId)
117
+ return text(400, 'Invalid ServiceID');
118
+ const expected = eghlSha(opts.password, SALE_FIELDS.map((k) => fields[k]));
119
+ if (f('HashValue').toLowerCase() !== expected)
120
+ return text(400, 'Invalid HashValue');
121
+ const id = f('PaymentID');
122
+ if (payments.get(id)?.fromSale)
123
+ return text(400, 'Duplicate PaymentID');
124
+ payments.set(id, {
125
+ ...open(id, f('Amount'), f('OrderNumber')),
126
+ CurrencyCode: f('CurrencyCode'),
127
+ sentMethod: f('PymtMethod'),
128
+ Param6: f('Param6'),
129
+ Param7: f('Param7'),
130
+ fromSale: true,
131
+ });
132
+ return text(200, '<!doctype html><title>eGHL (fake)</title><h1>Payment page (fake)</h1>', 'text/html');
133
+ }
134
+ case 'QUERY': {
135
+ for (const k of ['PymtMethod', 'ServiceID', 'PaymentID', 'Amount', 'CurrencyCode', 'HashValue']) {
136
+ if (!f(k))
137
+ return text(400, `Param '${k}' is required`);
138
+ }
139
+ const signedQuery = eghlSha(opts.password, QUERY_FIELDS.map((k) => fields[k]));
140
+ if (f('ServiceID') !== opts.serviceId || f('HashValue').toLowerCase() !== signedQuery) {
141
+ return text(200, answer({ TxnExists: '1', TxnStatus: '-2', TxnMessage: 'Invalid HashValue' }));
142
+ }
143
+ const p = payments.get(f('PaymentID'));
144
+ const method = opts.queryMethod === 'sent' ? p?.sentMethod : (p?.paidMethod ?? p?.sentMethod);
145
+ if (!p ||
146
+ p.Amount !== f('Amount') ||
147
+ p.CurrencyCode !== f('CurrencyCode') ||
148
+ method !== f('PymtMethod')) {
149
+ return text(200, answer({
150
+ ServiceID: f('ServiceID'),
151
+ PaymentID: f('PaymentID'),
152
+ Amount: f('Amount'),
153
+ CurrencyCode: f('CurrencyCode'),
154
+ TxnExists: '1',
155
+ TxnStatus: '-1',
156
+ TxnMessage: 'Transaction not found',
157
+ }));
158
+ }
159
+ return text(200, answer({
160
+ TransactionType: 'QUERY',
161
+ PymtMethod: f('PymtMethod'),
162
+ ServiceID: opts.serviceId,
163
+ PaymentID: p.PaymentID,
164
+ Amount: p.Amount,
165
+ CurrencyCode: p.CurrencyCode,
166
+ TxnID: p.TxnID,
167
+ TxnExists: '0',
168
+ TxnStatus: p.TxnStatus,
169
+ AuthCode: p.AuthCode,
170
+ BankRefNo: p.TxnStatus === '0' ? `BR${p.AuthCode}` : '',
171
+ TxnMessage: p.TxnMessage,
172
+ }));
173
+ }
174
+ default:
175
+ return text(400, `TransactionType [${f('TransactionType')}] is not supported by this fake`);
176
+ }
177
+ });
178
+ });
179
+ /** A URL-encoded QUERY answer with the 7-field response HashValue merchant-api verifies. */
180
+ function answer(o) {
181
+ const HashValue = eghlSha(opts.password, RESPONSE_FIELDS.map((k) => o[k]));
182
+ return new URLSearchParams({ ...o, HashValue }).toString();
183
+ }
184
+ function open(paymentId, amount, orderNumber) {
185
+ auth += 1;
186
+ return {
187
+ PaymentID: paymentId,
188
+ OrderNumber: orderNumber,
189
+ Amount: amount,
190
+ CurrencyCode: 'MYR',
191
+ sentMethod: 'ANY',
192
+ TxnID: `${opts.serviceId}${paymentId}`,
193
+ AuthCode: `A${String(auth).padStart(5, '0')}`,
194
+ TxnStatus: '2',
195
+ TxnMessage: 'Pending',
196
+ Param6: '',
197
+ Param7: '',
198
+ fromSale: false,
199
+ };
200
+ }
201
+ /** The payment for an adapter id `<PaymentID>.<sen>[.<method>]`, opened as the customer's browser would. */
202
+ function byId(id) {
203
+ const m = /^(.+?)\.(\d+)(?:\.[A-Za-z]+)?$/.exec(id);
204
+ if (!m?.[1] || !m[2])
205
+ throw new Error(`fake eGHL: not an adapter id: ${id}`);
206
+ const existing = payments.get(m[1]);
207
+ if (existing)
208
+ return existing;
209
+ const p = open(m[1], (Number(m[2]) / 100).toFixed(2), m[1]);
210
+ payments.set(m[1], p);
211
+ return p;
212
+ }
213
+ await new Promise((r) => server.listen(0, '127.0.0.1', r));
214
+ const origin = `http://127.0.0.1:${server.address().port}`;
215
+ return {
216
+ url: `${origin}/IPGSG/payment.aspx`,
217
+ requests,
218
+ payment: (paymentId) => payments.get(paymentId),
219
+ markPaid(id) {
220
+ const p = byId(id);
221
+ p.TxnStatus = '0';
222
+ p.TxnMessage = 'Transaction Successful';
223
+ p.paidMethod = 'DD';
224
+ },
225
+ callbackFor(id, override = {}) {
226
+ const p = byId(id);
227
+ // The Omnipay response field set (spec §4). It claims success even before markPaid (a replayed or
228
+ // forged-with-a-leaked-password callback), while the fake's own record stays unpaid.
229
+ const fields = {
230
+ TransactionType: 'SALE',
231
+ PymtMethod: p.paidMethod ?? 'DD',
232
+ ServiceID: opts.serviceId,
233
+ PaymentID: p.PaymentID,
234
+ OrderNumber: p.OrderNumber,
235
+ Amount: p.Amount,
236
+ CurrencyCode: p.CurrencyCode,
237
+ TxnID: p.TxnID,
238
+ IssuingBank: 'HostSim',
239
+ TxnStatus: '0',
240
+ AuthCode: p.AuthCode,
241
+ TxnMessage: 'Transaction Successful',
242
+ ...(p.Param6 ? { Param6: p.Param6 } : {}),
243
+ ...(p.Param7 ? { Param7: p.Param7 } : {}),
244
+ ...override,
245
+ };
246
+ const { HashValue, HashValue2, ...signed } = fields;
247
+ const posted = {
248
+ ...signed,
249
+ HashValue: HashValue ??
250
+ eghlSha(opts.password, RESPONSE_FIELDS.map((k) => signed[k])),
251
+ HashValue2: HashValue2 ??
252
+ eghlSha(opts.password, RESPONSE2_FIELDS.map((k) => signed[k])),
253
+ };
254
+ return {
255
+ fields: posted,
256
+ rawBody: new URLSearchParams(posted).toString(),
257
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
258
+ };
259
+ },
260
+ tamper(cb) {
261
+ const fields = { ...cb.fields, HashValue2: flip(cb.fields.HashValue2 ?? '') };
262
+ return { ...cb, fields, rawBody: new URLSearchParams(fields).toString() };
263
+ },
264
+ close: () => new Promise((r) => server.close(() => r())),
265
+ };
266
+ }
267
+ //# sourceMappingURL=eghl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eghl.js","sourceRoot":"","sources":["../../src/fakes/eghl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type FakeGateway } from './types.js';
2
+ export interface FakeFiuu extends FakeGateway {
3
+ /** Every request received (payment page and requery), with the fields as posted or in the query string. */
4
+ requests: {
5
+ method: string;
6
+ path: string;
7
+ fields: Record<string, string>;
8
+ }[];
9
+ /** Set the transaction's requery status directly (e.g. `'11', 'failed'` or `'00', 'authorized'`). */
10
+ setStatus(id: string, statCode: '00' | '11' | '22', statName: string): void;
11
+ /** From now on every requery answers this PSQ error code (e.g. `Q99`); `null` restores normal answers. */
12
+ failQueriesWith(code: string | null): void;
13
+ }
14
+ export interface FakeFiuuOptions {
15
+ merchantId: string;
16
+ verifyKey: string;
17
+ secretKey: string;
18
+ /** Portal option "Use extended format for Verify Payment": vcode then includes the currency. Default false. */
19
+ extendedVcode?: boolean;
20
+ /**
21
+ * `type` is "obsoleted in new API sets" for q_by_tid (spec p73): with `'text'` every requery answers plain
22
+ * `Key: value` lines whatever `type` asks for. Default `'type'` (JSON when `type=2`).
23
+ */
24
+ queryOutput?: 'type' | 'text';
25
+ }
26
+ export declare function startFakeFiuu(opts: FakeFiuuOptions): Promise<FakeFiuu>;
27
+ //# sourceMappingURL=fiuu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiuu.d.ts","sourceRoot":"","sources":["../../src/fakes/fiuu.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,KAAK,WAAW,EAAQ,MAAM,YAAY,CAAA;AAkBnD,MAAM,WAAW,QAAS,SAAQ,WAAW;IAC3C,2GAA2G;IAC3G,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAA;IAC5E,qGAAqG;IACrG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3E,0GAA0G;IAC1G,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,+GAA+G;IAC/G,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC9B;AAqBD,wBAAsB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4L5E"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * A fake Fiuu (formerly Razer Merchant Services / MOLPay), built from the official API spec PDF v13.97 and the
3
+ * official plugins/SDKs — see gateways/fiuu/spec.md. NOT yet measured against the sandbox: when someone does, change
4
+ * this file first so it answers like the real thing, then the adapter.
5
+ *
6
+ * What it serves (paths as in the spec, `/RMS/…`, not the plugins' `/MOLPay/…` alias, C9):
7
+ * - `GET|POST /RMS/pay/{merchantID}/` — the hosted payment page. Checks `vcode` (standard, or extended with the
8
+ * currency when started with `extendedVcode`), the mandatory fields and the amount format, then registers the order;
9
+ * - `GET|POST /RMS/q_by_tid.php` and `/RMS/query/q_by_oid.php` — status requery, `skey = md5(id.domain.verify_key.amount)`,
10
+ * answering `Key: value` lines (type 0, default) or JSON (type 2), signed with `VrfKey`.
11
+ *
12
+ * Fiuu has no server-side "create": the adapter only builds the payment URL. So this fake also knows an order from the
13
+ * adapter's payment id (`<orderid>:<amount>`), and `callbackFor`/`markPaid` create the transaction (with its `tranID`)
14
+ * when the page was never visited.
15
+ *
16
+ * Where the docs are silent this fake picks one shape and says so (ASSUMED); the adapter must not depend on those
17
+ * shapes beyond "an error is an error".
18
+ */
19
+ import { createHash } from 'node:crypto';
20
+ import { createServer } from 'node:http';
21
+ import { flip } from './types.js';
22
+ /** Lowercase hex MD5 of a UTF-8 string — Fiuu's only hash. Written independently of the adapter. */
23
+ const md5 = (s) => createHash('md5').update(s, 'utf8').digest('hex');
24
+ const MY_OFFSET_MS = 8 * 3600_000;
25
+ const pad = (n) => String(n).padStart(2, '0');
26
+ /** `YYYY-MM-DD HH:mm:ss`. ASSUMED Malaysia time: the spec states no timezone (UNCONFIRMED). */
27
+ const paydateNow = () => {
28
+ const d = new Date(Date.now() + MY_OFFSET_MS);
29
+ return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
30
+ };
31
+ /** PSQ error texts, SPEC p147. */
32
+ const PSQ_ERRORS = {
33
+ Q01: 'Missing Required Parameter',
34
+ Q02: 'Invalid Parameter Value',
35
+ Q04: 'Merchant info not found.',
36
+ Q99: 'Service blocked due to massive connection. Please send only 1 request every 5 minutes.',
37
+ Q202: 'Incorrect skey',
38
+ Q203: 'Transaction record not found',
39
+ Q204: 'Incorrect amount',
40
+ };
41
+ export async function startFakeFiuu(opts) {
42
+ const byOrder = new Map();
43
+ const requests = [];
44
+ let nextTranID = 3036581200;
45
+ let queryError = null;
46
+ let origin = '';
47
+ const txnFor = (orderid, amount, currency = 'MYR') => {
48
+ let t = byOrder.get(orderid);
49
+ if (!t) {
50
+ nextTranID += 1;
51
+ t = {
52
+ tranID: String(nextTranID),
53
+ orderid,
54
+ amount,
55
+ currency,
56
+ statCode: '22',
57
+ statName: 'pending',
58
+ appcode: '',
59
+ paydate: paydateNow(),
60
+ channel: 'Credit',
61
+ };
62
+ byOrder.set(orderid, t);
63
+ }
64
+ return t;
65
+ };
66
+ /** The adapter's payment id: `<orderid>:<amount>`, optionally `:<tranID>` (from a callback). */
67
+ const fromId = (id) => {
68
+ const m = /^([^:]+):(\d+\.\d{2})(?::\d+)?$/.exec(id);
69
+ if (!m?.[1] || !m[2])
70
+ throw new Error(`fake Fiuu: not a payment id: ${id}`);
71
+ return txnFor(m[1], m[2]);
72
+ };
73
+ const server = createServer((req, res) => {
74
+ let raw = '';
75
+ req.on('data', (d) => {
76
+ raw += d;
77
+ });
78
+ req.on('end', () => {
79
+ const url = new URL(req.url ?? '/', 'http://fake');
80
+ // Spec: POST, GET or a mix; when both carry a parameter, POST wins (CHEAT L72).
81
+ const fields = {
82
+ ...Object.fromEntries(url.searchParams),
83
+ ...Object.fromEntries(new URLSearchParams(raw)),
84
+ };
85
+ const path = url.pathname;
86
+ requests.push({ method: req.method ?? '', path, fields });
87
+ const f = (k) => fields[k] ?? '';
88
+ const pay = /^\/RMS\/pay\/([^/]+)\/?$/.exec(path);
89
+ if (pay) {
90
+ // ASSUMED shape: the payment page shows the error code in HTML with status 200 (SPEC p142 lists codes only).
91
+ const page = (body) => {
92
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
93
+ res.end(`<!doctype html><title>Fake Fiuu</title><p>${body}</p>`);
94
+ };
95
+ if (pay[1] !== opts.merchantId)
96
+ return page('Error P01: Invalid merchant');
97
+ const amount = f('amount');
98
+ // SPEC p40: "integer or up to 2 decimal points", comma not allowed.
99
+ if (!/^\d+(\.\d{1,2})?$/.test(amount))
100
+ return page('Error P02: Invalid amount');
101
+ if (!/^[A-Za-z0-9-]{1,40}$/.test(f('orderid')))
102
+ return page('Error P02: Invalid orderid');
103
+ if (!/^[A-Z]{3}$/.test(f('currency')))
104
+ return page('Error P02: Invalid currency');
105
+ const vcodeSource = `${amount}${opts.merchantId}${f('orderid')}${opts.verifyKey}${opts.extendedVcode ? f('currency') : ''}`;
106
+ // ASSUMED: "Enable Verify Payment" is on, so vcode is mandatory (SPEC p19).
107
+ if (f('vcode').toLowerCase() !== md5(vcodeSource))
108
+ return page('Error P03: Invalid vcode');
109
+ // ASSUMED: the bill_* fields may be absent only with guest_checkout=1 (SPEC p40 says both "mandatory" and
110
+ // "1 if the merchant does not hold the customer's bill_name, bill_email or bill_mobile").
111
+ if (f('guest_checkout') !== '1' && (!f('bill_name') || !f('bill_email') || !f('bill_mobile')))
112
+ return page('Error P02: Missing buyer details');
113
+ if (!f('bill_desc'))
114
+ return page('Error P02: Missing bill_desc');
115
+ txnFor(f('orderid'), amount, f('currency'));
116
+ return page(`Fake Fiuu payment page for ${f('orderid').replace(/[^A-Za-z0-9-]/g, '')}`);
117
+ }
118
+ const byTid = path === '/RMS/q_by_tid.php';
119
+ const byOid = path === '/RMS/query/q_by_oid.php';
120
+ if (byTid || byOid) {
121
+ const json = f('type') === '2' && opts.queryOutput !== 'text';
122
+ const answer = (o) => {
123
+ res.writeHead(200, { 'content-type': json ? 'application/json' : 'text/plain' });
124
+ res.end(json
125
+ ? JSON.stringify(o)
126
+ : Object.entries(o)
127
+ .map(([k, v]) => `${k}: ${v ?? ''}`)
128
+ .join('\n'));
129
+ };
130
+ // ASSUMED error shape: the spec gives codes and texts only (SPEC p147).
131
+ const error = (code) => answer({ StatCode: null, ErrorCode: code, ErrorDesc: PSQ_ERRORS[code] ?? 'Error' });
132
+ if (queryError)
133
+ return error(queryError);
134
+ const id = byTid ? f('txID') : f('oID');
135
+ if (!id || !f('domain') || !f('amount') || !f('skey'))
136
+ return error('Q01');
137
+ if (f('domain') !== opts.merchantId)
138
+ return error('Q04');
139
+ if (f('skey').toLowerCase() !== md5(`${id}${f('domain')}${opts.verifyKey}${f('amount')}`))
140
+ return error('Q202');
141
+ const t = byTid ? [...byOrder.values()].find((x) => x.tranID === id) : byOrder.get(id);
142
+ if (!t)
143
+ return error('Q203');
144
+ if (Number(f('amount')) !== Number(t.amount))
145
+ return error('Q204');
146
+ const Amount = Number(t.amount).toFixed(2);
147
+ const VrfKey = md5(`${Amount}${opts.secretKey}${opts.merchantId}${byTid ? t.tranID : t.orderid}${t.statCode}`);
148
+ return answer({
149
+ StatCode: t.statCode,
150
+ StatName: t.statName,
151
+ TranID: t.tranID,
152
+ Amount,
153
+ Domain: opts.merchantId,
154
+ VrfKey,
155
+ Channel: t.channel,
156
+ OrderID: t.orderid,
157
+ Currency: t.currency,
158
+ ...(byOid ? { BillingDate: t.paydate } : {}),
159
+ ErrorCode: json ? null : '',
160
+ ErrorDesc: json ? null : '',
161
+ });
162
+ }
163
+ res.writeHead(404, { 'content-type': 'text/plain' });
164
+ res.end('Not found');
165
+ });
166
+ });
167
+ await new Promise((r) => server.listen(0, '127.0.0.1', r));
168
+ origin = `http://127.0.0.1:${server.address().port}`;
169
+ return {
170
+ url: origin,
171
+ requests,
172
+ markPaid(id) {
173
+ const t = fromId(id);
174
+ t.statCode = '00';
175
+ t.statName = 'captured';
176
+ t.appcode = '123456';
177
+ t.paydate = paydateNow();
178
+ },
179
+ setStatus(id, statCode, statName) {
180
+ const t = fromId(id);
181
+ t.statCode = statCode;
182
+ t.statName = statName;
183
+ },
184
+ failQueriesWith(code) {
185
+ queryError = code;
186
+ },
187
+ callbackFor(id, override = {}) {
188
+ const t = fromId(id);
189
+ // A notification (nbcb=2) claiming success even before markPaid (a replayed or forged-with-a-leaked-key
190
+ // callback). SPEC p56: form POST whose values "are not URL encoded".
191
+ const fields = {
192
+ nbcb: '2',
193
+ tranID: t.tranID,
194
+ orderid: t.orderid,
195
+ status: '00',
196
+ domain: opts.merchantId,
197
+ amount: t.amount,
198
+ currency: t.currency,
199
+ appcode: t.appcode || '123456',
200
+ paydate: t.paydate,
201
+ channel: t.channel,
202
+ error_code: '',
203
+ error_desc: '',
204
+ ...override,
205
+ };
206
+ const { skey: given, ...signed } = fields;
207
+ // SPEC p21: double MD5 over the posted strings, in this order, with the SECRET key.
208
+ const pre = md5(`${signed.tranID}${signed.orderid}${signed.status}${signed.domain}${signed.amount}${signed.currency}`);
209
+ const skey = given ?? md5(`${signed.paydate}${signed.domain}${pre}${signed.appcode}${opts.secretKey}`);
210
+ const rawBody = Object.entries({ ...signed, skey })
211
+ .map(([k, v]) => `${k}=${v}`)
212
+ .join('&');
213
+ return {
214
+ fields: Object.fromEntries(new URLSearchParams(rawBody)),
215
+ rawBody,
216
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
217
+ };
218
+ },
219
+ tamper: (cb) => {
220
+ const skey = flip(cb.fields.skey ?? '');
221
+ return {
222
+ ...cb,
223
+ fields: { ...cb.fields, skey },
224
+ rawBody: cb.rawBody.replace(/(^|&)skey=[^&]*/, `$1skey=${skey}`),
225
+ };
226
+ },
227
+ close: () => new Promise((r) => server.close(() => r())),
228
+ };
229
+ }
230
+ //# sourceMappingURL=fiuu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiuu.js","sourceRoot":"","sources":["../../src/fakes/fiuu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type FakeGateway } from './types.js';
2
+ export interface FakeGkash extends FakeGateway {
3
+ /** Every request received: JSON body as posted, and headers. */
4
+ requests: {
5
+ method: string;
6
+ path: string;
7
+ body: Record<string, unknown>;
8
+ contentType: string | undefined;
9
+ headers: Record<string, string | string[] | undefined>;
10
+ }[];
11
+ /** Set the full status text Gkash would report (e.g. `66 - Failed`), for tests of other outcomes. */
12
+ setStatus(id: string, status: string): void;
13
+ }
14
+ export declare function startFakeGkash(opts: {
15
+ cid: string;
16
+ signatureKey: string;
17
+ }): Promise<FakeGkash>;
18
+ //# sourceMappingURL=gkash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gkash.d.ts","sourceRoot":"","sources":["../../src/fakes/gkash.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,WAAW,EAAQ,MAAM,YAAY,CAAA;AAqBnD,MAAM,WAAW,SAAU,SAAQ,WAAW;IAC5C,gEAAgE;IAChE,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;QAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;KACvD,EAAE,CAAA;IACH,qGAAqG;IACrG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5C;AAKD,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAkKpG"}