react-sdk-feexpay 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.d.mts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +1405 -0
- package/dist/index.mjs +1371 -0
- package/package.json +46 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1371 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __async = (__this, __arguments, generator) => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
var fulfilled = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
step(generator.next(value));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
reject(e);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var rejected = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
step(generator.throw(value));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reject(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// #style-inject:#style-inject
|
|
42
|
+
function styleInject(css, { insertAt } = {}) {
|
|
43
|
+
if (!css || typeof document === "undefined") return;
|
|
44
|
+
const head = document.head || document.getElementsByTagName("head")[0];
|
|
45
|
+
const style = document.createElement("style");
|
|
46
|
+
style.type = "text/css";
|
|
47
|
+
if (insertAt === "top") {
|
|
48
|
+
if (head.firstChild) {
|
|
49
|
+
head.insertBefore(style, head.firstChild);
|
|
50
|
+
} else {
|
|
51
|
+
head.appendChild(style);
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
head.appendChild(style);
|
|
55
|
+
}
|
|
56
|
+
if (style.styleSheet) {
|
|
57
|
+
style.styleSheet.cssText = css;
|
|
58
|
+
} else {
|
|
59
|
+
style.appendChild(document.createTextNode(css));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/index.css
|
|
64
|
+
styleInject('*,\n::before,\n::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n*,\n::before,\n::after {\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n border-color: #e5e7eb;\n}\n::before,\n::after {\n --tw-content: "";\n}\nhtml,\n:host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n font-family:\n ui-sans-serif,\n system-ui,\n sans-serif,\n "Apple Color Emoji",\n "Segoe UI Emoji",\n "Segoe UI Symbol",\n "Noto Color Emoji";\n font-feature-settings: normal;\n font-variation-settings: normal;\n -webkit-tap-highlight-color: transparent;\n}\nbody {\n margin: 0;\n line-height: inherit;\n}\nhr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n}\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\na {\n color: inherit;\n text-decoration: inherit;\n}\nb,\nstrong {\n font-weight: bolder;\n}\ncode,\nkbd,\nsamp,\npre {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n font-feature-settings: normal;\n font-variation-settings: normal;\n font-size: 1em;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\ntable {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n font-size: 100%;\n font-weight: inherit;\n line-height: inherit;\n letter-spacing: inherit;\n color: inherit;\n margin: 0;\n padding: 0;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\ninput:where([type=button]),\ninput:where([type=reset]),\ninput:where([type=submit]) {\n -webkit-appearance: button;\n background-color: transparent;\n background-image: none;\n}\n:-moz-focusring {\n outline: auto;\n}\n:-moz-ui-invalid {\n box-shadow: none;\n}\nprogress {\n vertical-align: baseline;\n}\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n[type=search] {\n -webkit-appearance: textfield;\n outline-offset: -2px;\n}\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n::-webkit-file-upload-button {\n -webkit-appearance: button;\n font: inherit;\n}\nsummary {\n display: list-item;\n}\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\nfieldset {\n margin: 0;\n padding: 0;\n}\nlegend {\n padding: 0;\n}\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\ndialog {\n padding: 0;\n}\ntextarea {\n resize: vertical;\n}\ninput::-moz-placeholder,\ntextarea::-moz-placeholder {\n opacity: 1;\n color: #9ca3af;\n}\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1;\n color: #9ca3af;\n}\nbutton,\n[role=button] {\n cursor: pointer;\n}\n:disabled {\n cursor: default;\n}\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block;\n vertical-align: middle;\n}\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n[hidden]:where(:not([hidden=until-found])) {\n display: none;\n}\n.\\!container {\n width: 100% !important;\n}\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n .\\!container {\n max-width: 640px !important;\n }\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n .\\!container {\n max-width: 768px !important;\n }\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n .\\!container {\n max-width: 1024px !important;\n }\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n .\\!container {\n max-width: 1280px !important;\n }\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n .\\!container {\n max-width: 1536px !important;\n }\n .container {\n max-width: 1536px;\n }\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.visible {\n visibility: visible;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.inset-0 {\n inset: 0px;\n}\n.inset-y-0 {\n top: 0px;\n bottom: 0px;\n}\n.right-0 {\n right: 0px;\n}\n.right-2 {\n right: 0.5rem;\n}\n.top-2 {\n top: 0.5rem;\n}\n.z-10 {\n z-index: 10;\n}\n.z-20 {\n z-index: 20;\n}\n.z-50 {\n z-index: 50;\n}\n.mx-auto {\n margin-left: auto;\n margin-right: auto;\n}\n.-ml-1 {\n margin-left: -0.25rem;\n}\n.mb-1 {\n margin-bottom: 0.25rem;\n}\n.mb-2 {\n margin-bottom: 0.5rem;\n}\n.mb-4 {\n margin-bottom: 1rem;\n}\n.mb-5 {\n margin-bottom: 1.25rem;\n}\n.mb-6 {\n margin-bottom: 1.5rem;\n}\n.mr-2 {\n margin-right: 0.5rem;\n}\n.mt-2 {\n margin-top: 0.5rem;\n}\n.mt-6 {\n margin-top: 1.5rem;\n}\n.block {\n display: block;\n}\n.flex {\n display: flex;\n}\n.inline-flex {\n display: inline-flex;\n}\n.grid {\n display: grid;\n}\n.\\!hidden {\n display: none !important;\n}\n.hidden {\n display: none;\n}\n.h-1\\.5 {\n height: 0.375rem;\n}\n.h-11 {\n height: 2.75rem;\n}\n.h-20 {\n height: 5rem;\n}\n.h-4 {\n height: 1rem;\n}\n.h-5 {\n height: 1.25rem;\n}\n.h-6 {\n height: 1.5rem;\n}\n.h-8 {\n height: 2rem;\n}\n.h-full {\n height: 100%;\n}\n.max-h-\\[90vh\\] {\n max-height: 90vh;\n}\n.w-1\\/3 {\n width: 33.333333%;\n}\n.w-11 {\n width: 2.75rem;\n}\n.w-2\\/3 {\n width: 66.666667%;\n}\n.w-20 {\n width: 5rem;\n}\n.w-4 {\n width: 1rem;\n}\n.w-5 {\n width: 1.25rem;\n}\n.w-6 {\n width: 1.5rem;\n}\n.w-8 {\n width: 2rem;\n}\n.w-full {\n width: 100%;\n}\n.max-w-\\[120px\\] {\n max-width: 120px;\n}\n.max-w-md {\n max-width: 28rem;\n}\n.max-w-sm {\n max-width: 24rem;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.flex-shrink-0 {\n flex-shrink: 0;\n}\n.flex-grow {\n flex-grow: 1;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n.animate-spin {\n animation: spin 1s linear infinite;\n}\n.cursor-not-allowed {\n cursor: not-allowed;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.appearance-none {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.flex-col {\n flex-direction: column;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.gap-2 {\n gap: 0.5rem;\n}\n.gap-4 {\n gap: 1rem;\n}\n.space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.space-y-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem * var(--tw-space-y-reverse));\n}\n.space-y-6 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-2xl {\n border-radius: 1rem;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.rounded-lg {\n border-radius: 0.5rem;\n}\n.rounded-md {\n border-radius: 0.375rem;\n}\n.rounded-xl {\n border-radius: 0.75rem;\n}\n.rounded-l-md {\n border-top-left-radius: 0.375rem;\n border-bottom-left-radius: 0.375rem;\n}\n.rounded-r-md {\n border-top-right-radius: 0.375rem;\n border-bottom-right-radius: 0.375rem;\n}\n.border {\n border-width: 1px;\n}\n.border-0 {\n border-width: 0px;\n}\n.border-b {\n border-bottom-width: 1px;\n}\n.border-r-0 {\n border-right-width: 0px;\n}\n.border-\\[\\#D45D00\\] {\n --tw-border-opacity: 1;\n border-color: rgb(212 93 0 / var(--tw-border-opacity, 1));\n}\n.border-gray-200 {\n --tw-border-opacity: 1;\n border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));\n}\n.border-gray-300 {\n --tw-border-opacity: 1;\n border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));\n}\n.bg-\\[\\#fff7ed\\] {\n --tw-bg-opacity: 1;\n background-color: rgb(255 247 237 / var(--tw-bg-opacity, 1));\n}\n.bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\n}\n.bg-blue-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-200 {\n --tw-bg-opacity: 1;\n background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(156 163 175 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(107 114 128 / var(--tw-bg-opacity, 1));\n}\n.bg-gray-800 {\n --tw-bg-opacity: 1;\n background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));\n}\n.bg-green-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1));\n}\n.bg-green-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));\n}\n.bg-green-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));\n}\n.bg-orange-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(255 237 213 / var(--tw-bg-opacity, 1));\n}\n.bg-orange-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(251 146 60 / var(--tw-bg-opacity, 1));\n}\n.bg-primary-orange {\n --tw-bg-opacity: 1;\n background-color: rgb(212 93 0 / var(--tw-bg-opacity, 1));\n}\n.bg-red-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));\n}\n.bg-red-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(248 113 113 / var(--tw-bg-opacity, 1));\n}\n.bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));\n}\n.bg-opacity-50 {\n --tw-bg-opacity: 0.5;\n}\n.p-1 {\n padding: 0.25rem;\n}\n.p-2 {\n padding: 0.5rem;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-6 {\n padding: 1.5rem;\n}\n.px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.pb-4 {\n padding-bottom: 1rem;\n}\n.pr-8 {\n padding-right: 2rem;\n}\n.pt-2 {\n padding-top: 0.5rem;\n}\n.text-center {\n text-align: center;\n}\n.text-right {\n text-align: right;\n}\n.text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-bold {\n font-weight: 700;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.text-blue-900 {\n --tw-text-opacity: 1;\n color: rgb(30 58 138 / var(--tw-text-opacity, 1));\n}\n.text-gray-400 {\n --tw-text-opacity: 1;\n color: rgb(156 163 175 / var(--tw-text-opacity, 1));\n}\n.text-gray-500 {\n --tw-text-opacity: 1;\n color: rgb(107 114 128 / var(--tw-text-opacity, 1));\n}\n.text-gray-600 {\n --tw-text-opacity: 1;\n color: rgb(75 85 99 / var(--tw-text-opacity, 1));\n}\n.text-gray-700 {\n --tw-text-opacity: 1;\n color: rgb(55 65 81 / var(--tw-text-opacity, 1));\n}\n.text-gray-800 {\n --tw-text-opacity: 1;\n color: rgb(31 41 55 / var(--tw-text-opacity, 1));\n}\n.text-gray-900 {\n --tw-text-opacity: 1;\n color: rgb(17 24 39 / var(--tw-text-opacity, 1));\n}\n.text-green-500 {\n --tw-text-opacity: 1;\n color: rgb(34 197 94 / var(--tw-text-opacity, 1));\n}\n.text-orange-500 {\n --tw-text-opacity: 1;\n color: rgb(249 115 22 / var(--tw-text-opacity, 1));\n}\n.text-primary-blue {\n --tw-text-opacity: 1;\n color: rgb(17 44 86 / var(--tw-text-opacity, 1));\n}\n.text-primary-orange {\n --tw-text-opacity: 1;\n color: rgb(212 93 0 / var(--tw-text-opacity, 1));\n}\n.text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239 68 68 / var(--tw-text-opacity, 1));\n}\n.text-red-600 {\n --tw-text-opacity: 1;\n color: rgb(220 38 38 / var(--tw-text-opacity, 1));\n}\n.text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity, 1));\n}\n.underline {\n text-decoration-line: underline;\n}\n.opacity-25 {\n opacity: 0.25;\n}\n.opacity-70 {\n opacity: 0.7;\n}\n.opacity-75 {\n opacity: 0.75;\n}\n.shadow-2xl {\n --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.shadow-xl {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.outline {\n outline-style: solid;\n}\n.transition {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke,\n opacity,\n box-shadow,\n transform,\n filter,\n backdrop-filter;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.duration-200 {\n transition-duration: 200ms;\n}\n.duration-300 {\n transition-duration: 300ms;\n}\n.hover\\:border-\\[\\#D45D00\\]:hover {\n --tw-border-opacity: 1;\n border-color: rgb(212 93 0 / var(--tw-border-opacity, 1));\n}\n.hover\\:bg-gray-300:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));\n}\n.hover\\:bg-gray-600:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(75 85 99 / var(--tw-bg-opacity, 1));\n}\n.hover\\:bg-green-600:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1));\n}\n.hover\\:bg-orange-700:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(194 65 12 / var(--tw-bg-opacity, 1));\n}\n.hover\\:text-gray-700:hover {\n --tw-text-opacity: 1;\n color: rgb(55 65 81 / var(--tw-text-opacity, 1));\n}\n.focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus\\:ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ring-primary-orange:focus {\n --tw-ring-opacity: 1;\n --tw-ring-color: rgb(212 93 0 / var(--tw-ring-opacity, 1));\n}\n.focus\\:ring-offset-2:focus {\n --tw-ring-offset-width: 2px;\n}\n.disabled\\:opacity-50:disabled {\n opacity: 0.5;\n}\n');
|
|
65
|
+
|
|
66
|
+
// src/index.tsx
|
|
67
|
+
import React9 from "react";
|
|
68
|
+
|
|
69
|
+
// src/components/FeexPayButton.tsx
|
|
70
|
+
import React8, { useState as useState5, useEffect as useEffect4, useRef as useRef2, useCallback as useCallback2 } from "react";
|
|
71
|
+
|
|
72
|
+
// src/components/PaymentModal.tsx
|
|
73
|
+
import React7, { useState as useState4, useEffect as useEffect3, useCallback, useRef } from "react";
|
|
74
|
+
|
|
75
|
+
// src/components/CountrySelector.tsx
|
|
76
|
+
import React from "react";
|
|
77
|
+
var COUNTRY_OPTIONS = [
|
|
78
|
+
{ value: "BENIN", label: "\u{1F1E7}\u{1F1EF} B\xE9nin" },
|
|
79
|
+
{ value: "CONGO_BRAZZAVILLE", label: "\u{1F1E8}\u{1F1EC} Congo Brazzaville" },
|
|
80
|
+
{ value: "COTE_D_IVOIRE", label: "\u{1F1E8}\u{1F1EE} C\xF4te d'Ivoire" },
|
|
81
|
+
{ value: "SENEGAL", label: "\u{1F1F8}\u{1F1F3} S\xE9n\xE9gal" },
|
|
82
|
+
{ value: "TOGO", label: "\u{1F1F9}\u{1F1EC} Togo" }
|
|
83
|
+
];
|
|
84
|
+
var CountrySelector = ({ selectedCountry, onChange }) => /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
|
|
85
|
+
"select",
|
|
86
|
+
{
|
|
87
|
+
value: selectedCountry,
|
|
88
|
+
onChange: (e) => onChange(e.target.value),
|
|
89
|
+
className: "block w-full px-2 py-2 pr-8 border rounded-md appearance-none focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs"
|
|
90
|
+
},
|
|
91
|
+
COUNTRY_OPTIONS.map(({ value, label }) => /* @__PURE__ */ React.createElement("option", { key: value, value }, label))
|
|
92
|
+
), /* @__PURE__ */ React.createElement("div", { className: "absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none" }, /* @__PURE__ */ React.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }))));
|
|
93
|
+
var CountrySelector_default = CountrySelector;
|
|
94
|
+
|
|
95
|
+
// src/components/NetworkSelector.tsx
|
|
96
|
+
import React2, { useEffect } from "react";
|
|
97
|
+
|
|
98
|
+
// src/constants/index.ts
|
|
99
|
+
var BENIN_PREFIXES = {
|
|
100
|
+
CORIS: ["0142", "0146", "0150", "0151", "0152", "0153", "0154", "0156", "0157", "0159", "0161", "0162", "0166", "0145", "0155", "0158", "0160", "0163", "0164", "0165", "0168", "0194", "0195", "0198", "0199", "0140", "0141", "0143", "0144", "0147"],
|
|
101
|
+
MTN: ["0142", "0146", "0150", "0151", "0152", "0153", "0154", "0156", "0157", "0159", "0161", "0162", "0166", "0167", "0169", "0190", "0191", "0192", "0193", "0196", "0197"],
|
|
102
|
+
MOOV: ["0145", "0155", "0158", "0160", "0163", "0164", "0165", "0168", "0194", "0195", "0198", "0199"],
|
|
103
|
+
CELTIIS: ["0140", "0141", "0143", "0144", "0147"]
|
|
104
|
+
};
|
|
105
|
+
var NETWORK_FEES = {
|
|
106
|
+
BENIN: { MTN: 0.017, MOOV: 0.017, CELTIIS: 0.017, CORIS: 0.017 },
|
|
107
|
+
COTE_D_IVOIRE: { MTN: 0.029, ORANGE: 0.029, WAVE: 0.032 },
|
|
108
|
+
BURKINA_FASO: { MOOV: 0.032, ORANGE: 0.039 },
|
|
109
|
+
CONGO_BRAZZAVILLE: { MTN: 0.03 },
|
|
110
|
+
SENEGAL: { ORANGE: 0.019, FREE: 0.019, WAVE: 0.019 },
|
|
111
|
+
TOGO: { TOGOCOM: 0.03, MOOV: 0.03 }
|
|
112
|
+
};
|
|
113
|
+
var NETWORK_API_MAPPING = {
|
|
114
|
+
BENIN: { MTN: "MTN", MOOV: "MOOV", CELTIIS: "CELTIIS BJ", CORIS: "CORIS" },
|
|
115
|
+
COTE_D_IVOIRE: { MTN: "MTN CI", ORANGE: "ORANGE CI", WAVE: "WAVE CI" },
|
|
116
|
+
BURKINA_FASO: { MOOV: "MOOV BF", ORANGE: "ORANGE BF" },
|
|
117
|
+
CONGO_BRAZZAVILLE: { MTN: "MTN CG" },
|
|
118
|
+
SENEGAL: { ORANGE: "ORANGE SN", FREE: "FREE SN", WAVE: "WAVE SN" },
|
|
119
|
+
TOGO: { TOGOCOM: "TOGOCOM TG", MOOV: "MOOV TG" }
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/utils/paymentUtils.ts
|
|
123
|
+
var getNetworkByPhonePrefix = (prefix, currentNetwork) => {
|
|
124
|
+
if (currentNetwork === "CORIS") return "CORIS";
|
|
125
|
+
if (BENIN_PREFIXES.MTN.includes(prefix)) return "MTN";
|
|
126
|
+
if (BENIN_PREFIXES.MOOV.includes(prefix)) return "MOOV";
|
|
127
|
+
if (BENIN_PREFIXES.CELTIIS.includes(prefix)) return "CELTIIS";
|
|
128
|
+
return null;
|
|
129
|
+
};
|
|
130
|
+
var getNetworksForCountry = (country) => {
|
|
131
|
+
switch (country) {
|
|
132
|
+
case "BENIN":
|
|
133
|
+
return ["MTN", "MOOV", "CELTIIS"];
|
|
134
|
+
case "COTE_D_IVOIRE":
|
|
135
|
+
return ["MTN", "ORANGE"];
|
|
136
|
+
case "BURKINA_FASO":
|
|
137
|
+
return ["MOOV", "ORANGE"];
|
|
138
|
+
case "CONGO_BRAZZAVILLE":
|
|
139
|
+
return ["MTN"];
|
|
140
|
+
case "SENEGAL":
|
|
141
|
+
return ["ORANGE", "FREE", "WAVE"];
|
|
142
|
+
case "TOGO":
|
|
143
|
+
return ["TOGOCOM", "MOOV"];
|
|
144
|
+
default:
|
|
145
|
+
return ["MTN", "MOOV"];
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
var calculateFees = (amount, country, network, paymentMethod, cardType) => {
|
|
149
|
+
var _a;
|
|
150
|
+
if (paymentMethod === "CARD" && (cardType === "VISA" || cardType === "MASTERCARD")) {
|
|
151
|
+
return Math.ceil(amount * 0.045);
|
|
152
|
+
}
|
|
153
|
+
const countryFees = NETWORK_FEES[country];
|
|
154
|
+
const feePercentage = (_a = countryFees == null ? void 0 : countryFees[network]) != null ? _a : 0;
|
|
155
|
+
return Math.ceil(amount * feePercentage);
|
|
156
|
+
};
|
|
157
|
+
var getNetworkApiCode = (country, network) => {
|
|
158
|
+
const mapping = NETWORK_API_MAPPING[country];
|
|
159
|
+
return mapping && mapping[network] || network.toLowerCase();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// src/components/NetworkSelector.tsx
|
|
163
|
+
var NetworkSelector = ({ selectedNetwork, onChange, country }) => {
|
|
164
|
+
const availableNetworks = getNetworksForCountry(country);
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (availableNetworks.length > 0 && !availableNetworks.includes(selectedNetwork)) {
|
|
167
|
+
onChange(availableNetworks[0]);
|
|
168
|
+
}
|
|
169
|
+
}, [country, selectedNetwork, availableNetworks, onChange]);
|
|
170
|
+
return /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement(
|
|
171
|
+
"select",
|
|
172
|
+
{
|
|
173
|
+
value: selectedNetwork,
|
|
174
|
+
onChange: (e) => onChange(e.target.value),
|
|
175
|
+
className: "block w-full px-2 py-2 pr-8 border rounded-md appearance-none focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs"
|
|
176
|
+
},
|
|
177
|
+
availableNetworks.map((network) => /* @__PURE__ */ React2.createElement("option", { key: network, value: network }, network.replace("_", " ")))
|
|
178
|
+
), /* @__PURE__ */ React2.createElement("div", { className: "absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none" }, /* @__PURE__ */ React2.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React2.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }))));
|
|
179
|
+
};
|
|
180
|
+
var NetworkSelector_default = NetworkSelector;
|
|
181
|
+
|
|
182
|
+
// src/components/StatusModal.tsx
|
|
183
|
+
import React3 from "react";
|
|
184
|
+
var StatusModal = ({ isOpen, onClose, status }) => {
|
|
185
|
+
if (!isOpen) return null;
|
|
186
|
+
const isSuccess = status === "SUCCESSFUL" || status === "SUCCESS";
|
|
187
|
+
const isInsufficient = status === "INSUFFICIENT_FUNDS";
|
|
188
|
+
const isTimeout = status === "TIMEOUT";
|
|
189
|
+
const isFailed = status === "FAILED";
|
|
190
|
+
const icon = isSuccess ? /* @__PURE__ */ React3.createElement("div", { className: "w-20 h-20 mx-auto mb-5 bg-green-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React3.createElement("svg", { className: "h-11 w-11 text-green-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M5 13l4 4L19 7" }))) : isInsufficient ? /* @__PURE__ */ React3.createElement("div", { className: "w-20 h-20 mx-auto mb-5 bg-orange-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React3.createElement("svg", { className: "h-11 w-11 text-orange-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }))) : isTimeout ? /* @__PURE__ */ React3.createElement("div", { className: "w-20 h-20 mx-auto mb-5 bg-gray-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React3.createElement("svg", { className: "h-11 w-11 text-gray-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }))) : isFailed ? /* @__PURE__ */ React3.createElement("div", { className: "w-20 h-20 mx-auto mb-5 bg-red-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React3.createElement("svg", { className: "h-11 w-11 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React3.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }))) : /* @__PURE__ */ React3.createElement("div", { className: "w-20 h-20 mx-auto mb-5 bg-blue-50 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React3.createElement("svg", { className: "animate-spin h-11 w-11 text-primary-orange", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React3.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React3.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })));
|
|
191
|
+
const title = isSuccess ? "\u{1F389} Paiement r\xE9ussi !" : isInsufficient ? "Solde insuffisant" : isTimeout ? "D\xE9lai expir\xE9" : isFailed ? "Paiement \xE9chou\xE9" : "Traitement en cours\u2026";
|
|
192
|
+
const body = isSuccess ? "Votre transaction a \xE9t\xE9 confirm\xE9e avec succ\xE8s." : isInsufficient ? "Rechargez votre compte puis r\xE9essayez." : isTimeout ? "V\xE9rifiez votre compte avant de r\xE9essayer." : isFailed ? "Veuillez r\xE9essayer." : "Votre paiement est en cours de traitement, veuillez patienter.";
|
|
193
|
+
const btnLabel = isSuccess || isTimeout ? "Fermer" : "R\xE9essayer";
|
|
194
|
+
const btnClass = isSuccess ? "bg-green-500 hover:bg-green-600" : isTimeout ? "bg-gray-500 hover:bg-gray-600" : "bg-primary-orange hover:bg-orange-700";
|
|
195
|
+
const barClass = isSuccess ? "bg-green-400" : isInsufficient ? "bg-orange-400" : isTimeout ? "bg-gray-400" : isFailed ? "bg-red-400" : "bg-primary-orange";
|
|
196
|
+
return /* @__PURE__ */ React3.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50" }, /* @__PURE__ */ React3.createElement("div", { className: "bg-white rounded-2xl shadow-2xl w-full max-w-sm overflow-hidden" }, /* @__PURE__ */ React3.createElement("div", { className: `h-1.5 w-full ${barClass}` }), /* @__PURE__ */ React3.createElement("div", { className: "p-6 text-center" }, icon, /* @__PURE__ */ React3.createElement("h3", { className: "text-xl font-bold text-gray-800 mb-2" }, title), /* @__PURE__ */ React3.createElement("p", { className: "text-sm text-gray-500 mb-6" }, body), /* @__PURE__ */ React3.createElement(
|
|
197
|
+
"button",
|
|
198
|
+
{
|
|
199
|
+
onClick: onClose,
|
|
200
|
+
className: `w-full ${btnClass} text-white font-semibold py-3 px-4 rounded-xl transition-colors duration-200`
|
|
201
|
+
},
|
|
202
|
+
btnLabel
|
|
203
|
+
))));
|
|
204
|
+
};
|
|
205
|
+
var StatusModal_default = StatusModal;
|
|
206
|
+
|
|
207
|
+
// src/components/OTPModal.tsx
|
|
208
|
+
import React4, { useState } from "react";
|
|
209
|
+
var OTPModal = ({ isOpen, onClose, onSubmit, reference }) => {
|
|
210
|
+
const [otp, setOtp] = useState("");
|
|
211
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
212
|
+
const handleSubmit = (e) => {
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
setIsLoading(true);
|
|
215
|
+
onSubmit(otp);
|
|
216
|
+
};
|
|
217
|
+
if (!isOpen) return null;
|
|
218
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50 overflow-hidden" }, /* @__PURE__ */ React4.createElement("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-md relative" }, /* @__PURE__ */ React4.createElement("div", { className: "flex justify-between items-center border-b p-4" }, /* @__PURE__ */ React4.createElement("h3", { className: "text-lg font-medium" }, "Confirmation de paiement"), /* @__PURE__ */ React4.createElement("button", { onClick: onClose, className: "text-gray-500 hover:text-gray-700" }, /* @__PURE__ */ React4.createElement("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React4.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })))), /* @__PURE__ */ React4.createElement("div", { className: "p-6" }, /* @__PURE__ */ React4.createElement("p", { className: "text-sm text-gray-600 mb-4" }, "Un code de confirmation a \xE9t\xE9 envoy\xE9 \xE0 votre t\xE9l\xE9phone. Veuillez le saisir ci-dessous pour finaliser votre paiement."), /* @__PURE__ */ React4.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React4.createElement("p", { className: "text-sm text-gray-500 mb-1" }, "R\xE9f\xE9rence de transaction :"), /* @__PURE__ */ React4.createElement("p", { className: "font-medium" }, reference)), /* @__PURE__ */ React4.createElement("form", { onSubmit: handleSubmit }, /* @__PURE__ */ React4.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React4.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Code OTP"), /* @__PURE__ */ React4.createElement(
|
|
219
|
+
"input",
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
value: otp,
|
|
223
|
+
onChange: (e) => setOtp(e.target.value),
|
|
224
|
+
placeholder: "Entrez le code re\xE7u par SMS",
|
|
225
|
+
className: "w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange",
|
|
226
|
+
required: true
|
|
227
|
+
}
|
|
228
|
+
)), /* @__PURE__ */ React4.createElement(
|
|
229
|
+
"button",
|
|
230
|
+
{
|
|
231
|
+
type: "submit",
|
|
232
|
+
disabled: isLoading,
|
|
233
|
+
className: "w-full bg-primary-orange text-white py-2 px-4 rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-orange disabled:opacity-50"
|
|
234
|
+
},
|
|
235
|
+
isLoading ? "Traitement en cours..." : "Confirmer le paiement"
|
|
236
|
+
)))));
|
|
237
|
+
};
|
|
238
|
+
var OTPModal_default = OTPModal;
|
|
239
|
+
|
|
240
|
+
// src/components/HeaderBar.tsx
|
|
241
|
+
import React5, { useEffect as useEffect2, useState as useState2 } from "react";
|
|
242
|
+
|
|
243
|
+
// src/apis/feexPayApi.ts
|
|
244
|
+
var API_BASE = "https://api-v2.feexpay.me/api";
|
|
245
|
+
var getClientIP = () => __async(null, null, function* () {
|
|
246
|
+
try {
|
|
247
|
+
const res = yield fetch("https://api.ipify.org?format=json");
|
|
248
|
+
const data = yield res.json();
|
|
249
|
+
return data.ip;
|
|
250
|
+
} catch (e) {
|
|
251
|
+
return "127.0.0.1";
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
var requestToPay = (params) => __async(null, null, function* () {
|
|
255
|
+
const networkApiCode = getNetworkApiCode(params.country, params.network);
|
|
256
|
+
const merchantIp = yield getClientIP();
|
|
257
|
+
const merchantDomain = window.location.origin;
|
|
258
|
+
let cleanedPhone = params.phoneNumber.replace(/\+/g, "");
|
|
259
|
+
if (cleanedPhone.length >= 8) {
|
|
260
|
+
const prefix = cleanedPhone.slice(0, 3);
|
|
261
|
+
if (cleanedPhone.startsWith(prefix + prefix)) {
|
|
262
|
+
cleanedPhone = cleanedPhone.slice(prefix.length);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const isOrangeSN = params.network === "ORANGE" && params.country === "SENEGAL";
|
|
266
|
+
const isWaveSN = params.network === "WAVE" && params.country === "SENEGAL";
|
|
267
|
+
const isFreeSN = params.network === "FREE" && params.country === "SENEGAL";
|
|
268
|
+
let apiUrl;
|
|
269
|
+
let apiParams;
|
|
270
|
+
if (isOrangeSN) {
|
|
271
|
+
apiUrl = `${API_BASE}/transactions/public/requesttopay/orange_sn`;
|
|
272
|
+
apiParams = {
|
|
273
|
+
phoneNumber: cleanedPhone,
|
|
274
|
+
amount: params.amount,
|
|
275
|
+
shop: params.id,
|
|
276
|
+
first_name: params.first_name,
|
|
277
|
+
email: params.email,
|
|
278
|
+
callback_info: params.callback_info || {},
|
|
279
|
+
description: params.description,
|
|
280
|
+
om_otp: params.otp || ""
|
|
281
|
+
};
|
|
282
|
+
} else if (isWaveSN) {
|
|
283
|
+
apiUrl = `${API_BASE}/transactions/public/requesttopay/wave_sn`;
|
|
284
|
+
apiParams = {
|
|
285
|
+
phoneNumber: cleanedPhone,
|
|
286
|
+
amount: params.amount,
|
|
287
|
+
shop: params.id,
|
|
288
|
+
first_name: params.first_name,
|
|
289
|
+
email: params.email,
|
|
290
|
+
callback_info: params.callback_info || {},
|
|
291
|
+
description: params.description
|
|
292
|
+
};
|
|
293
|
+
} else if (isFreeSN) {
|
|
294
|
+
apiUrl = `${API_BASE}/transactions/public/requesttopay/free_sn`;
|
|
295
|
+
apiParams = {
|
|
296
|
+
phoneNumber: cleanedPhone,
|
|
297
|
+
amount: params.amount,
|
|
298
|
+
shop: params.id,
|
|
299
|
+
first_name: params.first_name,
|
|
300
|
+
email: params.email,
|
|
301
|
+
callback_info: params.callback_info || {},
|
|
302
|
+
description: params.description
|
|
303
|
+
};
|
|
304
|
+
} else {
|
|
305
|
+
apiUrl = `${API_BASE}/transactions/requesttopay/integration`;
|
|
306
|
+
apiParams = {
|
|
307
|
+
phoneNumber: cleanedPhone,
|
|
308
|
+
country: params.country,
|
|
309
|
+
amount: String(params.amount),
|
|
310
|
+
reseau: networkApiCode,
|
|
311
|
+
shop: params.id,
|
|
312
|
+
first_name: params.first_name,
|
|
313
|
+
email: params.email,
|
|
314
|
+
custom_id: params.customId || "",
|
|
315
|
+
otp: params.otp || "",
|
|
316
|
+
callback_info: params.callback_info || {},
|
|
317
|
+
description: params.description,
|
|
318
|
+
currency: params.currency || "XOF",
|
|
319
|
+
merchant_domain: merchantDomain,
|
|
320
|
+
merchant_ip: merchantIp,
|
|
321
|
+
payment_interface: "REACT"
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const response = yield fetch(apiUrl, {
|
|
325
|
+
method: "POST",
|
|
326
|
+
headers: {
|
|
327
|
+
"Content-Type": "application/json",
|
|
328
|
+
Authorization: `Bearer ${params.token}`
|
|
329
|
+
},
|
|
330
|
+
body: JSON.stringify(apiParams)
|
|
331
|
+
});
|
|
332
|
+
if (!response.ok) {
|
|
333
|
+
throw new Error("Payment request failed");
|
|
334
|
+
}
|
|
335
|
+
return response.json();
|
|
336
|
+
});
|
|
337
|
+
var requestWalletCorisPayment = (params) => __async(null, null, function* () {
|
|
338
|
+
const apiUrl = `${API_BASE}/transactions/requesttopay/integration`;
|
|
339
|
+
const phoneNumberRight = params.phoneNumber.startsWith("+229") ? params.phoneNumber.substring(4) : params.phoneNumber.startsWith("229") ? params.phoneNumber.substring(3) : params.phoneNumber;
|
|
340
|
+
const apiParams = {
|
|
341
|
+
phoneNumber: `229${phoneNumberRight}`,
|
|
342
|
+
country: "229",
|
|
343
|
+
phoneNumberRight,
|
|
344
|
+
amount: String(params.amount),
|
|
345
|
+
currency: "XOF",
|
|
346
|
+
description: params.description || "Paiement via FeexPay",
|
|
347
|
+
email: params.email,
|
|
348
|
+
first_name: params.first_name,
|
|
349
|
+
otp: params.otp || "",
|
|
350
|
+
custom_id: params.reference || "",
|
|
351
|
+
reseau: "CORIS",
|
|
352
|
+
shop: params.id,
|
|
353
|
+
token: params.token,
|
|
354
|
+
callback_info: params.callback_info || {},
|
|
355
|
+
payment_interface: "REACT"
|
|
356
|
+
};
|
|
357
|
+
const response = yield fetch(apiUrl, {
|
|
358
|
+
method: "POST",
|
|
359
|
+
headers: {
|
|
360
|
+
"Content-Type": "application/json",
|
|
361
|
+
Authorization: `Bearer ${params.token}`
|
|
362
|
+
},
|
|
363
|
+
body: JSON.stringify(apiParams)
|
|
364
|
+
});
|
|
365
|
+
const responseData = yield response.json();
|
|
366
|
+
return __spreadProps(__spreadValues({}, responseData), { statusCode: String(response.status) });
|
|
367
|
+
});
|
|
368
|
+
var checkTransactionStatus = (reference, token) => __async(null, null, function* () {
|
|
369
|
+
const apiUrl = `${API_BASE}/transactions/public/single/status/${reference}`;
|
|
370
|
+
const response = yield fetch(apiUrl, {
|
|
371
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
372
|
+
});
|
|
373
|
+
if (!response.ok) {
|
|
374
|
+
throw new Error("Status check failed");
|
|
375
|
+
}
|
|
376
|
+
return response.json();
|
|
377
|
+
});
|
|
378
|
+
var getTransactionDetails = (params) => __async(null, null, function* () {
|
|
379
|
+
const apiUrl = `${API_BASE}/transactions/details`;
|
|
380
|
+
const response = yield fetch(apiUrl, {
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: {
|
|
383
|
+
"Content-Type": "application/json",
|
|
384
|
+
Authorization: `Bearer ${params.token}`
|
|
385
|
+
},
|
|
386
|
+
body: JSON.stringify({
|
|
387
|
+
reseau: getNetworkApiCode(params.country, params.network),
|
|
388
|
+
amount: params.amount,
|
|
389
|
+
shop: params.id
|
|
390
|
+
})
|
|
391
|
+
});
|
|
392
|
+
if (!response.ok) {
|
|
393
|
+
throw new Error("Failed to get transaction details");
|
|
394
|
+
}
|
|
395
|
+
return response.json();
|
|
396
|
+
});
|
|
397
|
+
var getShop = (shop) => __async(null, null, function* () {
|
|
398
|
+
const apiUrl = `${API_BASE}/shop/${shop}/get_shop`;
|
|
399
|
+
const response = yield fetch(apiUrl);
|
|
400
|
+
if (!response.ok) {
|
|
401
|
+
throw new Error("Shop retrieval failed");
|
|
402
|
+
}
|
|
403
|
+
return response.json();
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// src/components/HeaderBar.tsx
|
|
407
|
+
var HeaderBar = ({ id, onClose }) => {
|
|
408
|
+
const [shopData, setShopData] = useState2(null);
|
|
409
|
+
useEffect2(() => {
|
|
410
|
+
getShop(id).then(setShopData).catch(() => {
|
|
411
|
+
});
|
|
412
|
+
}, [id]);
|
|
413
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "flex items-center justify-between px-4 py-2 border-b border-gray-200" }, /* @__PURE__ */ React5.createElement("div", null, /* @__PURE__ */ React5.createElement(
|
|
414
|
+
"img",
|
|
415
|
+
{
|
|
416
|
+
src: "https://api.feexpay.me/api/static/feexpay_logo-h.png",
|
|
417
|
+
width: "100",
|
|
418
|
+
alt: "FeexPay"
|
|
419
|
+
}
|
|
420
|
+
)), /* @__PURE__ */ React5.createElement("div", { className: "text-right text-xs text-gray-700" }, shopData && /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement("div", { className: "font-semibold" }, "MARCHAND: ", shopData.name), /* @__PURE__ */ React5.createElement("div", { className: "text-xs text-gray-500" }, "ID : ", shopData.reference))), /* @__PURE__ */ React5.createElement(
|
|
421
|
+
"button",
|
|
422
|
+
{
|
|
423
|
+
onClick: onClose,
|
|
424
|
+
className: "text-gray-500 hover:text-gray-700",
|
|
425
|
+
"aria-label": "Fermer"
|
|
426
|
+
},
|
|
427
|
+
/* @__PURE__ */ React5.createElement(
|
|
428
|
+
"svg",
|
|
429
|
+
{
|
|
430
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
431
|
+
className: "h-6 w-6",
|
|
432
|
+
fill: "none",
|
|
433
|
+
viewBox: "0 0 24 24",
|
|
434
|
+
stroke: "currentColor"
|
|
435
|
+
},
|
|
436
|
+
/* @__PURE__ */ React5.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })
|
|
437
|
+
)
|
|
438
|
+
));
|
|
439
|
+
};
|
|
440
|
+
var HeaderBar_default = HeaderBar;
|
|
441
|
+
|
|
442
|
+
// src/context/FeexPayContext.tsx
|
|
443
|
+
import React6, { createContext, useContext, useState as useState3 } from "react";
|
|
444
|
+
var FeexPayContext = createContext(void 0);
|
|
445
|
+
var useFeexPay = () => {
|
|
446
|
+
const context = useContext(FeexPayContext);
|
|
447
|
+
if (!context) {
|
|
448
|
+
throw new Error("useFeexPay must be used within a FeexPayProvider");
|
|
449
|
+
}
|
|
450
|
+
return context;
|
|
451
|
+
};
|
|
452
|
+
var defaultPaymentConfig = {
|
|
453
|
+
amount: 0,
|
|
454
|
+
description: "",
|
|
455
|
+
id: "",
|
|
456
|
+
token: "",
|
|
457
|
+
mode: "LIVE"
|
|
458
|
+
};
|
|
459
|
+
var FeexPayProvider = ({ children }) => {
|
|
460
|
+
const [paymentConfig, setPaymentConfig] = useState3(defaultPaymentConfig);
|
|
461
|
+
return /* @__PURE__ */ React6.createElement(FeexPayContext.Provider, { value: { paymentConfig, setPaymentConfig } }, children);
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// src/utils/phoneUtils.ts
|
|
465
|
+
var getFormattedPhoneNumber = (phoneNumber, country) => {
|
|
466
|
+
const cleaned = phoneNumber.replace(/\D/g, "");
|
|
467
|
+
const prefixes = {
|
|
468
|
+
BENIN: "229",
|
|
469
|
+
COTE_D_IVOIRE: "225",
|
|
470
|
+
BURKINA_FASO: "226",
|
|
471
|
+
CONGO_BRAZZAVILLE: "242",
|
|
472
|
+
SENEGAL: "221",
|
|
473
|
+
TOGO: "228"
|
|
474
|
+
};
|
|
475
|
+
const prefix = prefixes[country];
|
|
476
|
+
if (cleaned.startsWith(prefix + prefix)) return cleaned.slice(prefix.length);
|
|
477
|
+
if (cleaned.startsWith(prefix)) return cleaned;
|
|
478
|
+
return `${prefix}${cleaned}`;
|
|
479
|
+
};
|
|
480
|
+
var getPrefixFromCountry = (country) => {
|
|
481
|
+
const prefixes = {
|
|
482
|
+
BENIN: "+229",
|
|
483
|
+
COTE_D_IVOIRE: "+225",
|
|
484
|
+
BURKINA_FASO: "+226",
|
|
485
|
+
CONGO_BRAZZAVILLE: "+242",
|
|
486
|
+
SENEGAL: "+221",
|
|
487
|
+
TOGO: "+228"
|
|
488
|
+
};
|
|
489
|
+
return prefixes[country] || "";
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// src/utils/idUtils.ts
|
|
493
|
+
var generateRandomId = () => `TRX-${Math.random().toString(36).substring(2, 10).toUpperCase()}`;
|
|
494
|
+
|
|
495
|
+
// src/utils/paymentHandlers.ts
|
|
496
|
+
var startStatusCheck = (ref, props, network, getFormattedPhone) => {
|
|
497
|
+
let checkCount = 0;
|
|
498
|
+
const maxChecks = 12;
|
|
499
|
+
let timeoutId = null;
|
|
500
|
+
const { paymentConfig, setStateCallbacks, fullName, email } = props;
|
|
501
|
+
const { setPaymentStatus, setStatusMessage, setStatusModalOpen, setIsLoading } = setStateCallbacks;
|
|
502
|
+
const handleFinalStatus = (status, message, callbackStatus) => {
|
|
503
|
+
if (props.isCallbackCalledRef.current) return;
|
|
504
|
+
props.isCallbackCalledRef.current = true;
|
|
505
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
506
|
+
setPaymentStatus(status);
|
|
507
|
+
setStatusMessage(message);
|
|
508
|
+
setStatusModalOpen(true);
|
|
509
|
+
setIsLoading(false);
|
|
510
|
+
const callbackData = {
|
|
511
|
+
reference: ref,
|
|
512
|
+
status: callbackStatus,
|
|
513
|
+
phoneNumber: getFormattedPhone(),
|
|
514
|
+
reseau: network,
|
|
515
|
+
callback_info: paymentConfig.callback_info || {},
|
|
516
|
+
description: paymentConfig.description,
|
|
517
|
+
transaction_id: ref,
|
|
518
|
+
message,
|
|
519
|
+
amount: paymentConfig.amount,
|
|
520
|
+
currency: paymentConfig.currency || "XOF",
|
|
521
|
+
first_name: fullName,
|
|
522
|
+
email
|
|
523
|
+
};
|
|
524
|
+
if (paymentConfig.callback) paymentConfig.callback(callbackData);
|
|
525
|
+
const isSuccess = callbackStatus === "SUCCESSFUL" || callbackStatus === "SUCCESS";
|
|
526
|
+
if (isSuccess && paymentConfig.callback_url) {
|
|
527
|
+
window.location.href = `${paymentConfig.callback_url}?ref=${ref}`;
|
|
528
|
+
} else if (!isSuccess && paymentConfig.error_callback_url) {
|
|
529
|
+
window.location.href = `${paymentConfig.error_callback_url}?ref=${ref}`;
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
const checkStatus = () => __async(null, null, function* () {
|
|
533
|
+
var _a;
|
|
534
|
+
checkCount++;
|
|
535
|
+
try {
|
|
536
|
+
const status = yield checkTransactionStatus(ref, paymentConfig.token);
|
|
537
|
+
if (status.reason === "LOW_BALANCE_OR_PAYEE_LIMIT_REACHED_OR_NOT_ALLOWED") {
|
|
538
|
+
handleFinalStatus("INSUFFICIENT_FUNDS", "Fonds insuffisants. Veuillez v\xE9rifier votre solde.", "FAILED");
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
if (status.reason === "PAYER NOT FOUND") {
|
|
542
|
+
handleFinalStatus("FAILED", "Num\xE9ro de t\xE9l\xE9phone introuvable. Veuillez v\xE9rifier et r\xE9essayer.", "FAILED");
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const paymentStatus = ((_a = status.status) == null ? void 0 : _a.toUpperCase()) || "PENDING";
|
|
546
|
+
switch (paymentStatus) {
|
|
547
|
+
case "SUCCESSFUL":
|
|
548
|
+
case "SUCCESS":
|
|
549
|
+
handleFinalStatus("SUCCESSFUL", "Paiement r\xE9ussi !", paymentStatus);
|
|
550
|
+
break;
|
|
551
|
+
case "FAILED":
|
|
552
|
+
handleFinalStatus("FAILED", "Le paiement a \xE9chou\xE9. Veuillez r\xE9essayer.", "FAILED");
|
|
553
|
+
break;
|
|
554
|
+
case "INSUFFICIENT_FUNDS":
|
|
555
|
+
handleFinalStatus("INSUFFICIENT_FUNDS", "Fonds insuffisants. Veuillez v\xE9rifier votre solde.", "FAILED");
|
|
556
|
+
break;
|
|
557
|
+
case "TIMEOUT":
|
|
558
|
+
handleFinalStatus("TIMEOUT", "La v\xE9rification du paiement a expir\xE9.", "TIMEOUT");
|
|
559
|
+
break;
|
|
560
|
+
case "PENDING":
|
|
561
|
+
default:
|
|
562
|
+
if (checkCount >= maxChecks) {
|
|
563
|
+
handleFinalStatus("TIMEOUT", "La v\xE9rification du paiement a expir\xE9. Veuillez v\xE9rifier votre compte.", "TIMEOUT");
|
|
564
|
+
} else {
|
|
565
|
+
timeoutId = setTimeout(checkStatus, 1e4);
|
|
566
|
+
}
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
} catch (e) {
|
|
570
|
+
if (checkCount >= maxChecks) {
|
|
571
|
+
handleFinalStatus("TIMEOUT", "La v\xE9rification du paiement a \xE9chou\xE9 apr\xE8s plusieurs tentatives.", "TIMEOUT");
|
|
572
|
+
} else {
|
|
573
|
+
timeoutId = setTimeout(checkStatus, 1e4);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
checkStatus();
|
|
578
|
+
return () => {
|
|
579
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
580
|
+
props.isCallbackCalledRef.current = true;
|
|
581
|
+
};
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// src/components/PaymentModal.tsx
|
|
585
|
+
var PaymentModal = ({ isOpen, onClose }) => {
|
|
586
|
+
var _a;
|
|
587
|
+
const { paymentConfig } = useFeexPay();
|
|
588
|
+
const [paymentMethod, setPaymentMethod] = useState4(() => {
|
|
589
|
+
if (paymentConfig.case && ["MOBILE", "CARD", "WALLET"].includes(paymentConfig.case)) {
|
|
590
|
+
return paymentConfig.case;
|
|
591
|
+
}
|
|
592
|
+
return "MOBILE";
|
|
593
|
+
});
|
|
594
|
+
const [country, setCountry] = useState4("BENIN");
|
|
595
|
+
const [network, setNetwork] = useState4("MTN");
|
|
596
|
+
const [phoneNumber, setPhoneNumber] = useState4("");
|
|
597
|
+
const [fullName, setFullName] = useState4("");
|
|
598
|
+
const [email, setEmail] = useState4("");
|
|
599
|
+
const [typeCard, setTypeCard] = useState4("VISA");
|
|
600
|
+
const [baseAmount, setBaseAmount] = useState4(0);
|
|
601
|
+
const [total, setTotal] = useState4(0);
|
|
602
|
+
const [fees, setFees] = useState4(0);
|
|
603
|
+
const [feePercentage, setFeePercentage] = useState4(0);
|
|
604
|
+
const [transactionReference, setTransactionReference] = useState4("");
|
|
605
|
+
const [statusModalOpen, setStatusModalOpen] = useState4(false);
|
|
606
|
+
const [paymentStatus, setPaymentStatus] = useState4("PENDING");
|
|
607
|
+
const [statusMessage, setStatusMessage] = useState4("");
|
|
608
|
+
const [isLoading, setIsLoading] = useState4(false);
|
|
609
|
+
const [otpModalOpen, setOtpModalOpen] = useState4(false);
|
|
610
|
+
const [pendingReference, setPendingReference] = useState4("");
|
|
611
|
+
const [iframeUrl, setIframeUrl] = useState4(null);
|
|
612
|
+
const isCallbackCalledRef = useRef(false);
|
|
613
|
+
const otpInputRef = useRef(null);
|
|
614
|
+
useEffect3(() => {
|
|
615
|
+
if (!paymentConfig.defaultValueField) return;
|
|
616
|
+
const { country_iban, name, email: emailDef } = paymentConfig.defaultValueField;
|
|
617
|
+
const countryMap = {
|
|
618
|
+
BJ: "BENIN",
|
|
619
|
+
CI: "COTE_D_IVOIRE",
|
|
620
|
+
SN: "SENEGAL",
|
|
621
|
+
TG: "TOGO",
|
|
622
|
+
BF: "BURKINA_FASO"
|
|
623
|
+
};
|
|
624
|
+
if (country_iban && countryMap[country_iban]) setCountry(countryMap[country_iban]);
|
|
625
|
+
if (name) setFullName(name);
|
|
626
|
+
if (emailDef) setEmail(emailDef);
|
|
627
|
+
}, [paymentConfig.defaultValueField]);
|
|
628
|
+
useEffect3(() => {
|
|
629
|
+
if (paymentConfig.first_name) setFullName(paymentConfig.first_name);
|
|
630
|
+
if (paymentConfig.email) setEmail(paymentConfig.email);
|
|
631
|
+
}, [paymentConfig.first_name, paymentConfig.email]);
|
|
632
|
+
const calculateFeesLocally = useCallback(
|
|
633
|
+
(amt, c, n, method) => {
|
|
634
|
+
var _a2, _b;
|
|
635
|
+
const currentMethod = method || paymentMethod;
|
|
636
|
+
const calculated = calculateFees(amt, c, n, currentMethod, typeCard);
|
|
637
|
+
setFees(calculated);
|
|
638
|
+
setTotal(amt + calculated);
|
|
639
|
+
setBaseAmount(amt);
|
|
640
|
+
if (currentMethod === "CARD") {
|
|
641
|
+
setFeePercentage(4.5);
|
|
642
|
+
} else {
|
|
643
|
+
const pct = (_b = (_a2 = NETWORK_FEES[c]) == null ? void 0 : _a2[n]) != null ? _b : 0;
|
|
644
|
+
setFeePercentage(pct * 100);
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
[paymentMethod, typeCard]
|
|
648
|
+
);
|
|
649
|
+
const fetchTransactionDetails = useCallback(
|
|
650
|
+
(amt, c, n, method) => __async(null, null, function* () {
|
|
651
|
+
var _a2, _b;
|
|
652
|
+
try {
|
|
653
|
+
const details = yield getTransactionDetails({
|
|
654
|
+
network: n,
|
|
655
|
+
country: c,
|
|
656
|
+
amount: amt,
|
|
657
|
+
id: paymentConfig.id,
|
|
658
|
+
token: paymentConfig.token,
|
|
659
|
+
callback_info: paymentConfig.callback_info || {}
|
|
660
|
+
});
|
|
661
|
+
if (details == null ? void 0 : details.iffees) {
|
|
662
|
+
if (details.total !== void 0) {
|
|
663
|
+
setFees(details.total - amt);
|
|
664
|
+
setTotal(details.total);
|
|
665
|
+
} else {
|
|
666
|
+
calculateFeesLocally(amt, c, n, method);
|
|
667
|
+
}
|
|
668
|
+
const currentMethod = method || paymentMethod;
|
|
669
|
+
if (currentMethod === "CARD") {
|
|
670
|
+
setFeePercentage(4.5);
|
|
671
|
+
} else {
|
|
672
|
+
setFeePercentage(((_b = (_a2 = NETWORK_FEES[c]) == null ? void 0 : _a2[n]) != null ? _b : 0) * 100);
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
setFees(0);
|
|
676
|
+
setTotal(amt);
|
|
677
|
+
setFeePercentage(0);
|
|
678
|
+
}
|
|
679
|
+
setBaseAmount(amt);
|
|
680
|
+
} catch (e) {
|
|
681
|
+
calculateFeesLocally(amt, c, n, method);
|
|
682
|
+
}
|
|
683
|
+
}),
|
|
684
|
+
[paymentMethod, paymentConfig.id, paymentConfig.token, calculateFeesLocally]
|
|
685
|
+
);
|
|
686
|
+
useEffect3(() => {
|
|
687
|
+
if (paymentConfig.amount) {
|
|
688
|
+
calculateFeesLocally(paymentConfig.amount, country, network);
|
|
689
|
+
}
|
|
690
|
+
}, []);
|
|
691
|
+
useEffect3(() => {
|
|
692
|
+
if (paymentMethod === "WALLET") {
|
|
693
|
+
if (country === "BENIN") {
|
|
694
|
+
setNetwork("CORIS");
|
|
695
|
+
} else if (country === "COTE_D_IVOIRE") {
|
|
696
|
+
setNetwork("WAVE");
|
|
697
|
+
} else {
|
|
698
|
+
setCountry("BENIN");
|
|
699
|
+
setNetwork("CORIS");
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}, []);
|
|
703
|
+
const handleNetworkChange = (n) => {
|
|
704
|
+
setNetwork(n);
|
|
705
|
+
if (paymentConfig.amount) fetchTransactionDetails(paymentConfig.amount, country, n);
|
|
706
|
+
};
|
|
707
|
+
const handleCountryChange = (c) => {
|
|
708
|
+
setCountry(c);
|
|
709
|
+
if (paymentMethod === "WALLET") {
|
|
710
|
+
const walletNetwork = c === "COTE_D_IVOIRE" ? "WAVE" : "CORIS";
|
|
711
|
+
setNetwork(walletNetwork);
|
|
712
|
+
if (paymentConfig.amount) fetchTransactionDetails(paymentConfig.amount, c, walletNetwork);
|
|
713
|
+
} else {
|
|
714
|
+
const available = getNetworksForCountry(c);
|
|
715
|
+
setNetwork(available[0]);
|
|
716
|
+
if (paymentConfig.amount) fetchTransactionDetails(paymentConfig.amount, c, available[0]);
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
const resetAllFields = () => {
|
|
720
|
+
setFullName(paymentConfig.first_name || "");
|
|
721
|
+
setEmail(paymentConfig.email || "");
|
|
722
|
+
setPhoneNumber("");
|
|
723
|
+
setTypeCard("VISA");
|
|
724
|
+
};
|
|
725
|
+
const handlePaymentMethodChange = (method) => {
|
|
726
|
+
resetAllFields();
|
|
727
|
+
setFees(0);
|
|
728
|
+
setTotal(paymentConfig.amount || 0);
|
|
729
|
+
setFeePercentage(0);
|
|
730
|
+
setPaymentMethod(method);
|
|
731
|
+
if (method === "WALLET") {
|
|
732
|
+
const walletNetwork = country === "COTE_D_IVOIRE" ? "WAVE" : "CORIS";
|
|
733
|
+
if (country !== "BENIN" && country !== "COTE_D_IVOIRE") {
|
|
734
|
+
setCountry("BENIN");
|
|
735
|
+
setNetwork("CORIS");
|
|
736
|
+
} else {
|
|
737
|
+
setNetwork(walletNetwork);
|
|
738
|
+
}
|
|
739
|
+
} else if (method === "MOBILE") {
|
|
740
|
+
const available = getNetworksForCountry(country);
|
|
741
|
+
if (!available.includes(network)) setNetwork(available[0]);
|
|
742
|
+
if (paymentConfig.amount) fetchTransactionDetails(paymentConfig.amount, country, network, method);
|
|
743
|
+
} else if (method === "CARD" && paymentConfig.amount) {
|
|
744
|
+
fetchTransactionDetails(paymentConfig.amount, country, network, method);
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
const handlePhoneChange = (e) => {
|
|
748
|
+
const value = e.target.value;
|
|
749
|
+
if (country === "BENIN" && paymentMethod !== "WALLET" && value.length >= 4) {
|
|
750
|
+
const prefix = value.substring(0, 4);
|
|
751
|
+
const detected = getNetworkByPhonePrefix(prefix, network);
|
|
752
|
+
if (detected) setNetwork(detected);
|
|
753
|
+
}
|
|
754
|
+
setPhoneNumber(value);
|
|
755
|
+
};
|
|
756
|
+
const getFormattedPhone = () => {
|
|
757
|
+
if (!phoneNumber) return phoneNumber;
|
|
758
|
+
return getFormattedPhoneNumber(phoneNumber, country);
|
|
759
|
+
};
|
|
760
|
+
const validateForm = () => {
|
|
761
|
+
const hidden2 = paymentConfig.fields_to_hide || [];
|
|
762
|
+
if (paymentMethod === "MOBILE" || paymentMethod === "WALLET") {
|
|
763
|
+
if (!hidden2.includes("name") && !fullName.trim()) {
|
|
764
|
+
setStatusMessage("Veuillez entrer votre nom complet");
|
|
765
|
+
setPaymentStatus("FAILED");
|
|
766
|
+
setStatusModalOpen(true);
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
if (!hidden2.includes("email") && (!email.trim() || !email.includes("@"))) {
|
|
770
|
+
setStatusMessage("Veuillez entrer une adresse email valide");
|
|
771
|
+
setPaymentStatus("FAILED");
|
|
772
|
+
setStatusModalOpen(true);
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
if (!phoneNumber.trim() || phoneNumber.length < 4) {
|
|
776
|
+
setStatusMessage("Veuillez entrer un num\xE9ro de t\xE9l\xE9phone valide");
|
|
777
|
+
setPaymentStatus("FAILED");
|
|
778
|
+
setStatusModalOpen(true);
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
781
|
+
if (paymentMethod === "WALLET" && country !== "BENIN" && country !== "COTE_D_IVOIRE") {
|
|
782
|
+
setStatusMessage("Seuls le B\xE9nin (Coris) et la C\xF4te d'Ivoire (Wave) sont support\xE9s pour les paiements Wallet");
|
|
783
|
+
setPaymentStatus("FAILED");
|
|
784
|
+
setStatusModalOpen(true);
|
|
785
|
+
return false;
|
|
786
|
+
}
|
|
787
|
+
} else if (paymentMethod === "CARD") {
|
|
788
|
+
if (!fullName || fullName.trim().split(" ").length < 2) {
|
|
789
|
+
setStatusMessage("Veuillez entrer votre nom et pr\xE9nom complets");
|
|
790
|
+
setPaymentStatus("FAILED");
|
|
791
|
+
setStatusModalOpen(true);
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
if (!email || !email.includes("@")) {
|
|
795
|
+
setStatusMessage("Veuillez entrer une adresse email valide");
|
|
796
|
+
setPaymentStatus("FAILED");
|
|
797
|
+
setStatusModalOpen(true);
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
if (!phoneNumber) {
|
|
801
|
+
setStatusMessage("Veuillez entrer un num\xE9ro de t\xE9l\xE9phone valide");
|
|
802
|
+
setPaymentStatus("FAILED");
|
|
803
|
+
setStatusModalOpen(true);
|
|
804
|
+
return false;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return true;
|
|
808
|
+
};
|
|
809
|
+
const buildHandlerProps = () => ({
|
|
810
|
+
phoneNumber,
|
|
811
|
+
baseAmount,
|
|
812
|
+
network,
|
|
813
|
+
country,
|
|
814
|
+
paymentConfig,
|
|
815
|
+
transactionReference,
|
|
816
|
+
generateRandomId,
|
|
817
|
+
fullName,
|
|
818
|
+
email,
|
|
819
|
+
isCallbackCalledRef,
|
|
820
|
+
setStateCallbacks: {
|
|
821
|
+
setTransactionReference,
|
|
822
|
+
setPaymentStatus,
|
|
823
|
+
setStatusMessage,
|
|
824
|
+
setStatusModalOpen,
|
|
825
|
+
setIsLoading
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
const handleStatusCheck = (ref) => {
|
|
829
|
+
startStatusCheck(ref, buildHandlerProps(), network, getFormattedPhone);
|
|
830
|
+
};
|
|
831
|
+
const handlePaymentSubmit = (e) => __async(null, null, function* () {
|
|
832
|
+
var _a2;
|
|
833
|
+
e.preventDefault();
|
|
834
|
+
if (!validateForm()) return;
|
|
835
|
+
isCallbackCalledRef.current = false;
|
|
836
|
+
setIsLoading(true);
|
|
837
|
+
const networkApiCode = getNetworkApiCode(country, network);
|
|
838
|
+
const iframeNetworks = ["WAVE CI", "ORANGE CI", "MOOV BF", "ORANGE BF"];
|
|
839
|
+
const dedicatedSNNetworks = ["ORANGE SN", "WAVE SN", "FREE SN"];
|
|
840
|
+
const isSNDedicated = dedicatedSNNetworks.includes(networkApiCode);
|
|
841
|
+
const isIframe = iframeNetworks.includes(networkApiCode);
|
|
842
|
+
try {
|
|
843
|
+
if (paymentMethod === "MOBILE" && (isIframe || isSNDedicated)) {
|
|
844
|
+
const response = yield requestToPay({
|
|
845
|
+
phoneNumber: getFormattedPhone(),
|
|
846
|
+
amount: baseAmount,
|
|
847
|
+
network,
|
|
848
|
+
country,
|
|
849
|
+
description: paymentConfig.description || "",
|
|
850
|
+
customId: paymentConfig.customId || "",
|
|
851
|
+
id: paymentConfig.id,
|
|
852
|
+
token: paymentConfig.token,
|
|
853
|
+
currency: paymentConfig.currency || "XOF",
|
|
854
|
+
callback_info: paymentConfig.callback_info || {},
|
|
855
|
+
first_name: fullName || "",
|
|
856
|
+
email: email || "",
|
|
857
|
+
otp: ((_a2 = otpInputRef.current) == null ? void 0 : _a2.value) || ""
|
|
858
|
+
});
|
|
859
|
+
if (response.payment_url || response.order_id) {
|
|
860
|
+
setIframeUrl(response.payment_url || null);
|
|
861
|
+
setIsLoading(false);
|
|
862
|
+
}
|
|
863
|
+
if (response.reference) {
|
|
864
|
+
setTransactionReference(response.reference);
|
|
865
|
+
handleStatusCheck(response.reference);
|
|
866
|
+
}
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
if (paymentMethod === "MOBILE") {
|
|
870
|
+
const response = yield requestToPay({
|
|
871
|
+
phoneNumber: getFormattedPhone(),
|
|
872
|
+
amount: baseAmount,
|
|
873
|
+
network,
|
|
874
|
+
country,
|
|
875
|
+
description: paymentConfig.description || "",
|
|
876
|
+
customId: paymentConfig.customId || generateRandomId(),
|
|
877
|
+
id: paymentConfig.id,
|
|
878
|
+
token: paymentConfig.token,
|
|
879
|
+
currency: paymentConfig.currency || "XOF",
|
|
880
|
+
callback_info: paymentConfig.callback_info || {},
|
|
881
|
+
first_name: fullName,
|
|
882
|
+
email
|
|
883
|
+
});
|
|
884
|
+
if (response.statusCode === "10") {
|
|
885
|
+
setPaymentStatus("INSUFFICIENT_FUNDS");
|
|
886
|
+
setStatusMessage("Fonds insuffisants. Veuillez v\xE9rifier votre solde et r\xE9essayer.");
|
|
887
|
+
setStatusModalOpen(true);
|
|
888
|
+
setIsLoading(false);
|
|
889
|
+
if (paymentConfig.error_callback_url)
|
|
890
|
+
window.location.href = `${paymentConfig.error_callback_url}?ref=${response.reference}`;
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
if (response.statusCode === "92") {
|
|
894
|
+
setPaymentStatus("FAILED");
|
|
895
|
+
setStatusMessage("La transaction a \xE9t\xE9 annul\xE9e. Veuillez r\xE9essayer.");
|
|
896
|
+
setStatusModalOpen(true);
|
|
897
|
+
setIsLoading(false);
|
|
898
|
+
if (paymentConfig.error_callback_url)
|
|
899
|
+
window.location.href = `${paymentConfig.error_callback_url}?ref=${response.reference}`;
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
if (response.reference) {
|
|
903
|
+
setTransactionReference(response.reference);
|
|
904
|
+
handleStatusCheck(response.reference);
|
|
905
|
+
} else {
|
|
906
|
+
setPaymentStatus("FAILED");
|
|
907
|
+
setStatusMessage("La demande de paiement a \xE9chou\xE9. Veuillez r\xE9essayer.");
|
|
908
|
+
setStatusModalOpen(true);
|
|
909
|
+
setIsLoading(false);
|
|
910
|
+
}
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (paymentMethod === "WALLET") {
|
|
914
|
+
if (country === "BENIN" && network === "CORIS") {
|
|
915
|
+
const nameParts = fullName.split(" ");
|
|
916
|
+
const formattedPhone = phoneNumber.startsWith("+229") ? phoneNumber : `+229${phoneNumber}`;
|
|
917
|
+
const response2 = yield requestWalletCorisPayment({
|
|
918
|
+
phoneNumber: formattedPhone,
|
|
919
|
+
amount: baseAmount,
|
|
920
|
+
id: paymentConfig.id,
|
|
921
|
+
email,
|
|
922
|
+
first_name: nameParts[0] || "",
|
|
923
|
+
description: paymentConfig.description || "Paiement via FeexPay",
|
|
924
|
+
token: paymentConfig.token,
|
|
925
|
+
currency: paymentConfig.currency || "XOF",
|
|
926
|
+
callback_info: paymentConfig.callback_info || {}
|
|
927
|
+
});
|
|
928
|
+
if (response2.statusCode === "201") {
|
|
929
|
+
setPendingReference(response2.reference);
|
|
930
|
+
setOtpModalOpen(true);
|
|
931
|
+
setIsLoading(false);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
setPaymentStatus("FAILED");
|
|
935
|
+
setStatusMessage("La demande de paiement a \xE9chou\xE9. Veuillez r\xE9essayer.");
|
|
936
|
+
setStatusModalOpen(true);
|
|
937
|
+
setIsLoading(false);
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const response = yield requestToPay({
|
|
941
|
+
phoneNumber: getFormattedPhone(),
|
|
942
|
+
amount: baseAmount,
|
|
943
|
+
network,
|
|
944
|
+
country,
|
|
945
|
+
description: paymentConfig.description || "",
|
|
946
|
+
customId: paymentConfig.customId || generateRandomId(),
|
|
947
|
+
id: paymentConfig.id,
|
|
948
|
+
token: paymentConfig.token,
|
|
949
|
+
currency: paymentConfig.currency || "XOF",
|
|
950
|
+
callback_info: paymentConfig.callback_info || {},
|
|
951
|
+
first_name: fullName,
|
|
952
|
+
email
|
|
953
|
+
});
|
|
954
|
+
if (response.payment_url) {
|
|
955
|
+
setIframeUrl(response.payment_url);
|
|
956
|
+
setIsLoading(false);
|
|
957
|
+
}
|
|
958
|
+
if (response.reference) {
|
|
959
|
+
setTransactionReference(response.reference);
|
|
960
|
+
handleStatusCheck(response.reference);
|
|
961
|
+
}
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
setIsLoading(false);
|
|
965
|
+
} catch (e2) {
|
|
966
|
+
setPaymentStatus("FAILED");
|
|
967
|
+
setStatusMessage("Une erreur est survenue lors du traitement du paiement. Veuillez r\xE9essayer.");
|
|
968
|
+
setStatusModalOpen(true);
|
|
969
|
+
setIsLoading(false);
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
const handleOTPSubmit = (otp) => __async(null, null, function* () {
|
|
973
|
+
setIsLoading(true);
|
|
974
|
+
const nameParts = fullName.split(" ");
|
|
975
|
+
const formattedPhone = phoneNumber.startsWith("+229") ? phoneNumber : `+229${phoneNumber}`;
|
|
976
|
+
try {
|
|
977
|
+
const response = yield requestWalletCorisPayment({
|
|
978
|
+
phoneNumber: formattedPhone,
|
|
979
|
+
amount: baseAmount,
|
|
980
|
+
id: paymentConfig.id,
|
|
981
|
+
email,
|
|
982
|
+
first_name: nameParts[0] || "",
|
|
983
|
+
description: paymentConfig.description || "Paiement via FeexPay",
|
|
984
|
+
reference: pendingReference,
|
|
985
|
+
otp,
|
|
986
|
+
token: paymentConfig.token,
|
|
987
|
+
currency: paymentConfig.currency || "XOF",
|
|
988
|
+
callback_info: paymentConfig.callback_info || {}
|
|
989
|
+
});
|
|
990
|
+
setOtpModalOpen(false);
|
|
991
|
+
if (response.reference) {
|
|
992
|
+
if (response.status === "SUCCESSFUL" || response.status === "SUCCESS") {
|
|
993
|
+
setPaymentStatus("SUCCESSFUL");
|
|
994
|
+
setStatusMessage("Paiement effectu\xE9 avec succ\xE8s !");
|
|
995
|
+
setStatusModalOpen(true);
|
|
996
|
+
setIsLoading(false);
|
|
997
|
+
if (paymentConfig.callback_url)
|
|
998
|
+
setTimeout(() => window.location.href = `${paymentConfig.callback_url}?ref=${response.reference}`, 2e3);
|
|
999
|
+
} else if (response.status === "PENDING") {
|
|
1000
|
+
setTransactionReference(response.reference);
|
|
1001
|
+
handleStatusCheck(response.reference);
|
|
1002
|
+
} else {
|
|
1003
|
+
setPaymentStatus("FAILED");
|
|
1004
|
+
setStatusMessage(response.message || "La transaction a \xE9chou\xE9. Veuillez r\xE9essayer.");
|
|
1005
|
+
setStatusModalOpen(true);
|
|
1006
|
+
setIsLoading(false);
|
|
1007
|
+
}
|
|
1008
|
+
} else {
|
|
1009
|
+
setPaymentStatus("FAILED");
|
|
1010
|
+
setStatusMessage(response.message || "La confirmation du paiement a \xE9chou\xE9.");
|
|
1011
|
+
setStatusModalOpen(true);
|
|
1012
|
+
setIsLoading(false);
|
|
1013
|
+
}
|
|
1014
|
+
} catch (e) {
|
|
1015
|
+
setPaymentStatus("FAILED");
|
|
1016
|
+
setStatusMessage("Une erreur est survenue lors de la confirmation. Veuillez r\xE9essayer.");
|
|
1017
|
+
setStatusModalOpen(true);
|
|
1018
|
+
setIsLoading(false);
|
|
1019
|
+
setOtpModalOpen(false);
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
if (!isOpen) return null;
|
|
1023
|
+
const hidden = paymentConfig.fields_to_hide || [];
|
|
1024
|
+
const showPersonalInfo = paymentMethod !== "CARD" && !(hidden.includes("email") && hidden.includes("name"));
|
|
1025
|
+
const paymentTabs = [
|
|
1026
|
+
{
|
|
1027
|
+
label: "Mobile Money",
|
|
1028
|
+
value: "MOBILE",
|
|
1029
|
+
icon: /* @__PURE__ */ React7.createElement("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#D45D00", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React7.createElement("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", ry: "2" }), /* @__PURE__ */ React7.createElement("line", { x1: "12", y1: "18", x2: "12", y2: "18" }))
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
label: "Carte Bancaire",
|
|
1033
|
+
value: "CARD",
|
|
1034
|
+
icon: /* @__PURE__ */ React7.createElement("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React7.createElement("path", { d: "M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" }), /* @__PURE__ */ React7.createElement("path", { fillRule: "evenodd", d: "M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z", clipRule: "evenodd" }))
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
label: "Wallet",
|
|
1038
|
+
value: "WALLET",
|
|
1039
|
+
icon: /* @__PURE__ */ React7.createElement("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React7.createElement("path", { fillRule: "evenodd", d: "M10 2a1 1 0 00-1 1v1a1 1 0 002 0V3a1 1 0 00-1-1zM4 4h3a3 3 0 006 0h3a2 2 0 012 2v9a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2zm2.5 7a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm2.45 4a2.5 2.5 0 10-4.9 0h4.9zM12 9a1 1 0 100 2h3a1 1 0 100-2h-3zm-1 4a1 1 0 011-1h2a1 1 0 110 2h-2a1 1 0 01-1-1z", clipRule: "evenodd" }))
|
|
1040
|
+
}
|
|
1041
|
+
];
|
|
1042
|
+
return /* @__PURE__ */ React7.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50 overflow-hidden" }, /* @__PURE__ */ React7.createElement("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-md relative max-h-[90vh] flex flex-col" }, iframeUrl && /* @__PURE__ */ React7.createElement("div", { className: "absolute inset-0 bg-white z-10 rounded-lg overflow-hidden" }, /* @__PURE__ */ React7.createElement(
|
|
1043
|
+
"button",
|
|
1044
|
+
{
|
|
1045
|
+
onClick: () => setIframeUrl(null),
|
|
1046
|
+
className: "absolute top-2 right-2 z-20 bg-gray-200 text-gray-800 rounded-full p-1 hover:bg-gray-300 focus:outline-none",
|
|
1047
|
+
"aria-label": "Fermer la passerelle de paiement"
|
|
1048
|
+
},
|
|
1049
|
+
/* @__PURE__ */ React7.createElement("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React7.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }))
|
|
1050
|
+
), /* @__PURE__ */ React7.createElement("iframe", { src: iframeUrl, className: "w-full h-full border-0", title: "Payment Gateway", allow: "payment" })), /* @__PURE__ */ React7.createElement(HeaderBar_default, { id: paymentConfig.id, onClose }), /* @__PURE__ */ React7.createElement("div", { className: "p-6 overflow-y-auto flex-grow" }, /* @__PURE__ */ React7.createElement("p", { className: "text-sm text-gray-600 text-center mb-4" }, "Remplissez les champs suivants pour effectuer votre paiement"), !paymentConfig.case && /* @__PURE__ */ React7.createElement("div", { className: "flex justify-center mb-6 border-b pb-4 w-full gap-2" }, paymentTabs.map(({ label, value, icon }) => /* @__PURE__ */ React7.createElement(
|
|
1051
|
+
"div",
|
|
1052
|
+
{
|
|
1053
|
+
key: value,
|
|
1054
|
+
onClick: () => handlePaymentMethodChange(value),
|
|
1055
|
+
className: `flex flex-col items-center flex-1 max-w-[120px] px-3 py-2 cursor-pointer rounded border ${paymentMethod === value ? "bg-[#fff7ed] border-[#D45D00]" : "bg-white border-gray-300 hover:border-[#D45D00]"}`
|
|
1056
|
+
},
|
|
1057
|
+
/* @__PURE__ */ React7.createElement("div", { className: "w-8 h-8 rounded-full flex items-center justify-center mb-1" }, icon),
|
|
1058
|
+
/* @__PURE__ */ React7.createElement("span", { className: "text-xs font-medium text-center" }, label)
|
|
1059
|
+
))), /* @__PURE__ */ React7.createElement("div", { className: "space-y-6" }, showPersonalInfo && /* @__PURE__ */ React7.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React7.createElement("h2", { className: "font-bold text-gray-800 mb-2 flex items-center" }, /* @__PURE__ */ React7.createElement("span", { className: "bg-gray-800 text-white rounded-full w-5 h-5 inline-flex items-center justify-center text-xs mr-2" }, "1"), "Informations Personnelles"), !hidden.includes("name") && /* @__PURE__ */ React7.createElement(
|
|
1060
|
+
"input",
|
|
1061
|
+
{
|
|
1062
|
+
type: "text",
|
|
1063
|
+
placeholder: "Nom et Pr\xE9noms",
|
|
1064
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1065
|
+
value: fullName,
|
|
1066
|
+
onChange: (e) => setFullName(e.target.value)
|
|
1067
|
+
}
|
|
1068
|
+
), !hidden.includes("email") && /* @__PURE__ */ React7.createElement(
|
|
1069
|
+
"input",
|
|
1070
|
+
{
|
|
1071
|
+
type: "email",
|
|
1072
|
+
placeholder: "Email",
|
|
1073
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1074
|
+
value: email,
|
|
1075
|
+
onChange: (e) => setEmail(e.target.value)
|
|
1076
|
+
}
|
|
1077
|
+
)), /* @__PURE__ */ React7.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React7.createElement("h2", { className: "font-bold text-gray-800 mb-2 flex items-center" }, /* @__PURE__ */ React7.createElement("span", { className: "bg-gray-800 text-white rounded-full w-5 h-5 inline-flex items-center justify-center text-xs mr-2" }, paymentMethod === "CARD" || hidden.includes("email") && hidden.includes("name") ? "1" : "2"), paymentMethod === "CARD" ? "Paiement par Carte Bancaire" : "M\xE9thodes de paiement"), paymentMethod === "MOBILE" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React7.createElement(CountrySelector_default, { selectedCountry: country, onChange: handleCountryChange }), /* @__PURE__ */ React7.createElement(NetworkSelector_default, { selectedNetwork: network, onChange: handleNetworkChange, country })), /* @__PURE__ */ React7.createElement("div", { className: "flex" }, /* @__PURE__ */ React7.createElement("div", { className: "bg-gray-100 px-3 py-2 border border-r-0 rounded-l-md flex items-center justify-center" }, /* @__PURE__ */ React7.createElement("span", { className: "text-gray-600 text-xs" }, getPrefixFromCountry(country))), /* @__PURE__ */ React7.createElement(
|
|
1078
|
+
"input",
|
|
1079
|
+
{
|
|
1080
|
+
type: "tel",
|
|
1081
|
+
placeholder: "Num\xE9ro sans indicatif",
|
|
1082
|
+
className: "flex-1 px-2 py-2 border rounded-r-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1083
|
+
value: phoneNumber,
|
|
1084
|
+
onChange: handlePhoneChange
|
|
1085
|
+
}
|
|
1086
|
+
)), country === "SENEGAL" && network === "ORANGE" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
|
|
1087
|
+
"input",
|
|
1088
|
+
{
|
|
1089
|
+
type: "text",
|
|
1090
|
+
ref: otpInputRef,
|
|
1091
|
+
placeholder: "Code OTP de validation",
|
|
1092
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs"
|
|
1093
|
+
}
|
|
1094
|
+
), /* @__PURE__ */ React7.createElement("span", { className: "text-xs text-gray-900" }, "Code obtenu en tapant *144*391# sur votre t\xE9l\xE9phone"))), paymentMethod === "CARD" && /* @__PURE__ */ React7.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React7.createElement("p", { className: "text-red-500 text-sm" }, "Les paiements par cartes sont momentan\xE9ment indisponibles."), /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Pr\xE9nom"), /* @__PURE__ */ React7.createElement(
|
|
1095
|
+
"input",
|
|
1096
|
+
{
|
|
1097
|
+
type: "text",
|
|
1098
|
+
placeholder: "Pr\xE9nom",
|
|
1099
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1100
|
+
value: fullName.split(" ")[0] || "",
|
|
1101
|
+
onChange: (e) => {
|
|
1102
|
+
const lastName = fullName.split(" ").slice(1).join(" ");
|
|
1103
|
+
setFullName(`${e.target.value} ${lastName}`.trim());
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
)), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Nom"), /* @__PURE__ */ React7.createElement(
|
|
1107
|
+
"input",
|
|
1108
|
+
{
|
|
1109
|
+
type: "text",
|
|
1110
|
+
placeholder: "Nom",
|
|
1111
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1112
|
+
value: fullName.split(" ").slice(1).join(" ") || "",
|
|
1113
|
+
onChange: (e) => {
|
|
1114
|
+
const firstName = fullName.split(" ")[0] || "";
|
|
1115
|
+
setFullName(`${firstName} ${e.target.value}`.trim());
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Email"), /* @__PURE__ */ React7.createElement(
|
|
1119
|
+
"input",
|
|
1120
|
+
{
|
|
1121
|
+
type: "email",
|
|
1122
|
+
placeholder: "exemple@email.com",
|
|
1123
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1124
|
+
value: email,
|
|
1125
|
+
onChange: (e) => setEmail(e.target.value)
|
|
1126
|
+
}
|
|
1127
|
+
)), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "T\xE9l\xE9phone"), /* @__PURE__ */ React7.createElement(
|
|
1128
|
+
"input",
|
|
1129
|
+
{
|
|
1130
|
+
type: "tel",
|
|
1131
|
+
placeholder: "Num\xE9ro avec indicatif",
|
|
1132
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1133
|
+
value: phoneNumber,
|
|
1134
|
+
onChange: (e) => setPhoneNumber(e.target.value)
|
|
1135
|
+
}
|
|
1136
|
+
)), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Type de carte"), /* @__PURE__ */ React7.createElement(
|
|
1137
|
+
"select",
|
|
1138
|
+
{
|
|
1139
|
+
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1140
|
+
value: typeCard,
|
|
1141
|
+
onChange: (e) => setTypeCard(e.target.value)
|
|
1142
|
+
},
|
|
1143
|
+
/* @__PURE__ */ React7.createElement("option", { value: "VISA" }, "VISA"),
|
|
1144
|
+
/* @__PURE__ */ React7.createElement("option", { value: "MASTERCARD" }, "MASTERCARD")
|
|
1145
|
+
))), paymentMethod === "WALLET" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React7.createElement("div", { className: "relative" }, /* @__PURE__ */ React7.createElement(
|
|
1146
|
+
"select",
|
|
1147
|
+
{
|
|
1148
|
+
value: country,
|
|
1149
|
+
onChange: (e) => handleCountryChange(e.target.value),
|
|
1150
|
+
className: "block w-full px-2 py-2 pr-8 border rounded-md appearance-none focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs"
|
|
1151
|
+
},
|
|
1152
|
+
/* @__PURE__ */ React7.createElement("option", { value: "BENIN" }, "\u{1F1E7}\u{1F1EF} B\xE9nin"),
|
|
1153
|
+
/* @__PURE__ */ React7.createElement("option", { value: "COTE_D_IVOIRE" }, "\u{1F1E8}\u{1F1EE} C\xF4te d'Ivoire")
|
|
1154
|
+
), /* @__PURE__ */ React7.createElement("div", { className: "pointer-events-none absolute inset-y-0 right-2 flex items-center" }, /* @__PURE__ */ React7.createElement("svg", { className: "h-4 w-4 text-gray-400", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React7.createElement("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" })))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(
|
|
1155
|
+
"select",
|
|
1156
|
+
{
|
|
1157
|
+
value: network,
|
|
1158
|
+
disabled: true,
|
|
1159
|
+
className: "block w-full px-2 py-2 pr-8 border rounded-md appearance-none focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs bg-gray-50"
|
|
1160
|
+
},
|
|
1161
|
+
country === "BENIN" && /* @__PURE__ */ React7.createElement("option", { value: "CORIS" }, "CORIS"),
|
|
1162
|
+
country === "COTE_D_IVOIRE" && /* @__PURE__ */ React7.createElement("option", { value: "WAVE" }, "WAVE")
|
|
1163
|
+
))), /* @__PURE__ */ React7.createElement("div", { className: "flex" }, /* @__PURE__ */ React7.createElement("div", { className: "bg-gray-100 px-3 py-2 border border-r-0 rounded-l-md flex items-center justify-center" }, /* @__PURE__ */ React7.createElement("span", { className: "text-gray-600 text-sm" }, country === "BENIN" ? "+229" : country === "COTE_D_IVOIRE" ? "+225" : "")), /* @__PURE__ */ React7.createElement(
|
|
1164
|
+
"input",
|
|
1165
|
+
{
|
|
1166
|
+
type: "tel",
|
|
1167
|
+
placeholder: "Num\xE9ro sans indicatif",
|
|
1168
|
+
className: "flex-1 px-2 py-2 border rounded-r-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
|
|
1169
|
+
value: phoneNumber,
|
|
1170
|
+
onChange: handlePhoneChange
|
|
1171
|
+
}
|
|
1172
|
+
))), /* @__PURE__ */ React7.createElement("div", { className: "bg-gray-50 p-4 rounded-md" }, /* @__PURE__ */ React7.createElement("div", { className: "flex justify-between mb-1" }, /* @__PURE__ */ React7.createElement("span", { className: "text-sm text-gray-600" }, "Montant :"), /* @__PURE__ */ React7.createElement("span", { className: "text-sm font-medium" }, (_a = paymentConfig.amount) == null ? void 0 : _a.toLocaleString("fr-FR"), " ", paymentConfig.currency || "XOF")), /* @__PURE__ */ React7.createElement("div", { className: "flex justify-between mb-1" }, /* @__PURE__ */ React7.createElement("span", { className: "text-sm text-gray-600" }, "Frais* :"), /* @__PURE__ */ React7.createElement("span", { className: "text-sm font-medium" }, fees > 0 ? `${fees.toLocaleString("fr-FR")} ${paymentConfig.currency || "XOF"}` : `0 ${paymentConfig.currency || "XOF"}`)), /* @__PURE__ */ React7.createElement("div", { className: "flex justify-between font-bold" }, /* @__PURE__ */ React7.createElement("span", null, "Montant total \xE0 payer :"), /* @__PURE__ */ React7.createElement("span", null, total.toLocaleString("fr-FR"), " ", paymentConfig.currency || "XOF")), /* @__PURE__ */ React7.createElement("p", { className: "text-xs text-gray-500 mt-2" }, fees > 0 ? `*Les frais de transaction sont de ${feePercentage.toFixed(1).replace(".", ",")}% du montant.` : "*Aucun frais de transaction applicable pour cette transaction.")), /* @__PURE__ */ React7.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React7.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React7.createElement(
|
|
1173
|
+
"button",
|
|
1174
|
+
{
|
|
1175
|
+
onClick: onClose,
|
|
1176
|
+
className: "w-1/3 bg-gray-200 hover:bg-gray-300 text-primary-blue font-bold py-2 px-4 rounded-md transition-colors duration-300 flex items-center justify-center"
|
|
1177
|
+
},
|
|
1178
|
+
"Retour"
|
|
1179
|
+
), /* @__PURE__ */ React7.createElement(
|
|
1180
|
+
"button",
|
|
1181
|
+
{
|
|
1182
|
+
onClick: handlePaymentSubmit,
|
|
1183
|
+
disabled: isLoading,
|
|
1184
|
+
className: `w-2/3 bg-primary-orange hover:bg-orange-700 text-white font-bold py-2 px-4 rounded-md transition-colors duration-300 flex items-center justify-center ${isLoading ? "opacity-70 cursor-not-allowed" : ""}`
|
|
1185
|
+
},
|
|
1186
|
+
isLoading && /* @__PURE__ */ React7.createElement("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-white", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React7.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React7.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })),
|
|
1187
|
+
"Payer ",
|
|
1188
|
+
total.toLocaleString("fr-FR"),
|
|
1189
|
+
" ",
|
|
1190
|
+
paymentConfig.currency || "XOF"
|
|
1191
|
+
))))), /* @__PURE__ */ React7.createElement("div", { className: "mt-6 text-center text-xs text-gray-500 flex-shrink-0 bg-gray-50 w-full p-2" }, /* @__PURE__ */ React7.createElement("p", { className: "mt-2" }, "Paiements s\xE9curis\xE9s par FeexPay"), /* @__PURE__ */ React7.createElement("p", { className: "mt-2" }, "En payant par ce plugin, vous acceptez les", " ", /* @__PURE__ */ React7.createElement(
|
|
1192
|
+
"a",
|
|
1193
|
+
{
|
|
1194
|
+
className: "text-blue-900",
|
|
1195
|
+
style: { textDecoration: "underline" },
|
|
1196
|
+
target: "_blank",
|
|
1197
|
+
rel: "noreferrer",
|
|
1198
|
+
href: "https://feexpay.me/fr/terms-and-conditions"
|
|
1199
|
+
},
|
|
1200
|
+
"conditions g\xE9n\xE9rales d'utilisation de FeexPay"
|
|
1201
|
+
))))), /* @__PURE__ */ React7.createElement(
|
|
1202
|
+
StatusModal_default,
|
|
1203
|
+
{
|
|
1204
|
+
isOpen: statusModalOpen,
|
|
1205
|
+
onClose: () => setStatusModalOpen(false),
|
|
1206
|
+
status: paymentStatus,
|
|
1207
|
+
message: statusMessage
|
|
1208
|
+
}
|
|
1209
|
+
), /* @__PURE__ */ React7.createElement(
|
|
1210
|
+
OTPModal_default,
|
|
1211
|
+
{
|
|
1212
|
+
isOpen: otpModalOpen,
|
|
1213
|
+
onClose: () => {
|
|
1214
|
+
setOtpModalOpen(false);
|
|
1215
|
+
setIsLoading(false);
|
|
1216
|
+
},
|
|
1217
|
+
onSubmit: handleOTPSubmit,
|
|
1218
|
+
reference: pendingReference
|
|
1219
|
+
}
|
|
1220
|
+
));
|
|
1221
|
+
};
|
|
1222
|
+
var PaymentModal_default = PaymentModal;
|
|
1223
|
+
|
|
1224
|
+
// src/components/FeexPayButton.tsx
|
|
1225
|
+
var FeexPayButtonInner = ({
|
|
1226
|
+
amount,
|
|
1227
|
+
description = "",
|
|
1228
|
+
id,
|
|
1229
|
+
token,
|
|
1230
|
+
callback_url,
|
|
1231
|
+
error_callback_url,
|
|
1232
|
+
mode = "LIVE",
|
|
1233
|
+
customId,
|
|
1234
|
+
fields_to_hide,
|
|
1235
|
+
callback,
|
|
1236
|
+
currency = "XOF",
|
|
1237
|
+
case: caseType,
|
|
1238
|
+
callback_info,
|
|
1239
|
+
first_name,
|
|
1240
|
+
email,
|
|
1241
|
+
custom_button = false,
|
|
1242
|
+
buttonText,
|
|
1243
|
+
buttonClass,
|
|
1244
|
+
defaultValueField
|
|
1245
|
+
}) => {
|
|
1246
|
+
const [isModalOpen, setIsModalOpen] = useState5(false);
|
|
1247
|
+
const [shopLoaded, setShopLoaded] = useState5(false);
|
|
1248
|
+
const [shopError, setShopError] = useState5(null);
|
|
1249
|
+
const { setPaymentConfig } = useFeexPay();
|
|
1250
|
+
const containerRef = useRef2(null);
|
|
1251
|
+
useEffect4(() => {
|
|
1252
|
+
getShop(id).then(() => setShopLoaded(true)).catch(() => setShopError("Veuillez v\xE9rifier vos identifiants de boutique (ID et token)."));
|
|
1253
|
+
}, [id]);
|
|
1254
|
+
const handlePaymentClick = useCallback2(() => {
|
|
1255
|
+
setPaymentConfig({
|
|
1256
|
+
amount,
|
|
1257
|
+
description,
|
|
1258
|
+
id,
|
|
1259
|
+
token,
|
|
1260
|
+
callback_url,
|
|
1261
|
+
error_callback_url,
|
|
1262
|
+
mode,
|
|
1263
|
+
customId,
|
|
1264
|
+
fields_to_hide,
|
|
1265
|
+
callback,
|
|
1266
|
+
currency,
|
|
1267
|
+
case: caseType,
|
|
1268
|
+
callback_info,
|
|
1269
|
+
first_name,
|
|
1270
|
+
email,
|
|
1271
|
+
buttonText,
|
|
1272
|
+
buttonClass,
|
|
1273
|
+
defaultValueField
|
|
1274
|
+
});
|
|
1275
|
+
setIsModalOpen(true);
|
|
1276
|
+
}, [
|
|
1277
|
+
amount,
|
|
1278
|
+
description,
|
|
1279
|
+
id,
|
|
1280
|
+
token,
|
|
1281
|
+
callback_url,
|
|
1282
|
+
error_callback_url,
|
|
1283
|
+
mode,
|
|
1284
|
+
customId,
|
|
1285
|
+
fields_to_hide,
|
|
1286
|
+
callback,
|
|
1287
|
+
currency,
|
|
1288
|
+
caseType,
|
|
1289
|
+
callback_info,
|
|
1290
|
+
first_name,
|
|
1291
|
+
email,
|
|
1292
|
+
buttonText,
|
|
1293
|
+
buttonClass,
|
|
1294
|
+
defaultValueField,
|
|
1295
|
+
setPaymentConfig
|
|
1296
|
+
]);
|
|
1297
|
+
useEffect4(() => {
|
|
1298
|
+
const container = containerRef.current;
|
|
1299
|
+
if (!container) return;
|
|
1300
|
+
const handler = () => handlePaymentClick();
|
|
1301
|
+
container.addEventListener("feexpay:trigger", handler);
|
|
1302
|
+
return () => container.removeEventListener("feexpay:trigger", handler);
|
|
1303
|
+
}, [handlePaymentClick]);
|
|
1304
|
+
const defaultButtonText = buttonText || `Payer ${amount == null ? void 0 : amount.toLocaleString("fr-FR")} ${currency}`;
|
|
1305
|
+
return /* @__PURE__ */ React8.createElement("div", { ref: containerRef }, shopError ? /* @__PURE__ */ React8.createElement("p", { className: "text-red-600 text-sm mb-2" }, shopError) : shopLoaded && !custom_button ? /* @__PURE__ */ React8.createElement(
|
|
1306
|
+
"button",
|
|
1307
|
+
{
|
|
1308
|
+
onClick: handlePaymentClick,
|
|
1309
|
+
className: buttonClass || "bg-primary-orange hover:bg-orange-700 text-white font-bold py-3 px-4 rounded-md transition-colors duration-300 flex items-center justify-center"
|
|
1310
|
+
},
|
|
1311
|
+
defaultButtonText
|
|
1312
|
+
) : null, isModalOpen && /* @__PURE__ */ React8.createElement(PaymentModal_default, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false) }));
|
|
1313
|
+
};
|
|
1314
|
+
var FeexPayButton_default = FeexPayButtonInner;
|
|
1315
|
+
|
|
1316
|
+
// src/index.tsx
|
|
1317
|
+
var FeexPay = ({
|
|
1318
|
+
amount,
|
|
1319
|
+
token,
|
|
1320
|
+
id,
|
|
1321
|
+
description,
|
|
1322
|
+
callback,
|
|
1323
|
+
callback_url,
|
|
1324
|
+
error_callback_url,
|
|
1325
|
+
callback_info,
|
|
1326
|
+
reference,
|
|
1327
|
+
customId,
|
|
1328
|
+
fieldsToHide,
|
|
1329
|
+
fields_to_hide,
|
|
1330
|
+
buttonClass,
|
|
1331
|
+
buttonText,
|
|
1332
|
+
defaultValueField,
|
|
1333
|
+
mode,
|
|
1334
|
+
currency,
|
|
1335
|
+
case: caseType,
|
|
1336
|
+
first_name,
|
|
1337
|
+
email
|
|
1338
|
+
}) => {
|
|
1339
|
+
const effectiveCustomId = reference || customId;
|
|
1340
|
+
const effectiveFieldsToHide = fieldsToHide || fields_to_hide;
|
|
1341
|
+
return /* @__PURE__ */ React9.createElement(FeexPayProvider, null, /* @__PURE__ */ React9.createElement(
|
|
1342
|
+
FeexPayButton_default,
|
|
1343
|
+
{
|
|
1344
|
+
amount,
|
|
1345
|
+
token,
|
|
1346
|
+
id,
|
|
1347
|
+
description,
|
|
1348
|
+
callback,
|
|
1349
|
+
callback_url,
|
|
1350
|
+
error_callback_url,
|
|
1351
|
+
callback_info,
|
|
1352
|
+
customId: effectiveCustomId,
|
|
1353
|
+
fields_to_hide: effectiveFieldsToHide,
|
|
1354
|
+
buttonClass,
|
|
1355
|
+
buttonText,
|
|
1356
|
+
defaultValueField,
|
|
1357
|
+
mode,
|
|
1358
|
+
currency,
|
|
1359
|
+
case: caseType,
|
|
1360
|
+
first_name,
|
|
1361
|
+
email
|
|
1362
|
+
}
|
|
1363
|
+
));
|
|
1364
|
+
};
|
|
1365
|
+
var FeexPayButton = (props) => /* @__PURE__ */ React9.createElement(FeexPay, __spreadValues({}, props));
|
|
1366
|
+
var index_default = FeexPay;
|
|
1367
|
+
export {
|
|
1368
|
+
FeexPayButton,
|
|
1369
|
+
FeexPayProvider,
|
|
1370
|
+
index_default as default
|
|
1371
|
+
};
|