@feexpay/react-sdk
Version:
SDK React officiel pour intégrer les paiements FeexPay dans vos applications React
1,199 lines • 59.2 kB
JavaScript
import { jsxs as i, jsx as t, Fragment as Z } from "react/jsx-runtime";
import { useEffect as z, useState as g, createContext as Fe, useContext as Te, useRef as te, useCallback as re } from "react";
const Me = ({ selectedCountry: r, onChange: l }) => /* @__PURE__ */ i("div", { className: "relative", children: [
/* @__PURE__ */ i(
"select",
{
value: r,
onChange: (e) => l(e.target.value),
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",
children: [
/* @__PURE__ */ t("option", { value: "BENIN", children: "🇧🇯 Benin" }),
/* @__PURE__ */ t("option", { value: "BURKINA_FASO", children: "🇧🇫 Burkina Faso" }),
/* @__PURE__ */ t("option", { value: "CONGO_BRAZZAVILLE", children: "🇨🇬 Congo Brazzaville" }),
/* @__PURE__ */ t("option", { value: "COTE_D_IVOIRE", children: "🇨🇮 Côte d'Ivoire" }),
/* @__PURE__ */ t("option", { value: "SENEGAL", children: "🇸🇳 Sénégal" }),
/* @__PURE__ */ t("option", { value: "TOGO", children: "🇹🇬 Togo" })
]
}
),
/* @__PURE__ */ t("div", { className: "absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) }) })
] }), ee = {
MTN: ["0142", "0146", "0150", "0151", "0152", "0153", "0154", "0156", "0157", "0159", "0161", "0162", "0166", "0167", "0169", "0190", "0191", "0192", "0193", "0196", "0197"],
MOOV: ["0145", "0155", "0158", "0160", "0163", "0164", "0165", "0168", "0194", "0195", "0198", "0199"],
CELTIIS: ["0140", "0141", "0143", "0144", "0147"]
}, me = {
MOOV: ["01", "02", "03", "40", "41", "42", "43", "50", "51", "52", "53", "70", "71", "72", "73", "80", "81", "82", "83", "90", "91", "92", "93"],
MTN: ["04", "05", "06", "44", "45", "46", "54", "55", "56", "64", "65", "66", "74", "75", "76", "84", "85", "86", "94", "95", "96"]
}, H = {
BENIN: {
MTN: 0.017,
MOOV: 0.017,
CELTIIS: 0.017,
CORIS: 0.017
},
COTE_D_IVOIRE: {
MTN: 0.029,
MOOV: 0.029,
ORANGE: 0.029,
WAVE: 0.032
},
BURKINA_FASO: {
MOOV: 0.032,
ORANGE: 0.039
},
CONGO_BRAZZAVILLE: {
MTN: 0.03
},
SENEGAL: {
ORANGE: 0.019,
FREE: 0.019
},
TOGO: {
TOGOCOM: 0.03,
MOOV: 0.03
}
}, Re = {
BENIN: {
MTN: "MTN",
MOOV: "MOOV",
CELTIIS: "CELTIIS BJ",
CORIS: "CORIS"
},
COTE_D_IVOIRE: {
MTN: "MTN CI",
MOOV: "MOOV CI",
ORANGE: "ORANGE CI",
WAVE: "WAVE CI"
},
BURKINA_FASO: {
MOOV: "MOOV BF",
ORANGE: "ORANGE BF"
},
CONGO_BRAZZAVILLE: {
MTN: "MTN CG"
},
SENEGAL: {
ORANGE: "ORANGE SN",
FREE: "FREE SN"
},
TOGO: {
TOGOCOM: "TOGOCOM TG",
MOOV: "MOOV TG"
}
}, he = (r, l) => me.MTN.includes(r) ? "MTN" : me.MOOV.includes(r) ? "MOOV" : ee.MTN.includes(r) ? "MTN" : ee.MOOV.includes(r) ? "MOOV" : ee.CELTIIS.includes(r) ? "CELTIIS" : null, ne = (r) => {
switch (r) {
case "BENIN":
return ["MTN", "MOOV", "CELTIIS"];
case "COTE_D_IVOIRE":
return ["MTN", "MOOV", "ORANGE", "WAVE"];
case "BURKINA_FASO":
return ["MOOV", "ORANGE"];
case "CONGO_BRAZZAVILLE":
return ["MTN"];
case "SENEGAL":
return ["ORANGE", "FREE"];
case "TOGO":
return ["TOGOCOM", "MOOV"];
default:
return ["MTN", "MOOV"];
}
}, De = (r, l, e, s, d) => {
if (s === "CARD" && (d === "VISA" || d === "MASTERCARD"))
return Math.ceil(r * 0.045);
const o = H[l];
let y = 0;
o && o[e] && (y = o[e]);
const a = r * y;
return Math.ceil(a);
}, ae = (r, l) => {
const e = Re[r];
return e && e[l] ? e[l] : l.toLowerCase();
}, Pe = ({
selectedNetwork: r,
onChange: l,
country: e
}) => {
const s = ne(e);
return z(() => {
s.length > 0 && !s.includes(r) && l(s[0]);
}, [e, r, s, l]), /* @__PURE__ */ i("div", { className: "relative", children: [
/* @__PURE__ */ t(
"select",
{
value: r,
onChange: (d) => l(d.target.value),
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",
children: s == null ? void 0 : s.map((d) => /* @__PURE__ */ t("option", { value: d, children: d.replace("_", " ") }, d))
}
),
/* @__PURE__ */ t("div", { className: "absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) }) })
] });
}, Ve = ({
isOpen: r,
onClose: l,
status: e,
message: s
}) => {
if (z(() => {
if (e === "SUCCESSFUL" || e === "SUCCESS") {
const a = setTimeout(() => {
l();
}, 5e3);
return () => clearTimeout(a);
}
}, [e, l]), !r) return null;
const d = () => {
switch (e) {
case "SUCCESSFUL":
case "SUCCESS":
return /* @__PURE__ */ t("div", { className: "w-16 h-16 mx-auto mb-4 bg-green-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-10 w-10 text-green-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) });
case "FAILED":
return /* @__PURE__ */ t("div", { className: "w-16 h-16 mx-auto mb-4 bg-red-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-10 w-10 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) });
case "PENDING":
return /* @__PURE__ */ t("div", { className: "w-16 h-16 mx-auto mb-4 bg-yellow-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ i("svg", { className: "animate-spin h-10 w-10 text-yellow-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ t("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
/* @__PURE__ */ t("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" })
] }) });
case "TIMEOUT":
return /* @__PURE__ */ t("div", { className: "w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-10 w-10 text-gray-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) }) });
default:
return null;
}
}, o = () => {
switch (e) {
case "SUCCESSFUL":
case "SUCCESS":
return "Continuer";
case "FAILED":
case "TIMEOUT":
return "Réessayer";
default:
return "Fermer";
}
}, y = () => {
switch (e) {
case "SUCCESSFUL":
case "SUCCESS":
return "bg-green-500 hover:bg-green-600";
case "FAILED":
return "bg-red-500 hover:bg-red-600";
case "TIMEOUT":
return "bg-gray-500 hover:bg-gray-600";
default:
return "bg-gray-500 hover:bg-gray-600";
}
};
return /* @__PURE__ */ t("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50", children: /* @__PURE__ */ i("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-sm p-6 text-center", children: [
d(),
/* @__PURE__ */ t("h3", { className: "text-xl font-bold mb-2", children: e === "SUCCESSFUL" ? "Paiement Réussi" : e === "FAILED" ? "Paiement Échoué" : e === "SUCCESS" ? "Paiement Réussi" : e === "PENDING" ? "Traitement en cours" : "Vérification expirée" }),
/* @__PURE__ */ t("p", { className: "text-gray-600 mb-6", children: s }),
/* @__PURE__ */ t(
"button",
{
onClick: l,
className: `w-full ${y()} text-white font-bold py-3 px-4 rounded-md transition-colors duration-300`,
children: o()
}
)
] }) });
}, Ue = ({ isOpen: r, onClose: l, onSubmit: e }) => {
const [s, d] = g(""), [o, y] = g(!1), a = (f) => {
f.preventDefault(), y(!0), e(s);
};
return r ? /* @__PURE__ */ t("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50 overflow-hidden", children: /* @__PURE__ */ i("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-md relative", children: [
/* @__PURE__ */ i("div", { className: "flex justify-between items-center border-b p-4", children: [
/* @__PURE__ */ t("h3", { className: "text-lg font-medium", children: "Confirmation de paiement" }),
/* @__PURE__ */ t(
"button",
{
onClick: l,
className: "text-gray-500 hover:text-gray-700",
children: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
}
)
] }),
/* @__PURE__ */ i("div", { className: "p-6", children: [
/* @__PURE__ */ t("p", { className: "text-sm text-gray-600 mb-4", children: "Un code de confirmation a été envoyé à votre téléphone. Veuillez le saisir ci-dessous pour finaliser votre paiement." }),
/* @__PURE__ */ i("form", { onSubmit: a, children: [
/* @__PURE__ */ i("div", { className: "mb-4", children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Code OTP" }),
/* @__PURE__ */ t(
"input",
{
type: "text",
value: s,
onChange: (f) => d(f.target.value),
placeholder: "Entrez le code reçu par SMS",
className: "w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange",
required: !0
}
)
] }),
/* @__PURE__ */ t(
"button",
{
type: "submit",
disabled: o,
className: "w-full bg-primary-orange text-white py-2 px-4 rounded-md hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-orange disabled:opacity-50",
children: o ? "Traitement en cours..." : "Confirmer le paiement"
}
)
] })
] })
] }) }) : null;
}, ye = Fe(void 0), Ne = () => {
const r = Te(ye);
if (!r)
throw new Error("useFeexPay must be used within a FeexPayProvider");
return r;
}, Be = {
amount: 0,
description: "",
id: "",
token: "",
mode: "SANDBOX"
}, He = ({ children: r }) => {
const [l, e] = g(Be);
return /* @__PURE__ */ t(ye.Provider, { value: { paymentConfig: l, setPaymentConfig: e }, children: r });
}, ze = async () => {
try {
return (await (await fetch("https://api.ipify.org?format=json")).json()).ip;
} catch {
return "unknown";
}
}, be = async (r) => {
if (r.mode === "SANDBOX")
return {
status: "SUCCESSFUL",
message: "Payment successful (SANDBOX MODE)",
transaction_id: "ref_c36484845FDVvgDFEGEGEGE_REACT",
reference: "ref_c36484845FDVvgDFEGEGEGE_REACT"
};
if (r.mode == "LIVE" && !r.token.startsWith("fp_"))
throw new Error("Invalid token");
const l = ae(r.country, r.network), e = "https://api.feexpay.me/api/transactions/requesttopay/integration";
let s = r.phoneNumber.replace(/\+/g, "");
if (s.length >= 8) {
const d = s.slice(0, 3);
s.startsWith(d + d) && (s = s.slice(d.length));
}
try {
const d = window.location.origin, o = await ze();
let y = r.description;
r.network === "MTN" && (y = y.replace(/[^a-zA-Z0-9 ]/g, ""));
const a = {
phoneNumber: s,
amount: r.amount,
reseau: l,
description: y,
customId: r.customId,
shop: r.id,
token: r.token,
merchant_domain: d,
merchant_ip: o,
payment_interface: "REACT",
callback_info: r.callback_info || {},
currency: r.currency || "XOF",
first_name: r.first_name,
email: r.email,
otp: r.otp || ""
}, f = await fetch(e, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${r.token}`
},
body: JSON.stringify(a)
});
if (!f.ok)
throw new Error("Payment request failed");
return await f.json();
} catch (d) {
throw console.error("Payment request error:", d), d;
}
}, Ge = async (r) => {
const l = `https://api.feexpay.me/api/transactions/getrequesttopay/integration/${r}`;
try {
const e = await fetch(l);
if (!e.ok)
throw new Error("Status check failed");
return await e.json();
} catch (e) {
throw console.error("Status check error:", e), e;
}
}, We = async (r) => {
const l = "https://api.feexpay.me/api/transactions/details";
try {
const s = {
network: ae(r.country, r.network),
amount: r.amount,
shop: r.id
}, d = await fetch(l, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${r.token}`
},
body: JSON.stringify(s)
});
if (!d.ok)
throw new Error("Failed to get transaction details");
return await d.json();
} catch (e) {
throw console.error("Transaction details error:", e), e;
}
}, je = async (r) => {
const l = "https://api.feexpay.me/api/transactions/public/initcard";
try {
const e = {
phone: r.phone,
amount: r.amount,
shop: r.id,
first_name: r.first_name,
last_name: r.last_name,
email: r.email,
type_card: r.type_card,
currency: "XOF"
// La devise est toujours XOF pour FeexPay
}, s = await fetch(l, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${r.token}`
},
body: JSON.stringify(e)
});
if (!s.ok)
throw new Error("Card payment request failed");
return await s.json();
} catch (e) {
throw console.error("Card payment request error:", e), e;
}
}, pe = async (r) => {
if (r.mode === "SANDBOX")
return {
status: "SUCCESSFUL",
message: "Payment successful (SANDBOX MODE)",
transaction_id: "sandbox-tx-id-" + (/* @__PURE__ */ new Date()).getTime(),
reference: r.customId || "sandbox-ref-" + (/* @__PURE__ */ new Date()).getTime()
// Remplissez les autres champs de TransactionResponse avec des données factices si nécessaire
};
const l = "https://api.feexpay.me/api/transactions/requesttopay/integration";
let e = r.description;
r.network === "MTN" && (e = e.replace(/[^a-zA-Z0-9 ]/g, ""));
try {
const s = "229", d = r.phoneNumber.startsWith("+229") ? r.phoneNumber.substring(4) : r.phoneNumber.startsWith("229") ? r.phoneNumber.substring(3) : r.phoneNumber, o = {
phoneNumber: `229${d}`,
country: s,
phoneNumberRight: d,
amount: r.amount,
currency: "XOF",
description: e,
email: r.email,
first_name: r.first_name,
otp: r.otp || "",
reseau: "CORIS",
shop: r.id,
token: r.token,
callback_info: r.callback_info || {}
}, y = await fetch(l, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(o)
});
return {
...await y.json(),
statusCode: y.status.toString()
};
} catch (s) {
throw console.error("Wallet Coris payment request error:", s), s;
}
}, Ee = async (r) => {
const l = `https://api.feexpay.me/api/shop/${r}/get_shop`;
try {
const e = await fetch(l);
if (!e.ok)
throw new Error("Shop retrieval failed");
return await e.json();
} catch (e) {
throw console.error("Shop retrieval error:", e), e;
}
}, ge = async (r, l, e, s) => {
if (r.preventDefault(), !e())
return;
const {
baseAmount: d,
network: o,
country: y,
paymentConfig: a,
generateRandomId: f,
fullName: h,
email: _,
setStateCallbacks: b
} = l, {
setTransactionReference: T,
setPaymentStatus: N,
setStatusMessage: F,
setStatusModalOpen: L,
setIsLoading: E
} = b;
E(!0);
try {
const x = s(), m = await be({
mode: a.mode,
phoneNumber: x,
amount: d,
// Envoyer le montant sans frais
network: o,
country: y,
// Ajout du paramètre country
description: a.description,
customId: a.customId || f(),
id: a.id,
token: a.token,
currency: a.currency || "XOF",
callback_info: a.callback_info || {},
first_name: h,
email: _
});
if (m.status === "SUCCESSFUL") {
N("SUCCESSFUL"), E(!1), a.callback && a.callback({
...m,
status: "SUCCESSFUL",
message: m.message ?? "Payment successful (SANDBOX)",
transaction_id: m.transaction_id ?? `sandbox-tx-${Date.now()}`,
reference: m.reference ?? "",
reseau: o,
phoneNumber: x,
amount: d,
currency: a.currency || "XOF",
description: a.description || "",
callback_info: a.callback_info || {},
first_name: h || "",
email: _ || ""
});
return;
}
if (m.statusCode === "10") {
N("INSUFFICIENT_FUNDS"), F("Fonds insuffisants. Veuillez vérifier votre solde et réessayer."), L(!0), E(!1), a.callback && a.callback({
reference: m.reference,
status: "FAILED",
phoneNumber: x,
reseau: o,
callback_info: a.callback_info || {},
description: a.description,
transaction_id: m.reference,
message: "Le paiement a échoué. Veuillez vérifier votre solde et réessayer.",
amount: a.amount,
currency: a.currency || "XOF",
first_name: h,
email: _
}), a.error_callback_url && (window.location.href = `${a.error_callback_url}?ref=${m.reference}`);
return;
} else if (m.statusCode === "37") {
N("FAILED"), F("Le montant est inférieur au minimum autorisé par l'opérateur."), L(!0), E(!1), a.callback && a.callback({
reference: m.reference,
status: "FAILED",
phoneNumber: x,
reseau: o,
callback_info: a.callback_info || {},
description: a.description,
transaction_id: m.reference,
message: "Le montant est inférieur au minimum autorisé par l'opérateur.",
amount: a.amount,
currency: a.currency || "XOF",
first_name: h,
email: _
}), a.error_callback_url && (window.location.href = `${a.error_callback_url}?ref=${m.reference}`);
return;
} else if (m.statusCode === "92") {
N("FAILED"), F("La transaction a été annulée. Veuillez réessayer."), L(!0), E(!1), a.callback && a.callback({
reference: m.reference,
status: "FAILED",
phoneNumber: x,
reseau: o,
callback_info: a.callback_info || {},
description: a.description,
transaction_id: m.reference,
message: "La transaction a été annulée. Veuillez réessayer.",
amount: a.amount,
first_name: h,
email: _,
currency: a.currency || "XOF"
}), a.error_callback_url && (window.location.href = `${a.error_callback_url}?ref=${m.reference}`);
return;
}
return T(m.reference), xe(m.reference, l, o, s), { reference: m.reference };
} catch (x) {
console.error("Payment error:", x), N("FAILED"), F("Le paiement a échoué. Veuillez réessayer."), L(!0), E(!1);
}
}, xe = (r, l, e, s) => {
let d = 0;
const o = 12;
let y = !1, a = null;
const {
paymentConfig: f,
setStateCallbacks: h,
fullName: _,
email: b
} = l, {
setPaymentStatus: T,
setStatusMessage: N,
setStatusModalOpen: F,
setIsLoading: L
} = h, E = (m, R, M) => {
if (l.isCallbackCalledRef.current) return;
l.isCallbackCalledRef.current = !0, a && clearTimeout(a), T(m), N(R), F(!0), L(!1);
const U = {
reference: r,
status: M,
phoneNumber: s(),
reseau: e,
callback_info: f.callback_info || {},
description: f.description,
transaction_id: r,
message: R,
amount: f.amount,
currency: f.currency || "XOF",
first_name: _,
email: b
};
f.callback && f.callback(U);
const D = M === "SUCCESSFUL" || M === "SUCCESS";
D && f.callback_url ? window.location.href = `${f.callback_url}?ref=${r}` : !D && f.error_callback_url && (window.location.href = `${f.error_callback_url}?ref=${r}`);
}, x = async () => {
if (!y) {
d++;
try {
const m = await Ge(r);
if (m.reason === "LOW_BALANCE_OR_PAYEE_LIMIT_REACHED_OR_NOT_ALLOWED") {
E("INSUFFICIENT_FUNDS", "Fonds insuffisants. Veuillez vérifier votre solde et réessayer.", "FAILED");
return;
} else if (m.reason === "PAYER NOT FOUND" || m.reason === "PAYER_NOT_FOUND") {
E("FAILED", "Numéro de téléphone non trouvé. Veuillez vérifier le numéro et réessayer.", "FAILED");
return;
}
const R = m.status.toUpperCase();
switch (R) {
case "SUCCESSFUL":
case "SUCCESS":
E("SUCCESSFUL", "Paiement réussi !", R);
break;
case "FAILED":
E("FAILED", "Le paiement a échoué. Veuillez réessayer.", "FAILED");
break;
case "INSUFFICIENT_FUNDS":
E("INSUFFICIENT_FUNDS", "Fonds insuffisants. Veuillez vérifier votre solde et réessayer.", "INSUFFICIENT_FUNDS");
break;
case "TIMEOUT":
E("TIMEOUT", "La vérification du paiement a expiré.", "TIMEOUT");
break;
case "PENDING":
d >= o ? E("TIMEOUT", "La vérification du paiement a expiré. Veuillez vérifier votre compte.", "TIMEOUT") : a = setTimeout(x, 1e4);
break;
default:
d >= o && E("TIMEOUT", "Statut de transaction inconnu après plusieurs tentatives.", "TIMEOUT");
break;
}
} catch (m) {
console.error(`Status check failed for ref ${r}:`, m), d >= o && E("TIMEOUT", "La vérification du paiement a échoué après plusieurs tentatives.", "TIMEOUT");
}
}
};
return x(), () => {
a && clearTimeout(a), y = !0;
};
}, $e = ({ id: r, onClose: l }) => {
const [e, s] = g(null);
return z(() => {
(async () => {
try {
const o = await Ee(r);
s(o);
} catch (o) {
console.error("Erreur de récupération du id :", o);
}
})();
}, [r]), /* @__PURE__ */ i("div", { className: "flex items-center justify-between px-4 py-2 border-b border-gray-200", children: [
/* @__PURE__ */ t("div", { children: /* @__PURE__ */ t("img", { src: "https://api.feexpay.me/api/static/feexpay_logo-h.png", width: "100", alt: "Logo" }) }),
/* @__PURE__ */ t("div", { className: "text-right text-xs text-gray-700 ", children: e && /* @__PURE__ */ i(Z, { children: [
/* @__PURE__ */ i("div", { className: "font-semibold", children: [
"MARCHAND: ",
e.name
] }),
/* @__PURE__ */ i("div", { className: "text-xs text-gray-500", children: [
"ID : ",
e.reference
] })
] }) }),
/* @__PURE__ */ t(
"button",
{
onClick: l,
className: "text-gray-500 hover:text-gray-700",
children: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
}
)
] });
}, Xe = ({ isOpen: r, onClose: l }) => {
var fe;
const { paymentConfig: e } = Ne(), [s, d] = g(() => e.case && ["MOBILE", "CARD", "WALLET"].includes(e.case) ? e.case : "MOBILE"), [o, y] = g("BENIN"), [a, f] = g("MTN"), [h, _] = g(""), [b, T] = g(""), [N, F] = g(""), [L, E] = g("VISA"), [x, m] = g(0), [R, M] = g(0), [U, D] = g(0), [j, P] = g(0), [G, B] = g(""), [Ce, C] = g(!1), [K, k] = g("PENDING"), [ve, v] = g(""), [J, S] = g(!1), [Oe, X] = g(!1), [Se, we] = g(""), [se, oe] = g(null), W = te(!1), ie = te(null), Y = re((n, u, p, w) => {
const O = De(n, u, p, w || s, L);
if (D(O), M(n + O), m(n), s === "CARD" && (L === "VISA" || L === "MASTERCARD"))
P(4.5);
else {
const V = H[u];
V && V[p] ? P(V[p] * 100) : P(0);
}
}, [s, L]), A = re(async (n, u, p, w) => {
try {
const c = w || s, O = await We({
network: p,
country: u,
amount: n,
id: e.id,
token: e.token
});
if (O && O.iffees) {
let V = !1;
if (n <= 30) {
const I = H[u];
I && I[p] && I[p] > 0 && (D(1), M(n + 1), P(I[p] * 100), V = !0);
}
if (!V) {
if (O.total !== void 0) {
const I = O.total - n;
D(I), M(O.total);
} else
Y(n, u, p, c);
if (c === "CARD")
P(4.5);
else {
const I = H[u];
I && I[p] ? P(I[p] * 100) : P(0);
}
}
} else
D(0), M(n), P(0);
m(n);
} catch (c) {
console.error("Erreur lors de la récupération des détails de transaction:", c), Y(n, u, p, w);
}
}, [s, e.id, e.token, Y]);
z(() => {
e.amount && (m(e.amount), A(e.amount, o, a));
}, [e, o, a, A]), z(() => {
s === "WALLET" && (o === "BENIN" ? (f("CORIS"), e.amount && A(e.amount, o, "CORIS", s)) : o === "COTE_D_IVOIRE" ? (f("WAVE"), e.amount && A(e.amount, o, "WAVE", s)) : (y("BENIN"), f("CORIS"), e.amount && A(e.amount, "BENIN", "CORIS", s)));
}, []), z(() => {
if (K === "SUCCESSFUL") {
const n = setTimeout(() => {
l();
}, 1500);
return () => clearTimeout(n);
}
}, [K, l]);
const le = (n) => {
f(n), e.amount && A(e.amount, o, n);
}, Ie = () => {
T(""), F(""), _(""), E("VISA");
}, ke = (n) => {
if (Ie(), D(0), M(e.amount || 0), P(0), d(n), n === "WALLET")
o === "BENIN" ? (f("CORIS"), e.amount && A(e.amount, o, "CORIS", n)) : o === "COTE_D_IVOIRE" ? (f("WAVE"), e.amount && A(e.amount, o, "WAVE", n)) : (y("BENIN"), f("CORIS"), e.amount && A(e.amount, "BENIN", "CORIS", n));
else if (n === "MOBILE") {
const u = ne(o);
u.length > 0 && (u.includes(a) || f(u[0]), e.amount && A(e.amount, o, a, n));
} else n === "CARD" && e.amount && A(e.amount, o, a, n);
}, ce = (n) => {
if (y(n), s === "WALLET")
n === "BENIN" ? (f("CORIS"), e.amount && A(e.amount, n, "CORIS")) : n === "COTE_D_IVOIRE" && (f("WAVE"), e.amount && A(e.amount, n, "WAVE"));
else {
const u = ne(n);
f(u[0]), e.amount && A(e.amount, n, u[0]);
}
}, ue = (n) => {
const u = n.target.value;
if (s === "WALLET") {
_(u);
return;
}
if (o === "COTE_D_IVOIRE") {
if (u.length >= 2) {
const p = u.substring(0, 2), w = he(p);
console.log(`[DEBUG] CIV Prefix: ${p}, Detected Network: ${w}`), w && f(w);
}
} else if (o === "BENIN" && u.length >= 4) {
const p = u.substring(0, 4), w = he(p);
w && f(w);
}
_(u);
}, $ = () => {
if (!h) return h;
let n = h.replace(/[^0-9]/g, ""), u = "";
switch (o) {
case "BENIN":
u = "229";
break;
case "COTE_D_IVOIRE":
u = "225";
break;
case "BURKINA_FASO":
u = "226";
break;
case "CONGO_BRAZZAVILLE":
u = "242";
break;
case "SENEGAL":
u = "221";
break;
case "TOGO":
u = "228";
break;
default:
return n;
}
return n.startsWith(u + u) && (n = n.slice(u.length)), n.startsWith(u) ? n : u + n;
}, Le = (n) => {
switch (n) {
case "BENIN":
return "+229";
case "COTE_D_IVOIRE":
return "+225";
case "BURKINA_FASO":
return "+226";
case "CONGO_BRAZZAVILLE":
return "+242";
case "SENEGAL":
return "+221";
case "TOGO":
return "+228";
default:
return "";
}
}, _e = async (n) => {
var w;
if (n.preventDefault(), !Q())
return;
W.current = !1, S(!0);
const u = ["MOOV CI", "ORANGE CI", "MOOV BF", "ORANGE BF", "FREE SN", "WAVE CI", "ORANGE SN"], p = ae(o, a);
if (u.includes(p)) {
try {
const c = await be({
mode: e.mode,
// Ajout du mode ici
phoneNumber: $(),
amount: x,
network: a,
country: o,
description: e.description || "Payment",
customId: e.customId || "",
id: e.id,
token: e.token,
currency: e.currency || "XOF",
callback_info: e.callback_info || {},
first_name: b || "",
email: N || "",
otp: ((w = ie.current) == null ? void 0 : w.value) || ""
});
if (c.status === "SUCCESSFUL") {
e.callback && !W.current && (e.callback({
...c,
transaction_id: c.transaction_id ?? "sandbox-tx-id",
message: c.message ?? "Payment successful",
status: "SUCCESSFUL",
reseau: a,
phoneNumber: $(),
amount: x,
currency: e.currency || "XOF",
description: e.description || "Payment",
callback_info: e.callback_info || {},
first_name: b || "",
email: N || ""
}), W.current = !0), S(!1), k("SUCCESSFUL");
return;
}
if (c.payment_url && oe(c.payment_url), c.reference)
B(c.reference), q(c.reference);
else if (!c.payment_url)
throw new Error("La réponse de paiement est invalide.");
} catch (c) {
console.error("Payment error:", c), k("FAILED"), v("Le paiement a échoué. Veuillez réessayer."), C(!0);
} finally {
S(!1);
}
return;
}
try {
if (s === "CARD") {
const c = b.split(" "), O = c[0] || "", V = c.slice(1).join(" ") || "", I = await je({
phone: h,
amount: x,
id: e.id,
first_name: O,
last_name: V,
email: N,
type_card: L,
token: e.token,
currency: e.currency || "XOF"
});
I && I.reference ? (B(I.reference), q(I.reference)) : (k("FAILED"), v("La demande de paiement par carte a échoué. Veuillez réessayer."), C(!0), S(!1));
} else if (s === "MOBILE") {
const c = await ge(
n,
{
phoneNumber: h,
baseAmount: x,
network: a,
country: o,
paymentConfig: e,
transactionReference: G,
fullName: b,
email: N,
generateRandomId: de,
isCallbackCalledRef: W,
setStateCallbacks: {
setTransactionReference: B,
setPaymentStatus: k,
setStatusMessage: v,
setStatusModalOpen: C,
setIsLoading: S
}
},
Q,
$
);
c && c.reference && q(c.reference);
} else if (s === "WALLET")
if (o === "BENIN" && a === "CORIS")
try {
const O = b.split(" ")[0] || "", V = h.startsWith("+229") ? h : `+229${h}`, I = await pe({
phoneNumber: V,
amount: x,
id: e.id,
email: N,
first_name: O,
description: "Paiement via FeexPay",
token: e.token,
currency: e.currency || "XOF",
callback_info: e.callback_info || {},
network: a,
country: o,
customId: e.customId || ""
});
I.statusCode === "201" ? (we(I.reference), X(!0), S(!1)) : (k("FAILED"), v("La demande de paiement a échoué. Veuillez réessayer."), C(!0), S(!1));
} catch (c) {
console.error("Error in Coris Wallet payment:", c), k("FAILED"), v("Une erreur est survenue lors du traitement du paiement. Veuillez réessayer."), C(!0), S(!1);
}
else {
const O = await ge(n, {
phoneNumber: h,
baseAmount: x,
network: a,
country: o,
paymentConfig: e,
transactionReference: G,
generateRandomId: de,
fullName: b,
email: N,
isCallbackCalledRef: W,
setStateCallbacks: {
setTransactionReference: B,
setPaymentStatus: k,
setStatusMessage: v,
setStatusModalOpen: C,
setIsLoading: S
}
}, Q, $);
O && O.reference && q(O.reference);
}
} catch (c) {
console.error("Error in payment submission:", c), k("FAILED"), v("Une erreur est survenue lors du traitement du paiement. Veuillez réessayer."), C(!0), S(!1);
}
}, Q = () => {
const n = e.fields_to_hide || [];
if (s === "MOBILE" || s === "WALLET") {
if (!n.includes("name") && !b.trim())
return v("Veuillez entrer votre nom complet"), C(!0), !1;
if (!n.includes("email") && (!N.trim() || !N.includes("@")))
return v("Veuillez entrer une adresse email valide"), C(!0), !1;
if (!h.trim() || h.length < 8)
return v("Veuillez entrer un numéro de téléphone valide"), C(!0), !1;
if (s === "WALLET" && o !== "BENIN" && o !== "COTE_D_IVOIRE")
return v("Seuls le Bénin (Coris) et la Côte d'Ivoire (Wave) sont supportés pour les paiements Wallet"), C(!0), !1;
} else if (s === "CARD") {
if (!b || b.trim().split(" ").length < 2)
return v("Veuillez entrer votre nom et prénom complets"), k("FAILED"), C(!0), !1;
if (!N || !N.includes("@"))
return v("Veuillez entrer une adresse email valide"), k("FAILED"), C(!0), !1;
if (!h)
return v("Veuillez entrer un numéro de téléphone valide"), k("FAILED"), C(!0), !1;
}
return !0;
}, de = () => `TRX-${Math.random().toString(36).substring(2, 10).toUpperCase()}`, Ae = async (n) => {
S(!0);
try {
const p = b.split(" ")[0] || "", w = h.startsWith("+229") ? h : `+229${h}`, c = await pe({
phoneNumber: w,
amount: x,
id: e.id,
email: N,
first_name: p,
description: "Paiement via FeexPay",
otp: n,
token: e.token,
currency: e.currency || "XOF",
callback_info: e.callback_info || {},
network: a,
country: o,
customId: e.customId || ""
});
if (X(!1), c.status === "FAILED") {
k("FAILED"), v(c.message ?? "Le paiement a échoué."), C(!0), S(!1), e.callback && e.callback({
reference: c.reference ?? "",
status: "FAILED",
phoneNumber: w,
reseau: a,
callback_info: e.callback_info || {},
description: e.description ?? "",
transaction_id: c.reference ?? "",
message: c.message ?? "Le paiement a échoué.",
amount: e.amount,
currency: e.currency || "XOF",
first_name: b,
email: N
}), e.error_callback_url && (window.location.href = `${e.error_callback_url}?ref=${c.reference}`);
return;
}
if (c.reference)
c.status && (c.status.toUpperCase() === "SUCCESSFUL" || c.status.toUpperCase() === "SUCCESS") ? (k("SUCCESSFUL"), v("Paiement effectué avec succès!"), C(!0), S(!1), e.onPaymentSuccess && e.onPaymentSuccess({ status: "SUCCESSFUL", reference: c.reference, message: "Paiement effectué avec succès!" }), e.callback_url && setTimeout(() => {
window.location.href = `${e.callback_url}?ref=${c.reference}`;
}, 2e3)) : (k("FAILED"), v(c.message || "La transaction a échoué. Veuillez réessayer."), C(!0), S(!1), e.onPaymentFailure && e.onPaymentFailure({ status: "FAILED", reference: c.reference, message: c.message || "La transaction a échoué. Veuillez réessayer." }), e.error_callback_url && setTimeout(() => {
window.location.href = `${e.error_callback_url}?ref=${c.reference}`;
}, 2e3));
else {
const O = c.message || "La confirmation du paiement a échoué. Veuillez réessayer.";
k("FAILED"), v(O), C(!0), S(!1), e.onPaymentFailure && e.onPaymentFailure({ status: "FAILED", message: O });
}
} catch (u) {
console.error("Error in OTP submission:", u);
const p = "Une erreur est survenue lors de la confirmation du paiement. Veuillez réessayer.";
k("FAILED"), v(p), C(!0), S(!1), X(!1), e.onPaymentFailure && e.onPaymentFailure({ status: "FAILED", message: p });
}
}, q = (n) => {
xe(n, {
paymentConfig: e,
fullName: b,
email: N,
isCallbackCalledRef: W,
setStateCallbacks: {
setTransactionReference: B,
setPaymentStatus: k,
setStatusMessage: v,
setStatusModalOpen: C,
setIsLoading: S
}
}, a, $);
};
return r ? /* @__PURE__ */ i("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50 overflow-hidden", children: [
/* @__PURE__ */ i("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-md relative max-h-[90vh] flex flex-col", children: [
se && /* @__PURE__ */ i("div", { className: "absolute inset-0 bg-white z-10 rounded-lg overflow-hidden", children: [
/* @__PURE__ */ t(
"button",
{
onClick: () => oe(null),
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",
"aria-label": "Fermer la passerelle de paiement",
children: /* @__PURE__ */ t("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
}
),
/* @__PURE__ */ t(
"iframe",
{
src: se,
className: "w-full h-full border-0",
title: "Payment Gateway",
allow: "payment"
}
)
] }),
/* @__PURE__ */ t($e, { id: e.id, onClose: l }),
/* @__PURE__ */ i("div", { className: "p-6 overflow-y-auto flex-grow", children: [
/* @__PURE__ */ t("p", { className: "text-sm text-gray-600 text-center mb-4", children: "Remplissez les champs suivants pour effectuer votre paiement" }),
!e.case && /* @__PURE__ */ t("div", { className: "flex justify-center mb-6 border-b pb-4 w-fit gap-2", children: [
{ label: "Mobile Money", value: "MOBILE", icon: /* @__PURE__ */ i("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#D45D00", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
/* @__PURE__ */ t("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", ry: "2" }),
/* @__PURE__ */ t("line", { x1: "12", y1: "18", x2: "12", y2: "18" })
] }) },
{ label: "Carte Bancaire", value: "CARD", icon: /* @__PURE__ */ i("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: [
/* @__PURE__ */ t("path", { d: "M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" }),
/* @__PURE__ */ t("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" })
] }) },
{ label: "Wallet", value: "WALLET", icon: /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t("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" }) }) }
].map(({ label: n, value: u, icon: p }) => /* @__PURE__ */ i(
"div",
{
className: `flex flex-col items-center px-4 py-2 cursor-pointer rounded border ${s === u ? "bg-[#fff7ed] border-[#D45D00]" : "bg-white border-[#D45D00]"}`,
onClick: () => ke(u),
children: [
/* @__PURE__ */ t("div", { className: "w-8 h-8 rounded-full flex items-center justify-center mb-1", children: p }),
/* @__PURE__ */ t("span", { className: "text-xs font-medium", children: n })
]
},
u
)) }),
/* @__PURE__ */ i("div", { className: "space-y-6", children: [
!((e.fields_to_hide || []).includes("email") && (e.fields_to_hide || []).includes("name")) && s !== "CARD" ? /* @__PURE__ */ i("div", { className: "space-y-4", children: [
/* @__PURE__ */ i("h2", { className: "font-bold text-gray-800 mb-2 flex items-center", children: [
/* @__PURE__ */ t("span", { className: "bg-gray-800 text-white rounded-full w-5 h-5 inline-flex items-center justify-center text-xs mr-2", children: "1" }),
"Informations Personnelles"
] }),
!(e.fields_to_hide || []).includes("name") && /* @__PURE__ */ t("div", { children: /* @__PURE__ */ t(
"input",
{
type: "text",
placeholder: "Nom et Prénoms",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: b,
onChange: (n) => T(n.target.value)
}
) }),
!(e.fields_to_hide || []).includes("email") && /* @__PURE__ */ t("div", { children: /* @__PURE__ */ t(
"input",
{
type: "email",
placeholder: "Email",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: N,
onChange: (n) => F(n.target.value)
}
) })
] }) : null,
/* @__PURE__ */ i("div", { className: "space-y-4", children: [
/* @__PURE__ */ i("h2", { className: "font-bold text-gray-800 mb-2 flex items-center", children: [
/* @__PURE__ */ t("span", { className: "bg-gray-800 text-white rounded-full w-5 h-5 inline-flex items-center justify-center text-xs mr-2", children: s === "CARD" || (e.fields_to_hide || []).includes("email") && (e.fields_to_hide || []).includes("name") ? "1" : "2" }),
s === "CARD" ? "Méthode de paiement" : "Méthodes de paiement"
] }),
s === "MOBILE" && /* @__PURE__ */ i(Z, { children: [
/* @__PURE__ */ i("div", { className: "grid grid-cols-2 gap-4", children: [
/* @__PURE__ */ t("div", { children: /* @__PURE__ */ t(
Me,
{
selectedCountry: o,
onChange: ce
}
) }),
/* @__PURE__ */ t("div", { children: /* @__PURE__ */ t(
Pe,
{
selectedNetwork: a,
onChange: le,
country: o
}
) })
] }),
/* @__PURE__ */ i("div", { className: "flex", children: [
/* @__PURE__ */ t("div", { className: "bg-gray-100 px-3 py-2 border border-r-0 rounded-l-md flex items-center justify-center", children: /* @__PURE__ */ t("span", { className: "text-gray-600 text-xs", children: Le(o) }) }),
/* @__PURE__ */ t(
"input",
{
type: "tel",
placeholder: "Numéro de téléphone sans indicatif",
className: "flex-1 px-2 py-2 border rounded-r-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: h,
onChange: ue
}
)
] }),
o === "SENEGAL" && a === "ORANGE" && /* @__PURE__ */ i(Z, { children: [
/* @__PURE__ */ t(
"input",
{
type: "text",
ref: ie,
id: "otp",
placeholder: "L’otp de validation",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs"
}
),
/* @__PURE__ */ t("span", { className: "text-xs text-gray-900", children: "L’otp de validation de la transaction obtenu en tapant #144#391# sur votre téléphone" })
] })
] }),
s === "CARD" && /* @__PURE__ */ i("div", { className: "space-y-4", children: [
/* @__PURE__ */ i("div", { className: "grid grid-cols-2 gap-4", children: [
/* @__PURE__ */ i("div", { children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Prénom" }),
/* @__PURE__ */ t(
"input",
{
type: "text",
placeholder: "Prénom",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: b.split(" ")[0] || "",
onChange: (n) => {
const u = b.split(" ").slice(1).join(" ");
T(`${n.target.value} ${u}`.trim());
}
}
)
] }),
/* @__PURE__ */ i("div", { children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Nom" }),
/* @__PURE__ */ t(
"input",
{
type: "text",
placeholder: "Nom",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: b.split(" ").slice(1).join(" ") || "",
onChange: (n) => {
const u = b.split(" ")[0] || "";
T(`${u} ${n.target.value}`.trim());
}
}
)
] })
] }),
/* @__PURE__ */ i("div", { children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Email" }),
/* @__PURE__ */ t(
"input",
{
type: "email",
placeholder: "exemple@email.com",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: N,
onChange: (n) => F(n.target.value)
}
)
] }),
/* @__PURE__ */ i("div", { children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Téléphone" }),
/* @__PURE__ */ t(
"input",
{
type: "tel",
placeholder: "Numéro de téléphone avec indicatif",
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: h,
onChange: (n) => _(n.target.value)
}
)
] }),
/* @__PURE__ */ i("div", { children: [
/* @__PURE__ */ t("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: "Type de carte" }),
/* @__PURE__ */ i(
"select",
{
className: "w-full px-2 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary-orange text-xs",
value: L,
onChange: (n) => E(n.target.value),
children: [
/* @__PURE__ */ t("option", { value: "VISA", children: "VISA" }),
/* @__PURE__ */ t("option", { value: "MASTERCARD", children: "MASTERCARD" })
]
}
)
] })
]