@waffo/waffo-node 2.0.3 → 2.1.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.
package/dist/index.mjs CHANGED
@@ -1,1750 +1,1209 @@
1
- import crypto from 'crypto';
1
+ import * as crypto from 'crypto';
2
2
 
3
- // src/types/config.ts
3
+ // src/types/config/environment.ts
4
4
  var Environment = /* @__PURE__ */ ((Environment2) => {
5
- Environment2["SANDBOX"] = "sandbox";
6
- Environment2["PRODUCTION"] = "production";
5
+ Environment2["SANDBOX"] = "SANDBOX";
6
+ Environment2["PRODUCTION"] = "PRODUCTION";
7
7
  return Environment2;
8
8
  })(Environment || {});
9
- var EnvironmentUrls = {
10
- ["sandbox" /* SANDBOX */]: "https://api-sandbox.waffo.com/api/v1",
11
- ["production" /* PRODUCTION */]: "https://api.waffo.com/api/v1"
9
+ var EnvironmentBaseUrl = {
10
+ ["SANDBOX" /* SANDBOX */]: "https://api-sandbox.waffo.com/api/v1",
11
+ ["PRODUCTION" /* PRODUCTION */]: "https://api.waffo.com/api/v1"
12
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
13
 
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 || {});
14
+ // src/errors/waffo-error.ts
15
+ var WaffoError = class _WaffoError extends Error {
16
+ /** Error code identifying the type of error */
17
+ errorCode;
18
+ /** The underlying error that caused this error, if any */
19
+ cause;
20
+ /**
21
+ * Creates a new WaffoError.
22
+ *
23
+ * @param errorCode - The error code (e.g., "S0003" for signing failure)
24
+ * @param message - Human-readable error message
25
+ * @param cause - The underlying error that caused this error
26
+ */
27
+ constructor(errorCode, message, cause) {
28
+ super(message);
29
+ this.name = "WaffoError";
30
+ this.errorCode = errorCode;
31
+ this.cause = cause;
32
+ if (Error.captureStackTrace) {
33
+ Error.captureStackTrace(this, _WaffoError);
34
+ }
35
+ }
36
+ /**
37
+ * Returns a string representation of the error.
38
+ */
39
+ toString() {
40
+ return `[${this.errorCode}] ${this.message}`;
41
+ }
42
+ };
43
+ var WaffoErrorCode = {
44
+ /** Invalid public key */
45
+ INVALID_PUBLIC_KEY: "S0002",
46
+ /** Failed to sign data */
47
+ SIGN_FAILED: "S0003",
48
+ /** Response signature verification failed */
49
+ VERIFY_FAILED: "S0004",
50
+ /** Request serialization failed */
51
+ SERIALIZE_FAILED: "S0005",
52
+ /** Unexpected error */
53
+ UNEXPECTED: "S0006",
54
+ /** Invalid private key */
55
+ INVALID_PRIVATE_KEY: "S0007"
56
+ };
544
57
 
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 || {});
58
+ // src/errors/waffo-unknown-status-error.ts
59
+ var WaffoUnknownStatusError = class _WaffoUnknownStatusError extends Error {
60
+ /** Error code for network errors */
61
+ static CODE_NETWORK_ERROR = "S0001";
62
+ /** Error code for unknown server status */
63
+ static CODE_UNKNOWN_STATUS = "E0001";
64
+ /** Error code identifying the type of error */
65
+ errorCode;
66
+ /** The underlying error that caused this error, if any */
67
+ cause;
68
+ /**
69
+ * Creates a new WaffoUnknownStatusError.
70
+ *
71
+ * @param errorCode - The error code (e.g., "S0001" for network error)
72
+ * @param message - Human-readable error message
73
+ * @param cause - The underlying error that caused this error
74
+ */
75
+ constructor(errorCode, message, cause) {
76
+ super(message);
77
+ this.name = "WaffoUnknownStatusError";
78
+ this.errorCode = errorCode;
79
+ this.cause = cause;
80
+ if (Error.captureStackTrace) {
81
+ Error.captureStackTrace(this, _WaffoUnknownStatusError);
82
+ }
83
+ }
84
+ /**
85
+ * Returns a string representation of the error.
86
+ */
87
+ toString() {
88
+ return `[${this.errorCode}] ${this.message}`;
89
+ }
90
+ };
553
91
 
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) {
92
+ // src/utils/rsa-utils.ts
93
+ var ALGORITHM = "RSA-SHA256";
94
+ var KEY_SIZE = 2048;
95
+ function sign(data, base64PrivateKey) {
601
96
  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;
97
+ const privateKeyBuffer = Buffer.from(base64PrivateKey, "base64");
98
+ const signer = crypto.createSign(ALGORITHM);
99
+ signer.update(data, "utf8");
100
+ const signature = signer.sign({
101
+ key: privateKeyBuffer,
102
+ format: "der",
103
+ type: "pkcs8"
104
+ });
105
+ return signature.toString("base64");
106
+ } catch (error) {
107
+ throw new WaffoError(
108
+ WaffoErrorCode.SIGN_FAILED,
109
+ `Failed to sign data: ${error instanceof Error ? error.message : String(error)}`,
110
+ error instanceof Error ? error : void 0
111
+ );
613
112
  }
614
113
  }
615
- function verify(body, sign, publicKey, charSet = "utf8", onError) {
114
+ function verify(data, base64Signature, base64PublicKey) {
616
115
  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)));
116
+ const publicKeyBuffer = Buffer.from(base64PublicKey, "base64");
117
+ const signatureBuffer = Buffer.from(base64Signature, "base64");
118
+ const verifier = crypto.createVerify(ALGORITHM);
119
+ verifier.update(data, "utf8");
120
+ return verifier.verify(
121
+ {
122
+ key: publicKeyBuffer,
123
+ format: "der",
124
+ type: "spki"
125
+ },
126
+ signatureBuffer
127
+ );
128
+ } catch {
627
129
  return false;
628
130
  }
629
131
  }
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"
132
+ function validatePrivateKey(base64PrivateKey) {
133
+ if (!base64PrivateKey || base64PrivateKey.trim() === "") {
134
+ throw new WaffoError(
135
+ WaffoErrorCode.INVALID_PRIVATE_KEY,
136
+ "Private key is null or empty"
137
+ );
138
+ }
139
+ try {
140
+ const keyBuffer = Buffer.from(base64PrivateKey, "base64");
141
+ crypto.createPrivateKey({
142
+ key: keyBuffer,
143
+ format: "der",
144
+ type: "pkcs8"
145
+ });
146
+ } catch (error) {
147
+ if (error instanceof WaffoError) throw error;
148
+ const message = error instanceof Error ? error.message : String(error);
149
+ if (message.includes("bad base64")) {
150
+ throw new WaffoError(
151
+ WaffoErrorCode.INVALID_PRIVATE_KEY,
152
+ "Invalid private key: not valid Base64 encoding",
153
+ error instanceof Error ? error : void 0
154
+ );
640
155
  }
641
- });
642
- const keyMap = {
643
- PRIVATE_KEY_NAME: privateKey.toString("base64"),
644
- PUBLIC_KEY_NAME: publicKey.toString("base64")
645
- };
646
- return keyMap;
156
+ throw new WaffoError(
157
+ WaffoErrorCode.INVALID_PRIVATE_KEY,
158
+ `Invalid private key: ${message}`,
159
+ error instanceof Error ? error : void 0
160
+ );
161
+ }
647
162
  }
648
-
649
- // src/utils/webhook.ts
650
- function verifyWebhookSignature(requestBody, signature, waffoPublicKey) {
163
+ function validatePublicKey(base64PublicKey) {
164
+ if (!base64PublicKey || base64PublicKey.trim() === "") {
165
+ throw new WaffoError(
166
+ WaffoErrorCode.INVALID_PUBLIC_KEY,
167
+ "Public key is null or empty"
168
+ );
169
+ }
651
170
  try {
652
- const isValid = verify(requestBody, signature, waffoPublicKey);
653
- if (!isValid) {
654
- return {
655
- isValid: false,
656
- error: "Signature verification failed"
657
- };
171
+ const keyBuffer = Buffer.from(base64PublicKey, "base64");
172
+ crypto.createPublicKey({
173
+ key: keyBuffer,
174
+ format: "der",
175
+ type: "spki"
176
+ });
177
+ } catch (error) {
178
+ if (error instanceof WaffoError) throw error;
179
+ const message = error instanceof Error ? error.message : String(error);
180
+ if (message.includes("bad base64")) {
181
+ throw new WaffoError(
182
+ WaffoErrorCode.INVALID_PUBLIC_KEY,
183
+ "Invalid public key: not valid Base64 encoding",
184
+ error instanceof Error ? error : void 0
185
+ );
658
186
  }
659
- const notification = JSON.parse(requestBody);
660
- const eventType = notification.eventType;
187
+ throw new WaffoError(
188
+ WaffoErrorCode.INVALID_PUBLIC_KEY,
189
+ `Invalid public key: ${message}`,
190
+ error instanceof Error ? error : void 0
191
+ );
192
+ }
193
+ }
194
+ function generateKeyPair() {
195
+ try {
196
+ const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
197
+ modulusLength: KEY_SIZE,
198
+ publicKeyEncoding: {
199
+ type: "spki",
200
+ format: "der"
201
+ },
202
+ privateKeyEncoding: {
203
+ type: "pkcs8",
204
+ format: "der"
205
+ }
206
+ });
661
207
  return {
662
- isValid: true,
663
- notification,
664
- eventType
208
+ privateKey: privateKey.toString("base64"),
209
+ publicKey: publicKey.toString("base64")
665
210
  };
666
211
  } catch (error) {
667
- return {
668
- isValid: false,
669
- error: `Failed to verify webhook: ${error.message}`
670
- };
212
+ throw new WaffoError(
213
+ WaffoErrorCode.SIGN_FAILED,
214
+ `Failed to generate key pair: ${error instanceof Error ? error.message : String(error)}`,
215
+ error instanceof Error ? error : void 0
216
+ );
671
217
  }
672
218
  }
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");
219
+ var RsaUtils = {
220
+ sign,
221
+ verify,
222
+ validatePrivateKey,
223
+ validatePublicKey,
224
+ generateKeyPair
225
+ };
226
+
227
+ // src/types/config/waffo-config.ts
228
+ var WaffoConfigEnvVars = {
229
+ API_KEY: "WAFFO_API_KEY",
230
+ PRIVATE_KEY: "WAFFO_PRIVATE_KEY",
231
+ PUBLIC_KEY: "WAFFO_PUBLIC_KEY",
232
+ MERCHANT_ID: "WAFFO_MERCHANT_ID",
233
+ ENVIRONMENT: "WAFFO_ENVIRONMENT"
234
+ };
235
+ var WaffoConfigDefaults = {
236
+ CONNECT_TIMEOUT: 1e4,
237
+ READ_TIMEOUT: 3e4
238
+ };
239
+ function createWaffoConfig(config) {
240
+ if (!config.apiKey) {
241
+ throw new Error("apiKey is required");
242
+ }
243
+ if (!config.privateKey) {
244
+ throw new Error("privateKey is required");
245
+ }
246
+ if (!config.waffoPublicKey) {
247
+ throw new Error("waffoPublicKey is required");
681
248
  }
249
+ if (!config.environment) {
250
+ throw new Error("environment is required (SANDBOX or PRODUCTION)");
251
+ }
252
+ if (!config.merchantId) {
253
+ throw new Error("merchantId is required");
254
+ }
255
+ RsaUtils.validatePrivateKey(config.privateKey);
256
+ RsaUtils.validatePublicKey(config.waffoPublicKey);
682
257
  return {
683
- header: {
684
- "Content-Type": "application/json",
685
- "X-SIGNATURE": signature
686
- },
687
- body
258
+ ...config,
259
+ connectTimeout: config.connectTimeout ?? WaffoConfigDefaults.CONNECT_TIMEOUT,
260
+ readTimeout: config.readTimeout ?? WaffoConfigDefaults.READ_TIMEOUT
688
261
  };
689
262
  }
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;
263
+ function fromEnv() {
264
+ const getEnv = (name, required = true) => {
265
+ const value = process.env[name];
266
+ if (required && (!value || value.trim() === "")) {
267
+ throw new Error(`Required environment variable ${name} is not set`);
268
+ }
269
+ return value || "";
270
+ };
271
+ const apiKey = getEnv(WaffoConfigEnvVars.API_KEY);
272
+ const privateKey = getEnv(WaffoConfigEnvVars.PRIVATE_KEY);
273
+ const waffoPublicKey = getEnv(WaffoConfigEnvVars.PUBLIC_KEY);
274
+ const envStr = getEnv(WaffoConfigEnvVars.ENVIRONMENT);
275
+ const merchantId = getEnv(WaffoConfigEnvVars.MERCHANT_ID);
276
+ const environment = envStr.toUpperCase();
277
+ if (environment !== "SANDBOX" /* SANDBOX */ && environment !== "PRODUCTION" /* PRODUCTION */) {
278
+ throw new Error(
279
+ `Invalid ${WaffoConfigEnvVars.ENVIRONMENT} value: ${envStr}. Must be SANDBOX or PRODUCTION`
280
+ );
705
281
  }
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;
282
+ return createWaffoConfig({
283
+ apiKey,
284
+ privateKey,
285
+ waffoPublicKey,
286
+ environment,
287
+ merchantId
288
+ });
718
289
  }
719
290
 
720
- // src/core/httpClient.ts
721
- var HttpClient = class {
291
+ // src/types/api-response.ts
292
+ var ApiResponse = class _ApiResponse {
293
+ /** Response code. "0" indicates success, other values indicate errors. */
294
+ code;
295
+ /** Response data (present when code is "0") */
296
+ data;
297
+ /** Error message (present when code is not "0") */
298
+ message;
299
+ constructor(code, data, message) {
300
+ this.code = code;
301
+ this.data = data;
302
+ this.message = message;
303
+ }
722
304
  /**
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
- * });
305
+ * Creates a successful response.
741
306
  *
742
- * @see {@link WaffoConfig} for configuration options
307
+ * @param data - The response data
743
308
  */
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
- });
309
+ static success(data) {
310
+ return new _ApiResponse("0", data);
759
311
  }
760
312
  /**
761
- * Generates an RSA-SHA256 signature for the request body.
313
+ * Creates an error response.
762
314
  *
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
315
+ * @param code - The error code
316
+ * @param message - The error message
767
317
  */
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;
318
+ static error(code, message) {
319
+ return new _ApiResponse(code, void 0, message);
774
320
  }
775
321
  /**
776
- * Verifies the RSA-SHA256 signature of the response body.
322
+ * Checks if the response indicates success.
777
323
  *
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
324
+ * @returns true if the response code is "0"
784
325
  */
785
- verifyResponseSignature(responseBody, signature) {
786
- return verify(responseBody, signature, this.config.waffoPublicKey);
326
+ isSuccess() {
327
+ return this.code === "0";
787
328
  }
788
329
  /**
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
330
+ * Gets the response data.
803
331
  *
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
332
+ * @returns The response data, or undefined if the response is an error
333
+ */
334
+ getData() {
335
+ return this.data;
336
+ }
337
+ /**
338
+ * Gets the error message.
811
339
  *
812
- * @returns {Promise<ApiResponse<T>>} Response object with success status and data/error
340
+ * @returns The error message, or undefined if the response is successful
341
+ */
342
+ getMessage() {
343
+ return this.message;
344
+ }
345
+ /**
346
+ * Gets the response code.
813
347
  *
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
- * });
348
+ * @returns The response code
349
+ */
350
+ getCode() {
351
+ return this.code;
352
+ }
353
+ /**
354
+ * Gets the response data or throws an error.
823
355
  *
824
- * if (result.success) {
825
- * console.log('Order created:', result.data.acquiringOrderId);
826
- * } else {
827
- * console.error('Error:', result.error);
828
- * }
356
+ * @returns The response data
357
+ * @throws Error if the response is not successful or data is undefined
358
+ */
359
+ getDataOrThrow() {
360
+ if (!this.isSuccess()) {
361
+ throw new Error(`[${this.code}] ${this.message ?? "API error"}`);
362
+ }
363
+ if (this.data === void 0) {
364
+ throw new Error("Response data is undefined");
365
+ }
366
+ return this.data;
367
+ }
368
+ };
369
+
370
+ // src/net/default-http-transport.ts
371
+ var DefaultHttpTransport = class {
372
+ /**
373
+ * Sends an HTTP request using native fetch.
829
374
  *
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
- * }
375
+ * @param request - The HTTP request to send
376
+ * @returns The HTTP response
377
+ * @throws Error if the request fails (network error, timeout, etc.)
378
+ */
379
+ async send(request) {
380
+ const connectController = new AbortController();
381
+ let connectTimeoutId;
382
+ let readTimeoutId;
383
+ let timeoutPhase = "connect";
384
+ try {
385
+ connectTimeoutId = setTimeout(() => {
386
+ connectController.abort();
387
+ }, request.connectTimeout);
388
+ const response = await fetch(request.url, {
389
+ method: request.method,
390
+ headers: request.headers,
391
+ body: request.body,
392
+ signal: connectController.signal
393
+ });
394
+ clearTimeout(connectTimeoutId);
395
+ connectTimeoutId = void 0;
396
+ timeoutPhase = "read";
397
+ const readController = new AbortController();
398
+ readTimeoutId = setTimeout(() => {
399
+ readController.abort();
400
+ }, request.readTimeout);
401
+ const body = await Promise.race([
402
+ response.text(),
403
+ new Promise((_, reject) => {
404
+ readController.signal.addEventListener("abort", () => {
405
+ reject(new Error("AbortError"));
406
+ });
407
+ })
408
+ ]);
409
+ clearTimeout(readTimeoutId);
410
+ readTimeoutId = void 0;
411
+ const headers = {};
412
+ response.headers.forEach((value, key) => {
413
+ headers[key.toLowerCase()] = value;
414
+ });
415
+ return {
416
+ statusCode: response.status,
417
+ headers,
418
+ body
419
+ };
420
+ } catch (error) {
421
+ if (error instanceof Error) {
422
+ if (error.name === "AbortError" || error.message === "AbortError") {
423
+ const timeout = timeoutPhase === "connect" ? request.connectTimeout : request.readTimeout;
424
+ throw new Error(`Request ${timeoutPhase} timeout after ${timeout}ms`);
425
+ }
426
+ throw error;
427
+ }
428
+ throw new Error(`HTTP request failed: ${String(error)}`);
429
+ } finally {
430
+ if (connectTimeoutId) clearTimeout(connectTimeoutId);
431
+ if (readTimeoutId) clearTimeout(readTimeoutId);
432
+ }
433
+ }
434
+ };
435
+
436
+ // src/core/waffo-http-client.ts
437
+ var HEADER_API_KEY = "x-api-key";
438
+ var HEADER_SIGNATURE = "x-signature";
439
+ var HEADER_API_VERSION = "x-api-version";
440
+ var HEADER_SDK_VERSION = "x-sdk-version";
441
+ var HEADER_CONTENT_TYPE = "content-type";
442
+ var CONTENT_TYPE_JSON = "application/json";
443
+ var API_VERSION = "1.0.0";
444
+ var SDK_VERSION = "waffo-node/2.1.0";
445
+ var WaffoHttpClient = class {
446
+ baseUrl;
447
+ apiKey;
448
+ privateKey;
449
+ waffoPublicKey;
450
+ merchantId;
451
+ connectTimeout;
452
+ readTimeout;
453
+ logger;
454
+ httpTransport;
455
+ constructor(config) {
456
+ this.baseUrl = EnvironmentBaseUrl[config.environment];
457
+ this.apiKey = config.apiKey;
458
+ this.privateKey = config.privateKey;
459
+ this.waffoPublicKey = config.waffoPublicKey;
460
+ this.merchantId = config.merchantId;
461
+ this.connectTimeout = config.connectTimeout ?? WaffoConfigDefaults.CONNECT_TIMEOUT;
462
+ this.readTimeout = config.readTimeout ?? WaffoConfigDefaults.READ_TIMEOUT;
463
+ this.logger = config.logger;
464
+ this.httpTransport = config.httpTransport ?? new DefaultHttpTransport();
465
+ }
466
+ /**
467
+ * Sends a POST request to the Waffo API.
836
468
  *
837
- * @see {@link ApiResponse} for the response format
838
- * @see {@link RequestOptions} for request options
469
+ * @param path - API endpoint path (e.g., "/order/create")
470
+ * @param request - Request body
471
+ * @param options - Per-request options
472
+ * @returns API response
473
+ * @throws WaffoUnknownStatusError for network errors or unknown status
839
474
  */
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);
475
+ async post(path, request, options) {
476
+ const url = this.baseUrl + path;
477
+ const effectiveConnectTimeout = options?.connectTimeout ?? this.connectTimeout;
478
+ const effectiveReadTimeout = options?.readTimeout ?? this.readTimeout;
852
479
  try {
853
- const response = await fetch(url, {
480
+ this.injectMerchantIdIfNeeded(request);
481
+ const requestBody = JSON.stringify(request);
482
+ const signature = RsaUtils.sign(requestBody, this.privateKey);
483
+ this.logger?.debug(`Request URL: ${url}`);
484
+ this.logger?.debug(`Request Body: ${requestBody}`);
485
+ const httpResponse = await this.httpTransport.send({
486
+ url,
854
487
  method: "POST",
855
488
  headers: {
856
- "Content-Type": "application/json",
857
- "X-API-KEY": this.config.apiKey,
858
- "X-SIGNATURE": signature,
859
- ...headers
489
+ [HEADER_CONTENT_TYPE]: CONTENT_TYPE_JSON,
490
+ [HEADER_API_KEY]: this.apiKey,
491
+ [HEADER_SIGNATURE]: signature,
492
+ [HEADER_API_VERSION]: API_VERSION,
493
+ [HEADER_SDK_VERSION]: SDK_VERSION
860
494
  },
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
495
+ body: requestBody,
496
+ connectTimeout: effectiveConnectTimeout,
497
+ readTimeout: effectiveReadTimeout
872
498
  });
873
- if (!responseSignature) {
874
- this.config.logger?.warn(
875
- "[Waffo SDK] Missing X-SIGNATURE in response headers"
499
+ this.logger?.debug(`Response Status: ${httpResponse.statusCode}`);
500
+ this.logger?.debug(`Response Body: ${httpResponse.body}`);
501
+ const responseSignature = httpResponse.headers[HEADER_SIGNATURE];
502
+ if (responseSignature) {
503
+ const isValid = RsaUtils.verify(
504
+ httpResponse.body,
505
+ responseSignature,
506
+ this.waffoPublicKey
876
507
  );
877
- return {
878
- success: false,
879
- statusCode,
880
- error: "Missing X-SIGNATURE in response headers"
881
- };
508
+ if (!isValid) {
509
+ this.logger?.error("Response signature verification failed");
510
+ return ApiResponse.error(
511
+ WaffoErrorCode.VERIFY_FAILED,
512
+ "Response signature verification failed"
513
+ );
514
+ }
882
515
  }
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
- };
516
+ const response = this.parseResponse(httpResponse.body);
517
+ if (response.code === "E0001") {
518
+ throw new WaffoUnknownStatusError(
519
+ WaffoUnknownStatusError.CODE_UNKNOWN_STATUS,
520
+ response.getMessage() ?? "Unknown status from server"
521
+ );
894
522
  }
895
- let parsedBody = null;
896
- try {
897
- parsedBody = JSON.parse(responseBody);
898
- } catch {
523
+ return response;
524
+ } catch (error) {
525
+ if (error instanceof WaffoUnknownStatusError) {
526
+ throw error;
899
527
  }
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
- };
528
+ if (this.isNetworkError(error)) {
529
+ this.logger?.error("Network error", error);
530
+ throw new WaffoUnknownStatusError(
531
+ WaffoUnknownStatusError.CODE_NETWORK_ERROR,
532
+ `Network error, payment status unknown: ${error instanceof Error ? error.message : String(error)}`,
533
+ error instanceof Error ? error : void 0
534
+ );
914
535
  }
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
- };
536
+ if (error instanceof SyntaxError) {
537
+ this.logger?.error("JSON serialization error", error);
538
+ return ApiResponse.error(
539
+ WaffoErrorCode.SERIALIZE_FAILED,
540
+ `Request serialization failed: ${error.message}`
541
+ );
926
542
  }
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
- };
543
+ this.logger?.error("Unexpected error", error);
544
+ return ApiResponse.error(
545
+ WaffoErrorCode.UNEXPECTED,
546
+ `Unexpected error: ${error instanceof Error ? error.message : String(error)}`
547
+ );
548
+ }
549
+ }
550
+ /**
551
+ * Parses the API response body.
552
+ */
553
+ parseResponse(responseBody) {
554
+ try {
555
+ const parsed = JSON.parse(responseBody);
556
+ const { code, msg, data } = parsed;
557
+ if (code === "0") {
558
+ return ApiResponse.success(data);
559
+ } else {
560
+ return ApiResponse.error(code ?? "UNKNOWN", msg);
942
561
  }
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
- };
562
+ } catch (error) {
563
+ this.logger?.error("Failed to parse response", error);
564
+ return ApiResponse.error(
565
+ "C0001",
566
+ `Failed to parse response: ${error instanceof Error ? error.message : String(error)}`
567
+ );
953
568
  }
954
569
  }
570
+ /**
571
+ * Auto-injects merchantId into the request if configured.
572
+ */
573
+ injectMerchantIdIfNeeded(request) {
574
+ if (!this.merchantId) return;
575
+ const req = request;
576
+ if (typeof req.merchantInfo === "object" && req.merchantInfo !== null && !("merchantId" in req.merchantInfo && req.merchantInfo.merchantId)) {
577
+ req.merchantInfo.merchantId = this.merchantId;
578
+ } else if ("merchantId" in req && !req.merchantId) {
579
+ req.merchantId = this.merchantId;
580
+ }
581
+ }
582
+ /**
583
+ * Checks if the error is a network-related error.
584
+ */
585
+ isNetworkError(error) {
586
+ if (!(error instanceof Error)) return false;
587
+ const message = error.message.toLowerCase();
588
+ return error.name === "AbortError" || message.includes("timeout") || message.includes("econnrefused") || message.includes("enotfound") || message.includes("network") || message.includes("socket") || message.includes("connection");
589
+ }
955
590
  };
956
591
 
957
- // src/core/webhook.ts
592
+ // src/core/webhook-handler.ts
593
+ var WebhookEventType = /* @__PURE__ */ ((WebhookEventType2) => {
594
+ WebhookEventType2["PAYMENT_NOTIFICATION"] = "PAYMENT_NOTIFICATION";
595
+ WebhookEventType2["REFUND_NOTIFICATION"] = "REFUND_NOTIFICATION";
596
+ WebhookEventType2["SUBSCRIPTION_STATUS_NOTIFICATION"] = "SUBSCRIPTION_STATUS_NOTIFICATION";
597
+ WebhookEventType2["SUBSCRIPTION_PAYMENT_NOTIFICATION"] = "SUBSCRIPTION_PAYMENT_NOTIFICATION";
598
+ WebhookEventType2["SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION"] = "SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION";
599
+ return WebhookEventType2;
600
+ })(WebhookEventType || {});
958
601
  var WebhookHandler = class {
602
+ waffoPublicKey;
603
+ privateKey;
604
+ logger;
605
+ paymentHandler;
606
+ refundHandler;
607
+ subscriptionStatusHandler;
608
+ subscriptionPaymentHandler;
609
+ subscriptionPeriodChangedHandler;
610
+ constructor(config) {
611
+ this.waffoPublicKey = config.waffoPublicKey;
612
+ this.privateKey = config.privateKey;
613
+ this.logger = config.logger;
614
+ }
959
615
  /**
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
616
+ * Registers a handler for payment notifications.
976
617
  */
977
- constructor(config) {
978
- const environment = config.environment || "production" /* PRODUCTION */;
979
- this.config = {
980
- privateKey: config.privateKey,
981
- waffoPublicKey: config.waffoPublicKey || EnvironmentPublicKeys[environment]
982
- };
618
+ onPayment(handler) {
619
+ this.paymentHandler = handler;
620
+ return this;
983
621
  }
984
622
  /**
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
- * }
623
+ * Registers a handler for refund notifications.
624
+ */
625
+ onRefund(handler) {
626
+ this.refundHandler = handler;
627
+ return this;
628
+ }
629
+ /**
630
+ * Registers a handler for subscription status notifications.
631
+ */
632
+ onSubscriptionStatus(handler) {
633
+ this.subscriptionStatusHandler = handler;
634
+ return this;
635
+ }
636
+ /**
637
+ * Registers a handler for subscription payment notifications.
638
+ */
639
+ onSubscriptionPayment(handler) {
640
+ this.subscriptionPaymentHandler = handler;
641
+ return this;
642
+ }
643
+ /**
644
+ * Registers a handler for subscription period changed notifications.
645
+ */
646
+ onSubscriptionPeriodChanged(handler) {
647
+ this.subscriptionPeriodChangedHandler = handler;
648
+ return this;
649
+ }
650
+ /**
651
+ * Processes a webhook notification.
1050
652
  *
1051
- * @see {@link WebhookHandlerOptions} for handler configuration
1052
- * @see {@link WebhookHandlerResult} for return type
653
+ * @param body - The raw webhook body
654
+ * @param signature - The X-SIGNATURE header value
655
+ * @returns Result with response body and signature
1053
656
  */
1054
- async handle(requestBody, signature, options = {}) {
1055
- const {
1056
- onPayment,
1057
- onRefund,
1058
- onSubscriptionStatus,
1059
- onSubscriptionPayment,
1060
- onError
1061
- } = options;
657
+ async handleWebhook(body, signature) {
1062
658
  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
- };
659
+ if (!signature) {
660
+ this.logger?.warn("Missing webhook signature");
661
+ return this.createFailedResult("Missing signature");
1081
662
  }
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
- };
663
+ const isValid = RsaUtils.verify(body, signature, this.waffoPublicKey);
664
+ if (!isValid) {
665
+ this.logger?.error("Invalid webhook signature");
666
+ return this.createFailedResult("Invalid signature");
1094
667
  }
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
- });
668
+ const parsed = JSON.parse(body);
669
+ const eventType = parsed.eventType;
670
+ switch (eventType) {
671
+ case "PAYMENT_NOTIFICATION" /* PAYMENT_NOTIFICATION */:
672
+ if (this.paymentHandler) {
673
+ await this.paymentHandler(parsed);
674
+ }
675
+ break;
676
+ case "REFUND_NOTIFICATION" /* REFUND_NOTIFICATION */:
677
+ if (this.refundHandler) {
678
+ await this.refundHandler(parsed);
679
+ }
680
+ break;
681
+ case "SUBSCRIPTION_STATUS_NOTIFICATION" /* SUBSCRIPTION_STATUS_NOTIFICATION */:
682
+ if (this.subscriptionStatusHandler) {
683
+ await this.subscriptionStatusHandler(parsed);
684
+ }
685
+ break;
686
+ case "SUBSCRIPTION_PAYMENT_NOTIFICATION" /* SUBSCRIPTION_PAYMENT_NOTIFICATION */:
687
+ if (this.subscriptionPaymentHandler) {
688
+ await this.subscriptionPaymentHandler(parsed);
689
+ }
690
+ break;
691
+ case "SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION" /* SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION */:
692
+ if (this.subscriptionPeriodChangedHandler) {
693
+ await this.subscriptionPeriodChangedHandler(parsed);
694
+ }
695
+ break;
696
+ default:
697
+ this.logger?.warn(`Unknown webhook event type: ${eventType}`);
698
+ return this.createFailedResult(`Unknown event type: ${eventType}`);
1119
699
  }
1120
- return {
1121
- success: true,
1122
- response: buildWebhookResponse(
1123
- "success" /* SUCCESS */,
1124
- this.config.privateKey
1125
- )
1126
- };
700
+ return this.createSuccessResult();
1127
701
  } 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
- };
702
+ this.logger?.error("Error handling webhook", error);
703
+ return this.createFailedResult(
704
+ `Error handling webhook: ${error instanceof Error ? error.message : String(error)}`
705
+ );
1138
706
  }
1139
707
  }
1140
- };
1141
-
1142
- // src/resources/base.ts
1143
- var BaseResource = class {
1144
708
  /**
1145
- * Initializes the base resource with HTTP client and base path.
709
+ * Verifies a webhook signature.
1146
710
  *
1147
- * @param {HttpClient} client - HTTP client instance
1148
- * @param {string} basePath - Base path for API endpoints
1149
- * @protected
711
+ * @param body - The raw webhook body
712
+ * @param signature - The X-SIGNATURE header value
713
+ * @returns true if signature is valid
1150
714
  */
1151
- constructor(client, basePath) {
1152
- this.client = client;
1153
- this.basePath = basePath;
715
+ verifySignature(body, signature) {
716
+ return RsaUtils.verify(body, signature, this.waffoPublicKey);
717
+ }
718
+ /**
719
+ * Builds a success response with signature.
720
+ */
721
+ buildSuccessResponse() {
722
+ const body = JSON.stringify({ status: "success" });
723
+ const signature = RsaUtils.sign(body, this.privateKey);
724
+ return { body, signature };
725
+ }
726
+ /**
727
+ * Builds a failed response with signature.
728
+ */
729
+ buildFailedResponse(message) {
730
+ const body = JSON.stringify({ status: "failed", message });
731
+ const signature = RsaUtils.sign(body, this.privateKey);
732
+ return { body, signature };
733
+ }
734
+ createSuccessResult() {
735
+ const { body, signature } = this.buildSuccessResponse();
736
+ return {
737
+ success: true,
738
+ responseBody: body,
739
+ responseSignature: signature
740
+ };
741
+ }
742
+ createFailedResult(error) {
743
+ const { body, signature } = this.buildFailedResponse(error);
744
+ return {
745
+ success: false,
746
+ responseBody: body,
747
+ responseSignature: signature,
748
+ error
749
+ };
1154
750
  }
1155
751
  };
1156
752
 
1157
- // src/resources/order/resource.ts
1158
- var OrderResource = class extends BaseResource {
753
+ // src/resources/base-resource.ts
754
+ var BaseResource = class {
755
+ httpClient;
756
+ basePath;
757
+ constructor(httpClient, basePath) {
758
+ this.httpClient = httpClient;
759
+ this.basePath = basePath;
760
+ }
1159
761
  /**
1160
- * Creates an Order resource instance.
1161
- * @param {HttpClient} client - HTTP client instance
762
+ * Gets the full path for an endpoint.
763
+ *
764
+ * @param endpoint - The endpoint (e.g., "/create")
765
+ * @returns Full path (e.g., "/order/create")
1162
766
  */
1163
- constructor(client) {
1164
- super(client, "/order");
767
+ getPath(endpoint) {
768
+ return this.basePath + endpoint;
1165
769
  }
770
+ };
771
+
772
+ // src/resources/order-resource.ts
773
+ var OrderResource = class _OrderResource extends BaseResource {
774
+ static PATH_CREATE = "/create";
775
+ static PATH_INQUIRY = "/inquiry";
776
+ static PATH_CANCEL = "/cancel";
777
+ static PATH_REFUND = "/refund";
778
+ static PATH_CAPTURE = "/capture";
1166
779
  /**
1167
780
  * Creates a new payment order.
1168
781
  *
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
782
+ * @param params - Order creation parameters
783
+ * @param options - Optional request options
784
+ * @returns API response with order data
785
+ * @throws WaffoUnknownStatusError for network errors
1206
786
  */
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 }
787
+ async create(params, options) {
788
+ return this.httpClient.post(
789
+ this.getPath(_OrderResource.PATH_CREATE),
790
+ params,
791
+ options
1215
792
  );
1216
793
  }
1217
794
  /**
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
- * });
795
+ * Queries an existing order.
1241
796
  *
1242
- * @see {@link InquiryOrderData} for response structure
797
+ * @param params - Order inquiry parameters
798
+ * @param options - Optional request options
799
+ * @returns API response with order data
800
+ * @throws WaffoUnknownStatusError for network errors
1243
801
  */
1244
- async inquiry(params) {
1245
- return this.client.post(
1246
- `${this.basePath}/inquiry`,
1247
- { body: params }
802
+ async inquiry(params, options) {
803
+ return this.httpClient.post(
804
+ this.getPath(_OrderResource.PATH_INQUIRY),
805
+ params,
806
+ options
1248
807
  );
1249
808
  }
1250
809
  /**
1251
- * Cancels an unpaid order.
810
+ * Cancels an existing order.
1252
811
  *
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
812
+ * @param params - Order cancellation parameters
813
+ * @param options - Optional request options
814
+ * @returns API response with cancellation result
815
+ * @throws WaffoUnknownStatusError for network errors
1270
816
  */
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 }
817
+ async cancel(params, options) {
818
+ return this.httpClient.post(
819
+ this.getPath(_OrderResource.PATH_CANCEL),
820
+ params,
821
+ options
1279
822
  );
1280
823
  }
1281
824
  /**
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
- * });
825
+ * Refunds an existing order.
1315
826
  *
1316
- * @see {@link CreateRefundData} for response structure
827
+ * @param params - Order refund parameters
828
+ * @param options - Optional request options
829
+ * @returns API response with refund result
830
+ * @throws WaffoUnknownStatusError for network errors
1317
831
  */
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 }
832
+ async refund(params, options) {
833
+ return this.httpClient.post(
834
+ this.getPath(_OrderResource.PATH_REFUND),
835
+ params,
836
+ options
1326
837
  );
1327
838
  }
1328
839
  /**
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
- * });
840
+ * Captures an authorized order.
1344
841
  *
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
842
+ * @param params - Order capture parameters
843
+ * @param options - Optional request options
844
+ * @returns API response with capture result
845
+ * @throws WaffoUnknownStatusError for network errors
1358
846
  */
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 }
847
+ async capture(params, options) {
848
+ return this.httpClient.post(
849
+ this.getPath(_OrderResource.PATH_CAPTURE),
850
+ params,
851
+ options
1367
852
  );
1368
853
  }
1369
854
  };
1370
855
 
1371
- // src/resources/refund/resource.ts
1372
- var RefundResource = class extends BaseResource {
856
+ // src/resources/subscription-resource.ts
857
+ var SubscriptionResource = class _SubscriptionResource extends BaseResource {
858
+ static PATH_CREATE = "/create";
859
+ static PATH_INQUIRY = "/inquiry";
860
+ static PATH_CANCEL = "/cancel";
861
+ static PATH_MANAGE = "/manage";
862
+ static PATH_CHANGE = "/change";
863
+ static PATH_CHANGE_INQUIRY = "/change/inquiry";
1373
864
  /**
1374
- * Creates a Refund resource instance.
1375
- * @param {HttpClient} client - HTTP client instance
865
+ * Creates a new subscription.
866
+ *
867
+ * @param params - Subscription creation parameters
868
+ * @param options - Optional request options
869
+ * @returns API response with subscription data
870
+ * @throws WaffoUnknownStatusError for network errors
1376
871
  */
1377
- constructor(client) {
1378
- super(client, "/refund");
872
+ async create(params, options) {
873
+ return this.httpClient.post(
874
+ this.getPath(_SubscriptionResource.PATH_CREATE),
875
+ params,
876
+ options
877
+ );
1379
878
  }
1380
879
  /**
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
- * }
880
+ * Queries an existing subscription.
1400
881
  *
1401
- * @example
1402
- * // Query by acquiring refund order ID
1403
- * const result = await waffo.refund.inquiry({
1404
- * acquiringRefundOrderId: 'REF123456789',
1405
- * });
882
+ * @param params - Subscription inquiry parameters
883
+ * @param options - Optional request options
884
+ * @returns API response with subscription data
885
+ * @throws WaffoUnknownStatusError for network errors
886
+ */
887
+ async inquiry(params, options) {
888
+ return this.httpClient.post(
889
+ this.getPath(_SubscriptionResource.PATH_INQUIRY),
890
+ params,
891
+ options
892
+ );
893
+ }
894
+ /**
895
+ * Cancels an existing subscription.
1406
896
  *
1407
- * @see {@link InquiryRefundData} for response structure
897
+ * @param params - Subscription cancellation parameters
898
+ * @param options - Optional request options
899
+ * @returns API response with cancellation result
900
+ * @throws WaffoUnknownStatusError for network errors
1408
901
  */
1409
- async inquiry(params) {
1410
- return this.client.post(
1411
- `${this.basePath}/inquiry`,
1412
- { body: params }
902
+ async cancel(params, options) {
903
+ return this.httpClient.post(
904
+ this.getPath(_SubscriptionResource.PATH_CANCEL),
905
+ params,
906
+ options
1413
907
  );
1414
908
  }
1415
- };
1416
-
1417
- // src/resources/subscription/resource.ts
1418
- var SubscriptionResource = class extends BaseResource {
1419
909
  /**
1420
- * Creates a Subscription resource instance.
1421
- * @param {HttpClient} client - HTTP client instance
910
+ * Manages an existing subscription (pause, resume, update).
911
+ *
912
+ * @param params - Subscription management parameters
913
+ * @param options - Optional request options
914
+ * @returns API response with management result
915
+ * @throws WaffoUnknownStatusError for network errors
1422
916
  */
1423
- constructor(client) {
1424
- super(client, "/subscription");
917
+ async manage(params, options) {
918
+ return this.httpClient.post(
919
+ this.getPath(_SubscriptionResource.PATH_MANAGE),
920
+ params,
921
+ options
922
+ );
1425
923
  }
1426
924
  /**
1427
- * Creates a new subscription signing request for recurring payments.
925
+ * Changes (upgrades/downgrades) an existing subscription.
1428
926
  *
1429
- * After creation, redirect the user to the signing URL to authorize
1430
- * the recurring payment agreement.
927
+ * This method allows changing an active subscription to a new plan with different
928
+ * pricing, billing period, or other terms. The remaining amount from the original
929
+ * subscription can be applied to the new subscription.
1431
930
  *
1432
- * @param {CreateSubscriptionParams} params - Subscription creation parameters
1433
- * @returns {Promise<ApiResponse<CreateSubscriptionData>>} Subscription creation result
931
+ * @param params - Subscription change parameters
932
+ * @param options - Optional request options
933
+ * @returns API response with change result
934
+ * @throws WaffoUnknownStatusError for network errors
1434
935
  *
1435
936
  * @example
1436
- * const result = await waffo.subscription.create({
1437
- * subscriptionRequest: 'sub-' + Date.now(),
937
+ * ```typescript
938
+ * const response = await waffo.subscription().change({
939
+ * subscriptionRequest: 'new-request-id',
940
+ * originSubscriptionRequest: 'original-request-id',
941
+ * remainingAmount: '50.00',
1438
942
  * 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
- * },
943
+ * requestedAt: new Date().toISOString(),
1460
944
  * notifyUrl: 'https://example.com/webhook',
1461
- * successRedirectUrl: 'https://example.com/success',
945
+ * productInfoList: [{
946
+ * description: 'Premium Monthly',
947
+ * periodType: 'MONTH',
948
+ * periodInterval: '1',
949
+ * amount: '199.00',
950
+ * }],
951
+ * userInfo: { userId: 'user-123', userEmail: 'user@example.com' },
952
+ * goodsInfo: { goodsId: 'premium', goodsName: 'Premium Plan' },
953
+ * paymentInfo: { productName: 'SUBSCRIPTION' },
1462
954
  * });
1463
955
  *
1464
- * if (result.success) {
1465
- * // Redirect user to subscription signing page
1466
- * const signingUrl = result.data.subscriptionAction?.webUrl;
956
+ * if (response.isSuccess()) {
957
+ * const data = response.getData();
958
+ * if (data?.subscriptionChangeStatus === 'AUTHORIZATION_REQUIRED') {
959
+ * // Redirect user to authorization URL
960
+ * const webUrl = JSON.parse(data.subscriptionAction || '{}').webUrl;
961
+ * }
1467
962
  * }
1468
- *
1469
- * @see {@link CreateSubscriptionData} for response structure
963
+ * ```
1470
964
  */
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 }
965
+ async change(params, options) {
966
+ return this.httpClient.post(
967
+ this.getPath(_SubscriptionResource.PATH_CHANGE),
968
+ params,
969
+ options
1479
970
  );
1480
971
  }
1481
972
  /**
1482
- * Queries subscription details and optionally payment history.
973
+ * Queries the status of a subscription change.
1483
974
  *
1484
- * @param {InquirySubscriptionParams} params - Query parameters
1485
- * @returns {Promise<ApiResponse<InquirySubscriptionData>>} Subscription details
975
+ * Use this method to check the current status of a subscription change operation,
976
+ * especially after network errors or when status is uncertain.
1486
977
  *
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
- * }
978
+ * @param params - Change inquiry parameters
979
+ * @param options - Optional request options
980
+ * @returns API response with change inquiry data
1497
981
  *
1498
982
  * @example
1499
- * // Query with payment history
1500
- * const result = await waffo.subscription.inquiry({
1501
- * subscriptionId: 'SUB123456789',
1502
- * paymentDetails: '1', // Include payment history
983
+ * ```typescript
984
+ * const response = await waffo.subscription().changeInquiry({
985
+ * subscriptionRequest: 'new-request-id',
986
+ * originSubscriptionRequest: 'original-request-id',
1503
987
  * });
1504
988
  *
1505
- * if (result.success && result.data.paymentDetails) {
1506
- * result.data.paymentDetails.forEach(payment => {
1507
- * console.log(`Period ${payment.period}: ${payment.orderStatus}`);
1508
- * });
989
+ * if (response.isSuccess()) {
990
+ * const data = response.getData();
991
+ * console.log('Change status:', data?.subscriptionChangeStatus);
1509
992
  * }
993
+ * ```
994
+ */
995
+ async changeInquiry(params, options) {
996
+ try {
997
+ return await this.httpClient.post(
998
+ this.getPath(_SubscriptionResource.PATH_CHANGE_INQUIRY),
999
+ params,
1000
+ options
1001
+ );
1002
+ } catch (error) {
1003
+ if (error && typeof error === "object" && "errorCode" in error) {
1004
+ return ApiResponse.error("E0001", String(error.message || "Unknown error"));
1005
+ }
1006
+ throw error;
1007
+ }
1008
+ }
1009
+ };
1010
+
1011
+ // src/resources/refund-resource.ts
1012
+ var RefundResource = class _RefundResource extends BaseResource {
1013
+ static PATH_INQUIRY = "/inquiry";
1014
+ /**
1015
+ * Queries the status of a refund.
1510
1016
  *
1511
- * @see {@link InquirySubscriptionData} for response structure
1017
+ * @param params - Refund inquiry parameters
1018
+ * @param options - Optional request options
1019
+ * @returns API response with refund data
1020
+ * @throws WaffoUnknownStatusError for network errors
1512
1021
  */
1513
- async inquiry(params) {
1514
- return this.client.post(
1515
- `${this.basePath}/inquiry`,
1516
- { body: params }
1022
+ async inquiry(params, options) {
1023
+ return this.httpClient.post(
1024
+ this.getPath(_RefundResource.PATH_INQUIRY),
1025
+ params,
1026
+ options
1517
1027
  );
1518
1028
  }
1029
+ };
1030
+
1031
+ // src/resources/merchant-config-resource.ts
1032
+ var MerchantConfigResource = class _MerchantConfigResource extends BaseResource {
1033
+ static PATH_INQUIRY = "/inquiry";
1519
1034
  /**
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
- * }
1035
+ * Queries merchant configuration.
1537
1036
  *
1538
- * @see {@link CancelSubscriptionData} for response structure
1037
+ * @param params - Merchant config inquiry parameters
1038
+ * @param options - Optional request options
1039
+ * @returns API response with merchant config data
1040
+ * @throws WaffoUnknownStatusError for network errors
1539
1041
  */
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 }
1042
+ async inquiry(params, options) {
1043
+ return this.httpClient.post(
1044
+ this.getPath(_MerchantConfigResource.PATH_INQUIRY),
1045
+ params,
1046
+ options
1548
1047
  );
1549
1048
  }
1049
+ };
1050
+
1051
+ // src/resources/pay-method-config-resource.ts
1052
+ var PayMethodConfigResource = class _PayMethodConfigResource extends BaseResource {
1053
+ static PATH_INQUIRY = "/inquiry";
1550
1054
  /**
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
- * });
1055
+ * Queries available payment methods.
1563
1056
  *
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
1057
+ * @param params - Pay method config inquiry parameters
1058
+ * @param options - Optional request options
1059
+ * @returns API response with pay method config data
1060
+ * @throws WaffoUnknownStatusError for network errors
1571
1061
  */
1572
- async manage(params) {
1573
- return this.client.post(
1574
- `${this.basePath}/manage`,
1575
- { body: params }
1062
+ async inquiry(params, options) {
1063
+ return this.httpClient.post(
1064
+ this.getPath(_PayMethodConfigResource.PATH_INQUIRY),
1065
+ params,
1066
+ options
1576
1067
  );
1577
1068
  }
1578
1069
  };
1579
1070
 
1580
- // src/resources/merchantconfig/resource.ts
1581
- var MerchantConfigResource = class extends BaseResource {
1071
+ // src/waffo.ts
1072
+ var Waffo = class _Waffo {
1073
+ config;
1074
+ httpClient;
1075
+ // Lazy-initialized resources
1076
+ _order;
1077
+ _subscription;
1078
+ _refund;
1079
+ _merchantConfig;
1080
+ _payMethodConfig;
1582
1081
  /**
1583
- * Creates a Merchant Config resource instance.
1584
- * @param {HttpClient} client - HTTP client instance
1082
+ * Creates a new Waffo SDK instance.
1083
+ *
1084
+ * @param config - SDK configuration
1585
1085
  */
1586
- constructor(client) {
1587
- super(client, "/merchantconfig");
1086
+ constructor(config) {
1087
+ this.config = config;
1088
+ this.httpClient = new WaffoHttpClient(config);
1588
1089
  }
1589
1090
  /**
1590
- * Queries merchant configuration including transaction limits.
1591
- *
1592
- * @param {MerchantConfigInquiryParams} params - Query parameters
1593
- * @returns {Promise<ApiResponse<MerchantConfigInquiryData>>} Merchant configuration
1091
+ * Creates a Waffo SDK instance from environment variables.
1594
1092
  *
1595
- * @example
1596
- * const result = await waffo.merchantConfig.inquiry({
1597
- * merchantId: 'M001',
1598
- * });
1093
+ * Required environment variables:
1094
+ * - WAFFO_API_KEY
1095
+ * - WAFFO_PRIVATE_KEY
1096
+ * - WAFFO_PUBLIC_KEY
1097
+ * - WAFFO_ENVIRONMENT (SANDBOX or PRODUCTION)
1599
1098
  *
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
- * }
1099
+ * Optional environment variables:
1100
+ * - WAFFO_MERCHANT_ID
1101
+ * - WAFFO_CONNECT_TIMEOUT
1102
+ * - WAFFO_READ_TIMEOUT
1608
1103
  *
1609
- * @see {@link MerchantConfigInquiryData} for response structure
1104
+ * @returns Waffo SDK instance
1610
1105
  */
1611
- async inquiry(params) {
1612
- return this.client.post(`${this.basePath}/inquiry`, { body: params });
1106
+ static fromEnv() {
1107
+ return new _Waffo(fromEnv());
1613
1108
  }
1614
- };
1615
-
1616
- // src/resources/paymethodconfig/resource.ts
1617
- var PayMethodConfigResource = class extends BaseResource {
1618
1109
  /**
1619
- * Creates a Pay Method Config resource instance.
1620
- * @param {HttpClient} client - HTTP client instance
1110
+ * Returns the order resource for managing payment orders.
1111
+ *
1112
+ * @returns Order resource
1621
1113
  */
1622
- constructor(client) {
1623
- super(client, "/paymethodconfig");
1114
+ order() {
1115
+ if (!this._order) {
1116
+ this._order = new OrderResource(this.httpClient, "/order");
1117
+ }
1118
+ return this._order;
1624
1119
  }
1625
1120
  /**
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}`);
1121
+ * Returns the subscription resource for managing recurring payments.
1640
1122
  *
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
1123
+ * @returns Subscription resource
1655
1124
  */
1656
- async inquiry(params) {
1657
- return this.client.post(`${this.basePath}/inquiry`, { body: params });
1125
+ subscription() {
1126
+ if (!this._subscription) {
1127
+ this._subscription = new SubscriptionResource(this.httpClient, "/subscription");
1128
+ }
1129
+ return this._subscription;
1658
1130
  }
1659
- };
1660
-
1661
- // src/core/waffo.ts
1662
- var Waffo = class {
1663
1131
  /**
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
1132
+ * Returns the refund resource for querying refund status.
1678
1133
  *
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
1134
+ * @returns Refund resource
1699
1135
  */
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);
1136
+ refund() {
1137
+ if (!this._refund) {
1138
+ this._refund = new RefundResource(this.httpClient, "/refund");
1139
+ }
1140
+ return this._refund;
1708
1141
  }
1709
1142
  /**
1710
- * Generates a new 2048-bit RSA key pair for API signing and verification.
1143
+ * Returns the merchant config resource.
1711
1144
  *
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)
1145
+ * @returns Merchant config resource
1146
+ */
1147
+ merchantConfig() {
1148
+ if (!this._merchantConfig) {
1149
+ this._merchantConfig = new MerchantConfigResource(this.httpClient, "/merchant/config");
1150
+ }
1151
+ return this._merchantConfig;
1152
+ }
1153
+ /**
1154
+ * Returns the pay method config resource.
1715
1155
  *
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
1156
+ * @returns Pay method config resource
1157
+ */
1158
+ payMethodConfig() {
1159
+ if (!this._payMethodConfig) {
1160
+ this._payMethodConfig = new PayMethodConfigResource(this.httpClient, "/paymethod/config");
1161
+ }
1162
+ return this._payMethodConfig;
1163
+ }
1164
+ /**
1165
+ * Creates a webhook handler for processing Waffo webhook notifications.
1721
1166
  *
1722
- * @static
1723
- * @returns {KeyPair} Object containing the generated key pair
1167
+ * @returns Webhook handler
1724
1168
  *
1725
1169
  * @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);
1170
+ * ```typescript
1171
+ * // Setup webhook handler
1172
+ * const handler = waffo.webhook()
1173
+ * .onPayment((notification) => {
1174
+ * console.log('Payment:', notification.orderStatus);
1175
+ * })
1176
+ * .onRefund((notification) => {
1177
+ * console.log('Refund:', notification.refundStatus);
1178
+ * })
1179
+ * .onSubscriptionStatus((notification) => {
1180
+ * console.log('Subscription:', notification.subscriptionStatus);
1181
+ * });
1182
+ *
1183
+ * // In Express.js route handler
1184
+ * app.post('/webhook', async (req, res) => {
1185
+ * const body = req.body.toString();
1186
+ * const signature = req.headers['x-signature'] as string;
1187
+ * const result = await handler.handleWebhook(body, signature);
1730
1188
  *
1731
- * // Use the private key to initialize SDK
1732
- * const waffo = new Waffo({
1733
- * apiKey: 'your-api-key',
1734
- * privateKey: keys.privateKey,
1189
+ * res.setHeader('X-SIGNATURE', result.responseSignature);
1190
+ * res.status(200).send(result.responseBody);
1735
1191
  * });
1192
+ * ```
1193
+ */
1194
+ webhook() {
1195
+ return new WebhookHandler(this.config);
1196
+ }
1197
+ /**
1198
+ * Returns the current configuration.
1736
1199
  *
1737
- * @see {@link KeyPair} for the return type structure
1200
+ * @returns SDK configuration (with sensitive data)
1738
1201
  */
1739
- static generateKeyPair() {
1740
- const keys = createKeyPair();
1741
- return {
1742
- privateKey: keys.PRIVATE_KEY_NAME,
1743
- publicKey: keys.PUBLIC_KEY_NAME
1744
- };
1202
+ getConfig() {
1203
+ return this.config;
1745
1204
  }
1746
1205
  };
1747
1206
 
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 };
1207
+ export { ApiResponse, Environment, EnvironmentBaseUrl, MerchantConfigResource, OrderResource, PayMethodConfigResource, RefundResource, RsaUtils, SubscriptionResource, Waffo, WaffoConfigDefaults, WaffoError, WaffoErrorCode, WaffoHttpClient, WaffoUnknownStatusError, WebhookEventType, WebhookHandler };
1749
1208
  //# sourceMappingURL=index.mjs.map
1750
1209
  //# sourceMappingURL=index.mjs.map