@waffo/waffo-node 2.0.2

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.mjs ADDED
@@ -0,0 +1,1750 @@
1
+ import crypto from 'crypto';
2
+
3
+ // src/types/config.ts
4
+ var Environment = /* @__PURE__ */ ((Environment2) => {
5
+ Environment2["SANDBOX"] = "sandbox";
6
+ Environment2["PRODUCTION"] = "production";
7
+ return Environment2;
8
+ })(Environment || {});
9
+ var EnvironmentUrls = {
10
+ ["sandbox" /* SANDBOX */]: "https://api-sandbox.waffo.com/api/v1",
11
+ ["production" /* PRODUCTION */]: "https://api.waffo.com/api/v1"
12
+ };
13
+ var EnvironmentPublicKeys = {
14
+ ["sandbox" /* SANDBOX */]: "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAhAbK3dBDZdCaX/5cqlO8EYYL4M4DyigqAMoIaT6R0SuSENu279dHZ3JiS8JukHx/xg85T9S3wDNwnu8KDypcwi8TxNQKgBE4czgAJ5GFEdJ+jtUS1dK46gjJFUnUlavb3uMLJJ0xZZKH0B5GtKOq75MwHWtXLK3zQrPqZosXqdgZhfbV+7bXlQaABdPlqif/ybN1DRrvcWmNVLAgsRiQvu4QnDOTMafzrSsF5tf8Ud3gK+JhcJs50NsXLPZZSc6NryZoH++xmz8atp0dOrBKmsJkZRWjrH+aXDZZT1sZDlgsKBMoRPf6F+lztFOPerrhSE81Y5MFaAp8R/QicMGCPueLhlebjx1OF0oowUD9b7ggZ8LiYpaR4HT9OmDpsu6NMN7zNG81qo7vnKCyy//xdOkpr4bQsm581r312y1UUjaYTZTlqAe+qbGZmZ7zS+ra0uwS6zLoZOY1ToOwlJbTwRPx2epweJcRnJVueiS1fPxaAlQz+tuVtIGONmZ836aHAgMBAAE=",
15
+ ["production" /* PRODUCTION */]: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqVHKdn76r6IhRXxWihdy+AiG0tzVR8LjDXC+0WFdTkn05Ga7ZS0WC3MRpxgRsbBWDlEVZYPUBdrtAmQeZYD7rwKSKSTdd62eZxehDI8DCzNhxppbeMPBhMn72eQvB/RQl1qhP7HLZx9IyTC7EbWWO0zhhomzf0hQ2K7KXDFq9bSYdBGAzSg+kOQFP2eifON8qm4TuwlxNSdTcgRWa8cRwy9h9aLra1iaeFRx9k68KxIcK0ZiGbD6KiR1a2NtZuxjB6bTJ7N/ydfKqQY+wB1CTWIlvouW1qajYYGBAcde9JN6o6CiWz3sPt42312CF3+k+gQeiuofdXkzVlMryVivfwIDAQAB"
16
+ };
17
+
18
+ // src/types/network.ts
19
+ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
20
+ HttpStatusCode2[HttpStatusCode2["OK"] = 200] = "OK";
21
+ HttpStatusCode2[HttpStatusCode2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
22
+ HttpStatusCode2[HttpStatusCode2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
23
+ HttpStatusCode2[HttpStatusCode2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
24
+ HttpStatusCode2[HttpStatusCode2["FORBIDDEN"] = 403] = "FORBIDDEN";
25
+ HttpStatusCode2[HttpStatusCode2["NOT_FOUND"] = 404] = "NOT_FOUND";
26
+ HttpStatusCode2[HttpStatusCode2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
27
+ HttpStatusCode2[HttpStatusCode2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
28
+ HttpStatusCode2[HttpStatusCode2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
29
+ HttpStatusCode2[HttpStatusCode2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
30
+ HttpStatusCode2[HttpStatusCode2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
31
+ HttpStatusCode2[HttpStatusCode2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
32
+ HttpStatusCode2[HttpStatusCode2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
33
+ return HttpStatusCode2;
34
+ })(HttpStatusCode || {});
35
+
36
+ // src/types/webhook.ts
37
+ var WebhookEventType = /* @__PURE__ */ ((WebhookEventType2) => {
38
+ WebhookEventType2["PAYMENT_NOTIFICATION"] = "PAYMENT_NOTIFICATION";
39
+ WebhookEventType2["REFUND_NOTIFICATION"] = "REFUND_NOTIFICATION";
40
+ WebhookEventType2["SUBSCRIPTION_STATUS_NOTIFICATION"] = "SUBSCRIPTION_STATUS_NOTIFICATION";
41
+ return WebhookEventType2;
42
+ })(WebhookEventType || {});
43
+ var WebhookResponseStatus = /* @__PURE__ */ ((WebhookResponseStatus2) => {
44
+ WebhookResponseStatus2["SUCCESS"] = "success";
45
+ WebhookResponseStatus2["FAILED"] = "failed";
46
+ WebhookResponseStatus2["UNKNOWN"] = "unknown";
47
+ return WebhookResponseStatus2;
48
+ })(WebhookResponseStatus || {});
49
+
50
+ // src/types/iso.ts
51
+ var CountryCode = /* @__PURE__ */ ((CountryCode2) => {
52
+ CountryCode2["AFG"] = "AFG";
53
+ CountryCode2["ALB"] = "ALB";
54
+ CountryCode2["DZA"] = "DZA";
55
+ CountryCode2["ASM"] = "ASM";
56
+ CountryCode2["AND"] = "AND";
57
+ CountryCode2["AGO"] = "AGO";
58
+ CountryCode2["AIA"] = "AIA";
59
+ CountryCode2["ATA"] = "ATA";
60
+ CountryCode2["ATG"] = "ATG";
61
+ CountryCode2["ARG"] = "ARG";
62
+ CountryCode2["ARM"] = "ARM";
63
+ CountryCode2["ABW"] = "ABW";
64
+ CountryCode2["AUS"] = "AUS";
65
+ CountryCode2["AUT"] = "AUT";
66
+ CountryCode2["AZE"] = "AZE";
67
+ CountryCode2["BHS"] = "BHS";
68
+ CountryCode2["BHR"] = "BHR";
69
+ CountryCode2["BGD"] = "BGD";
70
+ CountryCode2["BRB"] = "BRB";
71
+ CountryCode2["BLR"] = "BLR";
72
+ CountryCode2["BEL"] = "BEL";
73
+ CountryCode2["BLZ"] = "BLZ";
74
+ CountryCode2["BEN"] = "BEN";
75
+ CountryCode2["BMU"] = "BMU";
76
+ CountryCode2["BTN"] = "BTN";
77
+ CountryCode2["BOL"] = "BOL";
78
+ CountryCode2["BES"] = "BES";
79
+ CountryCode2["BIH"] = "BIH";
80
+ CountryCode2["BWA"] = "BWA";
81
+ CountryCode2["BVT"] = "BVT";
82
+ CountryCode2["BRA"] = "BRA";
83
+ CountryCode2["IOT"] = "IOT";
84
+ CountryCode2["BRN"] = "BRN";
85
+ CountryCode2["BGR"] = "BGR";
86
+ CountryCode2["BFA"] = "BFA";
87
+ CountryCode2["BDI"] = "BDI";
88
+ CountryCode2["CPV"] = "CPV";
89
+ CountryCode2["KHM"] = "KHM";
90
+ CountryCode2["CMR"] = "CMR";
91
+ CountryCode2["CAN"] = "CAN";
92
+ CountryCode2["CYM"] = "CYM";
93
+ CountryCode2["CAF"] = "CAF";
94
+ CountryCode2["TCD"] = "TCD";
95
+ CountryCode2["CHL"] = "CHL";
96
+ CountryCode2["CHN"] = "CHN";
97
+ CountryCode2["CXR"] = "CXR";
98
+ CountryCode2["CCK"] = "CCK";
99
+ CountryCode2["COL"] = "COL";
100
+ CountryCode2["COM"] = "COM";
101
+ CountryCode2["COD"] = "COD";
102
+ CountryCode2["COG"] = "COG";
103
+ CountryCode2["COK"] = "COK";
104
+ CountryCode2["CRI"] = "CRI";
105
+ CountryCode2["HRV"] = "HRV";
106
+ CountryCode2["CUB"] = "CUB";
107
+ CountryCode2["CUW"] = "CUW";
108
+ CountryCode2["CYP"] = "CYP";
109
+ CountryCode2["CZE"] = "CZE";
110
+ CountryCode2["CIV"] = "CIV";
111
+ CountryCode2["DNK"] = "DNK";
112
+ CountryCode2["DJI"] = "DJI";
113
+ CountryCode2["DMA"] = "DMA";
114
+ CountryCode2["DOM"] = "DOM";
115
+ CountryCode2["ECU"] = "ECU";
116
+ CountryCode2["EGY"] = "EGY";
117
+ CountryCode2["SLV"] = "SLV";
118
+ CountryCode2["GNQ"] = "GNQ";
119
+ CountryCode2["ERI"] = "ERI";
120
+ CountryCode2["EST"] = "EST";
121
+ CountryCode2["SWZ"] = "SWZ";
122
+ CountryCode2["ETH"] = "ETH";
123
+ CountryCode2["FLK"] = "FLK";
124
+ CountryCode2["FRO"] = "FRO";
125
+ CountryCode2["FJI"] = "FJI";
126
+ CountryCode2["FIN"] = "FIN";
127
+ CountryCode2["FRA"] = "FRA";
128
+ CountryCode2["GUF"] = "GUF";
129
+ CountryCode2["PYF"] = "PYF";
130
+ CountryCode2["ATF"] = "ATF";
131
+ CountryCode2["GAB"] = "GAB";
132
+ CountryCode2["GMB"] = "GMB";
133
+ CountryCode2["GEO"] = "GEO";
134
+ CountryCode2["DEU"] = "DEU";
135
+ CountryCode2["GHA"] = "GHA";
136
+ CountryCode2["GIB"] = "GIB";
137
+ CountryCode2["GRC"] = "GRC";
138
+ CountryCode2["GRL"] = "GRL";
139
+ CountryCode2["GRD"] = "GRD";
140
+ CountryCode2["GLP"] = "GLP";
141
+ CountryCode2["GUM"] = "GUM";
142
+ CountryCode2["GTM"] = "GTM";
143
+ CountryCode2["GGY"] = "GGY";
144
+ CountryCode2["GIN"] = "GIN";
145
+ CountryCode2["GNB"] = "GNB";
146
+ CountryCode2["GUY"] = "GUY";
147
+ CountryCode2["HTI"] = "HTI";
148
+ CountryCode2["HMD"] = "HMD";
149
+ CountryCode2["VAT"] = "VAT";
150
+ CountryCode2["HND"] = "HND";
151
+ CountryCode2["HKG"] = "HKG";
152
+ CountryCode2["HUN"] = "HUN";
153
+ CountryCode2["ISL"] = "ISL";
154
+ CountryCode2["IND"] = "IND";
155
+ CountryCode2["IDN"] = "IDN";
156
+ CountryCode2["IRN"] = "IRN";
157
+ CountryCode2["IRQ"] = "IRQ";
158
+ CountryCode2["IRL"] = "IRL";
159
+ CountryCode2["IMN"] = "IMN";
160
+ CountryCode2["ISR"] = "ISR";
161
+ CountryCode2["ITA"] = "ITA";
162
+ CountryCode2["JAM"] = "JAM";
163
+ CountryCode2["JPN"] = "JPN";
164
+ CountryCode2["JEY"] = "JEY";
165
+ CountryCode2["JOR"] = "JOR";
166
+ CountryCode2["KAZ"] = "KAZ";
167
+ CountryCode2["KEN"] = "KEN";
168
+ CountryCode2["KIR"] = "KIR";
169
+ CountryCode2["PRK"] = "PRK";
170
+ CountryCode2["KOR"] = "KOR";
171
+ CountryCode2["KWT"] = "KWT";
172
+ CountryCode2["KGZ"] = "KGZ";
173
+ CountryCode2["LAO"] = "LAO";
174
+ CountryCode2["LVA"] = "LVA";
175
+ CountryCode2["LBN"] = "LBN";
176
+ CountryCode2["LSO"] = "LSO";
177
+ CountryCode2["LBR"] = "LBR";
178
+ CountryCode2["LBY"] = "LBY";
179
+ CountryCode2["LIE"] = "LIE";
180
+ CountryCode2["LTU"] = "LTU";
181
+ CountryCode2["LUX"] = "LUX";
182
+ CountryCode2["MAC"] = "MAC";
183
+ CountryCode2["MDG"] = "MDG";
184
+ CountryCode2["MWI"] = "MWI";
185
+ CountryCode2["MYS"] = "MYS";
186
+ CountryCode2["MDV"] = "MDV";
187
+ CountryCode2["MLI"] = "MLI";
188
+ CountryCode2["MLT"] = "MLT";
189
+ CountryCode2["MHL"] = "MHL";
190
+ CountryCode2["MTQ"] = "MTQ";
191
+ CountryCode2["MRT"] = "MRT";
192
+ CountryCode2["MUS"] = "MUS";
193
+ CountryCode2["MYT"] = "MYT";
194
+ CountryCode2["MEX"] = "MEX";
195
+ CountryCode2["FSM"] = "FSM";
196
+ CountryCode2["MDA"] = "MDA";
197
+ CountryCode2["MCO"] = "MCO";
198
+ CountryCode2["MNG"] = "MNG";
199
+ CountryCode2["MNE"] = "MNE";
200
+ CountryCode2["MSR"] = "MSR";
201
+ CountryCode2["MAR"] = "MAR";
202
+ CountryCode2["MOZ"] = "MOZ";
203
+ CountryCode2["MMR"] = "MMR";
204
+ CountryCode2["NAM"] = "NAM";
205
+ CountryCode2["NRU"] = "NRU";
206
+ CountryCode2["NPL"] = "NPL";
207
+ CountryCode2["NLD"] = "NLD";
208
+ CountryCode2["NCL"] = "NCL";
209
+ CountryCode2["NZL"] = "NZL";
210
+ CountryCode2["NIC"] = "NIC";
211
+ CountryCode2["NER"] = "NER";
212
+ CountryCode2["NGA"] = "NGA";
213
+ CountryCode2["NIU"] = "NIU";
214
+ CountryCode2["NFK"] = "NFK";
215
+ CountryCode2["MKD"] = "MKD";
216
+ CountryCode2["MNP"] = "MNP";
217
+ CountryCode2["NOR"] = "NOR";
218
+ CountryCode2["OMN"] = "OMN";
219
+ CountryCode2["PAK"] = "PAK";
220
+ CountryCode2["PLW"] = "PLW";
221
+ CountryCode2["PSE"] = "PSE";
222
+ CountryCode2["PAN"] = "PAN";
223
+ CountryCode2["PNG"] = "PNG";
224
+ CountryCode2["PRY"] = "PRY";
225
+ CountryCode2["PER"] = "PER";
226
+ CountryCode2["PHL"] = "PHL";
227
+ CountryCode2["PCN"] = "PCN";
228
+ CountryCode2["POL"] = "POL";
229
+ CountryCode2["PRT"] = "PRT";
230
+ CountryCode2["PRI"] = "PRI";
231
+ CountryCode2["QAT"] = "QAT";
232
+ CountryCode2["ROU"] = "ROU";
233
+ CountryCode2["RUS"] = "RUS";
234
+ CountryCode2["RWA"] = "RWA";
235
+ CountryCode2["REU"] = "REU";
236
+ CountryCode2["BLM"] = "BLM";
237
+ CountryCode2["SHN"] = "SHN";
238
+ CountryCode2["KNA"] = "KNA";
239
+ CountryCode2["LCA"] = "LCA";
240
+ CountryCode2["MAF"] = "MAF";
241
+ CountryCode2["SPM"] = "SPM";
242
+ CountryCode2["VCT"] = "VCT";
243
+ CountryCode2["WSM"] = "WSM";
244
+ CountryCode2["SMR"] = "SMR";
245
+ CountryCode2["STP"] = "STP";
246
+ CountryCode2["SAU"] = "SAU";
247
+ CountryCode2["SEN"] = "SEN";
248
+ CountryCode2["SRB"] = "SRB";
249
+ CountryCode2["SYC"] = "SYC";
250
+ CountryCode2["SLE"] = "SLE";
251
+ CountryCode2["SGP"] = "SGP";
252
+ CountryCode2["SXM"] = "SXM";
253
+ CountryCode2["SVK"] = "SVK";
254
+ CountryCode2["SVN"] = "SVN";
255
+ CountryCode2["SLB"] = "SLB";
256
+ CountryCode2["SOM"] = "SOM";
257
+ CountryCode2["ZAF"] = "ZAF";
258
+ CountryCode2["SGS"] = "SGS";
259
+ CountryCode2["SSD"] = "SSD";
260
+ CountryCode2["ESP"] = "ESP";
261
+ CountryCode2["LKA"] = "LKA";
262
+ CountryCode2["SDN"] = "SDN";
263
+ CountryCode2["SUR"] = "SUR";
264
+ CountryCode2["SJM"] = "SJM";
265
+ CountryCode2["SWE"] = "SWE";
266
+ CountryCode2["CHE"] = "CHE";
267
+ CountryCode2["SYR"] = "SYR";
268
+ CountryCode2["TWN"] = "TWN";
269
+ CountryCode2["TJK"] = "TJK";
270
+ CountryCode2["TZA"] = "TZA";
271
+ CountryCode2["THA"] = "THA";
272
+ CountryCode2["TLS"] = "TLS";
273
+ CountryCode2["TGO"] = "TGO";
274
+ CountryCode2["TKL"] = "TKL";
275
+ CountryCode2["TON"] = "TON";
276
+ CountryCode2["TTO"] = "TTO";
277
+ CountryCode2["TUN"] = "TUN";
278
+ CountryCode2["TUR"] = "TUR";
279
+ CountryCode2["TKM"] = "TKM";
280
+ CountryCode2["TCA"] = "TCA";
281
+ CountryCode2["TUV"] = "TUV";
282
+ CountryCode2["UGA"] = "UGA";
283
+ CountryCode2["UKR"] = "UKR";
284
+ CountryCode2["ARE"] = "ARE";
285
+ CountryCode2["GBR"] = "GBR";
286
+ CountryCode2["UMI"] = "UMI";
287
+ CountryCode2["USA"] = "USA";
288
+ CountryCode2["URY"] = "URY";
289
+ CountryCode2["UZB"] = "UZB";
290
+ CountryCode2["VUT"] = "VUT";
291
+ CountryCode2["VEN"] = "VEN";
292
+ CountryCode2["VNM"] = "VNM";
293
+ CountryCode2["VGB"] = "VGB";
294
+ CountryCode2["VIR"] = "VIR";
295
+ CountryCode2["WLF"] = "WLF";
296
+ CountryCode2["ESH"] = "ESH";
297
+ CountryCode2["YEM"] = "YEM";
298
+ CountryCode2["ZMB"] = "ZMB";
299
+ CountryCode2["ZWE"] = "ZWE";
300
+ CountryCode2["ALA"] = "ALA";
301
+ return CountryCode2;
302
+ })(CountryCode || {});
303
+ var CurrencyCode = /* @__PURE__ */ ((CurrencyCode2) => {
304
+ CurrencyCode2["AED"] = "AED";
305
+ CurrencyCode2["AFN"] = "AFN";
306
+ CurrencyCode2["ALL"] = "ALL";
307
+ CurrencyCode2["AMD"] = "AMD";
308
+ CurrencyCode2["ANG"] = "ANG";
309
+ CurrencyCode2["AOA"] = "AOA";
310
+ CurrencyCode2["ARS"] = "ARS";
311
+ CurrencyCode2["AUD"] = "AUD";
312
+ CurrencyCode2["AWG"] = "AWG";
313
+ CurrencyCode2["AZN"] = "AZN";
314
+ CurrencyCode2["BAM"] = "BAM";
315
+ CurrencyCode2["BBD"] = "BBD";
316
+ CurrencyCode2["BDT"] = "BDT";
317
+ CurrencyCode2["BGN"] = "BGN";
318
+ CurrencyCode2["BHD"] = "BHD";
319
+ CurrencyCode2["BIF"] = "BIF";
320
+ CurrencyCode2["BMD"] = "BMD";
321
+ CurrencyCode2["BND"] = "BND";
322
+ CurrencyCode2["BOB"] = "BOB";
323
+ CurrencyCode2["BOV"] = "BOV";
324
+ CurrencyCode2["BRL"] = "BRL";
325
+ CurrencyCode2["BSD"] = "BSD";
326
+ CurrencyCode2["BTN"] = "BTN";
327
+ CurrencyCode2["BWP"] = "BWP";
328
+ CurrencyCode2["BYN"] = "BYN";
329
+ CurrencyCode2["BZD"] = "BZD";
330
+ CurrencyCode2["CAD"] = "CAD";
331
+ CurrencyCode2["CDF"] = "CDF";
332
+ CurrencyCode2["CHE"] = "CHE";
333
+ CurrencyCode2["CHF"] = "CHF";
334
+ CurrencyCode2["CHW"] = "CHW";
335
+ CurrencyCode2["CLF"] = "CLF";
336
+ CurrencyCode2["CLP"] = "CLP";
337
+ CurrencyCode2["CNY"] = "CNY";
338
+ CurrencyCode2["COP"] = "COP";
339
+ CurrencyCode2["COU"] = "COU";
340
+ CurrencyCode2["CRC"] = "CRC";
341
+ CurrencyCode2["CUC"] = "CUC";
342
+ CurrencyCode2["CUP"] = "CUP";
343
+ CurrencyCode2["CVE"] = "CVE";
344
+ CurrencyCode2["CZK"] = "CZK";
345
+ CurrencyCode2["DJF"] = "DJF";
346
+ CurrencyCode2["DKK"] = "DKK";
347
+ CurrencyCode2["DOP"] = "DOP";
348
+ CurrencyCode2["DZD"] = "DZD";
349
+ CurrencyCode2["EGP"] = "EGP";
350
+ CurrencyCode2["ERN"] = "ERN";
351
+ CurrencyCode2["ETB"] = "ETB";
352
+ CurrencyCode2["EUR"] = "EUR";
353
+ CurrencyCode2["FJD"] = "FJD";
354
+ CurrencyCode2["FKP"] = "FKP";
355
+ CurrencyCode2["GBP"] = "GBP";
356
+ CurrencyCode2["GEL"] = "GEL";
357
+ CurrencyCode2["GHS"] = "GHS";
358
+ CurrencyCode2["GIP"] = "GIP";
359
+ CurrencyCode2["GMD"] = "GMD";
360
+ CurrencyCode2["GNF"] = "GNF";
361
+ CurrencyCode2["GTQ"] = "GTQ";
362
+ CurrencyCode2["GYD"] = "GYD";
363
+ CurrencyCode2["HKD"] = "HKD";
364
+ CurrencyCode2["HNL"] = "HNL";
365
+ CurrencyCode2["HRK"] = "HRK";
366
+ CurrencyCode2["HTG"] = "HTG";
367
+ CurrencyCode2["HUF"] = "HUF";
368
+ CurrencyCode2["IDR"] = "IDR";
369
+ CurrencyCode2["ILS"] = "ILS";
370
+ CurrencyCode2["INR"] = "INR";
371
+ CurrencyCode2["IQD"] = "IQD";
372
+ CurrencyCode2["IRR"] = "IRR";
373
+ CurrencyCode2["ISK"] = "ISK";
374
+ CurrencyCode2["JMD"] = "JMD";
375
+ CurrencyCode2["JOD"] = "JOD";
376
+ CurrencyCode2["JPY"] = "JPY";
377
+ CurrencyCode2["KES"] = "KES";
378
+ CurrencyCode2["KGS"] = "KGS";
379
+ CurrencyCode2["KHR"] = "KHR";
380
+ CurrencyCode2["KMF"] = "KMF";
381
+ CurrencyCode2["KPW"] = "KPW";
382
+ CurrencyCode2["KRW"] = "KRW";
383
+ CurrencyCode2["KWD"] = "KWD";
384
+ CurrencyCode2["KYD"] = "KYD";
385
+ CurrencyCode2["KZT"] = "KZT";
386
+ CurrencyCode2["LAK"] = "LAK";
387
+ CurrencyCode2["LBP"] = "LBP";
388
+ CurrencyCode2["LKR"] = "LKR";
389
+ CurrencyCode2["LRD"] = "LRD";
390
+ CurrencyCode2["LSL"] = "LSL";
391
+ CurrencyCode2["LYD"] = "LYD";
392
+ CurrencyCode2["MAD"] = "MAD";
393
+ CurrencyCode2["MDL"] = "MDL";
394
+ CurrencyCode2["MGA"] = "MGA";
395
+ CurrencyCode2["MKD"] = "MKD";
396
+ CurrencyCode2["MMK"] = "MMK";
397
+ CurrencyCode2["MNT"] = "MNT";
398
+ CurrencyCode2["MOP"] = "MOP";
399
+ CurrencyCode2["MRU"] = "MRU";
400
+ CurrencyCode2["MUR"] = "MUR";
401
+ CurrencyCode2["MVR"] = "MVR";
402
+ CurrencyCode2["MWK"] = "MWK";
403
+ CurrencyCode2["MXN"] = "MXN";
404
+ CurrencyCode2["MXV"] = "MXV";
405
+ CurrencyCode2["MYR"] = "MYR";
406
+ CurrencyCode2["MZN"] = "MZN";
407
+ CurrencyCode2["NAD"] = "NAD";
408
+ CurrencyCode2["NGN"] = "NGN";
409
+ CurrencyCode2["NIO"] = "NIO";
410
+ CurrencyCode2["NOK"] = "NOK";
411
+ CurrencyCode2["NPR"] = "NPR";
412
+ CurrencyCode2["NZD"] = "NZD";
413
+ CurrencyCode2["OMR"] = "OMR";
414
+ CurrencyCode2["PAB"] = "PAB";
415
+ CurrencyCode2["PEN"] = "PEN";
416
+ CurrencyCode2["PGK"] = "PGK";
417
+ CurrencyCode2["PHP"] = "PHP";
418
+ CurrencyCode2["PKR"] = "PKR";
419
+ CurrencyCode2["PLN"] = "PLN";
420
+ CurrencyCode2["PYG"] = "PYG";
421
+ CurrencyCode2["QAR"] = "QAR";
422
+ CurrencyCode2["RON"] = "RON";
423
+ CurrencyCode2["RSD"] = "RSD";
424
+ CurrencyCode2["RUB"] = "RUB";
425
+ CurrencyCode2["RWF"] = "RWF";
426
+ CurrencyCode2["SAR"] = "SAR";
427
+ CurrencyCode2["SBD"] = "SBD";
428
+ CurrencyCode2["SCR"] = "SCR";
429
+ CurrencyCode2["SDG"] = "SDG";
430
+ CurrencyCode2["SEK"] = "SEK";
431
+ CurrencyCode2["SGD"] = "SGD";
432
+ CurrencyCode2["SHP"] = "SHP";
433
+ CurrencyCode2["SLE"] = "SLE";
434
+ CurrencyCode2["SLL"] = "SLL";
435
+ CurrencyCode2["SOS"] = "SOS";
436
+ CurrencyCode2["SRD"] = "SRD";
437
+ CurrencyCode2["SSP"] = "SSP";
438
+ CurrencyCode2["STN"] = "STN";
439
+ CurrencyCode2["SVC"] = "SVC";
440
+ CurrencyCode2["SYP"] = "SYP";
441
+ CurrencyCode2["SZL"] = "SZL";
442
+ CurrencyCode2["THB"] = "THB";
443
+ CurrencyCode2["TJS"] = "TJS";
444
+ CurrencyCode2["TMT"] = "TMT";
445
+ CurrencyCode2["TND"] = "TND";
446
+ CurrencyCode2["TOP"] = "TOP";
447
+ CurrencyCode2["TRY"] = "TRY";
448
+ CurrencyCode2["TTD"] = "TTD";
449
+ CurrencyCode2["TWD"] = "TWD";
450
+ CurrencyCode2["TZS"] = "TZS";
451
+ CurrencyCode2["UAH"] = "UAH";
452
+ CurrencyCode2["UGX"] = "UGX";
453
+ CurrencyCode2["USD"] = "USD";
454
+ CurrencyCode2["USN"] = "USN";
455
+ CurrencyCode2["UYI"] = "UYI";
456
+ CurrencyCode2["UYU"] = "UYU";
457
+ CurrencyCode2["UYW"] = "UYW";
458
+ CurrencyCode2["UZS"] = "UZS";
459
+ CurrencyCode2["VED"] = "VED";
460
+ CurrencyCode2["VES"] = "VES";
461
+ CurrencyCode2["VND"] = "VND";
462
+ CurrencyCode2["VUV"] = "VUV";
463
+ CurrencyCode2["WST"] = "WST";
464
+ CurrencyCode2["XAF"] = "XAF";
465
+ CurrencyCode2["XAG"] = "XAG";
466
+ CurrencyCode2["XAU"] = "XAU";
467
+ CurrencyCode2["XBA"] = "XBA";
468
+ CurrencyCode2["XBB"] = "XBB";
469
+ CurrencyCode2["XBC"] = "XBC";
470
+ CurrencyCode2["XBD"] = "XBD";
471
+ CurrencyCode2["XCD"] = "XCD";
472
+ CurrencyCode2["XDR"] = "XDR";
473
+ CurrencyCode2["XOF"] = "XOF";
474
+ CurrencyCode2["XPD"] = "XPD";
475
+ CurrencyCode2["XPF"] = "XPF";
476
+ CurrencyCode2["XPT"] = "XPT";
477
+ CurrencyCode2["XSU"] = "XSU";
478
+ CurrencyCode2["XTS"] = "XTS";
479
+ CurrencyCode2["XUA"] = "XUA";
480
+ CurrencyCode2["XXX"] = "XXX";
481
+ CurrencyCode2["YER"] = "YER";
482
+ CurrencyCode2["ZAR"] = "ZAR";
483
+ CurrencyCode2["ZMW"] = "ZMW";
484
+ CurrencyCode2["ZWL"] = "ZWL";
485
+ return CurrencyCode2;
486
+ })(CurrencyCode || {});
487
+
488
+ // src/types/payment.ts
489
+ var ProductName = /* @__PURE__ */ ((ProductName2) => {
490
+ ProductName2["ONE_TIME_PAYMENT"] = "ONE_TIME_PAYMENT";
491
+ ProductName2["MINI_PROGRAM_PAYMENT"] = "MINI_PROGRAM_PAYMENT";
492
+ ProductName2["DIRECT_PAYMENT"] = "DIRECT_PAYMENT";
493
+ return ProductName2;
494
+ })(ProductName || {});
495
+ var SubscriptionProductName = /* @__PURE__ */ ((SubscriptionProductName2) => {
496
+ SubscriptionProductName2["SUBSCRIPTION"] = "SUBSCRIPTION";
497
+ SubscriptionProductName2["MINI_PROGRAM_SUBSCRIPTION"] = "MINI_PROGRAM_SUBSCRIPTION";
498
+ return SubscriptionProductName2;
499
+ })(SubscriptionProductName || {});
500
+
501
+ // src/types/order.ts
502
+ var UserTerminalType = /* @__PURE__ */ ((UserTerminalType2) => {
503
+ UserTerminalType2["WEB"] = "WEB";
504
+ UserTerminalType2["APP"] = "APP";
505
+ UserTerminalType2["IN_WALLET_APP"] = "IN_WALLET_APP";
506
+ UserTerminalType2["IN_MINI_PROGRAM"] = "IN_MINI_PROGRAM";
507
+ return UserTerminalType2;
508
+ })(UserTerminalType || {});
509
+ var OrderStatus = /* @__PURE__ */ ((OrderStatus2) => {
510
+ OrderStatus2["PAY_IN_PROGRESS"] = "PAY_IN_PROGRESS";
511
+ OrderStatus2["AUTHORIZATION_REQUIRED"] = "AUTHORIZATION_REQUIRED";
512
+ OrderStatus2["AUTHED_WAITING_CAPTURE"] = "AUTHED_WAITING_CAPTURE";
513
+ OrderStatus2["PAY_SUCCESS"] = "PAY_SUCCESS";
514
+ OrderStatus2["ORDER_CLOSE"] = "ORDER_CLOSE";
515
+ OrderStatus2["CAPTURE_IN_PROGRESS"] = "CAPTURE_IN_PROGRESS";
516
+ return OrderStatus2;
517
+ })(OrderStatus || {});
518
+ var OrderActionType = /* @__PURE__ */ ((OrderActionType2) => {
519
+ OrderActionType2["WEB"] = "WEB";
520
+ OrderActionType2["DEEPLINK"] = "DEEPLINK";
521
+ return OrderActionType2;
522
+ })(OrderActionType || {});
523
+ var PayMethodUserAccountType = /* @__PURE__ */ ((PayMethodUserAccountType2) => {
524
+ PayMethodUserAccountType2["EMAIL"] = "EMAIL";
525
+ PayMethodUserAccountType2["PHONE_NO"] = "PHONE_NO";
526
+ PayMethodUserAccountType2["ACCOUNT_ID"] = "ACCOUNT_ID";
527
+ return PayMethodUserAccountType2;
528
+ })(PayMethodUserAccountType || {});
529
+ var CaptureMode = /* @__PURE__ */ ((CaptureMode2) => {
530
+ CaptureMode2["MANUAL_CAPTURE"] = "manualCapture";
531
+ return CaptureMode2;
532
+ })(CaptureMode || {});
533
+ var MerchantInitiatedMode = /* @__PURE__ */ ((MerchantInitiatedMode2) => {
534
+ MerchantInitiatedMode2["SCHEDULED"] = "scheduled";
535
+ MerchantInitiatedMode2["UNSCHEDULED"] = "unscheduled";
536
+ return MerchantInitiatedMode2;
537
+ })(MerchantInitiatedMode || {});
538
+ var ThreeDsDecision = /* @__PURE__ */ ((ThreeDsDecision2) => {
539
+ ThreeDsDecision2["FORCE"] = "3DS_FORCE";
540
+ ThreeDsDecision2["ATTEMPT"] = "3DS_ATTEMPT";
541
+ ThreeDsDecision2["NO_3DS"] = "NO_3DS";
542
+ return ThreeDsDecision2;
543
+ })(ThreeDsDecision || {});
544
+
545
+ // src/types/refund.ts
546
+ var RefundStatus = /* @__PURE__ */ ((RefundStatus2) => {
547
+ RefundStatus2["REFUND_IN_PROGRESS"] = "REFUND_IN_PROGRESS";
548
+ RefundStatus2["ORDER_PARTIALLY_REFUNDED"] = "ORDER_PARTIALLY_REFUNDED";
549
+ RefundStatus2["ORDER_FULLY_REFUNDED"] = "ORDER_FULLY_REFUNDED";
550
+ RefundStatus2["ORDER_REFUND_FAILED"] = "ORDER_REFUND_FAILED";
551
+ return RefundStatus2;
552
+ })(RefundStatus || {});
553
+
554
+ // src/types/subscription.ts
555
+ var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
556
+ SubscriptionStatus2["AUTHORIZATION_REQUIRED"] = "AUTHORIZATION_REQUIRED";
557
+ SubscriptionStatus2["IN_PROGRESS"] = "IN_PROGRESS";
558
+ SubscriptionStatus2["ACTIVE"] = "ACTIVE";
559
+ SubscriptionStatus2["CLOSE"] = "CLOSE";
560
+ SubscriptionStatus2["MERCHANT_CANCELLED"] = "MERCHANT_CANCELLED";
561
+ SubscriptionStatus2["USER_CANCELLED"] = "USER_CANCELLED";
562
+ SubscriptionStatus2["CHANNEL_CANCELLED"] = "CHANNEL_CANCELLED";
563
+ SubscriptionStatus2["EXPIRED"] = "EXPIRED";
564
+ return SubscriptionStatus2;
565
+ })(SubscriptionStatus || {});
566
+ var PeriodType = /* @__PURE__ */ ((PeriodType2) => {
567
+ PeriodType2["DAILY"] = "DAILY";
568
+ PeriodType2["WEEKLY"] = "WEEKLY";
569
+ PeriodType2["MONTHLY"] = "MONTHLY";
570
+ return PeriodType2;
571
+ })(PeriodType || {});
572
+ var SubscriptionUserTerminalType = /* @__PURE__ */ ((SubscriptionUserTerminalType2) => {
573
+ SubscriptionUserTerminalType2["WEB"] = "WEB";
574
+ SubscriptionUserTerminalType2["APP"] = "APP";
575
+ return SubscriptionUserTerminalType2;
576
+ })(SubscriptionUserTerminalType || {});
577
+ var CashierLanguage = /* @__PURE__ */ ((CashierLanguage2) => {
578
+ CashierLanguage2["EN_HK"] = "en-HK";
579
+ CashierLanguage2["ZH_HANT_HK"] = "zh-Hant-HK";
580
+ CashierLanguage2["ZH_HANS_HK"] = "zh-Hans-HK";
581
+ return CashierLanguage2;
582
+ })(CashierLanguage || {});
583
+ var SubscriptionPayMethodUserAccountType = /* @__PURE__ */ ((SubscriptionPayMethodUserAccountType2) => {
584
+ SubscriptionPayMethodUserAccountType2["EMAIL"] = "EMAIL";
585
+ SubscriptionPayMethodUserAccountType2["PHONE_NO"] = "PHONE_NO";
586
+ SubscriptionPayMethodUserAccountType2["ACCOUNT_ID"] = "ACCOUNT_ID";
587
+ return SubscriptionPayMethodUserAccountType2;
588
+ })(SubscriptionPayMethodUserAccountType || {});
589
+ var SubscriptionOrderStatus = /* @__PURE__ */ ((SubscriptionOrderStatus2) => {
590
+ SubscriptionOrderStatus2["PAY_SUCCESS"] = "PAY_SUCCESS";
591
+ SubscriptionOrderStatus2["ORDER_CLOSE"] = "ORDER_CLOSE";
592
+ return SubscriptionOrderStatus2;
593
+ })(SubscriptionOrderStatus || {});
594
+ var SubscriptionEventType = /* @__PURE__ */ ((SubscriptionEventType2) => {
595
+ SubscriptionEventType2["SUBSCRIPTION_STATUS_NOTIFICATION"] = "SUBSCRIPTION_STATUS_NOTIFICATION";
596
+ SubscriptionEventType2["PAYMENT_NOTIFICATION"] = "PAYMENT_NOTIFICATION";
597
+ return SubscriptionEventType2;
598
+ })(SubscriptionEventType || {});
599
+ var SIGN_ALGORITHMS = "RSA-SHA256";
600
+ function signForRSA(body, privateKey, charSet = "utf8", onError) {
601
+ try {
602
+ const privateKeyDer = Buffer.from(privateKey, "base64");
603
+ const privateKeyPem = `-----BEGIN PRIVATE KEY-----
604
+ ${privateKeyDer.toString("base64").match(/.{1,64}/g)?.join("\n")}
605
+ -----END PRIVATE KEY-----`;
606
+ const signature = crypto.createSign(SIGN_ALGORITHMS);
607
+ signature.update(body, charSet);
608
+ const signed = signature.sign(privateKeyPem, "base64");
609
+ return signed;
610
+ } catch (e) {
611
+ onError?.(e instanceof Error ? e : new Error(String(e)));
612
+ return null;
613
+ }
614
+ }
615
+ function verify(body, sign, publicKey, charSet = "utf8", onError) {
616
+ try {
617
+ const publicKeyDer = Buffer.from(publicKey, "base64");
618
+ const publicKeyPem = `-----BEGIN PUBLIC KEY-----
619
+ ${publicKeyDer.toString("base64").match(/.{1,64}/g)?.join("\n")}
620
+ -----END PUBLIC KEY-----`;
621
+ const verifier = crypto.createVerify(SIGN_ALGORITHMS);
622
+ verifier.update(body, charSet);
623
+ const signatureBuffer = Buffer.from(sign, "base64");
624
+ return verifier.verify(publicKeyPem, signatureBuffer);
625
+ } catch (e) {
626
+ onError?.(e instanceof Error ? e : new Error(String(e)));
627
+ return false;
628
+ }
629
+ }
630
+ function createKeyPair() {
631
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
632
+ modulusLength: 2048,
633
+ publicKeyEncoding: {
634
+ type: "spki",
635
+ format: "der"
636
+ },
637
+ privateKeyEncoding: {
638
+ type: "pkcs8",
639
+ format: "der"
640
+ }
641
+ });
642
+ const keyMap = {
643
+ PRIVATE_KEY_NAME: privateKey.toString("base64"),
644
+ PUBLIC_KEY_NAME: publicKey.toString("base64")
645
+ };
646
+ return keyMap;
647
+ }
648
+
649
+ // src/utils/webhook.ts
650
+ function verifyWebhookSignature(requestBody, signature, waffoPublicKey) {
651
+ try {
652
+ const isValid = verify(requestBody, signature, waffoPublicKey);
653
+ if (!isValid) {
654
+ return {
655
+ isValid: false,
656
+ error: "Signature verification failed"
657
+ };
658
+ }
659
+ const notification = JSON.parse(requestBody);
660
+ const eventType = notification.eventType;
661
+ return {
662
+ isValid: true,
663
+ notification,
664
+ eventType
665
+ };
666
+ } catch (error) {
667
+ return {
668
+ isValid: false,
669
+ error: `Failed to verify webhook: ${error.message}`
670
+ };
671
+ }
672
+ }
673
+ function buildWebhookResponse(status, merchantPrivateKey) {
674
+ const body = {
675
+ message: status
676
+ };
677
+ const bodyString = JSON.stringify(body);
678
+ const signature = signForRSA(bodyString, merchantPrivateKey);
679
+ if (!signature) {
680
+ throw new Error("Failed to sign webhook response");
681
+ }
682
+ return {
683
+ header: {
684
+ "Content-Type": "application/json",
685
+ "X-SIGNATURE": signature
686
+ },
687
+ body
688
+ };
689
+ }
690
+ function buildSuccessResponse(merchantPrivateKey) {
691
+ return buildWebhookResponse(
692
+ "success" /* SUCCESS */,
693
+ merchantPrivateKey
694
+ );
695
+ }
696
+ function buildFailedResponse(merchantPrivateKey) {
697
+ return buildWebhookResponse("failed" /* FAILED */, merchantPrivateKey);
698
+ }
699
+ function getWebhookEventType(notification) {
700
+ try {
701
+ const parsed = typeof notification === "string" ? JSON.parse(notification) : notification;
702
+ return parsed.eventType;
703
+ } catch {
704
+ return void 0;
705
+ }
706
+ }
707
+ function isPaymentNotification(notification) {
708
+ return notification.eventType === "PAYMENT_NOTIFICATION" /* PAYMENT_NOTIFICATION */;
709
+ }
710
+ function isRefundNotification(notification) {
711
+ return notification.eventType === "REFUND_NOTIFICATION" /* REFUND_NOTIFICATION */;
712
+ }
713
+ function isSubscriptionStatusNotification(notification) {
714
+ return notification.eventType === "SUBSCRIPTION_STATUS_NOTIFICATION" /* SUBSCRIPTION_STATUS_NOTIFICATION */;
715
+ }
716
+ function isSubscriptionPaymentNotification(notification) {
717
+ return notification.eventType === "PAYMENT_NOTIFICATION" /* PAYMENT_NOTIFICATION */ && "subscriptionId" in notification.result;
718
+ }
719
+
720
+ // src/core/httpClient.ts
721
+ var HttpClient = class {
722
+ /**
723
+ * Creates an HTTP client instance with the provided SDK configuration.
724
+ *
725
+ * Resolves environment-specific settings such as API base URL and public key.
726
+ *
727
+ * @param {WaffoConfig} config - Waffo SDK configuration object
728
+ * @param {string} config.apiKey - API key assigned by Waffo
729
+ * @param {string} config.privateKey - Merchant private key (Base64 encoded PKCS8 DER)
730
+ * @param {string} [config.waffoPublicKey] - Waffo public key for response verification
731
+ * @param {Environment} [config.environment=Environment.PRODUCTION] - API environment
732
+ * @param {number} [config.timeout=30000] - Request timeout in milliseconds
733
+ * @param {Logger} [config.logger] - Logger instance for debugging
734
+ *
735
+ * @example
736
+ * const client = new HttpClient({
737
+ * apiKey: 'your-api-key',
738
+ * privateKey: 'your-private-key',
739
+ * environment: Environment.SANDBOX,
740
+ * });
741
+ *
742
+ * @see {@link WaffoConfig} for configuration options
743
+ */
744
+ constructor(config) {
745
+ const environment = config.environment || "production" /* PRODUCTION */;
746
+ this.config = {
747
+ apiKey: config.apiKey,
748
+ privateKey: config.privateKey,
749
+ waffoPublicKey: config.waffoPublicKey || EnvironmentPublicKeys[environment],
750
+ baseUrl: EnvironmentUrls[environment],
751
+ timeout: config.timeout || 3e4,
752
+ logger: config.logger
753
+ };
754
+ this.config.logger?.debug("[Waffo SDK] HttpClient initialized", {
755
+ environment,
756
+ baseUrl: this.config.baseUrl,
757
+ timeout: this.config.timeout
758
+ });
759
+ }
760
+ /**
761
+ * Generates an RSA-SHA256 signature for the request body.
762
+ *
763
+ * @param {string} payload - Request body string to sign (JSON serialized)
764
+ * @returns {string} Base64 encoded RSA-SHA256 signature
765
+ * @throws {Error} "Failed to generate RSA signature" when signing fails
766
+ * @private
767
+ */
768
+ generateSignature(payload) {
769
+ const signature = signForRSA(payload, this.config.privateKey);
770
+ if (!signature) {
771
+ throw new Error("Failed to generate RSA signature");
772
+ }
773
+ return signature;
774
+ }
775
+ /**
776
+ * Verifies the RSA-SHA256 signature of the response body.
777
+ *
778
+ * Ensures the response has not been tampered with during transmission.
779
+ *
780
+ * @param {string} responseBody - Response body string (raw JSON)
781
+ * @param {string} signature - X-SIGNATURE header value (Base64 encoded)
782
+ * @returns {boolean} `true` if signature is valid, `false` otherwise
783
+ * @private
784
+ */
785
+ verifyResponseSignature(responseBody, signature) {
786
+ return verify(responseBody, signature, this.config.waffoPublicKey);
787
+ }
788
+ /**
789
+ * Sends an HTTP POST request with automatic signing and verification.
790
+ *
791
+ * **Request Flow:**
792
+ * 1. Serializes the request body to JSON
793
+ * 2. Signs the request body using RSA-SHA256
794
+ * 3. Sends the request with X-API-KEY and X-SIGNATURE headers
795
+ * 4. Verifies the response signature using Waffo's public key
796
+ * 5. Parses and returns the response in standardized format
797
+ *
798
+ * **Error Handling:**
799
+ * - Network errors: `{ success: false, error: message }`
800
+ * - Timeout: status code 408 (REQUEST_TIMEOUT)
801
+ * - Invalid signature: returns error
802
+ * - Business errors (code !== "0"): parsed and returned as errors
803
+ *
804
+ * @template T - Expected response data type
805
+ * @template B - Request body type (must extend object)
806
+ *
807
+ * @param {string} endpoint - API endpoint path (e.g., '/order/create')
808
+ * @param {RequestOptions<B>} [options={}] - Request options
809
+ * @param {B} [options.body] - Request body object (will be JSON serialized)
810
+ * @param {Record<string, string>} [options.headers] - Additional request headers
811
+ *
812
+ * @returns {Promise<ApiResponse<T>>} Response object with success status and data/error
813
+ *
814
+ * @example
815
+ * // Make a POST request
816
+ * const result = await httpClient.post<CreateOrderData>('/order/create', {
817
+ * body: {
818
+ * paymentRequestId: 'req-123',
819
+ * merchantOrderId: 'order-456',
820
+ * // ... other fields
821
+ * },
822
+ * });
823
+ *
824
+ * if (result.success) {
825
+ * console.log('Order created:', result.data.acquiringOrderId);
826
+ * } else {
827
+ * console.error('Error:', result.error);
828
+ * }
829
+ *
830
+ * @example
831
+ * // Handle timeout errors
832
+ * const result = await httpClient.post('/order/create', { body: params });
833
+ * if (!result.success && result.statusCode === HttpStatusCode.REQUEST_TIMEOUT) {
834
+ * console.log('Request timed out, please retry');
835
+ * }
836
+ *
837
+ * @see {@link ApiResponse} for the response format
838
+ * @see {@link RequestOptions} for request options
839
+ */
840
+ async post(endpoint, options = {}) {
841
+ const { body, headers = {} } = options;
842
+ const payload = body ? JSON.stringify(body) : "";
843
+ const signature = this.generateSignature(payload);
844
+ const url = `${this.config.baseUrl}${endpoint}`;
845
+ this.config.logger?.debug("[Waffo SDK] Sending request", {
846
+ method: "POST",
847
+ url,
848
+ body
849
+ });
850
+ const controller = new AbortController();
851
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
852
+ try {
853
+ const response = await fetch(url, {
854
+ method: "POST",
855
+ headers: {
856
+ "Content-Type": "application/json",
857
+ "X-API-KEY": this.config.apiKey,
858
+ "X-SIGNATURE": signature,
859
+ ...headers
860
+ },
861
+ body: payload || void 0,
862
+ signal: controller.signal
863
+ });
864
+ clearTimeout(timeoutId);
865
+ const statusCode = response.status;
866
+ const responseSignature = response.headers.get("X-SIGNATURE");
867
+ const responseBody = await response.text();
868
+ this.config.logger?.debug("[Waffo SDK] Received response", {
869
+ statusCode,
870
+ hasSignature: !!responseSignature,
871
+ body: responseBody
872
+ });
873
+ if (!responseSignature) {
874
+ this.config.logger?.warn(
875
+ "[Waffo SDK] Missing X-SIGNATURE in response headers"
876
+ );
877
+ return {
878
+ success: false,
879
+ statusCode,
880
+ error: "Missing X-SIGNATURE in response headers"
881
+ };
882
+ }
883
+ const isValid = this.verifyResponseSignature(
884
+ responseBody,
885
+ responseSignature
886
+ );
887
+ if (!isValid) {
888
+ this.config.logger?.warn("[Waffo SDK] Invalid response signature");
889
+ return {
890
+ success: false,
891
+ statusCode,
892
+ error: "Invalid response signature"
893
+ };
894
+ }
895
+ let parsedBody = null;
896
+ try {
897
+ parsedBody = JSON.parse(responseBody);
898
+ } catch {
899
+ }
900
+ const isWaffoFormat = (body2) => {
901
+ return body2 !== null && typeof body2 === "object" && "code" in body2;
902
+ };
903
+ if (!response.ok) {
904
+ const errorMsg = isWaffoFormat(parsedBody) && parsedBody.msg ? `[${parsedBody.code}] ${parsedBody.msg}` : `HTTP ${response.status}: ${response.statusText}`;
905
+ this.config.logger?.error("[Waffo SDK] HTTP error", {
906
+ statusCode,
907
+ error: errorMsg
908
+ });
909
+ return {
910
+ success: false,
911
+ statusCode,
912
+ error: errorMsg
913
+ };
914
+ }
915
+ if (isWaffoFormat(parsedBody) && parsedBody.code && parsedBody.code !== "0") {
916
+ const errorMsg = `[${parsedBody.code}] ${parsedBody.msg || "Unknown error"}`;
917
+ this.config.logger?.error("[Waffo SDK] Business error", {
918
+ code: parsedBody.code,
919
+ msg: parsedBody.msg
920
+ });
921
+ return {
922
+ success: false,
923
+ statusCode,
924
+ error: errorMsg
925
+ };
926
+ }
927
+ const data = isWaffoFormat(parsedBody) ? parsedBody.data : parsedBody;
928
+ this.config.logger?.debug("[Waffo SDK] Request successful", { data });
929
+ return { success: true, statusCode, data };
930
+ } catch (error) {
931
+ clearTimeout(timeoutId);
932
+ if (error instanceof Error && error.name === "AbortError") {
933
+ this.config.logger?.error("[Waffo SDK] Request timeout", {
934
+ timeout: this.config.timeout,
935
+ url
936
+ });
937
+ return {
938
+ success: false,
939
+ statusCode: 408 /* REQUEST_TIMEOUT */,
940
+ error: `Request timeout after ${this.config.timeout}ms`
941
+ };
942
+ }
943
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
944
+ this.config.logger?.error("[Waffo SDK] Request failed", {
945
+ error: errorMessage,
946
+ url
947
+ });
948
+ return {
949
+ success: false,
950
+ statusCode: 500 /* INTERNAL_SERVER_ERROR */,
951
+ error: errorMessage
952
+ };
953
+ }
954
+ }
955
+ };
956
+
957
+ // src/core/webhook.ts
958
+ var WebhookHandler = class {
959
+ /**
960
+ * Creates a webhook handler instance.
961
+ *
962
+ * Initializes the handler with SDK configuration and resolves
963
+ * environment-specific settings such as Waffo's public key.
964
+ *
965
+ * @param {WaffoConfig} config - Waffo SDK configuration object
966
+ * @param {string} config.privateKey - Merchant private key (Base64 encoded PKCS8 DER)
967
+ * @param {string} [config.waffoPublicKey] - Waffo public key for request verification
968
+ * @param {Environment} [config.environment=Environment.PRODUCTION] - API environment
969
+ *
970
+ * @example
971
+ * // Typically created automatically by Waffo SDK
972
+ * const waffo = new Waffo(config);
973
+ * // Access via: waffo.webhook
974
+ *
975
+ * @see {@link WaffoConfig} for configuration options
976
+ */
977
+ constructor(config) {
978
+ const environment = config.environment || "production" /* PRODUCTION */;
979
+ this.config = {
980
+ privateKey: config.privateKey,
981
+ waffoPublicKey: config.waffoPublicKey || EnvironmentPublicKeys[environment]
982
+ };
983
+ }
984
+ /**
985
+ * Processes an incoming webhook notification from Waffo.
986
+ *
987
+ * **Processing Flow:**
988
+ * 1. Verifies the request signature using Waffo's public key
989
+ * 2. Parses the notification and determines its type
990
+ * 3. Routes to the appropriate handler based on event type
991
+ * 4. Returns a signed response to acknowledge receipt
992
+ *
993
+ * **Supported Event Types:**
994
+ * - `PAYMENT_NOTIFICATION` - Payment order status changes
995
+ * - `REFUND_NOTIFICATION` - Refund status changes
996
+ * - `SUBSCRIPTION_STATUS_NOTIFICATION` - Subscription status changes
997
+ * - `PAYMENT_NOTIFICATION` with subscriptionId - Subscription payments
998
+ *
999
+ * @param {string} requestBody - Raw request body string (JSON)
1000
+ * @param {string} signature - X-SIGNATURE header value from Waffo
1001
+ * @param {WebhookHandlerOptions} options - Handler configuration options
1002
+ *
1003
+ * @returns {Promise<WebhookHandlerResult>} Result with success status and signed response
1004
+ *
1005
+ * @example
1006
+ * // Express.js endpoint
1007
+ * app.post('/webhook', async (req, res) => {
1008
+ * const result = await waffo.webhook.handle(
1009
+ * JSON.stringify(req.body),
1010
+ * req.headers['x-signature'],
1011
+ * {
1012
+ * onPayment: async ({ notification }) => {
1013
+ * const { orderStatus, acquiringOrderId } = notification.result;
1014
+ * await db.orders.updateStatus(acquiringOrderId, orderStatus);
1015
+ * },
1016
+ * onRefund: async ({ notification }) => {
1017
+ * const { refundStatus } = notification.result;
1018
+ * await db.refunds.update(notification.result);
1019
+ * },
1020
+ * onSubscriptionStatus: async ({ notification }) => {
1021
+ * await db.subscriptions.update(notification.result);
1022
+ * },
1023
+ * onSubscriptionPayment: async ({ notification }) => {
1024
+ * await db.payments.create(notification.result);
1025
+ * },
1026
+ * onError: async (error) => {
1027
+ * logger.error('Webhook error', error);
1028
+ * },
1029
+ * }
1030
+ * );
1031
+ *
1032
+ * // Return signed response to Waffo
1033
+ * res.set(result.response.header).json(result.response.body);
1034
+ * });
1035
+ *
1036
+ * @example
1037
+ * // Next.js API route
1038
+ * export async function POST(request: Request) {
1039
+ * const body = await request.text();
1040
+ * const signature = request.headers.get('x-signature') || '';
1041
+ *
1042
+ * const result = await waffo.webhook.handle(body, signature, {
1043
+ * onPayment: async (ctx) => { ... },
1044
+ * });
1045
+ *
1046
+ * return new Response(JSON.stringify(result.response.body), {
1047
+ * headers: result.response.header,
1048
+ * });
1049
+ * }
1050
+ *
1051
+ * @see {@link WebhookHandlerOptions} for handler configuration
1052
+ * @see {@link WebhookHandlerResult} for return type
1053
+ */
1054
+ async handle(requestBody, signature, options = {}) {
1055
+ const {
1056
+ onPayment,
1057
+ onRefund,
1058
+ onSubscriptionStatus,
1059
+ onSubscriptionPayment,
1060
+ onError
1061
+ } = options;
1062
+ try {
1063
+ const verificationResult = verifyWebhookSignature(
1064
+ requestBody,
1065
+ signature,
1066
+ this.config.waffoPublicKey
1067
+ );
1068
+ if (!verificationResult.isValid) {
1069
+ const error = new Error(
1070
+ verificationResult.error || "Signature verification failed"
1071
+ );
1072
+ await onError?.(error);
1073
+ return {
1074
+ success: false,
1075
+ response: buildWebhookResponse(
1076
+ "failed" /* FAILED */,
1077
+ this.config.privateKey
1078
+ ),
1079
+ error: verificationResult.error
1080
+ };
1081
+ }
1082
+ const { notification, eventType } = verificationResult;
1083
+ if (!notification || !eventType) {
1084
+ const error = new Error("Invalid notification format");
1085
+ await onError?.(error);
1086
+ return {
1087
+ success: false,
1088
+ response: buildWebhookResponse(
1089
+ "failed" /* FAILED */,
1090
+ this.config.privateKey
1091
+ ),
1092
+ error: "Invalid notification format"
1093
+ };
1094
+ }
1095
+ if (isSubscriptionPaymentNotification(notification)) {
1096
+ await onSubscriptionPayment?.({
1097
+ notification,
1098
+ rawBody: requestBody,
1099
+ eventType
1100
+ });
1101
+ } else if (isPaymentNotification(notification)) {
1102
+ await onPayment?.({
1103
+ notification,
1104
+ rawBody: requestBody,
1105
+ eventType
1106
+ });
1107
+ } else if (isRefundNotification(notification)) {
1108
+ await onRefund?.({
1109
+ notification,
1110
+ rawBody: requestBody,
1111
+ eventType
1112
+ });
1113
+ } else if (isSubscriptionStatusNotification(notification)) {
1114
+ await onSubscriptionStatus?.({
1115
+ notification,
1116
+ rawBody: requestBody,
1117
+ eventType
1118
+ });
1119
+ }
1120
+ return {
1121
+ success: true,
1122
+ response: buildWebhookResponse(
1123
+ "success" /* SUCCESS */,
1124
+ this.config.privateKey
1125
+ )
1126
+ };
1127
+ } catch (error) {
1128
+ const err = error instanceof Error ? error : new Error(String(error));
1129
+ await onError?.(err);
1130
+ return {
1131
+ success: false,
1132
+ response: buildWebhookResponse(
1133
+ "failed" /* FAILED */,
1134
+ this.config.privateKey
1135
+ ),
1136
+ error: err.message
1137
+ };
1138
+ }
1139
+ }
1140
+ };
1141
+
1142
+ // src/resources/base.ts
1143
+ var BaseResource = class {
1144
+ /**
1145
+ * Initializes the base resource with HTTP client and base path.
1146
+ *
1147
+ * @param {HttpClient} client - HTTP client instance
1148
+ * @param {string} basePath - Base path for API endpoints
1149
+ * @protected
1150
+ */
1151
+ constructor(client, basePath) {
1152
+ this.client = client;
1153
+ this.basePath = basePath;
1154
+ }
1155
+ };
1156
+
1157
+ // src/resources/order/resource.ts
1158
+ var OrderResource = class extends BaseResource {
1159
+ /**
1160
+ * Creates an Order resource instance.
1161
+ * @param {HttpClient} client - HTTP client instance
1162
+ */
1163
+ constructor(client) {
1164
+ super(client, "/order");
1165
+ }
1166
+ /**
1167
+ * Creates a new payment order.
1168
+ *
1169
+ * Supports multiple payment methods including e-wallet, credit card,
1170
+ * bank transfer, and more.
1171
+ *
1172
+ * @param {CreateOrderParams} params - Order creation parameters
1173
+ * @returns {Promise<ApiResponse<CreateOrderData>>} Order creation result
1174
+ *
1175
+ * @example
1176
+ * const result = await waffo.order.create({
1177
+ * paymentRequestId: 'req-' + Date.now(),
1178
+ * merchantOrderId: 'order-456',
1179
+ * orderCurrency: 'IDR',
1180
+ * orderAmount: '100000',
1181
+ * orderDescription: 'Product purchase',
1182
+ * merchantInfo: { merchantId: 'M001' },
1183
+ * userInfo: {
1184
+ * userId: 'U001',
1185
+ * userEmail: 'user@example.com',
1186
+ * userTerminal: 'WEB',
1187
+ * },
1188
+ * goodsInfo: {
1189
+ * goodsName: 'Premium Plan',
1190
+ * goodsUrl: 'https://example.com/product',
1191
+ * },
1192
+ * paymentInfo: {
1193
+ * productName: 'ONE_TIME_PAYMENT',
1194
+ * payMethodName: 'DANA',
1195
+ * },
1196
+ * notifyUrl: 'https://example.com/webhook',
1197
+ * successRedirectUrl: 'https://example.com/success',
1198
+ * });
1199
+ *
1200
+ * if (result.success) {
1201
+ * // Redirect user to payment page
1202
+ * const redirectUrl = result.data.orderAction?.webUrl;
1203
+ * }
1204
+ *
1205
+ * @see {@link CreateOrderParams} for all available parameters
1206
+ */
1207
+ async create(params) {
1208
+ const body = {
1209
+ ...params,
1210
+ orderRequestedAt: params.orderRequestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1211
+ };
1212
+ return this.client.post(
1213
+ `${this.basePath}/create`,
1214
+ { body }
1215
+ );
1216
+ }
1217
+ /**
1218
+ * Queries current order status and details.
1219
+ *
1220
+ * Provide either `paymentRequestId` or `acquiringOrderId` to identify the order.
1221
+ *
1222
+ * @param {InquiryOrderParams} params - Query parameters
1223
+ * @returns {Promise<ApiResponse<InquiryOrderData>>} Order details
1224
+ *
1225
+ * @example
1226
+ * // Query by acquiring order ID
1227
+ * const result = await waffo.order.inquiry({
1228
+ * acquiringOrderId: 'ACQ123456789',
1229
+ * });
1230
+ *
1231
+ * if (result.success) {
1232
+ * console.log('Order status:', result.data.orderStatus);
1233
+ * console.log('Amount:', result.data.orderAmount, result.data.orderCurrency);
1234
+ * }
1235
+ *
1236
+ * @example
1237
+ * // Query by payment request ID
1238
+ * const result = await waffo.order.inquiry({
1239
+ * paymentRequestId: 'req-123',
1240
+ * });
1241
+ *
1242
+ * @see {@link InquiryOrderData} for response structure
1243
+ */
1244
+ async inquiry(params) {
1245
+ return this.client.post(
1246
+ `${this.basePath}/inquiry`,
1247
+ { body: params }
1248
+ );
1249
+ }
1250
+ /**
1251
+ * Cancels an unpaid order.
1252
+ *
1253
+ * Only orders with status `AUTHORIZATION_REQUIRED` or `PAY_IN_PROGRESS` can be canceled.
1254
+ *
1255
+ * @param {CancelOrderParams} params - Cancel parameters
1256
+ * @returns {Promise<ApiResponse<CancelOrderData>>} Cancellation result
1257
+ *
1258
+ * @example
1259
+ * const result = await waffo.order.cancel({
1260
+ * acquiringOrderId: 'ACQ123456789',
1261
+ * merchantId: 'M001',
1262
+ * });
1263
+ *
1264
+ * if (result.success) {
1265
+ * console.log('Order canceled:', result.data.orderStatus);
1266
+ * // => 'ORDER_CLOSE'
1267
+ * }
1268
+ *
1269
+ * @see {@link CancelOrderData} for response structure
1270
+ */
1271
+ async cancel(params) {
1272
+ const body = {
1273
+ ...params,
1274
+ orderRequestedAt: params.orderRequestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1275
+ };
1276
+ return this.client.post(
1277
+ `${this.basePath}/cancel`,
1278
+ { body }
1279
+ );
1280
+ }
1281
+ /**
1282
+ * Initiates a refund request for a paid order.
1283
+ *
1284
+ * Supports both full and partial refunds. Multiple partial refunds can be
1285
+ * made until the total refunded amount equals the original order amount.
1286
+ *
1287
+ * @param {RefundOrderParams} params - Refund parameters
1288
+ * @returns {Promise<ApiResponse<CreateRefundData>>} Refund request result
1289
+ *
1290
+ * @example
1291
+ * // Full refund
1292
+ * const result = await waffo.order.refund({
1293
+ * refundRequestId: 'refund-' + Date.now(),
1294
+ * acquiringOrderId: 'ACQ123456789',
1295
+ * merchantId: 'M001',
1296
+ * refundAmount: '100000',
1297
+ * refundReason: 'Customer request',
1298
+ * refundNotifyUrl: 'https://example.com/refund-webhook',
1299
+ * });
1300
+ *
1301
+ * if (result.success) {
1302
+ * console.log('Refund status:', result.data.refundStatus);
1303
+ * console.log('Remaining refundable:', result.data.remainingRefundAmount);
1304
+ * }
1305
+ *
1306
+ * @example
1307
+ * // Partial refund
1308
+ * const result = await waffo.order.refund({
1309
+ * refundRequestId: 'refund-partial-123',
1310
+ * acquiringOrderId: 'ACQ123456789',
1311
+ * merchantId: 'M001',
1312
+ * refundAmount: '50000', // Partial amount
1313
+ * refundReason: 'Partial refund',
1314
+ * });
1315
+ *
1316
+ * @see {@link CreateRefundData} for response structure
1317
+ */
1318
+ async refund(params) {
1319
+ const body = {
1320
+ ...params,
1321
+ requestedAt: params.requestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1322
+ };
1323
+ return this.client.post(
1324
+ `${this.basePath}/refund`,
1325
+ { body }
1326
+ );
1327
+ }
1328
+ /**
1329
+ * Captures an authorized payment (manualCapture mode only).
1330
+ *
1331
+ * Converts an authorization to an actual charge. Supports both
1332
+ * partial and full capture amounts.
1333
+ *
1334
+ * @param {CaptureOrderParams} params - Capture parameters
1335
+ * @returns {Promise<ApiResponse<CaptureOrderData>>} Capture result
1336
+ *
1337
+ * @example
1338
+ * // Full capture
1339
+ * const result = await waffo.order.capture({
1340
+ * acquiringOrderId: 'ACQ123456789',
1341
+ * merchantId: 'M001',
1342
+ * captureAmount: '100000', // Full authorized amount
1343
+ * });
1344
+ *
1345
+ * if (result.success) {
1346
+ * console.log('Capture status:', result.data.orderStatus);
1347
+ * }
1348
+ *
1349
+ * @example
1350
+ * // Partial capture
1351
+ * const result = await waffo.order.capture({
1352
+ * acquiringOrderId: 'ACQ123456789',
1353
+ * merchantId: 'M001',
1354
+ * captureAmount: '75000', // Capture less than authorized
1355
+ * });
1356
+ *
1357
+ * @see {@link CaptureOrderData} for response structure
1358
+ */
1359
+ async capture(params) {
1360
+ const body = {
1361
+ ...params,
1362
+ captureRequestedAt: params.captureRequestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1363
+ };
1364
+ return this.client.post(
1365
+ `${this.basePath}/capture`,
1366
+ { body }
1367
+ );
1368
+ }
1369
+ };
1370
+
1371
+ // src/resources/refund/resource.ts
1372
+ var RefundResource = class extends BaseResource {
1373
+ /**
1374
+ * Creates a Refund resource instance.
1375
+ * @param {HttpClient} client - HTTP client instance
1376
+ */
1377
+ constructor(client) {
1378
+ super(client, "/refund");
1379
+ }
1380
+ /**
1381
+ * Queries current refund status and details.
1382
+ *
1383
+ * Provide either `refundRequestId` or `acquiringRefundOrderId` to identify the refund.
1384
+ *
1385
+ * @param {RefundInquiryParams} params - Query parameters
1386
+ * @returns {Promise<ApiResponse<InquiryRefundData>>} Refund details
1387
+ *
1388
+ * @example
1389
+ * // Query by refund request ID
1390
+ * const result = await waffo.refund.inquiry({
1391
+ * refundRequestId: 'refund-123',
1392
+ * });
1393
+ *
1394
+ * if (result.success) {
1395
+ * const { refundStatus, refundAmount, remainingRefundAmount } = result.data;
1396
+ * console.log(`Status: ${refundStatus}`);
1397
+ * console.log(`Refunded: ${refundAmount}`);
1398
+ * console.log(`Remaining: ${remainingRefundAmount}`);
1399
+ * }
1400
+ *
1401
+ * @example
1402
+ * // Query by acquiring refund order ID
1403
+ * const result = await waffo.refund.inquiry({
1404
+ * acquiringRefundOrderId: 'REF123456789',
1405
+ * });
1406
+ *
1407
+ * @see {@link InquiryRefundData} for response structure
1408
+ */
1409
+ async inquiry(params) {
1410
+ return this.client.post(
1411
+ `${this.basePath}/inquiry`,
1412
+ { body: params }
1413
+ );
1414
+ }
1415
+ };
1416
+
1417
+ // src/resources/subscription/resource.ts
1418
+ var SubscriptionResource = class extends BaseResource {
1419
+ /**
1420
+ * Creates a Subscription resource instance.
1421
+ * @param {HttpClient} client - HTTP client instance
1422
+ */
1423
+ constructor(client) {
1424
+ super(client, "/subscription");
1425
+ }
1426
+ /**
1427
+ * Creates a new subscription signing request for recurring payments.
1428
+ *
1429
+ * After creation, redirect the user to the signing URL to authorize
1430
+ * the recurring payment agreement.
1431
+ *
1432
+ * @param {CreateSubscriptionParams} params - Subscription creation parameters
1433
+ * @returns {Promise<ApiResponse<CreateSubscriptionData>>} Subscription creation result
1434
+ *
1435
+ * @example
1436
+ * const result = await waffo.subscription.create({
1437
+ * subscriptionRequest: 'sub-' + Date.now(),
1438
+ * currency: 'HKD',
1439
+ * amount: '99.00',
1440
+ * productInfo: {
1441
+ * description: 'Premium Monthly Plan',
1442
+ * periodType: 'MONTHLY',
1443
+ * periodInterval: '1',
1444
+ * numberOfPeriod: '12', // 12 months
1445
+ * },
1446
+ * merchantInfo: { merchantId: 'M001' },
1447
+ * userInfo: {
1448
+ * userId: 'U001',
1449
+ * userEmail: 'user@example.com',
1450
+ * },
1451
+ * goodsInfo: {
1452
+ * goodsId: 'PREMIUM-PLAN',
1453
+ * goodsName: 'Premium Plan',
1454
+ * goodsUrl: 'https://example.com/plan',
1455
+ * },
1456
+ * paymentInfo: {
1457
+ * productName: 'SUBSCRIPTION',
1458
+ * payMethodName: 'ALIPAY_HK',
1459
+ * },
1460
+ * notifyUrl: 'https://example.com/webhook',
1461
+ * successRedirectUrl: 'https://example.com/success',
1462
+ * });
1463
+ *
1464
+ * if (result.success) {
1465
+ * // Redirect user to subscription signing page
1466
+ * const signingUrl = result.data.subscriptionAction?.webUrl;
1467
+ * }
1468
+ *
1469
+ * @see {@link CreateSubscriptionData} for response structure
1470
+ */
1471
+ async create(params) {
1472
+ const body = {
1473
+ ...params,
1474
+ requestedAt: params.requestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1475
+ };
1476
+ return this.client.post(
1477
+ `${this.basePath}/create`,
1478
+ { body }
1479
+ );
1480
+ }
1481
+ /**
1482
+ * Queries subscription details and optionally payment history.
1483
+ *
1484
+ * @param {InquirySubscriptionParams} params - Query parameters
1485
+ * @returns {Promise<ApiResponse<InquirySubscriptionData>>} Subscription details
1486
+ *
1487
+ * @example
1488
+ * // Query subscription status
1489
+ * const result = await waffo.subscription.inquiry({
1490
+ * subscriptionId: 'SUB123456789',
1491
+ * });
1492
+ *
1493
+ * if (result.success) {
1494
+ * console.log('Status:', result.data.subscriptionStatus);
1495
+ * console.log('Next payment:', result.data.productInfo.nextPaymentDateTime);
1496
+ * }
1497
+ *
1498
+ * @example
1499
+ * // Query with payment history
1500
+ * const result = await waffo.subscription.inquiry({
1501
+ * subscriptionId: 'SUB123456789',
1502
+ * paymentDetails: '1', // Include payment history
1503
+ * });
1504
+ *
1505
+ * if (result.success && result.data.paymentDetails) {
1506
+ * result.data.paymentDetails.forEach(payment => {
1507
+ * console.log(`Period ${payment.period}: ${payment.orderStatus}`);
1508
+ * });
1509
+ * }
1510
+ *
1511
+ * @see {@link InquirySubscriptionData} for response structure
1512
+ */
1513
+ async inquiry(params) {
1514
+ return this.client.post(
1515
+ `${this.basePath}/inquiry`,
1516
+ { body: params }
1517
+ );
1518
+ }
1519
+ /**
1520
+ * Cancels an active subscription.
1521
+ *
1522
+ * Once canceled, no further recurring payments will be processed.
1523
+ *
1524
+ * @param {CancelSubscriptionParams} params - Cancel parameters
1525
+ * @returns {Promise<ApiResponse<CancelSubscriptionData>>} Cancellation result
1526
+ *
1527
+ * @example
1528
+ * const result = await waffo.subscription.cancel({
1529
+ * subscriptionId: 'SUB123456789',
1530
+ * merchantId: 'M001',
1531
+ * });
1532
+ *
1533
+ * if (result.success) {
1534
+ * console.log('Subscription canceled:', result.data.orderStatus);
1535
+ * // => 'MERCHANT_CANCELLED'
1536
+ * }
1537
+ *
1538
+ * @see {@link CancelSubscriptionData} for response structure
1539
+ */
1540
+ async cancel(params) {
1541
+ const body = {
1542
+ ...params,
1543
+ requestedAt: params.requestedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1544
+ };
1545
+ return this.client.post(
1546
+ `${this.basePath}/cancel`,
1547
+ { body }
1548
+ );
1549
+ }
1550
+ /**
1551
+ * Generates a temporary management URL for users to manage their subscription.
1552
+ *
1553
+ * The URL allows users to view subscription details and cancel if needed.
1554
+ * The URL expires after a certain period (check `expiredAt` in response).
1555
+ *
1556
+ * @param {ManageSubscriptionParams} params - Management parameters
1557
+ * @returns {Promise<ApiResponse<ManageSubscriptionData>>} Management URL and expiration
1558
+ *
1559
+ * @example
1560
+ * const result = await waffo.subscription.manage({
1561
+ * subscriptionId: 'SUB123456789',
1562
+ * });
1563
+ *
1564
+ * if (result.success) {
1565
+ * console.log('Management URL:', result.data.managementUrl);
1566
+ * console.log('Expires at:', result.data.expiredAt);
1567
+ * // Send URL to user via email or display in app
1568
+ * }
1569
+ *
1570
+ * @see {@link ManageSubscriptionData} for response structure
1571
+ */
1572
+ async manage(params) {
1573
+ return this.client.post(
1574
+ `${this.basePath}/manage`,
1575
+ { body: params }
1576
+ );
1577
+ }
1578
+ };
1579
+
1580
+ // src/resources/merchantconfig/resource.ts
1581
+ var MerchantConfigResource = class extends BaseResource {
1582
+ /**
1583
+ * Creates a Merchant Config resource instance.
1584
+ * @param {HttpClient} client - HTTP client instance
1585
+ */
1586
+ constructor(client) {
1587
+ super(client, "/merchantconfig");
1588
+ }
1589
+ /**
1590
+ * Queries merchant configuration including transaction limits.
1591
+ *
1592
+ * @param {MerchantConfigInquiryParams} params - Query parameters
1593
+ * @returns {Promise<ApiResponse<MerchantConfigInquiryData>>} Merchant configuration
1594
+ *
1595
+ * @example
1596
+ * const result = await waffo.merchantConfig.inquiry({
1597
+ * merchantId: 'M001',
1598
+ * });
1599
+ *
1600
+ * if (result.success) {
1601
+ * const { totalDailyLimit, remainingDailyLimit, transactionLimit } = result.data;
1602
+ *
1603
+ * // Limits are returned as currency -> value maps
1604
+ * console.log('Daily limit (USD):', totalDailyLimit?.['USD']);
1605
+ * console.log('Remaining (USD):', remainingDailyLimit?.['USD']);
1606
+ * console.log('Per transaction (USD):', transactionLimit?.['USD']);
1607
+ * }
1608
+ *
1609
+ * @see {@link MerchantConfigInquiryData} for response structure
1610
+ */
1611
+ async inquiry(params) {
1612
+ return this.client.post(`${this.basePath}/inquiry`, { body: params });
1613
+ }
1614
+ };
1615
+
1616
+ // src/resources/paymethodconfig/resource.ts
1617
+ var PayMethodConfigResource = class extends BaseResource {
1618
+ /**
1619
+ * Creates a Pay Method Config resource instance.
1620
+ * @param {HttpClient} client - HTTP client instance
1621
+ */
1622
+ constructor(client) {
1623
+ super(client, "/paymethodconfig");
1624
+ }
1625
+ /**
1626
+ * Queries available payment methods and their status.
1627
+ *
1628
+ * @param {PayMethodConfigInquiryParams} params - Query parameters
1629
+ * @returns {Promise<ApiResponse<PayMethodConfigInquiryData>>} Payment method details
1630
+ *
1631
+ * @example
1632
+ * const result = await waffo.payMethodConfig.inquiry({
1633
+ * merchantId: 'M001',
1634
+ * });
1635
+ *
1636
+ * if (result.success) {
1637
+ * result.data.payMethodDetails.forEach(method => {
1638
+ * const status = method.currentStatus === '1' ? 'Available' : 'Unavailable';
1639
+ * console.log(`${method.payMethodName} (${method.country}): ${status}`);
1640
+ *
1641
+ * // Check maintenance windows
1642
+ * if (method.fixedMaintenanceRules?.length) {
1643
+ * console.log(' Maintenance:', method.fixedMaintenanceRules);
1644
+ * }
1645
+ * });
1646
+ * }
1647
+ *
1648
+ * @example
1649
+ * // Filter available e-wallet methods
1650
+ * const ewallets = result.data.payMethodDetails.filter(
1651
+ * m => m.currentStatus === '1' && m.productName === 'ONE_TIME_PAYMENT'
1652
+ * );
1653
+ *
1654
+ * @see {@link PayMethodConfigInquiryData} for response structure
1655
+ */
1656
+ async inquiry(params) {
1657
+ return this.client.post(`${this.basePath}/inquiry`, { body: params });
1658
+ }
1659
+ };
1660
+
1661
+ // src/core/waffo.ts
1662
+ var Waffo = class {
1663
+ /**
1664
+ * Creates a new Waffo SDK instance.
1665
+ *
1666
+ * Initializes the SDK with the provided configuration. The SDK automatically
1667
+ * selects the appropriate API endpoint and public key based on the environment.
1668
+ *
1669
+ * @param {WaffoConfig} config - SDK configuration object
1670
+ * @param {string} config.apiKey - API key assigned by Waffo (required)
1671
+ * @param {string} config.privateKey - Merchant private key, Base64 encoded PKCS8 DER format (required)
1672
+ * @param {string} [config.waffoPublicKey] - Waffo public key for response verification (optional)
1673
+ * @param {Environment} [config.environment=Environment.PRODUCTION] - API environment (optional)
1674
+ * @param {number} [config.timeout=30000] - Request timeout in milliseconds (optional)
1675
+ * @param {Logger} [config.logger] - Logger instance for debugging (optional)
1676
+ *
1677
+ * @throws {Error} When API key or private key is missing or invalid
1678
+ *
1679
+ * @example
1680
+ * // Production configuration
1681
+ * const waffo = new Waffo({
1682
+ * apiKey: process.env.WAFFO_API_KEY,
1683
+ * privateKey: process.env.WAFFO_PRIVATE_KEY,
1684
+ * environment: Environment.PRODUCTION,
1685
+ * });
1686
+ *
1687
+ * @example
1688
+ * // Sandbox configuration with debugging
1689
+ * const waffo = new Waffo({
1690
+ * apiKey: 'sandbox-api-key',
1691
+ * privateKey: 'sandbox-private-key',
1692
+ * environment: Environment.SANDBOX,
1693
+ * timeout: 60000,
1694
+ * logger: console,
1695
+ * });
1696
+ *
1697
+ * @see {@link WaffoConfig} for configuration options
1698
+ * @see {@link Environment} for available environments
1699
+ */
1700
+ constructor(config) {
1701
+ this.httpClient = new HttpClient(config);
1702
+ this.webhook = new WebhookHandler(config);
1703
+ this.order = new OrderResource(this.httpClient);
1704
+ this.refund = new RefundResource(this.httpClient);
1705
+ this.subscription = new SubscriptionResource(this.httpClient);
1706
+ this.merchantConfig = new MerchantConfigResource(this.httpClient);
1707
+ this.payMethodConfig = new PayMethodConfigResource(this.httpClient);
1708
+ }
1709
+ /**
1710
+ * Generates a new 2048-bit RSA key pair for API signing and verification.
1711
+ *
1712
+ * **Generated key formats:**
1713
+ * - Private key: Base64 encoded PKCS8 DER format (for signing requests)
1714
+ * - Public key: Base64 encoded X509/SPKI DER format (for verification)
1715
+ *
1716
+ * **Usage:**
1717
+ * 1. Generate a key pair using this method
1718
+ * 2. Register the public key with Waffo via merchant dashboard
1719
+ * 3. Store the private key securely on your server
1720
+ * 4. Use the private key when initializing the SDK
1721
+ *
1722
+ * @static
1723
+ * @returns {KeyPair} Object containing the generated key pair
1724
+ *
1725
+ * @example
1726
+ * // Generate a new key pair
1727
+ * const keys = Waffo.generateKeyPair();
1728
+ * console.log('Private Key:', keys.privateKey);
1729
+ * console.log('Public Key:', keys.publicKey);
1730
+ *
1731
+ * // Use the private key to initialize SDK
1732
+ * const waffo = new Waffo({
1733
+ * apiKey: 'your-api-key',
1734
+ * privateKey: keys.privateKey,
1735
+ * });
1736
+ *
1737
+ * @see {@link KeyPair} for the return type structure
1738
+ */
1739
+ static generateKeyPair() {
1740
+ const keys = createKeyPair();
1741
+ return {
1742
+ privateKey: keys.PRIVATE_KEY_NAME,
1743
+ publicKey: keys.PUBLIC_KEY_NAME
1744
+ };
1745
+ }
1746
+ };
1747
+
1748
+ export { CaptureMode, CashierLanguage, CountryCode, CurrencyCode, Environment, EnvironmentPublicKeys, EnvironmentUrls, HttpClient, HttpStatusCode, MerchantInitiatedMode, OrderActionType, OrderStatus, PayMethodUserAccountType, PeriodType, ProductName, RefundStatus, SubscriptionEventType, SubscriptionOrderStatus, SubscriptionPayMethodUserAccountType, SubscriptionProductName, SubscriptionStatus, SubscriptionUserTerminalType, ThreeDsDecision, UserTerminalType, Waffo, WebhookEventType, WebhookHandler, WebhookResponseStatus, buildFailedResponse, buildSuccessResponse, buildWebhookResponse, createKeyPair, getWebhookEventType, isPaymentNotification, isRefundNotification, isSubscriptionPaymentNotification, isSubscriptionStatusNotification, signForRSA, verify, verifyWebhookSignature };
1749
+ //# sourceMappingURL=index.mjs.map
1750
+ //# sourceMappingURL=index.mjs.map