@miden-npm/react 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1825 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -14
- package/dist/index.d.ts +21 -14
- package/dist/index.js +1847 -395
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -0
- package/package.json +13 -10
package/dist/index.cjs
CHANGED
|
@@ -106,17 +106,25 @@ function usePaymentIntents() {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// src/buzapay-checkout/checkout-button.tsx
|
|
109
|
-
var
|
|
109
|
+
var import_react7 = require("react");
|
|
110
110
|
|
|
111
111
|
// src/utils/object.util.ts
|
|
112
112
|
var checkObjectTruthy = (obj) => {
|
|
113
113
|
if (obj == null || typeof obj !== "object") return false;
|
|
114
114
|
return Object.values(obj).every(Boolean);
|
|
115
115
|
};
|
|
116
|
+
var getQueryParams = (url) => {
|
|
117
|
+
const params = {};
|
|
118
|
+
const searchParams = new URL(url).searchParams;
|
|
119
|
+
searchParams.forEach((value, key) => {
|
|
120
|
+
params[key] = value;
|
|
121
|
+
});
|
|
122
|
+
return params;
|
|
123
|
+
};
|
|
116
124
|
|
|
117
125
|
// src/utils/api.util.ts
|
|
118
126
|
var getBaseUrl = (mode) => {
|
|
119
|
-
return mode === "sandbox" ? "https://sandbox-api.
|
|
127
|
+
return mode === "sandbox" ? "https://sandbox-api.buzapay.com/payment-gateway-api" : "";
|
|
120
128
|
};
|
|
121
129
|
|
|
122
130
|
// src/utils/string.util.ts
|
|
@@ -168,6 +176,246 @@ var restrictToNumericKeys = (event) => {
|
|
|
168
176
|
}
|
|
169
177
|
};
|
|
170
178
|
|
|
179
|
+
// src/utils/error.util.ts
|
|
180
|
+
var validateRegex = (value, regex) => regex.test(value);
|
|
181
|
+
function parseRules(rules) {
|
|
182
|
+
if (!rules) return [];
|
|
183
|
+
return rules.split("|").map((chunk) => {
|
|
184
|
+
const [rule, val] = chunk.split(":");
|
|
185
|
+
return { rule, value: val };
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function getValidationErrorMessage(rulesStr, inputValue, label) {
|
|
189
|
+
const errors = [];
|
|
190
|
+
const rules = parseRules(rulesStr);
|
|
191
|
+
const lowerLabel = (label || "This field").toLowerCase();
|
|
192
|
+
const v = inputValue ?? "";
|
|
193
|
+
const num = Number(v);
|
|
194
|
+
const hasNum = !Number.isNaN(num);
|
|
195
|
+
for (const r of rules) {
|
|
196
|
+
switch (r.rule) {
|
|
197
|
+
case "required":
|
|
198
|
+
if (!v) errors.push(`The ${lowerLabel} field is required`);
|
|
199
|
+
break;
|
|
200
|
+
case "alpha":
|
|
201
|
+
if (!validateRegex(v, /^[a-zA-Z]+$/))
|
|
202
|
+
errors.push(
|
|
203
|
+
`The ${lowerLabel} field must only contain alphabetic characters`
|
|
204
|
+
);
|
|
205
|
+
break;
|
|
206
|
+
case "at_least_one_uppercase":
|
|
207
|
+
if (!validateRegex(v, /.*[A-Z].*/))
|
|
208
|
+
errors.push(
|
|
209
|
+
`The ${lowerLabel} field must contain at least one uppercase character`
|
|
210
|
+
);
|
|
211
|
+
break;
|
|
212
|
+
case "at_least_one_lowercase":
|
|
213
|
+
if (!validateRegex(v, /.*[a-z].*/))
|
|
214
|
+
errors.push(
|
|
215
|
+
`The ${lowerLabel} field must contain at least one lowercase character`
|
|
216
|
+
);
|
|
217
|
+
break;
|
|
218
|
+
case "at_least_one_number":
|
|
219
|
+
if (!validateRegex(v, /.*\d.*/))
|
|
220
|
+
errors.push(
|
|
221
|
+
`The ${lowerLabel} field must contain at least one number`
|
|
222
|
+
);
|
|
223
|
+
break;
|
|
224
|
+
case "alpha_num":
|
|
225
|
+
if (!validateRegex(v, /^[a-z0-9]+$/i))
|
|
226
|
+
errors.push(
|
|
227
|
+
`The ${lowerLabel} field must only contain alphabetic characters and numbers`
|
|
228
|
+
);
|
|
229
|
+
break;
|
|
230
|
+
case "num_spaces":
|
|
231
|
+
if (!validateRegex(v, /^[0-9\s]+$/i))
|
|
232
|
+
errors.push(
|
|
233
|
+
`The ${lowerLabel} field must only contain space and numbers`
|
|
234
|
+
);
|
|
235
|
+
break;
|
|
236
|
+
case "alpha_spaces":
|
|
237
|
+
if (!validateRegex(v, /^[A-Za-z\s]*$/))
|
|
238
|
+
errors.push(
|
|
239
|
+
`The ${lowerLabel} field must only contain alphabetic characters and spaces`
|
|
240
|
+
);
|
|
241
|
+
break;
|
|
242
|
+
case "numeric":
|
|
243
|
+
if (!validateRegex(v, /^\d+$/))
|
|
244
|
+
errors.push(`The ${lowerLabel} field must only contain numbers`);
|
|
245
|
+
break;
|
|
246
|
+
case "no_special":
|
|
247
|
+
if (validateRegex(v, /[^a-zA-Z0-9\s]/))
|
|
248
|
+
errors.push(
|
|
249
|
+
`The ${lowerLabel} field must not contain special characters`
|
|
250
|
+
);
|
|
251
|
+
break;
|
|
252
|
+
case "at_least_one_special":
|
|
253
|
+
if (!validateRegex(v, /[^a-zA-Z0-9\s]/))
|
|
254
|
+
errors.push(
|
|
255
|
+
`The ${lowerLabel} field must contain at least one special character`
|
|
256
|
+
);
|
|
257
|
+
break;
|
|
258
|
+
case "email":
|
|
259
|
+
if (!validateRegex(v, /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/)) {
|
|
260
|
+
errors.push("Please enter a valid email address");
|
|
261
|
+
}
|
|
262
|
+
break;
|
|
263
|
+
case "is":
|
|
264
|
+
if (r.value !== v) errors.push(`Value entered must be ${r.value}`);
|
|
265
|
+
break;
|
|
266
|
+
case "is_not":
|
|
267
|
+
if (r.value === v) errors.push(`Value entered must not be ${r.value}`);
|
|
268
|
+
break;
|
|
269
|
+
case "char_length":
|
|
270
|
+
if (v.length !== Number(r.value))
|
|
271
|
+
errors.push(
|
|
272
|
+
`The ${lowerLabel} field must be ${r.value} characters long`
|
|
273
|
+
);
|
|
274
|
+
break;
|
|
275
|
+
case "min_char_length":
|
|
276
|
+
if (v.length < Number(r.value))
|
|
277
|
+
errors.push(
|
|
278
|
+
`The ${lowerLabel} field must not be less than ${r.value} characters long`
|
|
279
|
+
);
|
|
280
|
+
break;
|
|
281
|
+
case "max_char_length":
|
|
282
|
+
if (v.length > Number(r.value))
|
|
283
|
+
errors.push(
|
|
284
|
+
`The ${lowerLabel} field must not be greater than ${r.value} characters long`
|
|
285
|
+
);
|
|
286
|
+
break;
|
|
287
|
+
// Age rules treat the value as a number (strict numeric compare)
|
|
288
|
+
case "age":
|
|
289
|
+
if (!hasNum || num !== Number(r.value))
|
|
290
|
+
errors.push(`Age entered must be ${r.value}`);
|
|
291
|
+
break;
|
|
292
|
+
case "min_age":
|
|
293
|
+
if (!hasNum || num < Number(r.value))
|
|
294
|
+
errors.push(`Age entered must not be less than ${r.value}`);
|
|
295
|
+
break;
|
|
296
|
+
case "max_age":
|
|
297
|
+
if (!hasNum || num > Number(r.value))
|
|
298
|
+
errors.push(`Age entered must not be greater than ${r.value}`);
|
|
299
|
+
break;
|
|
300
|
+
// Numeric value rules (general numbers)
|
|
301
|
+
case "num_is":
|
|
302
|
+
if (!hasNum || num !== Number(r.value))
|
|
303
|
+
errors.push(`Number entered must be ${r.value}`);
|
|
304
|
+
break;
|
|
305
|
+
case "num_is_not":
|
|
306
|
+
if (hasNum && num === Number(r.value))
|
|
307
|
+
errors.push(`Number entered must not be ${r.value}`);
|
|
308
|
+
break;
|
|
309
|
+
case "min_number":
|
|
310
|
+
if (!hasNum || num < Number(r.value))
|
|
311
|
+
errors.push(`Number entered must not be less than ${r.value}`);
|
|
312
|
+
break;
|
|
313
|
+
case "max_number":
|
|
314
|
+
if (!hasNum || num > Number(r.value))
|
|
315
|
+
errors.push(`Number entered must not be greater than ${r.value}`);
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return errors.length > 0 ? errors[0] : null;
|
|
322
|
+
}
|
|
323
|
+
var validateGroup = (values, rulesMap, prettyLabels) => {
|
|
324
|
+
const out = {};
|
|
325
|
+
for (const [field, rules] of Object.entries(rulesMap)) {
|
|
326
|
+
if (!rules) continue;
|
|
327
|
+
const label = prettyLabels?.[field] ?? field;
|
|
328
|
+
const err = getValidationErrorMessage(rules, values[field] ?? "", label);
|
|
329
|
+
if (err) out[field] = err;
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// src/utils/card-scheme.util.ts
|
|
335
|
+
var CardSchemes = /* @__PURE__ */ ((CardSchemes2) => {
|
|
336
|
+
CardSchemes2[CardSchemes2["Visa"] = 1] = "Visa";
|
|
337
|
+
CardSchemes2[CardSchemes2["MasterCard"] = 2] = "MasterCard";
|
|
338
|
+
CardSchemes2[CardSchemes2["Verve"] = 3] = "Verve";
|
|
339
|
+
CardSchemes2[CardSchemes2["MastercardAndVisa"] = 4] = "MastercardAndVisa";
|
|
340
|
+
CardSchemes2[CardSchemes2["AmericanExpress"] = 5] = "AmericanExpress";
|
|
341
|
+
CardSchemes2[CardSchemes2["Discover"] = 6] = "Discover";
|
|
342
|
+
CardSchemes2[CardSchemes2["JCB"] = 7] = "JCB";
|
|
343
|
+
CardSchemes2[CardSchemes2["DinersClub"] = 8] = "DinersClub";
|
|
344
|
+
CardSchemes2[CardSchemes2["Maestro"] = 9] = "Maestro";
|
|
345
|
+
CardSchemes2[CardSchemes2["UnionPay"] = 10] = "UnionPay";
|
|
346
|
+
CardSchemes2[CardSchemes2["UnionPay3DS"] = 11] = "UnionPay3DS";
|
|
347
|
+
CardSchemes2[CardSchemes2["UnionPayNon3DS"] = 12] = "UnionPayNon3DS";
|
|
348
|
+
CardSchemes2[CardSchemes2["UATP"] = 13] = "UATP";
|
|
349
|
+
CardSchemes2[CardSchemes2["PayPak"] = 14] = "PayPak";
|
|
350
|
+
CardSchemes2[CardSchemes2["Jaywan"] = 15] = "Jaywan";
|
|
351
|
+
CardSchemes2[CardSchemes2["Mada"] = 16] = "Mada";
|
|
352
|
+
CardSchemes2[CardSchemes2["MadaVisa"] = 17] = "MadaVisa";
|
|
353
|
+
CardSchemes2[CardSchemes2["MadaMastercard"] = 18] = "MadaMastercard";
|
|
354
|
+
CardSchemes2[CardSchemes2["Unknown"] = 19] = "Unknown";
|
|
355
|
+
return CardSchemes2;
|
|
356
|
+
})(CardSchemes || {});
|
|
357
|
+
var VISA_RE = /^4\d{12}(\d{3}){0,2}$/;
|
|
358
|
+
var MC_RE = /^(?:5[1-5]\d{14}|2(?:2(?:2[1-9]|[3-9]\d)|[3-6]\d{2}|7(?:[01]\d|20))\d{12})(?:\d{0,3})?$/;
|
|
359
|
+
var AMEX_RE = /^(34|37)\d{13}$/;
|
|
360
|
+
var DISCOVER_RE = /^(?:6011|65|64[4-9]|622(?:12[6-9]|1[3-9]\d|[2-8]\d{2}|9(?:0\d|1\d|2[0-5])))\d{12,15}$/;
|
|
361
|
+
var JCB_RE = /^(?:35(?:2[8-9]|[3-8]\d))\d{12,15}$/;
|
|
362
|
+
var DINERS_RE = /^(?:3(?:0[0-5]\d|095|6\d|[89]\d))\d{11,13}$/;
|
|
363
|
+
var MAESTRO_RE = /^(?:50|5[6-9]|6[0-9])\d{10,17}$/;
|
|
364
|
+
var UNIONPAY_RE = /^62\d{14,17}$/;
|
|
365
|
+
var UATP_RE = /^1\d{14}$/;
|
|
366
|
+
var VERVE_BIN6_RANGES = [
|
|
367
|
+
[506099, 506198],
|
|
368
|
+
[650002, 650027]
|
|
369
|
+
];
|
|
370
|
+
var VERVE_BIN6_SINGLES = /* @__PURE__ */ new Set([507865, 507866]);
|
|
371
|
+
var PAYPAK_BIN6 = /* @__PURE__ */ new Set([220545, 220543]);
|
|
372
|
+
var JAYWAN_BIN7 = /* @__PURE__ */ new Set([6690109]);
|
|
373
|
+
var MADA_ONLY_BIN6 = /* @__PURE__ */ new Set([968209, 873646]);
|
|
374
|
+
var MADA_VISA_BIN6 = /* @__PURE__ */ new Set([422818, 486094]);
|
|
375
|
+
var MADA_MC_BIN6 = /* @__PURE__ */ new Set([529741, 543357]);
|
|
376
|
+
var UNIONPAY_3DS_BIN6 = /* @__PURE__ */ new Set([620108]);
|
|
377
|
+
var UNIONPAY_NON3DS_BIN6 = /* @__PURE__ */ new Set([621423]);
|
|
378
|
+
function cardTypeHandler(cardNumber) {
|
|
379
|
+
const scheme = detect(cardNumber);
|
|
380
|
+
return CardSchemes[scheme];
|
|
381
|
+
}
|
|
382
|
+
function detect(cardNumber) {
|
|
383
|
+
if (!cardNumber || !cardNumber.trim()) return 19 /* Unknown */;
|
|
384
|
+
const digits = cardNumber.replace(/\D/g, "");
|
|
385
|
+
if (digits.length < 12 || digits.length > 19) return 19 /* Unknown */;
|
|
386
|
+
if (digits.length >= 6) {
|
|
387
|
+
const bin6 = parseInt(digits.slice(0, 6), 10);
|
|
388
|
+
if (MADA_ONLY_BIN6.has(bin6) && digits.length >= 16 && digits.length <= 19)
|
|
389
|
+
return 16 /* Mada */;
|
|
390
|
+
if (MADA_VISA_BIN6.has(bin6) && VISA_RE.test(digits)) return 17 /* MadaVisa */;
|
|
391
|
+
if (MADA_MC_BIN6.has(bin6) && MC_RE.test(digits)) return 18 /* MadaMastercard */;
|
|
392
|
+
if (PAYPAK_BIN6.has(bin6) && digits.length === 16) return 14 /* PayPak */;
|
|
393
|
+
if (UNIONPAY_3DS_BIN6.has(bin6) && UNIONPAY_RE.test(digits)) return 11 /* UnionPay3DS */;
|
|
394
|
+
if (UNIONPAY_NON3DS_BIN6.has(bin6) && UNIONPAY_RE.test(digits))
|
|
395
|
+
return 12 /* UnionPayNon3DS */;
|
|
396
|
+
if (isVerve(bin6, digits.length)) return 3 /* Verve */;
|
|
397
|
+
}
|
|
398
|
+
if (digits.length >= 7) {
|
|
399
|
+
const bin7 = parseInt(digits.slice(0, 7), 10);
|
|
400
|
+
if (JAYWAN_BIN7.has(bin7) && digits.length === 16) return 15 /* Jaywan */;
|
|
401
|
+
}
|
|
402
|
+
if (UATP_RE.test(digits)) return 13 /* UATP */;
|
|
403
|
+
if (AMEX_RE.test(digits)) return 5 /* AmericanExpress */;
|
|
404
|
+
if (DISCOVER_RE.test(digits)) return 6 /* Discover */;
|
|
405
|
+
if (JCB_RE.test(digits)) return 7 /* JCB */;
|
|
406
|
+
if (DINERS_RE.test(digits)) return 8 /* DinersClub */;
|
|
407
|
+
if (MC_RE.test(digits)) return 2 /* MasterCard */;
|
|
408
|
+
if (VISA_RE.test(digits)) return 1 /* Visa */;
|
|
409
|
+
if (UNIONPAY_RE.test(digits)) return 10 /* UnionPay */;
|
|
410
|
+
if (MAESTRO_RE.test(digits)) return 9 /* Maestro */;
|
|
411
|
+
return 19 /* Unknown */;
|
|
412
|
+
}
|
|
413
|
+
function isVerve(bin6, length) {
|
|
414
|
+
if (length < 16 || length > 19) return false;
|
|
415
|
+
const inRange = VERVE_BIN6_RANGES.some(([start, end]) => bin6 >= start && bin6 <= end);
|
|
416
|
+
return inRange || VERVE_BIN6_SINGLES.has(bin6);
|
|
417
|
+
}
|
|
418
|
+
|
|
171
419
|
// src/apis/checkout.api.ts
|
|
172
420
|
async function createPaymentLink(paymentObject, environment, secretKey) {
|
|
173
421
|
try {
|
|
@@ -181,7 +429,189 @@ async function createPaymentLink(paymentObject, environment, secretKey) {
|
|
|
181
429
|
Accept: "application/json",
|
|
182
430
|
merchantId: secretKey
|
|
183
431
|
},
|
|
184
|
-
body: JSON.stringify(
|
|
432
|
+
body: JSON.stringify({
|
|
433
|
+
...paymentObject,
|
|
434
|
+
LinkName: `${Date.now()}-Link`
|
|
435
|
+
})
|
|
436
|
+
}
|
|
437
|
+
);
|
|
438
|
+
return await res.json();
|
|
439
|
+
} catch (error) {
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async function authorizeCardPayment(environment, { merchantId, ...rest }) {
|
|
443
|
+
try {
|
|
444
|
+
const baseUrl = getBaseUrl(environment);
|
|
445
|
+
const res = await fetch(
|
|
446
|
+
`${baseUrl}/api/v1/checkout/authorize-card-3ds-payment-sdk`,
|
|
447
|
+
{
|
|
448
|
+
method: "POST",
|
|
449
|
+
headers: {
|
|
450
|
+
"Content-Type": "application/json",
|
|
451
|
+
Accept: "application/json",
|
|
452
|
+
merchantId
|
|
453
|
+
},
|
|
454
|
+
body: JSON.stringify(rest)
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
return await res.json();
|
|
458
|
+
} catch (error) {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
async function getPaymentReferenceDetails(environment, paymentReference) {
|
|
462
|
+
try {
|
|
463
|
+
const baseUrl = getBaseUrl(environment);
|
|
464
|
+
const res = await fetch(
|
|
465
|
+
`${baseUrl}/api/v1/checkout/details/${paymentReference}`,
|
|
466
|
+
{
|
|
467
|
+
method: "GET",
|
|
468
|
+
headers: {
|
|
469
|
+
"Content-Type": "application/json",
|
|
470
|
+
Accept: "application/json"
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
);
|
|
474
|
+
return await res.json();
|
|
475
|
+
} catch (error) {
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
async function generatePaymentAccount(environment, { merchantId, ...rest }) {
|
|
479
|
+
try {
|
|
480
|
+
const baseUrl = getBaseUrl(environment);
|
|
481
|
+
const res = await fetch(
|
|
482
|
+
`${baseUrl}/api/v1/checkout/generate-payment-account`,
|
|
483
|
+
{
|
|
484
|
+
method: "POST",
|
|
485
|
+
headers: {
|
|
486
|
+
"Content-Type": "application/json",
|
|
487
|
+
Accept: "application/json",
|
|
488
|
+
merchantId
|
|
489
|
+
},
|
|
490
|
+
body: JSON.stringify(rest)
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
return await res.json();
|
|
494
|
+
} catch (error) {
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
async function generateStableCoinAddress(environment, { merchantId, ...rest }) {
|
|
498
|
+
try {
|
|
499
|
+
const baseUrl = getBaseUrl(environment);
|
|
500
|
+
const res = await fetch(
|
|
501
|
+
`${baseUrl}/api/v1/checkout/generate-payment-walletaddress`,
|
|
502
|
+
{
|
|
503
|
+
method: "POST",
|
|
504
|
+
headers: {
|
|
505
|
+
"Content-Type": "application/json",
|
|
506
|
+
Accept: "application/json",
|
|
507
|
+
merchantId
|
|
508
|
+
},
|
|
509
|
+
body: JSON.stringify(rest)
|
|
510
|
+
}
|
|
511
|
+
);
|
|
512
|
+
return await res.json();
|
|
513
|
+
} catch (error) {
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// src/apis/encrypt.api.ts
|
|
518
|
+
var import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
519
|
+
function encryptPayload(merchantId, formData = {}) {
|
|
520
|
+
const merchId = merchantId.replace(/-/g, "");
|
|
521
|
+
const first16Key = merchId.slice(0, 16);
|
|
522
|
+
const last16Iv = merchId.slice(-16);
|
|
523
|
+
const key = import_crypto_js.default.enc.Utf8.parse(first16Key);
|
|
524
|
+
const iv = import_crypto_js.default.enc.Utf8.parse(last16Iv);
|
|
525
|
+
const postDataObj = JSON.stringify(formData);
|
|
526
|
+
const encryptedData = import_crypto_js.default.AES.encrypt(
|
|
527
|
+
import_crypto_js.default.enc.Utf8.parse(postDataObj),
|
|
528
|
+
key,
|
|
529
|
+
{
|
|
530
|
+
keySize: 128 / 8,
|
|
531
|
+
iv,
|
|
532
|
+
mode: import_crypto_js.default.mode.CBC,
|
|
533
|
+
padding: import_crypto_js.default.pad.Pkcs7
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
return {
|
|
537
|
+
requestParam: encryptedData.toString()
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
function decryptPayload(merchantId, payload) {
|
|
541
|
+
const merchId = merchantId.replace(/-/g, "");
|
|
542
|
+
const first16Key = merchId.slice(0, 16);
|
|
543
|
+
const last16Iv = merchId.slice(-16);
|
|
544
|
+
const key = import_crypto_js.default.enc.Utf8.parse(first16Key);
|
|
545
|
+
const iv = import_crypto_js.default.enc.Utf8.parse(last16Iv);
|
|
546
|
+
const decryptedData = import_crypto_js.default.AES.decrypt(payload, key, {
|
|
547
|
+
keySize: 128 / 8,
|
|
548
|
+
iv,
|
|
549
|
+
mode: import_crypto_js.default.mode.CBC,
|
|
550
|
+
padding: import_crypto_js.default.pad.Pkcs7
|
|
551
|
+
});
|
|
552
|
+
const decryptedText = decryptedData.toString(import_crypto_js.default.enc.Utf8);
|
|
553
|
+
return JSON.parse(decryptedText);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/apis/resources.api.ts
|
|
557
|
+
async function getCountries(environment, secretKey) {
|
|
558
|
+
try {
|
|
559
|
+
const baseUrl = getBaseUrl(environment);
|
|
560
|
+
const res = await fetch(`${baseUrl}/api/v1/countries-iso`, {
|
|
561
|
+
method: "GET",
|
|
562
|
+
headers: {
|
|
563
|
+
"Content-Type": "application/json",
|
|
564
|
+
Accept: "application/json",
|
|
565
|
+
merchantId: secretKey
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
return await res.json();
|
|
569
|
+
} catch (error) {
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
async function getCountryStates(countryIso3, environment, secretKey) {
|
|
573
|
+
try {
|
|
574
|
+
const baseUrl = getBaseUrl(environment);
|
|
575
|
+
const res = await fetch(
|
|
576
|
+
`${baseUrl}/api/v1/state-by-country/${countryIso3}`,
|
|
577
|
+
{
|
|
578
|
+
method: "GET",
|
|
579
|
+
headers: {
|
|
580
|
+
"Content-Type": "application/json",
|
|
581
|
+
Accept: "application/json",
|
|
582
|
+
merchantId: secretKey
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
);
|
|
586
|
+
return await res.json();
|
|
587
|
+
} catch (error) {
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
async function getStableCoins(environment) {
|
|
591
|
+
try {
|
|
592
|
+
const baseUrl = getBaseUrl(environment);
|
|
593
|
+
const res = await fetch(`${baseUrl}/api/v1/checkout/stable-coin`, {
|
|
594
|
+
method: "GET",
|
|
595
|
+
headers: {
|
|
596
|
+
"Content-Type": "application/json",
|
|
597
|
+
Accept: "application/json"
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
return await res.json();
|
|
601
|
+
} catch (error) {
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async function getStableCoinNetworks(environment, stableCoin) {
|
|
605
|
+
try {
|
|
606
|
+
const baseUrl = getBaseUrl(environment);
|
|
607
|
+
const res = await fetch(
|
|
608
|
+
`${baseUrl}/api/v1/checkout/networks/${stableCoin}`,
|
|
609
|
+
{
|
|
610
|
+
method: "GET",
|
|
611
|
+
headers: {
|
|
612
|
+
"Content-Type": "application/json",
|
|
613
|
+
Accept: "application/json"
|
|
614
|
+
}
|
|
185
615
|
}
|
|
186
616
|
);
|
|
187
617
|
return await res.json();
|
|
@@ -839,13 +1269,33 @@ var BaseLabelInfo = ({
|
|
|
839
1269
|
|
|
840
1270
|
// src/components/base/success.tsx
|
|
841
1271
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
842
|
-
var BaseSuccess = ({
|
|
1272
|
+
var BaseSuccess = ({
|
|
1273
|
+
amount,
|
|
1274
|
+
currency,
|
|
1275
|
+
redirectUrl,
|
|
1276
|
+
successObject = {
|
|
1277
|
+
paymentDate: "",
|
|
1278
|
+
paymentId: "",
|
|
1279
|
+
paymentStatus: ""
|
|
1280
|
+
}
|
|
1281
|
+
}) => {
|
|
1282
|
+
const formatAmountHandler = formatAmount(amount, currency);
|
|
1283
|
+
const goToRedirectUrl = () => {
|
|
1284
|
+
window.open(redirectUrl, "_self", "noopener,noreferrer");
|
|
1285
|
+
};
|
|
1286
|
+
const paymentDate = new Date(
|
|
1287
|
+
successObject.paymentDate ?? ""
|
|
1288
|
+
).toLocaleDateString("en-US", {
|
|
1289
|
+
year: "numeric",
|
|
1290
|
+
month: "long",
|
|
1291
|
+
day: "2-digit"
|
|
1292
|
+
});
|
|
843
1293
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-8 p-16", children: [
|
|
844
1294
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
845
1295
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
846
1296
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IconCheckCircle, { color: "#F47A1F", className: "mx-auto" }),
|
|
847
1297
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col text-center", style: { gap: "2px" }, children: [
|
|
848
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-heading-text font-medium text-header-2xl", children:
|
|
1298
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-heading-text font-medium text-header-2xl", children: formatAmountHandler }),
|
|
849
1299
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sub-copy font-regular text-body-3xs", children: "Has been paid successfully" })
|
|
850
1300
|
] })
|
|
851
1301
|
] }),
|
|
@@ -855,7 +1305,7 @@ var BaseSuccess = ({}) => {
|
|
|
855
1305
|
{
|
|
856
1306
|
type: "horizontal",
|
|
857
1307
|
label: "Order ID",
|
|
858
|
-
value:
|
|
1308
|
+
value: successObject.paymentId
|
|
859
1309
|
}
|
|
860
1310
|
) }),
|
|
861
1311
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "py-4", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
@@ -863,7 +1313,7 @@ var BaseSuccess = ({}) => {
|
|
|
863
1313
|
{
|
|
864
1314
|
type: "horizontal",
|
|
865
1315
|
label: "Payment date",
|
|
866
|
-
value:
|
|
1316
|
+
value: paymentDate
|
|
867
1317
|
}
|
|
868
1318
|
) })
|
|
869
1319
|
] })
|
|
@@ -873,7 +1323,8 @@ var BaseSuccess = ({}) => {
|
|
|
873
1323
|
{
|
|
874
1324
|
label: "Return to Merchant Website",
|
|
875
1325
|
type: "secondary",
|
|
876
|
-
customClass: "w-full"
|
|
1326
|
+
customClass: "w-full",
|
|
1327
|
+
onClick: goToRedirectUrl
|
|
877
1328
|
}
|
|
878
1329
|
) })
|
|
879
1330
|
] });
|
|
@@ -893,6 +1344,7 @@ var BaseSelect = ({
|
|
|
893
1344
|
value,
|
|
894
1345
|
defaultValue,
|
|
895
1346
|
onChange,
|
|
1347
|
+
onBlur,
|
|
896
1348
|
placeholder = "Select an option",
|
|
897
1349
|
hasSearch = true,
|
|
898
1350
|
disabled = false,
|
|
@@ -965,6 +1417,7 @@ var BaseSelect = ({
|
|
|
965
1417
|
const commit = (val) => {
|
|
966
1418
|
if (!isControlled) setInternalValue(val);
|
|
967
1419
|
onChange?.(val);
|
|
1420
|
+
onBlur?.(val);
|
|
968
1421
|
closeMenu();
|
|
969
1422
|
};
|
|
970
1423
|
const onSearchInput = (e) => {
|
|
@@ -1115,6 +1568,7 @@ var BaseSelect = ({
|
|
|
1115
1568
|
ref: searchRef,
|
|
1116
1569
|
type: "text",
|
|
1117
1570
|
onChange: onSearchInput,
|
|
1571
|
+
onBlur: onSearchInput,
|
|
1118
1572
|
placeholder: `Search ${label || "options"}`,
|
|
1119
1573
|
className: "bg-transparent outline-none border-b pb-2 w-full focus:outline-none focus:ring-0 text-body-2xs text-light-copy font-normal"
|
|
1120
1574
|
}
|
|
@@ -1189,105 +1643,240 @@ var BaseCurrencyAmount = ({
|
|
|
1189
1643
|
] });
|
|
1190
1644
|
};
|
|
1191
1645
|
|
|
1192
|
-
// src/
|
|
1193
|
-
var import_react5 = require("react");
|
|
1646
|
+
// src/components/base/input.tsx
|
|
1647
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
1648
|
+
var import_react_imask = require("react-imask");
|
|
1194
1649
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
const
|
|
1218
|
-
const [
|
|
1219
|
-
|
|
1220
|
-
const launchIframe = (0, import_react5.useCallback)(
|
|
1221
|
-
(url2) => {
|
|
1222
|
-
if (!containerRef.current) return;
|
|
1223
|
-
if (iframeRef.current && iframeRef.current.parentNode) {
|
|
1224
|
-
iframeRef.current.parentNode.removeChild(iframeRef.current);
|
|
1225
|
-
}
|
|
1226
|
-
const iframe = document.createElement("iframe");
|
|
1227
|
-
iframe.src = url2;
|
|
1228
|
-
if (style.width) iframe.style.width = style.width;
|
|
1229
|
-
if (style.height) iframe.style.height = style.height;
|
|
1230
|
-
if (style.border) iframe.style.border = style.border;
|
|
1231
|
-
if (style.borderRadius) iframe.style.borderRadius = style.borderRadius;
|
|
1232
|
-
if (style.overflow) iframe.style.overflow = style.overflow;
|
|
1233
|
-
containerRef.current.appendChild(iframe);
|
|
1234
|
-
iframeRef.current = iframe;
|
|
1235
|
-
},
|
|
1236
|
-
[style]
|
|
1650
|
+
var BaseInput = ({
|
|
1651
|
+
label = "",
|
|
1652
|
+
type = "text",
|
|
1653
|
+
mask,
|
|
1654
|
+
placeholder,
|
|
1655
|
+
validationError = "",
|
|
1656
|
+
hint = "",
|
|
1657
|
+
rules = [],
|
|
1658
|
+
isAmountInput = false,
|
|
1659
|
+
required = false,
|
|
1660
|
+
disabled = false,
|
|
1661
|
+
loading = false,
|
|
1662
|
+
showCopyIcon = false,
|
|
1663
|
+
preventPaste = false,
|
|
1664
|
+
value,
|
|
1665
|
+
defaultValue,
|
|
1666
|
+
onChange,
|
|
1667
|
+
onBlur,
|
|
1668
|
+
prefix,
|
|
1669
|
+
suffix,
|
|
1670
|
+
className = ""
|
|
1671
|
+
}) => {
|
|
1672
|
+
const isControlled = value !== void 0;
|
|
1673
|
+
const [rawValue, setRawValue] = import_react5.default.useState(
|
|
1674
|
+
defaultValue ?? value ?? ""
|
|
1237
1675
|
);
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
if (!
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
);
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1676
|
+
const [localHint, setLocalHint] = import_react5.default.useState("");
|
|
1677
|
+
const [localError, setLocalError] = import_react5.default.useState("");
|
|
1678
|
+
import_react5.default.useEffect(() => {
|
|
1679
|
+
if (isControlled) setRawValue(value ?? "");
|
|
1680
|
+
}, [isControlled, value]);
|
|
1681
|
+
const formattedValue = isAmountInput ? formatAmount(rawValue.replace(/,/g, "")) : rawValue;
|
|
1682
|
+
const handleChange = (e) => {
|
|
1683
|
+
const incoming = e.target.value.replace(/,/g, "");
|
|
1684
|
+
if (!isControlled) setRawValue(incoming);
|
|
1685
|
+
onChange?.(incoming);
|
|
1686
|
+
setTimeout(() => {
|
|
1687
|
+
const el = e.target;
|
|
1688
|
+
el.selectionStart = el.selectionEnd = el.value.length;
|
|
1689
|
+
});
|
|
1690
|
+
};
|
|
1691
|
+
const handleBlur = () => {
|
|
1692
|
+
onBlur?.(rawValue);
|
|
1693
|
+
};
|
|
1694
|
+
const handleKeyDown = (e) => {
|
|
1695
|
+
if (rules.includes("numeric")) restrictToNumericKeys(e);
|
|
1696
|
+
};
|
|
1697
|
+
const handlePaste = (e) => {
|
|
1698
|
+
if (preventPaste) {
|
|
1699
|
+
e.preventDefault();
|
|
1700
|
+
setLocalError("Pasting is disabled for this input");
|
|
1263
1701
|
}
|
|
1264
1702
|
};
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1703
|
+
const containerBg = disabled ? "bg-grey-50 cursor-not-allowed" : "bg-white";
|
|
1704
|
+
const containerBorder = validationError || localError ? "border-red-300 bg-red-50" : "border-grey-100";
|
|
1705
|
+
const copyToClipboard = (text) => {
|
|
1706
|
+
return navigator.clipboard.writeText(text);
|
|
1707
|
+
};
|
|
1708
|
+
const copyHandler = () => {
|
|
1709
|
+
copyToClipboard(rawValue).then(() => {
|
|
1710
|
+
setLocalHint("Text copied to clipboard");
|
|
1711
|
+
}).catch(() => {
|
|
1712
|
+
setLocalError("Failed to copy text to clipboard");
|
|
1713
|
+
});
|
|
1714
|
+
};
|
|
1715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `flex flex-col gap-2 ${className}`, children: [
|
|
1716
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "mb-0 text-body-2xs font-normal text-heading-text", children: [
|
|
1717
|
+
label,
|
|
1718
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-orange-required", children: " *" })
|
|
1719
|
+
] }) : null,
|
|
1720
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
1721
|
+
"div",
|
|
1722
|
+
{
|
|
1723
|
+
className: `border-c px-3 py-2 flex items-center justify-between rounded-md h-12 ${containerBg} ${containerBorder}`,
|
|
1724
|
+
children: [
|
|
1725
|
+
prefix,
|
|
1726
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1727
|
+
import_react_imask.IMaskInput,
|
|
1728
|
+
{
|
|
1729
|
+
type,
|
|
1730
|
+
mask,
|
|
1731
|
+
value: formattedValue,
|
|
1732
|
+
onChange: handleChange,
|
|
1733
|
+
onBlur: handleBlur,
|
|
1734
|
+
onKeyDown: handleKeyDown,
|
|
1735
|
+
onPaste: handlePaste,
|
|
1736
|
+
disabled,
|
|
1737
|
+
placeholder: placeholder ?? (label ? `Enter ${label.toLowerCase()}` : void 0),
|
|
1738
|
+
inputMode: isAmountInput ? "decimal" : void 0,
|
|
1739
|
+
className: "search-input bg-transparent outline-none border-none focus:outline-none focus:ring-0 text-body-2xs text-light-copy font-normal w-full"
|
|
1740
|
+
}
|
|
1741
|
+
),
|
|
1742
|
+
!loading ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
1743
|
+
suffix,
|
|
1744
|
+
showCopyIcon && rawValue && rawValue.trim() !== "" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1745
|
+
BaseImage,
|
|
1746
|
+
{
|
|
1747
|
+
src: "assets/images/copyIcon.svg",
|
|
1748
|
+
alt: "copy",
|
|
1749
|
+
width: 16,
|
|
1750
|
+
height: 16,
|
|
1751
|
+
customClass: "cursor-pointer hover:opacity-70 transition-opacity",
|
|
1752
|
+
onClick: copyHandler
|
|
1753
|
+
}
|
|
1754
|
+
)
|
|
1755
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full" })
|
|
1756
|
+
]
|
|
1757
|
+
}
|
|
1758
|
+
),
|
|
1759
|
+
(hint || localHint) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-body-3xs text-light-copy", children: localHint || hint }),
|
|
1760
|
+
(validationError || localError) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-body-3xs text-red-500", children: localError || validationError })
|
|
1761
|
+
] });
|
|
1762
|
+
};
|
|
1272
1763
|
|
|
1273
|
-
// src/buzapay-checkout/checkout-
|
|
1764
|
+
// src/buzapay-checkout/checkout-iframe.tsx
|
|
1765
|
+
var import_react6 = require("react");
|
|
1274
1766
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1275
|
-
function
|
|
1767
|
+
function BzpCheckoutIframe({
|
|
1768
|
+
style = {
|
|
1769
|
+
width: "100%",
|
|
1770
|
+
height: "100vh",
|
|
1771
|
+
border: "0",
|
|
1772
|
+
borderRadius: "6px",
|
|
1773
|
+
overflow: "hidden"
|
|
1774
|
+
},
|
|
1775
|
+
url,
|
|
1276
1776
|
secretKey,
|
|
1277
1777
|
environment = "sandbox",
|
|
1278
1778
|
paymentObject = {
|
|
1779
|
+
merchantName: "",
|
|
1279
1780
|
amount: 0,
|
|
1280
1781
|
currency: "",
|
|
1281
1782
|
email: "",
|
|
1282
1783
|
phoneNumber: "",
|
|
1283
1784
|
narration: "",
|
|
1284
|
-
redirectUrl: ""
|
|
1785
|
+
redirectUrl: "https://sandbox-merchant.buzapay.com/account/three-ds-status"
|
|
1285
1786
|
},
|
|
1286
|
-
|
|
1787
|
+
onError
|
|
1287
1788
|
}) {
|
|
1789
|
+
const containerRef = (0, import_react6.useRef)(null);
|
|
1790
|
+
const iframeRef = (0, import_react6.useRef)(null);
|
|
1288
1791
|
const [message, setMessage] = (0, import_react6.useState)("");
|
|
1289
1792
|
const [launchUrl, setLaunchUrl] = (0, import_react6.useState)("");
|
|
1290
1793
|
const [loading, setLoading] = (0, import_react6.useState)(false);
|
|
1794
|
+
const launchIframe = (0, import_react6.useCallback)(
|
|
1795
|
+
(url2) => {
|
|
1796
|
+
if (iframeRef.current && iframeRef.current.parentNode) {
|
|
1797
|
+
iframeRef.current.parentNode.removeChild(iframeRef.current);
|
|
1798
|
+
}
|
|
1799
|
+
const iframe = document.createElement("iframe");
|
|
1800
|
+
iframe.src = url2;
|
|
1801
|
+
if (style.width) iframe.style.width = style.width;
|
|
1802
|
+
if (style.height) iframe.style.height = style.height;
|
|
1803
|
+
if (style.border) iframe.style.border = style.border;
|
|
1804
|
+
if (style.borderRadius) iframe.style.borderRadius = style.borderRadius;
|
|
1805
|
+
if (style.overflow) iframe.style.overflow = style.overflow;
|
|
1806
|
+
containerRef.current?.appendChild(iframe);
|
|
1807
|
+
iframeRef.current = iframe;
|
|
1808
|
+
},
|
|
1809
|
+
[style]
|
|
1810
|
+
);
|
|
1811
|
+
const generatePaymentLinkHandler = async () => {
|
|
1812
|
+
if (url) {
|
|
1813
|
+
launchIframe(url);
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
if (!secretKey) {
|
|
1817
|
+
return setMessage("Secret key is required.");
|
|
1818
|
+
}
|
|
1819
|
+
if (!checkObjectTruthy(paymentObject)) {
|
|
1820
|
+
return setMessage("Secret key is required.");
|
|
1821
|
+
}
|
|
1822
|
+
setLoading(true);
|
|
1823
|
+
try {
|
|
1824
|
+
const response = await createPaymentLink(
|
|
1825
|
+
paymentObject,
|
|
1826
|
+
environment,
|
|
1827
|
+
secretKey
|
|
1828
|
+
);
|
|
1829
|
+
if (response?.isSuccessful) {
|
|
1830
|
+
setLaunchUrl(response.launchUrl ?? "");
|
|
1831
|
+
setMessage("Payment link created successfully");
|
|
1832
|
+
if (response.launchUrl) {
|
|
1833
|
+
setLoading(false);
|
|
1834
|
+
launchIframe(`${response.launchUrl}&merchantId=${btoa(secretKey)}`);
|
|
1835
|
+
}
|
|
1836
|
+
} else {
|
|
1837
|
+
setLoading(false);
|
|
1838
|
+
setMessage("Failed to create payment link");
|
|
1839
|
+
}
|
|
1840
|
+
} catch (e) {
|
|
1841
|
+
setMessage(e?.message || "Failed to create payment link");
|
|
1842
|
+
onError?.({
|
|
1843
|
+
errorMessage: message
|
|
1844
|
+
});
|
|
1845
|
+
} finally {
|
|
1846
|
+
setLoading(false);
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
(0, import_react6.useEffect)(() => {
|
|
1850
|
+
if (!containerRef.current) return;
|
|
1851
|
+
generatePaymentLinkHandler();
|
|
1852
|
+
}, []);
|
|
1853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", style, children: [
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: containerRef, className: "w-full h-full" }),
|
|
1855
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute inset-0 grid place-items-center bg-white/60", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconLoader, {}) })
|
|
1856
|
+
] });
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/buzapay-checkout/checkout-button.tsx
|
|
1860
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1861
|
+
function BzpCheckoutButton({
|
|
1862
|
+
secretKey,
|
|
1863
|
+
environment = "sandbox",
|
|
1864
|
+
paymentObject = {
|
|
1865
|
+
merchantName: "",
|
|
1866
|
+
amount: 0,
|
|
1867
|
+
currency: "",
|
|
1868
|
+
email: "",
|
|
1869
|
+
phoneNumber: "",
|
|
1870
|
+
narration: "",
|
|
1871
|
+
redirectUrl: "https://sandbox-merchant.buzapay.com/account/three-ds-status"
|
|
1872
|
+
},
|
|
1873
|
+
mode = "redirect",
|
|
1874
|
+
onError
|
|
1875
|
+
}) {
|
|
1876
|
+
const [message, setMessage] = (0, import_react7.useState)("");
|
|
1877
|
+
const [launchUrl, setLaunchUrl] = (0, import_react7.useState)("");
|
|
1878
|
+
const [urlLaunchUrl, setUrlLaunchUrl] = (0, import_react7.useState)("");
|
|
1879
|
+
const [loading, setLoading] = (0, import_react7.useState)(false);
|
|
1291
1880
|
const generatePaymentLinkHandler = async () => {
|
|
1292
1881
|
if (!secretKey) {
|
|
1293
1882
|
setMessage("Secret key is required.");
|
|
@@ -1307,6 +1896,7 @@ function BzpCheckoutButton({
|
|
|
1307
1896
|
);
|
|
1308
1897
|
if (response?.isSuccessful && response.launchUrl) {
|
|
1309
1898
|
setLaunchUrl(response.launchUrl);
|
|
1899
|
+
setUrlLaunchUrl(`${response.launchUrl}&merchantId=${btoa(secretKey)}`);
|
|
1310
1900
|
setMessage("Payment link created successfully");
|
|
1311
1901
|
if (mode === "redirect") {
|
|
1312
1902
|
window.open(response.launchUrl, "_blank", "noopener,noreferrer");
|
|
@@ -1316,19 +1906,22 @@ function BzpCheckoutButton({
|
|
|
1316
1906
|
}
|
|
1317
1907
|
} catch (e) {
|
|
1318
1908
|
setMessage(e?.message || "Failed to create payment link");
|
|
1909
|
+
onError?.({
|
|
1910
|
+
errorMessage: message
|
|
1911
|
+
});
|
|
1319
1912
|
} finally {
|
|
1320
1913
|
setLoading(false);
|
|
1321
1914
|
}
|
|
1322
1915
|
};
|
|
1323
|
-
return
|
|
1916
|
+
return urlLaunchUrl && mode === "iframe" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1324
1917
|
BzpCheckoutIframe,
|
|
1325
1918
|
{
|
|
1326
|
-
url:
|
|
1919
|
+
url: urlLaunchUrl,
|
|
1327
1920
|
secretKey,
|
|
1328
1921
|
environment
|
|
1329
1922
|
}
|
|
1330
|
-
) : /* @__PURE__ */ (0,
|
|
1331
|
-
/* @__PURE__ */ (0,
|
|
1923
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1332
1925
|
BaseButton,
|
|
1333
1926
|
{
|
|
1334
1927
|
label: "Pay",
|
|
@@ -1338,7 +1931,7 @@ function BzpCheckoutButton({
|
|
|
1338
1931
|
onClick: generatePaymentLinkHandler
|
|
1339
1932
|
}
|
|
1340
1933
|
),
|
|
1341
|
-
/* @__PURE__ */ (0,
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BaseInputError, { errorMessage: message })
|
|
1342
1935
|
] });
|
|
1343
1936
|
}
|
|
1344
1937
|
|
|
@@ -1347,137 +1940,367 @@ var import_react11 = require("react");
|
|
|
1347
1940
|
|
|
1348
1941
|
// src/components/pay-by-card.tsx
|
|
1349
1942
|
var import_react8 = require("react");
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1943
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1944
|
+
function PayByCard({
|
|
1945
|
+
secretKey,
|
|
1946
|
+
paymentObject,
|
|
1947
|
+
environment = "sandbox",
|
|
1948
|
+
onPaymentAuthorized,
|
|
1949
|
+
onError
|
|
1950
|
+
}) {
|
|
1951
|
+
const [formIndex, setFormIndex] = (0, import_react8.useState)(0);
|
|
1952
|
+
const [message, setMessage] = (0, import_react8.useState)("");
|
|
1953
|
+
const [isMakingPayment, setIsMakingPayment] = (0, import_react8.useState)(false);
|
|
1954
|
+
const [loading, setLoading] = (0, import_react8.useState)(false);
|
|
1955
|
+
const [cardType, setCardType] = (0, import_react8.useState)("");
|
|
1956
|
+
const [transactionReference, setTransactionReference] = (0, import_react8.useState)("");
|
|
1957
|
+
const [loadingCountries, setLoadingCountries] = (0, import_react8.useState)(false);
|
|
1958
|
+
const [loadingStates, setLoadingStates] = (0, import_react8.useState)(false);
|
|
1959
|
+
const [rawCountries, setRawCountries] = (0, import_react8.useState)([]);
|
|
1960
|
+
const [countries, setCountries] = (0, import_react8.useState)([]);
|
|
1961
|
+
const [countryStates, setCountryStates] = (0, import_react8.useState)([]);
|
|
1962
|
+
const [billingForm, setBillingForm] = (0, import_react8.useState)({
|
|
1963
|
+
address1: "",
|
|
1964
|
+
address2: "",
|
|
1965
|
+
postalCode: "",
|
|
1966
|
+
state: "",
|
|
1967
|
+
city: "",
|
|
1968
|
+
country: "",
|
|
1969
|
+
emailAddress: "",
|
|
1970
|
+
phoneNumber: ""
|
|
1971
|
+
});
|
|
1972
|
+
const [payForm, setPayForm] = (0, import_react8.useState)({
|
|
1973
|
+
customerName: "",
|
|
1974
|
+
cardNo: "",
|
|
1975
|
+
expireDate: "",
|
|
1976
|
+
cvv: "",
|
|
1977
|
+
cardPin: ""
|
|
1978
|
+
// Only required for Verve cards
|
|
1979
|
+
});
|
|
1980
|
+
const [billingErrors, setBillingErrors] = (0, import_react8.useState)(
|
|
1981
|
+
{}
|
|
1377
1982
|
);
|
|
1378
|
-
const [
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
const el = e.target;
|
|
1390
|
-
el.selectionStart = el.selectionEnd = el.value.length;
|
|
1391
|
-
});
|
|
1983
|
+
const [payErrors, setPayErrors] = (0, import_react8.useState)({});
|
|
1984
|
+
const billingRules = {
|
|
1985
|
+
address1: "required",
|
|
1986
|
+
address2: "",
|
|
1987
|
+
// optional
|
|
1988
|
+
country: "required",
|
|
1989
|
+
state: "required",
|
|
1990
|
+
city: "required",
|
|
1991
|
+
postalCode: "required|no_special|char_length:6",
|
|
1992
|
+
emailAddress: "required|email",
|
|
1993
|
+
phoneNumber: "required"
|
|
1392
1994
|
};
|
|
1393
|
-
const
|
|
1394
|
-
|
|
1995
|
+
const payRules = {
|
|
1996
|
+
customerName: "required",
|
|
1997
|
+
cardNo: "required|num_spaces",
|
|
1998
|
+
expireDate: "required",
|
|
1999
|
+
cvv: "required|numeric",
|
|
2000
|
+
cardPin: ""
|
|
2001
|
+
// optional unless Verve
|
|
1395
2002
|
};
|
|
1396
|
-
const
|
|
1397
|
-
|
|
2003
|
+
const formatAmountHandler = formatAmount(
|
|
2004
|
+
paymentObject.amount,
|
|
2005
|
+
paymentObject.currency
|
|
2006
|
+
);
|
|
2007
|
+
const billingLabels = {
|
|
2008
|
+
address1: "Address Line 1",
|
|
2009
|
+
address2: "Address Line 2",
|
|
2010
|
+
postalCode: "Postal Code",
|
|
2011
|
+
state: "State",
|
|
2012
|
+
city: "City",
|
|
2013
|
+
country: "Country",
|
|
2014
|
+
emailAddress: "Email",
|
|
2015
|
+
phoneNumber: "Phone Number"
|
|
1398
2016
|
};
|
|
1399
|
-
const
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
2017
|
+
const payLabels = {
|
|
2018
|
+
customerName: "Card Name",
|
|
2019
|
+
cardNo: "Card Number",
|
|
2020
|
+
expireDate: "Expiry Date",
|
|
2021
|
+
cvv: "CVV",
|
|
2022
|
+
cardPin: "Card PIN"
|
|
1403
2023
|
};
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
2024
|
+
const proceedHandler = async () => {
|
|
2025
|
+
if (formIndex === 0) {
|
|
2026
|
+
const errs = validateGroup(billingForm, billingRules, billingLabels);
|
|
2027
|
+
setBillingErrors(errs);
|
|
2028
|
+
if (Object.keys(errs).length === 0) {
|
|
2029
|
+
setFormIndex(1);
|
|
2030
|
+
}
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
if (formIndex === 1) {
|
|
2034
|
+
const errs = validateGroup(payForm, payRules, payLabels);
|
|
2035
|
+
setPayErrors(errs);
|
|
2036
|
+
if (Object.keys(errs).length > 0) {
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
try {
|
|
2040
|
+
setIsMakingPayment(true);
|
|
2041
|
+
setMessage("");
|
|
2042
|
+
const cardDetails = {
|
|
2043
|
+
pan: payForm.cardNo ?? "",
|
|
2044
|
+
expiryDate: payForm.expireDate ?? "",
|
|
2045
|
+
cvv: payForm.cvv ?? "",
|
|
2046
|
+
cardScheme: cardType,
|
|
2047
|
+
nameOnCard: payForm.customerName ?? "",
|
|
2048
|
+
...cardType === "Verve" && { pin: payForm.cardPin ?? "" }
|
|
2049
|
+
};
|
|
2050
|
+
const billingDetails = {
|
|
2051
|
+
address1: billingForm.address1 ?? "",
|
|
2052
|
+
address2: billingForm.address2 ?? "",
|
|
2053
|
+
postalCode: billingForm.postalCode ?? "",
|
|
2054
|
+
state: billingForm.state ?? "",
|
|
2055
|
+
city: billingForm.city ?? "",
|
|
2056
|
+
country: billingForm.country ?? "",
|
|
2057
|
+
emailAddress: billingForm.emailAddress ?? "",
|
|
2058
|
+
phoneNumber: billingForm.phoneNumber ?? ""
|
|
2059
|
+
};
|
|
2060
|
+
const encryptedCardDetails = encryptPayload(secretKey, cardDetails);
|
|
2061
|
+
const payload = {
|
|
2062
|
+
customerId: paymentObject?.email || payForm.customerName || "",
|
|
2063
|
+
amount: String(paymentObject?.amount ?? ""),
|
|
2064
|
+
currency: paymentObject?.currency || "USD",
|
|
2065
|
+
narration: paymentObject?.narration || "Test transaction",
|
|
2066
|
+
encryptedCardDetails: encryptedCardDetails.requestParam,
|
|
2067
|
+
billingDetails,
|
|
2068
|
+
redirectUrl: paymentObject?.redirectUrl || "",
|
|
2069
|
+
paymentReference: transactionReference,
|
|
2070
|
+
isCheckout: true
|
|
2071
|
+
};
|
|
2072
|
+
const request = { ...payload, merchantId: secretKey };
|
|
2073
|
+
let response = await authorizeCardPayment(environment, request);
|
|
2074
|
+
if (response?.responseParam) {
|
|
2075
|
+
response = decryptPayload(environment, response.responseParam);
|
|
2076
|
+
}
|
|
2077
|
+
if (response?.isSuccessful) {
|
|
2078
|
+
if (response.threeDsInteractionRequired === true) {
|
|
2079
|
+
const threeDsData = {
|
|
2080
|
+
transactionReference: response.transactionReference,
|
|
2081
|
+
threeDsHtml: response.threeDsHtml,
|
|
2082
|
+
amount: response.amount,
|
|
2083
|
+
responseMessage: response.responseMessage,
|
|
2084
|
+
paReq: response.threeDsHtml?.paReq,
|
|
2085
|
+
termUrl: response.threeDsHtml?.termUrl,
|
|
2086
|
+
action: response.threeDsHtml?.action,
|
|
2087
|
+
acsUrl: response.threeDsHtml?.acsUrl,
|
|
2088
|
+
md: response.threeDsHtml?.md
|
|
2089
|
+
};
|
|
2090
|
+
const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
|
|
2091
|
+
const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(
|
|
2092
|
+
stringifiedThreeDsData
|
|
2093
|
+
)}&paymentReference=${response.transactionReference}`;
|
|
2094
|
+
window.open(threeDsUrl, "_self", "noopener,noreferrer");
|
|
2095
|
+
setMessage(
|
|
2096
|
+
"3D Secure authentication opened in new tab. Please complete the verification"
|
|
2097
|
+
);
|
|
2098
|
+
setIsMakingPayment(false);
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
if (response.responseMessage === "Payer Interaction Required" && response.threeDsHtml) {
|
|
2102
|
+
const threeDsData = {
|
|
2103
|
+
transactionReference: response.transactionReference,
|
|
2104
|
+
threeDsHtml: response.threeDsHtml,
|
|
2105
|
+
amount: response.amount,
|
|
2106
|
+
responseMessage: response.responseMessage,
|
|
2107
|
+
paReq: response.threeDsHtml?.paReq,
|
|
2108
|
+
termUrl: response.threeDsHtml?.termUrl,
|
|
2109
|
+
action: response.threeDsHtml?.action,
|
|
2110
|
+
acsUrl: response.threeDsHtml?.acsUrl,
|
|
2111
|
+
md: response.threeDsHtml?.md
|
|
2112
|
+
};
|
|
2113
|
+
const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
|
|
2114
|
+
const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(
|
|
2115
|
+
stringifiedThreeDsData
|
|
2116
|
+
)}&paymentReference=${response.transactionReference}`;
|
|
2117
|
+
window.open(threeDsUrl, "_self", "noopener,noreferrer");
|
|
2118
|
+
setMessage(
|
|
2119
|
+
"3D Secure authentication opened in new tab. Please complete the verification"
|
|
2120
|
+
);
|
|
2121
|
+
setIsMakingPayment(false);
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
if (response.transactionReference?.trim()) {
|
|
2125
|
+
onPaymentAuthorized?.({
|
|
2126
|
+
paymentId: response.transactionReference,
|
|
2127
|
+
paymentDate: response?.data?.updatedAt,
|
|
2128
|
+
// optional if present
|
|
2129
|
+
paymentStatus: "authorized",
|
|
2130
|
+
message
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
setMessage("Card payment authorized successfully");
|
|
2134
|
+
setIsMakingPayment(false);
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
setMessage(response?.responseMessage || "Payment failed");
|
|
2138
|
+
onPaymentAuthorized?.({
|
|
2139
|
+
paymentId: response?.transactionReference,
|
|
2140
|
+
paymentDate: response?.data?.updatedAt,
|
|
2141
|
+
paymentStatus: "payment failed",
|
|
2142
|
+
message
|
|
2143
|
+
});
|
|
2144
|
+
setIsMakingPayment(false);
|
|
2145
|
+
} catch (err) {
|
|
2146
|
+
let friendly = "Payment failed";
|
|
2147
|
+
if (err?.error?.responseParam) {
|
|
2148
|
+
try {
|
|
2149
|
+
const decryptedError = decryptPayload(
|
|
2150
|
+
environment,
|
|
2151
|
+
err.error.responseParam
|
|
2152
|
+
);
|
|
2153
|
+
friendly = decryptedError?.responseMessage || friendly;
|
|
2154
|
+
} catch {
|
|
2155
|
+
friendly = err?.error?.responseMessage || err?.error?.message || friendly;
|
|
2156
|
+
}
|
|
2157
|
+
} else {
|
|
2158
|
+
friendly = err?.error?.responseMessage || err?.error?.message || "Payment failed";
|
|
2159
|
+
}
|
|
2160
|
+
setMessage(friendly);
|
|
2161
|
+
setIsMakingPayment(false);
|
|
2162
|
+
onError?.({
|
|
2163
|
+
errorMessage: message
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
1410
2167
|
};
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
"
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
}
|
|
1435
|
-
),
|
|
1436
|
-
!loading ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
1437
|
-
suffix,
|
|
1438
|
-
showCopyIcon && rawValue && rawValue.trim() !== "" && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1439
|
-
BaseImage,
|
|
1440
|
-
{
|
|
1441
|
-
src: "assets/images/copyIcon.svg",
|
|
1442
|
-
alt: "copy",
|
|
1443
|
-
width: 16,
|
|
1444
|
-
height: 16,
|
|
1445
|
-
customClass: "cursor-pointer hover:opacity-70 transition-opacity",
|
|
1446
|
-
onClick: copyHandler
|
|
1447
|
-
}
|
|
1448
|
-
)
|
|
1449
|
-
] }) : (
|
|
1450
|
-
// Simple loader placeholder; swap for your icon component if desired
|
|
1451
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full" })
|
|
1452
|
-
)
|
|
1453
|
-
]
|
|
2168
|
+
const generatePaymentLinkHandler = async () => {
|
|
2169
|
+
if (!secretKey) {
|
|
2170
|
+
setMessage("Secret key is required.");
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
if (!checkObjectTruthy(paymentObject)) {
|
|
2174
|
+
setMessage("Kindly ensure you are passing all the required data.");
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
setLoading(true);
|
|
2178
|
+
setMessage("");
|
|
2179
|
+
try {
|
|
2180
|
+
const response = await createPaymentLink(
|
|
2181
|
+
paymentObject,
|
|
2182
|
+
environment,
|
|
2183
|
+
secretKey
|
|
2184
|
+
);
|
|
2185
|
+
if (response?.isSuccessful && response.launchUrl) {
|
|
2186
|
+
const queryParams = getQueryParams(response.launchUrl);
|
|
2187
|
+
setTransactionReference(queryParams["paymentReference"]);
|
|
2188
|
+
setMessage("Payment link created successfully");
|
|
2189
|
+
} else {
|
|
2190
|
+
setMessage("Failed to create payment link");
|
|
1454
2191
|
}
|
|
1455
|
-
)
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
};
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
const
|
|
2192
|
+
} catch (e) {
|
|
2193
|
+
setMessage(e?.message || "Failed to create payment link");
|
|
2194
|
+
onError?.({
|
|
2195
|
+
errorMessage: message
|
|
2196
|
+
});
|
|
2197
|
+
} finally {
|
|
2198
|
+
setLoading(false);
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
const getAllCountries = async () => {
|
|
2202
|
+
setLoadingCountries(true);
|
|
2203
|
+
try {
|
|
2204
|
+
const response = await getCountries(
|
|
2205
|
+
environment,
|
|
2206
|
+
secretKey
|
|
2207
|
+
);
|
|
2208
|
+
if (response?.isSuccessful) {
|
|
2209
|
+
setRawCountries(response.data);
|
|
2210
|
+
setCountries(
|
|
2211
|
+
(response.data ?? []).map((c) => {
|
|
2212
|
+
return { label: c.countryName, value: c.iso2 };
|
|
2213
|
+
})
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
} catch (e) {
|
|
2217
|
+
setMessage(e?.message || "Failed to get countries");
|
|
2218
|
+
onError?.({
|
|
2219
|
+
errorMessage: message
|
|
2220
|
+
});
|
|
2221
|
+
} finally {
|
|
2222
|
+
setLoadingCountries(false);
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
const getStates = async (countryIso2) => {
|
|
2226
|
+
const country = rawCountries.find((c) => c.iso2 === countryIso2);
|
|
2227
|
+
if (!country) return;
|
|
2228
|
+
setLoadingStates(true);
|
|
2229
|
+
try {
|
|
2230
|
+
const response = await getCountryStates(
|
|
2231
|
+
country.iso3,
|
|
2232
|
+
environment,
|
|
2233
|
+
secretKey
|
|
2234
|
+
);
|
|
2235
|
+
if (response?.isSuccessful) {
|
|
2236
|
+
setCountryStates(
|
|
2237
|
+
(response.data ?? []).map((s) => ({
|
|
2238
|
+
label: s.name,
|
|
2239
|
+
value: s.name
|
|
2240
|
+
}))
|
|
2241
|
+
);
|
|
2242
|
+
}
|
|
2243
|
+
} catch (e) {
|
|
2244
|
+
setMessage(e?.message || "Failed to get country states");
|
|
2245
|
+
onError?.({
|
|
2246
|
+
errorMessage: message
|
|
2247
|
+
});
|
|
2248
|
+
} finally {
|
|
2249
|
+
setLoadingStates(false);
|
|
2250
|
+
}
|
|
2251
|
+
};
|
|
2252
|
+
const cardNumberInputHandler = (event) => {
|
|
2253
|
+
setCardType(cardTypeHandler(event));
|
|
2254
|
+
payRules.cardPin = cardType === "Verve" ? "required|numeric" : "";
|
|
2255
|
+
};
|
|
2256
|
+
(0, import_react8.useEffect)(() => {
|
|
2257
|
+
(async () => {
|
|
2258
|
+
await generatePaymentLinkHandler();
|
|
2259
|
+
await getAllCountries();
|
|
2260
|
+
})();
|
|
2261
|
+
}, []);
|
|
1465
2262
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
1466
2263
|
formIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-6 overflow-y-auto", children: [
|
|
1467
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
2264
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2265
|
+
BaseInput,
|
|
2266
|
+
{
|
|
2267
|
+
label: "Address Line 1",
|
|
2268
|
+
required: true,
|
|
2269
|
+
value: billingForm.address1,
|
|
2270
|
+
onChange: (e) => {
|
|
2271
|
+
setBillingForm({ ...billingForm, address1: e });
|
|
2272
|
+
if (billingErrors.address1) {
|
|
2273
|
+
setBillingErrors((er) => ({ ...er, address1: "" }));
|
|
2274
|
+
}
|
|
2275
|
+
},
|
|
2276
|
+
validationError: billingErrors.address1 ?? ""
|
|
2277
|
+
}
|
|
2278
|
+
) }),
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2280
|
+
BaseInput,
|
|
2281
|
+
{
|
|
2282
|
+
label: "Address Line 2",
|
|
2283
|
+
value: billingForm.address2,
|
|
2284
|
+
onChange: (e) => setBillingForm({ ...billingForm, address2: e }),
|
|
2285
|
+
validationError: billingErrors.address2 ?? ""
|
|
2286
|
+
}
|
|
2287
|
+
) }),
|
|
1471
2288
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1472
2289
|
BaseSelect,
|
|
1473
2290
|
{
|
|
1474
2291
|
label: "Select Country",
|
|
1475
2292
|
required: true,
|
|
1476
|
-
options:
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
2293
|
+
options: countries,
|
|
2294
|
+
loading: loadingCountries,
|
|
2295
|
+
value: billingForm.country,
|
|
2296
|
+
onChange: (e) => {
|
|
2297
|
+
setBillingForm({ ...billingForm, country: e, state: "" });
|
|
2298
|
+
getStates(e);
|
|
2299
|
+
if (billingErrors.country) {
|
|
2300
|
+
setBillingErrors((er) => ({ ...er, country: "" }));
|
|
2301
|
+
}
|
|
2302
|
+
},
|
|
2303
|
+
validationError: billingErrors.country ?? ""
|
|
1481
2304
|
}
|
|
1482
2305
|
),
|
|
1483
2306
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
@@ -1485,37 +2308,180 @@ function PayByCard({}) {
|
|
|
1485
2308
|
{
|
|
1486
2309
|
label: "Select State",
|
|
1487
2310
|
required: true,
|
|
1488
|
-
options:
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
2311
|
+
options: countryStates,
|
|
2312
|
+
loading: loadingStates,
|
|
2313
|
+
value: billingForm.state,
|
|
2314
|
+
onChange: (e) => {
|
|
2315
|
+
setBillingForm({ ...billingForm, state: e });
|
|
2316
|
+
if (billingErrors.state) {
|
|
2317
|
+
setBillingErrors((er) => ({ ...er, state: "" }));
|
|
2318
|
+
}
|
|
2319
|
+
},
|
|
2320
|
+
validationError: billingErrors.state ?? ""
|
|
2321
|
+
}
|
|
2322
|
+
),
|
|
2323
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2324
|
+
BaseInput,
|
|
2325
|
+
{
|
|
2326
|
+
label: "City",
|
|
2327
|
+
required: true,
|
|
2328
|
+
value: billingForm.city,
|
|
2329
|
+
onChange: (e) => {
|
|
2330
|
+
setBillingForm({ ...billingForm, city: e });
|
|
2331
|
+
if (billingErrors.city) {
|
|
2332
|
+
setBillingErrors((er) => ({ ...er, city: "" }));
|
|
2333
|
+
}
|
|
2334
|
+
},
|
|
2335
|
+
validationError: billingErrors.city ?? ""
|
|
2336
|
+
}
|
|
2337
|
+
),
|
|
2338
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2339
|
+
BaseInput,
|
|
2340
|
+
{
|
|
2341
|
+
label: "Postal Code",
|
|
2342
|
+
required: true,
|
|
2343
|
+
value: billingForm.postalCode,
|
|
2344
|
+
onChange: (e) => {
|
|
2345
|
+
setBillingForm({ ...billingForm, postalCode: e });
|
|
2346
|
+
if (billingErrors.postalCode) {
|
|
2347
|
+
setBillingErrors((er) => ({ ...er, postalCode: "" }));
|
|
2348
|
+
}
|
|
2349
|
+
},
|
|
2350
|
+
validationError: billingErrors.postalCode ?? ""
|
|
1493
2351
|
}
|
|
1494
2352
|
),
|
|
1495
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1496
|
-
|
|
1497
|
-
|
|
2353
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2354
|
+
BaseInput,
|
|
2355
|
+
{
|
|
2356
|
+
label: "Email",
|
|
2357
|
+
required: true,
|
|
2358
|
+
value: billingForm.emailAddress,
|
|
2359
|
+
onChange: (e) => {
|
|
2360
|
+
setBillingForm({ ...billingForm, emailAddress: e });
|
|
2361
|
+
if (billingErrors.emailAddress) {
|
|
2362
|
+
setBillingErrors((er) => ({ ...er, emailAddress: "" }));
|
|
2363
|
+
}
|
|
2364
|
+
},
|
|
2365
|
+
validationError: billingErrors.emailAddress ?? ""
|
|
2366
|
+
}
|
|
2367
|
+
),
|
|
2368
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2369
|
+
BaseInput,
|
|
2370
|
+
{
|
|
2371
|
+
label: "Phone Number",
|
|
2372
|
+
required: true,
|
|
2373
|
+
value: billingForm.phoneNumber,
|
|
2374
|
+
onChange: (e) => {
|
|
2375
|
+
setBillingForm({ ...billingForm, phoneNumber: e });
|
|
2376
|
+
if (billingErrors.phoneNumber) {
|
|
2377
|
+
setBillingErrors((er) => ({ ...er, phoneNumber: "" }));
|
|
2378
|
+
}
|
|
2379
|
+
},
|
|
2380
|
+
validationError: billingErrors.phoneNumber ?? ""
|
|
2381
|
+
}
|
|
2382
|
+
)
|
|
1498
2383
|
] }),
|
|
1499
2384
|
formIndex === 1 && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
1500
2385
|
"div",
|
|
1501
2386
|
{
|
|
1502
2387
|
className: "grid grid-cols-2 gap-6 overflow-y-auto",
|
|
1503
|
-
style: { maxHeight:
|
|
2388
|
+
style: { maxHeight: 320 },
|
|
1504
2389
|
children: [
|
|
1505
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2391
|
+
BaseInput,
|
|
2392
|
+
{
|
|
2393
|
+
label: "Card Name",
|
|
2394
|
+
required: true,
|
|
2395
|
+
value: payForm.customerName,
|
|
2396
|
+
onChange: (e) => {
|
|
2397
|
+
setPayForm({ ...payForm, customerName: e });
|
|
2398
|
+
if (payErrors.customerName) {
|
|
2399
|
+
setPayErrors((er) => ({ ...er, customerName: "" }));
|
|
2400
|
+
}
|
|
2401
|
+
},
|
|
2402
|
+
validationError: payErrors.customerName ?? ""
|
|
2403
|
+
}
|
|
2404
|
+
) }),
|
|
2405
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2406
|
+
BaseInput,
|
|
2407
|
+
{
|
|
2408
|
+
label: "Card Number",
|
|
2409
|
+
required: true,
|
|
2410
|
+
rules: ["numeric"],
|
|
2411
|
+
mask: "0000 0000 0000 0000",
|
|
2412
|
+
placeholder: "0000 0000 0000 0000",
|
|
2413
|
+
value: payForm.cardNo,
|
|
2414
|
+
preventPaste: true,
|
|
2415
|
+
onChange: (e) => {
|
|
2416
|
+
setPayForm({ ...payForm, cardNo: e });
|
|
2417
|
+
if (payErrors.cardNo)
|
|
2418
|
+
setPayErrors((er) => ({ ...er, cardNo: "" }));
|
|
2419
|
+
cardNumberInputHandler(e);
|
|
2420
|
+
},
|
|
2421
|
+
validationError: payErrors.cardNo ?? ""
|
|
2422
|
+
}
|
|
2423
|
+
) }),
|
|
2424
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2425
|
+
BaseInput,
|
|
2426
|
+
{
|
|
2427
|
+
label: "Expiry Date",
|
|
2428
|
+
required: true,
|
|
2429
|
+
value: payForm.expireDate,
|
|
2430
|
+
mask: "00/00",
|
|
2431
|
+
placeholder: "00/00",
|
|
2432
|
+
onChange: (e) => {
|
|
2433
|
+
setPayForm({ ...payForm, expireDate: e });
|
|
2434
|
+
if (payErrors.expireDate)
|
|
2435
|
+
setPayErrors((er) => ({ ...er, expireDate: "" }));
|
|
2436
|
+
},
|
|
2437
|
+
validationError: payErrors.expireDate ?? ""
|
|
2438
|
+
}
|
|
2439
|
+
),
|
|
2440
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2441
|
+
BaseInput,
|
|
2442
|
+
{
|
|
2443
|
+
label: "CVV",
|
|
2444
|
+
required: true,
|
|
2445
|
+
rules: ["numeric"],
|
|
2446
|
+
value: payForm.cvv,
|
|
2447
|
+
mask: "000",
|
|
2448
|
+
placeholder: "000",
|
|
2449
|
+
onChange: (e) => {
|
|
2450
|
+
setPayForm({ ...payForm, cvv: e });
|
|
2451
|
+
if (payErrors.cvv) setPayErrors((er) => ({ ...er, cvv: "" }));
|
|
2452
|
+
},
|
|
2453
|
+
validationError: payErrors.cvv ?? ""
|
|
2454
|
+
}
|
|
2455
|
+
),
|
|
2456
|
+
cardType === "Verve" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2457
|
+
BaseInput,
|
|
2458
|
+
{
|
|
2459
|
+
label: "Card Pin",
|
|
2460
|
+
required: true,
|
|
2461
|
+
rules: ["numeric"],
|
|
2462
|
+
value: payForm.cardPin,
|
|
2463
|
+
mask: "0000",
|
|
2464
|
+
placeholder: "0000",
|
|
2465
|
+
onChange: (e) => {
|
|
2466
|
+
setPayForm({ ...payForm, cardPin: e });
|
|
2467
|
+
if (payErrors.cardPin)
|
|
2468
|
+
setPayErrors((er) => ({ ...er, cardPin: "" }));
|
|
2469
|
+
},
|
|
2470
|
+
validationError: payErrors.cardPin ?? ""
|
|
2471
|
+
}
|
|
2472
|
+
)
|
|
1509
2473
|
]
|
|
1510
2474
|
}
|
|
1511
2475
|
),
|
|
1512
2476
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1513
2477
|
BaseButton,
|
|
1514
2478
|
{
|
|
1515
|
-
label: formIndex === 0 ? "Proceed" :
|
|
2479
|
+
label: formIndex === 0 ? "Proceed" : `Pay ${formatAmountHandler}`,
|
|
1516
2480
|
type: "primary",
|
|
1517
2481
|
customClass: "w-full",
|
|
1518
|
-
|
|
2482
|
+
loading: isMakingPayment,
|
|
2483
|
+
onClick: proceedHandler,
|
|
2484
|
+
disabled: isMakingPayment
|
|
1519
2485
|
}
|
|
1520
2486
|
)
|
|
1521
2487
|
] });
|
|
@@ -1525,92 +2491,302 @@ function PayByCard({}) {
|
|
|
1525
2491
|
var import_react9 = require("react");
|
|
1526
2492
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1527
2493
|
var PayByTransfer = ({
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
2494
|
+
secretKey,
|
|
2495
|
+
paymentObject,
|
|
2496
|
+
environment = "sandbox",
|
|
2497
|
+
onPaymentAuthorized,
|
|
2498
|
+
onCancel,
|
|
2499
|
+
onError
|
|
1534
2500
|
}) => {
|
|
1535
|
-
const [
|
|
2501
|
+
const [formIndex, setFormIndex] = (0, import_react9.useState)(0);
|
|
2502
|
+
const [isMakingPayment, setIsMakingPayment] = (0, import_react9.useState)(false);
|
|
2503
|
+
const [isConfirmCall, setIsConfirmCall] = (0, import_react9.useState)(false);
|
|
2504
|
+
const [isPaymentConfirmed, setIsPaymentConfirmed] = (0, import_react9.useState)(false);
|
|
2505
|
+
const [transactionReference, setTransactionReference] = (0, import_react9.useState)("");
|
|
2506
|
+
const [paymentReferenceStatus, setPaymentReferenceStatus] = (0, import_react9.useState)("");
|
|
2507
|
+
const [isFetchingPaymentDetails, setIsFetchingPaymentDetails] = (0, import_react9.useState)(false);
|
|
2508
|
+
const [paymentReferenceDetails, setPaymentReferenceDetails] = (0, import_react9.useState)(null);
|
|
2509
|
+
const [paymentAccountDetails, setPaymentAccountDetails] = (0, import_react9.useState)(null);
|
|
2510
|
+
const [paymentMade, setPaymentMade] = (0, import_react9.useState)(false);
|
|
2511
|
+
const [loading, setLoading] = (0, import_react9.useState)(false);
|
|
2512
|
+
const [message, setMessage] = (0, import_react9.useState)("");
|
|
2513
|
+
const [remainingSeconds, setRemainingSeconds] = (0, import_react9.useState)(60);
|
|
2514
|
+
const [countDownTime, setCountDownTime] = (0, import_react9.useState)("00:00");
|
|
1536
2515
|
const intervalRef = (0, import_react9.useRef)(null);
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
2516
|
+
const [transferForm, setTransferForm] = (0, import_react9.useState)({
|
|
2517
|
+
customerName: ""
|
|
2518
|
+
});
|
|
2519
|
+
const [transferErrors, setTransferErrors] = (0, import_react9.useState)(
|
|
2520
|
+
{}
|
|
2521
|
+
);
|
|
2522
|
+
const transferRules = {
|
|
2523
|
+
customerName: "required"
|
|
2524
|
+
};
|
|
2525
|
+
const transferLabels = {
|
|
2526
|
+
customerName: "Customer Name"
|
|
2527
|
+
};
|
|
2528
|
+
const formatAmountHandler = formatAmount(
|
|
2529
|
+
paymentObject.amount,
|
|
2530
|
+
paymentObject.currency
|
|
2531
|
+
);
|
|
2532
|
+
const payHandler = async () => {
|
|
2533
|
+
if (formIndex === 0) {
|
|
2534
|
+
const errs = validateGroup(transferForm, transferRules, transferLabels);
|
|
2535
|
+
setTransferErrors(errs);
|
|
2536
|
+
if (Object.keys(errs).length === 0) {
|
|
2537
|
+
const payload = {
|
|
2538
|
+
paymentReference: transactionReference,
|
|
2539
|
+
channel: "virtual_account",
|
|
2540
|
+
customerName: transferForm.customerName ?? "",
|
|
2541
|
+
merchantId: secretKey
|
|
2542
|
+
};
|
|
2543
|
+
setIsMakingPayment(true);
|
|
2544
|
+
try {
|
|
2545
|
+
const response = await generatePaymentAccount(environment, payload);
|
|
2546
|
+
if (response?.isSuccessful) {
|
|
2547
|
+
setPaymentAccountDetails(response.data);
|
|
2548
|
+
startTimer();
|
|
2549
|
+
setMessage("Virtual account generated successfully for payment.");
|
|
2550
|
+
setIsMakingPayment(true);
|
|
2551
|
+
setFormIndex(1);
|
|
2552
|
+
}
|
|
2553
|
+
} catch (err) {
|
|
2554
|
+
setIsMakingPayment(false);
|
|
2555
|
+
setMessage(err.error.responseMessage || err.error.message);
|
|
2556
|
+
onError?.({
|
|
2557
|
+
errorMessage: message
|
|
2558
|
+
});
|
|
2559
|
+
}
|
|
1551
2560
|
}
|
|
1552
|
-
|
|
2561
|
+
return;
|
|
2562
|
+
}
|
|
2563
|
+
};
|
|
2564
|
+
const getReferenceDetails = async () => {
|
|
2565
|
+
setIsFetchingPaymentDetails(true);
|
|
2566
|
+
try {
|
|
2567
|
+
const response = await getPaymentReferenceDetails(
|
|
2568
|
+
environment,
|
|
2569
|
+
transactionReference
|
|
2570
|
+
);
|
|
2571
|
+
if (response?.isSuccessful) {
|
|
2572
|
+
setPaymentReferenceDetails(response.data);
|
|
2573
|
+
const made = response.data?.paymentStatus === "Payment Received";
|
|
2574
|
+
setPaymentMade(made);
|
|
2575
|
+
const noServerStatus = response.data?.finalTransactionStatus == null || response.data?.paymentStatus == null;
|
|
2576
|
+
if (noServerStatus) {
|
|
2577
|
+
if (isConfirmCall) {
|
|
2578
|
+
setMessage("Transaction not confirmed !!");
|
|
2579
|
+
}
|
|
2580
|
+
if (!isPaymentConfirmed && !made) {
|
|
2581
|
+
setPaymentReferenceStatus("pending");
|
|
2582
|
+
onPaymentAuthorized?.({
|
|
2583
|
+
paymentId: transactionReference,
|
|
2584
|
+
paymentDate: response.data?.updatedAt,
|
|
2585
|
+
paymentStatus: "pending",
|
|
2586
|
+
message
|
|
2587
|
+
});
|
|
2588
|
+
} else {
|
|
2589
|
+
setPaymentReferenceStatus("confirmed");
|
|
2590
|
+
onPaymentAuthorized?.({
|
|
2591
|
+
paymentId: transactionReference,
|
|
2592
|
+
paymentDate: response.data?.updatedAt,
|
|
2593
|
+
paymentStatus: "confirmed",
|
|
2594
|
+
message
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
} else if (response.data?.finalTransactionStatus === "Success" || response.data?.paymentStatus === "Received" || response.data?.paymentStatus === "Payment Received") {
|
|
2598
|
+
setPaymentReferenceStatus("confirmed");
|
|
2599
|
+
setIsPaymentConfirmed(true);
|
|
2600
|
+
setMessage("Transaction confirmed !!");
|
|
2601
|
+
onPaymentAuthorized?.({
|
|
2602
|
+
paymentId: transactionReference,
|
|
2603
|
+
paymentDate: response.data?.updatedAt,
|
|
2604
|
+
paymentStatus: "confirmed",
|
|
2605
|
+
message
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
} else if (!response?.isSuccessful && response?.responseCode === "119") {
|
|
2609
|
+
setPaymentReferenceStatus("used");
|
|
2610
|
+
setMessage(response.responseMessage || "");
|
|
2611
|
+
onPaymentAuthorized?.({
|
|
2612
|
+
paymentId: transactionReference,
|
|
2613
|
+
paymentDate: null,
|
|
2614
|
+
paymentStatus: "used",
|
|
2615
|
+
message
|
|
2616
|
+
});
|
|
2617
|
+
}
|
|
2618
|
+
} catch (err) {
|
|
2619
|
+
setPaymentReferenceStatus("");
|
|
2620
|
+
setMessage(
|
|
2621
|
+
err?.error?.responseMessage || err?.error?.message || "Something went wrong"
|
|
2622
|
+
);
|
|
2623
|
+
onError?.({
|
|
2624
|
+
errorMessage: message
|
|
2625
|
+
});
|
|
2626
|
+
} finally {
|
|
2627
|
+
setIsFetchingPaymentDetails(false);
|
|
2628
|
+
}
|
|
2629
|
+
};
|
|
2630
|
+
const generatePaymentLinkHandler = async () => {
|
|
2631
|
+
if (!secretKey) {
|
|
2632
|
+
setMessage("Secret key is required.");
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
if (!checkObjectTruthy(paymentObject)) {
|
|
2636
|
+
setMessage("Kindly ensure you are passing all the required data.");
|
|
2637
|
+
return;
|
|
2638
|
+
}
|
|
2639
|
+
setLoading(true);
|
|
2640
|
+
setMessage("");
|
|
2641
|
+
try {
|
|
2642
|
+
const response = await createPaymentLink(
|
|
2643
|
+
paymentObject,
|
|
2644
|
+
environment,
|
|
2645
|
+
secretKey
|
|
2646
|
+
);
|
|
2647
|
+
if (response?.isSuccessful && response.launchUrl) {
|
|
2648
|
+
const queryParams = getQueryParams(response.launchUrl);
|
|
2649
|
+
setTransactionReference(queryParams["paymentReference"]);
|
|
2650
|
+
setMessage("Payment link created successfully");
|
|
2651
|
+
} else {
|
|
2652
|
+
setMessage("Failed to create payment link");
|
|
2653
|
+
}
|
|
2654
|
+
} catch (e) {
|
|
2655
|
+
setMessage(e?.message || "Failed to create payment link");
|
|
2656
|
+
onError?.({
|
|
2657
|
+
errorMessage: message
|
|
2658
|
+
});
|
|
2659
|
+
} finally {
|
|
2660
|
+
setLoading(false);
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
const updateDisplay = (0, import_react9.useCallback)((secs) => {
|
|
2664
|
+
const minutes = String(Math.floor(secs / 60)).padStart(2, "0");
|
|
2665
|
+
const seconds = String(secs % 60).padStart(2, "0");
|
|
2666
|
+
setCountDownTime(`${minutes}:${seconds}`);
|
|
1553
2667
|
}, []);
|
|
1554
|
-
(0, import_react9.
|
|
1555
|
-
if (
|
|
2668
|
+
const startTimer = (0, import_react9.useCallback)(() => {
|
|
2669
|
+
if (intervalRef.current) {
|
|
2670
|
+
clearInterval(intervalRef.current);
|
|
2671
|
+
intervalRef.current = null;
|
|
2672
|
+
}
|
|
2673
|
+
updateDisplay(remainingSeconds);
|
|
2674
|
+
intervalRef.current = setInterval(() => {
|
|
2675
|
+
setRemainingSeconds((prev) => {
|
|
2676
|
+
const next = prev - 1;
|
|
2677
|
+
if (next < 0) {
|
|
2678
|
+
if (intervalRef.current) {
|
|
2679
|
+
clearInterval(intervalRef.current);
|
|
2680
|
+
intervalRef.current = null;
|
|
2681
|
+
}
|
|
2682
|
+
setCountDownTime("00:00");
|
|
2683
|
+
return 0;
|
|
2684
|
+
}
|
|
2685
|
+
updateDisplay(next);
|
|
2686
|
+
return next;
|
|
2687
|
+
});
|
|
2688
|
+
}, 1e3);
|
|
2689
|
+
}, [remainingSeconds, updateDisplay]);
|
|
2690
|
+
const stopTimer = () => {
|
|
2691
|
+
if (intervalRef.current) {
|
|
1556
2692
|
clearInterval(intervalRef.current);
|
|
1557
2693
|
intervalRef.current = null;
|
|
1558
2694
|
}
|
|
1559
|
-
}
|
|
2695
|
+
};
|
|
2696
|
+
(0, import_react9.useEffect)(() => {
|
|
2697
|
+
(async () => {
|
|
2698
|
+
await generatePaymentLinkHandler();
|
|
2699
|
+
})();
|
|
2700
|
+
}, []);
|
|
2701
|
+
(0, import_react9.useEffect)(() => {
|
|
2702
|
+
if (remainingSeconds < 0 && intervalRef.current) {
|
|
2703
|
+
stopTimer();
|
|
2704
|
+
}
|
|
2705
|
+
}, [remainingSeconds]);
|
|
1560
2706
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-10", children: [
|
|
1561
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("
|
|
1562
|
-
|
|
1563
|
-
|
|
2707
|
+
formIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-10", children: [
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2709
|
+
BaseInput,
|
|
2710
|
+
{
|
|
2711
|
+
label: "Customer Name",
|
|
2712
|
+
required: true,
|
|
2713
|
+
value: transferForm.customerName,
|
|
2714
|
+
onChange: (e) => {
|
|
2715
|
+
setTransferForm({ ...transferForm, customerName: e });
|
|
2716
|
+
if (transferForm.customerName) {
|
|
2717
|
+
setTransferErrors((er) => ({ ...er, customerName: "" }));
|
|
2718
|
+
}
|
|
2719
|
+
},
|
|
2720
|
+
validationError: transferErrors.customerName ?? ""
|
|
2721
|
+
}
|
|
2722
|
+
),
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2724
|
+
BaseButton,
|
|
2725
|
+
{
|
|
2726
|
+
label: `Pay ${formatAmountHandler}`,
|
|
2727
|
+
type: "primary",
|
|
2728
|
+
customClass: "w-full",
|
|
2729
|
+
loading: isMakingPayment,
|
|
2730
|
+
onClick: payHandler
|
|
2731
|
+
}
|
|
2732
|
+
)
|
|
1564
2733
|
] }),
|
|
1565
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "
|
|
1566
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.
|
|
1567
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2734
|
+
formIndex === 1 && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-10", children: [
|
|
2735
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "bg-[#EFF7FF] p-4 rounded-lg flex flex-col gap-6", children: [
|
|
1568
2736
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1569
2737
|
BaseLabelInfo,
|
|
1570
2738
|
{
|
|
1571
|
-
label: "
|
|
1572
|
-
value:
|
|
1573
|
-
type: "horizontal"
|
|
2739
|
+
label: "Bank Name",
|
|
2740
|
+
value: `${paymentAccountDetails?.bank} ${paymentAccountDetails?.accountName}`
|
|
1574
2741
|
}
|
|
1575
2742
|
),
|
|
1576
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2744
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2745
|
+
BaseLabelInfo,
|
|
2746
|
+
{
|
|
2747
|
+
label: "Account Number",
|
|
2748
|
+
value: paymentAccountDetails?.accountNumber
|
|
2749
|
+
}
|
|
2750
|
+
),
|
|
2751
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2752
|
+
BaseCopy,
|
|
2753
|
+
{
|
|
2754
|
+
color: "#9DBFDE",
|
|
2755
|
+
copyText: paymentAccountDetails?.accountNumber ?? ""
|
|
2756
|
+
}
|
|
2757
|
+
)
|
|
2758
|
+
] }),
|
|
2759
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2760
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(BaseLabelInfo, { label: "Amount", value: formatAmountHandler }),
|
|
2761
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(BaseCopy, { color: "#9DBFDE", copyText: formatAmountHandler })
|
|
2762
|
+
] })
|
|
2763
|
+
] }),
|
|
2764
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("p", { className: "w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy", children: [
|
|
2765
|
+
"This account is for this transaction only and expires in",
|
|
2766
|
+
" ",
|
|
2767
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-orange-500", children: remainingSeconds >= 0 ? countDownTime : "00:00" })
|
|
1577
2768
|
] }),
|
|
1578
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex
|
|
2769
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1579
2770
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1580
|
-
|
|
2771
|
+
BaseButton,
|
|
1581
2772
|
{
|
|
1582
|
-
label: "
|
|
1583
|
-
|
|
1584
|
-
|
|
2773
|
+
label: "I have paid the money",
|
|
2774
|
+
type: "primary",
|
|
2775
|
+
customClass: "w-full",
|
|
2776
|
+
loading: isFetchingPaymentDetails,
|
|
2777
|
+
onClick: getReferenceDetails
|
|
1585
2778
|
}
|
|
1586
2779
|
),
|
|
1587
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2780
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2781
|
+
"button",
|
|
2782
|
+
{
|
|
2783
|
+
type: "button",
|
|
2784
|
+
onClick: onCancel,
|
|
2785
|
+
className: "text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer",
|
|
2786
|
+
children: "Cancel Payment"
|
|
2787
|
+
}
|
|
2788
|
+
)
|
|
1588
2789
|
] })
|
|
1589
|
-
] }),
|
|
1590
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("p", { className: "w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy", children: [
|
|
1591
|
-
"This account is for this transaction only and expires in",
|
|
1592
|
-
" ",
|
|
1593
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-orange-500", children: remaining >= 0 ? countDownTime : "00:00" })
|
|
1594
|
-
] }),
|
|
1595
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1596
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1597
|
-
BaseButton,
|
|
1598
|
-
{
|
|
1599
|
-
label: "I have paid the money",
|
|
1600
|
-
type: "primary",
|
|
1601
|
-
customClass: "w-full",
|
|
1602
|
-
onClick: onConfirmPaid
|
|
1603
|
-
}
|
|
1604
|
-
),
|
|
1605
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1606
|
-
"button",
|
|
1607
|
-
{
|
|
1608
|
-
type: "button",
|
|
1609
|
-
onClick: onCancel,
|
|
1610
|
-
className: "text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer",
|
|
1611
|
-
children: "Cancel Payment"
|
|
1612
|
-
}
|
|
1613
|
-
)
|
|
1614
2790
|
] })
|
|
1615
2791
|
] });
|
|
1616
2792
|
};
|
|
@@ -1618,12 +2794,219 @@ var PayByTransfer = ({
|
|
|
1618
2794
|
// src/components/pay-by-stable-coin.tsx
|
|
1619
2795
|
var import_react10 = require("react");
|
|
1620
2796
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1621
|
-
var PayByStableCoin = ({
|
|
2797
|
+
var PayByStableCoin = ({
|
|
2798
|
+
secretKey,
|
|
2799
|
+
paymentObject,
|
|
2800
|
+
environment = "sandbox",
|
|
2801
|
+
onPaymentAuthorized,
|
|
2802
|
+
onError
|
|
2803
|
+
}) => {
|
|
1622
2804
|
const [formIndex, setFormIndex] = (0, import_react10.useState)(0);
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
2805
|
+
const [message, setMessage] = (0, import_react10.useState)("");
|
|
2806
|
+
const [loading, setLoading] = (0, import_react10.useState)(false);
|
|
2807
|
+
const [generatingAddress, setGeneratingAddress] = (0, import_react10.useState)(false);
|
|
2808
|
+
const [loadingStableCoins, setLoadingStableCoins] = (0, import_react10.useState)(false);
|
|
2809
|
+
const [loadingStableCoinNetworks, setLoadingStableCoinNetworks] = (0, import_react10.useState)(false);
|
|
2810
|
+
const [transactionReference, setTransactionReference] = (0, import_react10.useState)("");
|
|
2811
|
+
const [stableCoins, setStableCoins] = (0, import_react10.useState)([]);
|
|
2812
|
+
const [networkList, setNetworkList] = (0, import_react10.useState)([]);
|
|
2813
|
+
const [addressDetails, setAddressDetails] = (0, import_react10.useState)(null);
|
|
2814
|
+
const [generateAddressPayload, setGenerateAddressPayload] = (0, import_react10.useState)(null);
|
|
2815
|
+
const [isConfirmingPayment, setIsConfirmingPayment] = (0, import_react10.useState)(false);
|
|
2816
|
+
const [paymentReferenceDetails, setPaymentReferenceDetails] = (0, import_react10.useState)(null);
|
|
2817
|
+
const [paymentReferenceStatus, setPaymentReferenceStatus] = (0, import_react10.useState)("");
|
|
2818
|
+
const [stableCoinForm, setStableCoinForm] = (0, import_react10.useState)({
|
|
2819
|
+
stableCoin: "",
|
|
2820
|
+
network: ""
|
|
2821
|
+
});
|
|
2822
|
+
const [stableCoinErrors, setStableCoinErrors] = (0, import_react10.useState)({});
|
|
2823
|
+
const stableCoinRules = {
|
|
2824
|
+
stableCoin: "required",
|
|
2825
|
+
network: "required"
|
|
2826
|
+
};
|
|
2827
|
+
const stableCoinLabels = {
|
|
2828
|
+
stableCoin: "Stable Coin",
|
|
2829
|
+
network: "Network"
|
|
2830
|
+
};
|
|
2831
|
+
const generatePaymentLinkHandler = async () => {
|
|
2832
|
+
if (!secretKey) {
|
|
2833
|
+
setMessage("Secret key is required.");
|
|
2834
|
+
return;
|
|
2835
|
+
}
|
|
2836
|
+
if (!checkObjectTruthy(paymentObject)) {
|
|
2837
|
+
setMessage("Kindly ensure you are passing all the required data.");
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
setLoading(true);
|
|
2841
|
+
setMessage("");
|
|
2842
|
+
try {
|
|
2843
|
+
const response = await createPaymentLink(
|
|
2844
|
+
paymentObject,
|
|
2845
|
+
environment,
|
|
2846
|
+
secretKey
|
|
2847
|
+
);
|
|
2848
|
+
if (response?.isSuccessful && response.launchUrl) {
|
|
2849
|
+
const queryParams = getQueryParams(response.launchUrl);
|
|
2850
|
+
setTransactionReference(queryParams["paymentReference"]);
|
|
2851
|
+
setMessage("Payment link created successfully");
|
|
2852
|
+
} else {
|
|
2853
|
+
setMessage("Failed to create payment link");
|
|
2854
|
+
}
|
|
2855
|
+
} catch (e) {
|
|
2856
|
+
setMessage(e?.message || "Failed to create payment link");
|
|
2857
|
+
onError?.({
|
|
2858
|
+
errorMessage: message
|
|
2859
|
+
});
|
|
2860
|
+
} finally {
|
|
2861
|
+
setLoading(false);
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2864
|
+
const generateAddress = async (payload) => {
|
|
2865
|
+
if (!payload) return;
|
|
2866
|
+
setGeneratingAddress(true);
|
|
2867
|
+
try {
|
|
2868
|
+
const response = await generateStableCoinAddress(
|
|
2869
|
+
environment,
|
|
2870
|
+
payload
|
|
2871
|
+
);
|
|
2872
|
+
if (response?.isSuccessful) {
|
|
2873
|
+
setAddressDetails(response.data);
|
|
2874
|
+
setFormIndex(1);
|
|
2875
|
+
}
|
|
2876
|
+
} catch (e) {
|
|
2877
|
+
setMessage(e?.message || "Failed to generate address");
|
|
2878
|
+
onError?.({
|
|
2879
|
+
errorMessage: message
|
|
2880
|
+
});
|
|
2881
|
+
} finally {
|
|
2882
|
+
setGeneratingAddress(false);
|
|
2883
|
+
}
|
|
2884
|
+
};
|
|
2885
|
+
const getAllStableCoins = async () => {
|
|
2886
|
+
setLoadingStableCoins(true);
|
|
2887
|
+
try {
|
|
2888
|
+
const response = await getStableCoins(environment);
|
|
2889
|
+
if (response?.isSuccessful) {
|
|
2890
|
+
setStableCoins(
|
|
2891
|
+
response.data?.map((c) => ({
|
|
2892
|
+
label: c.name,
|
|
2893
|
+
value: c.name
|
|
2894
|
+
})) ?? []
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2897
|
+
} catch (e) {
|
|
2898
|
+
setMessage(e?.message || "Failed to get stable coins");
|
|
2899
|
+
onError?.({
|
|
2900
|
+
errorMessage: message
|
|
2901
|
+
});
|
|
2902
|
+
} finally {
|
|
2903
|
+
setLoadingStableCoins(false);
|
|
2904
|
+
}
|
|
2905
|
+
};
|
|
2906
|
+
const getAllStableCoinNetworks = async (stableCoin) => {
|
|
2907
|
+
setLoadingStableCoinNetworks(true);
|
|
2908
|
+
try {
|
|
2909
|
+
const response = await getStableCoinNetworks(
|
|
2910
|
+
environment,
|
|
2911
|
+
stableCoin
|
|
2912
|
+
);
|
|
2913
|
+
if (response?.isSuccessful) {
|
|
2914
|
+
setNetworkList(
|
|
2915
|
+
response.networks?.map((n) => ({
|
|
2916
|
+
label: n,
|
|
2917
|
+
value: n
|
|
2918
|
+
})) ?? []
|
|
2919
|
+
);
|
|
2920
|
+
}
|
|
2921
|
+
} catch (e) {
|
|
2922
|
+
setMessage(e?.message || "Failed to get stable coin networks");
|
|
2923
|
+
onError?.({
|
|
2924
|
+
errorMessage: message
|
|
2925
|
+
});
|
|
2926
|
+
} finally {
|
|
2927
|
+
setLoadingStableCoinNetworks(false);
|
|
2928
|
+
}
|
|
2929
|
+
};
|
|
2930
|
+
const confirmPaymentHandler = async () => {
|
|
2931
|
+
setIsConfirmingPayment(true);
|
|
2932
|
+
try {
|
|
2933
|
+
const response = await getPaymentReferenceDetails(environment, transactionReference);
|
|
2934
|
+
if (response?.isSuccessful) {
|
|
2935
|
+
setPaymentReferenceDetails(response.data);
|
|
2936
|
+
const needsConfirm = response.data?.finalTransactionStatus == null || response.data?.paymentStatus == null;
|
|
2937
|
+
if (needsConfirm) {
|
|
2938
|
+
setMessage("Transaction not confirmed !!");
|
|
2939
|
+
setPaymentReferenceStatus("pending");
|
|
2940
|
+
onPaymentAuthorized?.({
|
|
2941
|
+
paymentId: transactionReference,
|
|
2942
|
+
paymentDate: response.data?.updatedAt ?? "",
|
|
2943
|
+
paymentStatus: "pending",
|
|
2944
|
+
message
|
|
2945
|
+
});
|
|
2946
|
+
} else if (response.data?.finalTransactionStatus === "Success" || response.data?.paymentStatus === "Payment Received") {
|
|
2947
|
+
setMessage("Transaction confirmed !!");
|
|
2948
|
+
setPaymentReferenceStatus("confirmed");
|
|
2949
|
+
onPaymentAuthorized?.({
|
|
2950
|
+
paymentId: transactionReference,
|
|
2951
|
+
paymentDate: response.data?.updatedAt,
|
|
2952
|
+
paymentStatus: "confirmed",
|
|
2953
|
+
message
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
2956
|
+
} else if (!response?.isSuccessful && response?.responseCode === "119") {
|
|
2957
|
+
setPaymentReferenceStatus("used");
|
|
2958
|
+
setMessage(response.responseMessage || "");
|
|
2959
|
+
onPaymentAuthorized?.({
|
|
2960
|
+
paymentId: transactionReference,
|
|
2961
|
+
paymentDate: null,
|
|
2962
|
+
paymentStatus: "used",
|
|
2963
|
+
message
|
|
2964
|
+
});
|
|
2965
|
+
}
|
|
2966
|
+
} catch (err) {
|
|
2967
|
+
setPaymentReferenceStatus("");
|
|
2968
|
+
setMessage(
|
|
2969
|
+
err?.error?.responseMessage || err?.error?.message || "Something went wrong"
|
|
2970
|
+
);
|
|
2971
|
+
onError?.({
|
|
2972
|
+
errorMessage: message
|
|
2973
|
+
});
|
|
2974
|
+
} finally {
|
|
2975
|
+
setIsConfirmingPayment(false);
|
|
2976
|
+
}
|
|
2977
|
+
};
|
|
2978
|
+
const formatAmountHandler = formatAmount(
|
|
2979
|
+
paymentObject.amount,
|
|
2980
|
+
paymentObject.currency
|
|
2981
|
+
);
|
|
2982
|
+
const payHandler = async () => {
|
|
2983
|
+
const errs = validateGroup(
|
|
2984
|
+
stableCoinForm,
|
|
2985
|
+
stableCoinRules,
|
|
2986
|
+
stableCoinLabels
|
|
2987
|
+
);
|
|
2988
|
+
setStableCoinErrors(errs);
|
|
2989
|
+
if (Object.keys(errs).length === 0) {
|
|
2990
|
+
const payload = {
|
|
2991
|
+
paymentReference: transactionReference,
|
|
2992
|
+
currency: stableCoinForm.stableCoin,
|
|
2993
|
+
chain: stableCoinForm.network,
|
|
2994
|
+
transactionAmount: paymentObject.amount,
|
|
2995
|
+
merchantId: secretKey
|
|
2996
|
+
};
|
|
2997
|
+
setGenerateAddressPayload(payload);
|
|
2998
|
+
await generateAddress(payload);
|
|
2999
|
+
} else {
|
|
3000
|
+
return;
|
|
3001
|
+
}
|
|
1626
3002
|
};
|
|
3003
|
+
const amountPlusNetworkFee = addressDetails ? Number(addressDetails.transactionAmount) + addressDetails.networkFee : 0;
|
|
3004
|
+
(0, import_react10.useEffect)(() => {
|
|
3005
|
+
(async () => {
|
|
3006
|
+
await generatePaymentLinkHandler();
|
|
3007
|
+
await getAllStableCoins();
|
|
3008
|
+
})();
|
|
3009
|
+
}, []);
|
|
1627
3010
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
1628
3011
|
formIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
1629
3012
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-1 gap-6", children: [
|
|
@@ -1632,11 +3015,17 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1632
3015
|
{
|
|
1633
3016
|
label: "Select Crypto",
|
|
1634
3017
|
required: true,
|
|
1635
|
-
options:
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
3018
|
+
options: stableCoins,
|
|
3019
|
+
loading: loadingStableCoins,
|
|
3020
|
+
value: stableCoinForm.stableCoin,
|
|
3021
|
+
onChange: (e) => {
|
|
3022
|
+
setStableCoinForm({ ...stableCoinForm, stableCoin: e });
|
|
3023
|
+
getAllStableCoinNetworks(e);
|
|
3024
|
+
if (stableCoinErrors.stableCoin) {
|
|
3025
|
+
setStableCoinErrors((er) => ({ ...er, stableCoin: "" }));
|
|
3026
|
+
}
|
|
3027
|
+
},
|
|
3028
|
+
validationError: stableCoinErrors.stableCoin ?? ""
|
|
1640
3029
|
}
|
|
1641
3030
|
),
|
|
1642
3031
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
@@ -1644,52 +3033,46 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1644
3033
|
{
|
|
1645
3034
|
label: "Select Network",
|
|
1646
3035
|
required: true,
|
|
1647
|
-
options:
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
3036
|
+
options: networkList,
|
|
3037
|
+
loading: loadingStableCoinNetworks,
|
|
3038
|
+
value: stableCoinForm.network,
|
|
3039
|
+
onChange: (e) => {
|
|
3040
|
+
setStableCoinForm({ ...stableCoinForm, network: e });
|
|
3041
|
+
if (stableCoinErrors.network) {
|
|
3042
|
+
setStableCoinErrors((er) => ({ ...er, network: "" }));
|
|
3043
|
+
}
|
|
3044
|
+
},
|
|
3045
|
+
validationError: stableCoinErrors.network ?? ""
|
|
1652
3046
|
}
|
|
1653
3047
|
)
|
|
1654
3048
|
] }),
|
|
1655
3049
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1656
3050
|
BaseButton,
|
|
1657
3051
|
{
|
|
1658
|
-
label:
|
|
3052
|
+
label: `Pay ${formatAmountHandler}`,
|
|
1659
3053
|
type: "primary",
|
|
1660
3054
|
customClass: "w-full",
|
|
3055
|
+
loading: generatingAddress,
|
|
1661
3056
|
onClick: payHandler
|
|
1662
3057
|
}
|
|
1663
3058
|
)
|
|
1664
3059
|
] }),
|
|
1665
3060
|
formIndex === 1 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
1666
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.
|
|
1667
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1668
|
-
BaseImage,
|
|
1669
|
-
{
|
|
1670
|
-
src: "../../../assets/images/stable-coin-qr-code.png",
|
|
1671
|
-
alt: "QR Code",
|
|
1672
|
-
width: 122,
|
|
1673
|
-
height: 122,
|
|
1674
|
-
customClass: "mb-1"
|
|
1675
|
-
}
|
|
1676
|
-
),
|
|
1677
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-4xs text-light-copy font-normal text-center", children: "USDC" })
|
|
1678
|
-
] }),
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mx-auto", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-4xs text-light-copy font-normal text-center", children: generateAddressPayload?.currency }) }),
|
|
1679
3062
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-6 border-c border-grey-100 p-4 rounded-2xl bg-light-white-50", children: [
|
|
1680
3063
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "border-b border-grey-border pb-4 flex flex-col gap-2", children: [
|
|
1681
3064
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-3xs text-light-copy font-normal", children: "Network" }),
|
|
1682
3065
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between", children: [
|
|
1683
3066
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1684
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-2xs font-medium text-sub-copy", children:
|
|
3067
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-2xs font-medium text-sub-copy", children: addressDetails?.chain }),
|
|
1685
3068
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1686
3069
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-3xs text-light-copy font-normal", children: "*Est. arrival = 3 mins" }),
|
|
1687
3070
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-3xs text-light-copy font-normal", children: "|" }),
|
|
1688
3071
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1689
3072
|
BaseCurrencyAmount,
|
|
1690
3073
|
{
|
|
1691
|
-
currency: "
|
|
1692
|
-
amount:
|
|
3074
|
+
currency: generateAddressPayload?.currency ?? "",
|
|
3075
|
+
amount: addressDetails?.networkFee ?? 0,
|
|
1693
3076
|
textClass: "mb-0 text-body-3xs text-light-copy font-normal",
|
|
1694
3077
|
iconColorClass: "#557591",
|
|
1695
3078
|
iconWidth: 12,
|
|
@@ -1704,8 +3087,8 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1704
3087
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "pb-4 flex flex-col gap-2", children: [
|
|
1705
3088
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-3xs text-light-copy font-normal", children: "Deposit Address >" }),
|
|
1706
3089
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between", children: [
|
|
1707
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words", children:
|
|
1708
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(BaseCopy, { copyText: "
|
|
3090
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words", children: addressDetails?.walletAddress }),
|
|
3091
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(BaseCopy, { copyText: addressDetails?.walletAddress ?? "" })
|
|
1709
3092
|
] })
|
|
1710
3093
|
] })
|
|
1711
3094
|
] }),
|
|
@@ -1715,8 +3098,8 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1715
3098
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1716
3099
|
BaseCurrencyAmount,
|
|
1717
3100
|
{
|
|
1718
|
-
currency: "
|
|
1719
|
-
amount:
|
|
3101
|
+
currency: generateAddressPayload?.currency ?? "",
|
|
3102
|
+
amount: addressDetails?.networkFee ?? 0,
|
|
1720
3103
|
textClass: "mb-0 text-body-2xs font-extrabold text-primary-black",
|
|
1721
3104
|
iconColorClass: "#231F20"
|
|
1722
3105
|
}
|
|
@@ -1727,8 +3110,8 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1727
3110
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1728
3111
|
BaseCurrencyAmount,
|
|
1729
3112
|
{
|
|
1730
|
-
currency: "
|
|
1731
|
-
amount:
|
|
3113
|
+
currency: generateAddressPayload?.currency ?? "",
|
|
3114
|
+
amount: amountPlusNetworkFee,
|
|
1732
3115
|
textClass: "mb-0 text-body-lg font-extrabold text-primary-black",
|
|
1733
3116
|
iconColorClass: "#231F20",
|
|
1734
3117
|
iconWidth: 20,
|
|
@@ -1742,7 +3125,9 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1742
3125
|
{
|
|
1743
3126
|
label: "Confirm Payment",
|
|
1744
3127
|
type: "primary",
|
|
1745
|
-
customClass: "w-full"
|
|
3128
|
+
customClass: "w-full",
|
|
3129
|
+
loading: isConfirmingPayment,
|
|
3130
|
+
onClick: confirmPaymentHandler
|
|
1746
3131
|
}
|
|
1747
3132
|
) })
|
|
1748
3133
|
] })
|
|
@@ -1752,95 +3137,157 @@ var PayByStableCoin = ({ onProceedToPay }) => {
|
|
|
1752
3137
|
// src/buzapay-checkout/checkout-card.tsx
|
|
1753
3138
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1754
3139
|
function BzpCheckoutCard({
|
|
3140
|
+
secretKey,
|
|
1755
3141
|
options,
|
|
1756
3142
|
environment = "sandbox",
|
|
1757
3143
|
paymentObject = {
|
|
3144
|
+
merchantName: "",
|
|
1758
3145
|
amount: 0,
|
|
1759
3146
|
currency: "",
|
|
1760
3147
|
email: "",
|
|
1761
3148
|
phoneNumber: "",
|
|
1762
3149
|
narration: "",
|
|
1763
|
-
redirectUrl: ""
|
|
1764
|
-
}
|
|
3150
|
+
redirectUrl: "https://sandbox-merchant.buzapay.com/account/three-ds-status"
|
|
3151
|
+
},
|
|
3152
|
+
onPaymentAuthorized,
|
|
3153
|
+
onError
|
|
1765
3154
|
}) {
|
|
1766
|
-
const [checkoutState, setCheckoutState] = (0, import_react11.useState)("
|
|
3155
|
+
const [checkoutState, setCheckoutState] = (0, import_react11.useState)("PENDING");
|
|
1767
3156
|
const paymentTypeOptions = [
|
|
1768
3157
|
{ label: "Card", value: "CARD" },
|
|
1769
3158
|
{ label: "Bank Transfer", value: "BANK_TRANSFER" },
|
|
1770
3159
|
{ label: "Stable Coin", value: "STABLE_COIN" }
|
|
1771
3160
|
];
|
|
1772
3161
|
const [filteredPaymentTypeOptions, setFilteredPaymentTypeOptions] = (0, import_react11.useState)([]);
|
|
1773
|
-
const [paymentType, setPaymentType] = (0, import_react11.useState)(
|
|
1774
|
-
|
|
1775
|
-
|
|
3162
|
+
const [paymentType, setPaymentType] = (0, import_react11.useState)("");
|
|
3163
|
+
const [successObject, setSuccessObject] = (0, import_react11.useState)({
|
|
3164
|
+
paymentDate: "",
|
|
3165
|
+
paymentId: "",
|
|
3166
|
+
paymentStatus: ""
|
|
3167
|
+
});
|
|
1776
3168
|
const paymentTypeHandler = (event) => {
|
|
1777
3169
|
setPaymentType(event);
|
|
1778
3170
|
};
|
|
3171
|
+
const setSuccess = (event) => {
|
|
3172
|
+
setSuccessObject({ ...event });
|
|
3173
|
+
if (event.paymentStatus === "Authorized") {
|
|
3174
|
+
setCheckoutState("SUCCESS");
|
|
3175
|
+
} else if (event.paymentStatus === "Payment failed") {
|
|
3176
|
+
setCheckoutState("PENDING");
|
|
3177
|
+
} else if (event.paymentStatus === "used") {
|
|
3178
|
+
setCheckoutState("USED");
|
|
3179
|
+
} else {
|
|
3180
|
+
setCheckoutState("PENDING");
|
|
3181
|
+
}
|
|
3182
|
+
onPaymentAuthorized?.(event);
|
|
3183
|
+
};
|
|
1779
3184
|
(0, import_react11.useEffect)(() => {
|
|
1780
3185
|
let options2 = [];
|
|
1781
3186
|
if (paymentObject.currency === "USD") {
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
3187
|
+
if (paymentObject.amount < 50) {
|
|
3188
|
+
options2 = paymentTypeOptions.filter(
|
|
3189
|
+
(option) => option.value !== "BANK_TRANSFER" && option.value !== "STABLE_COIN"
|
|
3190
|
+
);
|
|
3191
|
+
} else {
|
|
3192
|
+
options2 = paymentTypeOptions.filter(
|
|
3193
|
+
(option) => option.value !== "BANK_TRANSFER"
|
|
3194
|
+
);
|
|
3195
|
+
}
|
|
1785
3196
|
} else {
|
|
1786
3197
|
options2 = paymentTypeOptions.filter(
|
|
1787
3198
|
(option) => option.value !== "STABLE_COIN"
|
|
1788
3199
|
);
|
|
1789
3200
|
}
|
|
1790
3201
|
setFilteredPaymentTypeOptions(options2);
|
|
1791
|
-
}, [paymentObject.currency]);
|
|
1792
|
-
|
|
1793
|
-
|
|
3202
|
+
}, [paymentObject.currency, paymentObject.amount]);
|
|
3203
|
+
(0, import_react11.useEffect)(() => {
|
|
3204
|
+
if (filteredPaymentTypeOptions.length) {
|
|
3205
|
+
setPaymentType(filteredPaymentTypeOptions[0].value);
|
|
3206
|
+
}
|
|
3207
|
+
}, [filteredPaymentTypeOptions]);
|
|
3208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(BaseCard, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-3", children: [
|
|
3209
|
+
checkoutState === "PENDING" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl", children: [
|
|
1794
3210
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-heading-text text-body-xs font-semibold", children: "Pay with" }),
|
|
1795
3211
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1796
3212
|
BaseRadioGroup,
|
|
1797
3213
|
{
|
|
1798
|
-
options:
|
|
3214
|
+
options: filteredPaymentTypeOptions,
|
|
1799
3215
|
selectedChange: (e) => paymentTypeHandler(e)
|
|
1800
3216
|
}
|
|
1801
3217
|
)
|
|
1802
3218
|
] }),
|
|
1803
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
3220
|
+
"div",
|
|
3221
|
+
{
|
|
3222
|
+
className: checkoutState === "SUCCESS" ? "col-span-3" : "col-span-2",
|
|
3223
|
+
children: [
|
|
3224
|
+
checkoutState === "PENDING" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between px-12 py-8", children: [
|
|
3225
|
+
options?.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3226
|
+
BaseImage,
|
|
3227
|
+
{
|
|
3228
|
+
src: options?.imageUrl ?? "",
|
|
3229
|
+
alt: "Merchant Logo",
|
|
3230
|
+
width: 52,
|
|
3231
|
+
height: 52,
|
|
3232
|
+
customClass: "rounded-lg"
|
|
3233
|
+
}
|
|
3234
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3235
|
+
"div",
|
|
3236
|
+
{
|
|
3237
|
+
className: "bg-heading-text rounded flex flex-col justify-center",
|
|
3238
|
+
style: { width: "52px", height: "52px" },
|
|
3239
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-white text-center text-body-2xs font-medium", children: "Logo" })
|
|
3240
|
+
}
|
|
3241
|
+
),
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3243
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-body-2xs font-regular text-sub-copy text-right", children: paymentObject.merchantName }),
|
|
3244
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("p", { className: "text-body-2xs font-regular text-sub-copy text-right", children: [
|
|
3245
|
+
"Pay:",
|
|
3246
|
+
" ",
|
|
3247
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-orange-500 font-extrabold", children: formatAmount(paymentObject.amount, paymentObject.currency) })
|
|
3248
|
+
] })
|
|
3249
|
+
] })
|
|
3250
|
+
] }),
|
|
3251
|
+
checkoutState === "PENDING" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "overflow-y-scroll px-10 pb-10 pt-2", children: paymentType === "CARD" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3252
|
+
PayByCard,
|
|
3253
|
+
{
|
|
3254
|
+
secretKey,
|
|
3255
|
+
environment,
|
|
3256
|
+
paymentObject,
|
|
3257
|
+
onPaymentAuthorized: setSuccess,
|
|
3258
|
+
onError
|
|
3259
|
+
}
|
|
3260
|
+
) : paymentType === "BANK_TRANSFER" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3261
|
+
PayByTransfer,
|
|
1808
3262
|
{
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
3263
|
+
secretKey,
|
|
3264
|
+
environment,
|
|
3265
|
+
paymentObject,
|
|
3266
|
+
onPaymentAuthorized: setSuccess,
|
|
3267
|
+
onError
|
|
1814
3268
|
}
|
|
1815
3269
|
) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1816
|
-
|
|
3270
|
+
PayByStableCoin,
|
|
1817
3271
|
{
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
3272
|
+
secretKey,
|
|
3273
|
+
environment,
|
|
3274
|
+
paymentObject,
|
|
3275
|
+
onPaymentAuthorized: setSuccess,
|
|
3276
|
+
onError
|
|
1821
3277
|
}
|
|
1822
|
-
),
|
|
1823
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "overflow-y-scroll px-10 pb-10 pt-2", children: paymentType === "CARD" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PayByCard, {}) : paymentType === "BANK_TRANSFER" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PayByTransfer, {}) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1836
|
-
PayByStableCoin,
|
|
1837
|
-
{
|
|
1838
|
-
onProceedToPay: () => setCheckoutState("STABLE_COIN_PAYMENT")
|
|
1839
|
-
}
|
|
1840
|
-
) })
|
|
1841
|
-
] }),
|
|
1842
|
-
checkoutState === "SUCCESS" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(BaseSuccess, {})
|
|
1843
|
-
] })
|
|
3278
|
+
) }),
|
|
3279
|
+
checkoutState === "SUCCESS" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3280
|
+
BaseSuccess,
|
|
3281
|
+
{
|
|
3282
|
+
amount: paymentObject.amount,
|
|
3283
|
+
currency: paymentObject.currency,
|
|
3284
|
+
redirectUrl: paymentObject.redirectUrl ?? "",
|
|
3285
|
+
successObject
|
|
3286
|
+
}
|
|
3287
|
+
)
|
|
3288
|
+
]
|
|
3289
|
+
}
|
|
3290
|
+
)
|
|
1844
3291
|
] }) });
|
|
1845
3292
|
}
|
|
1846
3293
|
// Annotate the CommonJS export names for ESM import in node:
|