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