@asteby/storefront-react 0.8.0 → 0.10.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/README.md +60 -1
- package/dist/cart.js +2 -1
- package/dist/cart.js.map +1 -1
- package/dist/checkout.cjs +440 -0
- package/dist/checkout.cjs.map +1 -0
- package/dist/checkout.css +100 -0
- package/dist/checkout.d.cts +197 -0
- package/dist/checkout.d.ts +197 -0
- package/dist/checkout.js +243 -0
- package/dist/checkout.js.map +1 -0
- package/dist/choices-DEPE9KRq.d.cts +130 -0
- package/dist/choices-DEPE9KRq.d.ts +130 -0
- package/dist/chunk-DSZVJ2PW.js +180 -0
- package/dist/chunk-DSZVJ2PW.js.map +1 -0
- package/dist/chunk-ISEOCKIR.js +160 -0
- package/dist/chunk-ISEOCKIR.js.map +1 -0
- package/dist/chunk-T52H5HL3.js +11 -0
- package/dist/chunk-T52H5HL3.js.map +1 -0
- package/dist/{chunk-2WZIWIBW.js → chunk-ZBH7JYU4.js} +4 -10
- package/dist/chunk-ZBH7JYU4.js.map +1 -0
- package/dist/payments-server.cjs +369 -0
- package/dist/payments-server.cjs.map +1 -0
- package/dist/payments-server.d.cts +145 -0
- package/dist/payments-server.d.ts +145 -0
- package/dist/payments-server.js +191 -0
- package/dist/payments-server.js.map +1 -0
- package/dist/payments.cjs +639 -2
- package/dist/payments.cjs.map +1 -1
- package/dist/payments.css +57 -0
- package/dist/payments.d.cts +137 -21
- package/dist/payments.d.ts +137 -21
- package/dist/payments.js +332 -37
- package/dist/payments.js.map +1 -1
- package/dist/promotions.js +2 -1
- package/dist/promotions.js.map +1 -1
- package/package.json +24 -2
- package/dist/chunk-2WZIWIBW.js.map +0 -1
package/dist/payments.cjs
CHANGED
|
@@ -730,10 +730,10 @@ function paymentCsp(clients, options = {}) {
|
|
|
730
730
|
const dir = (name, values) => `${name} ${values.join(" ")}`;
|
|
731
731
|
const parts = [
|
|
732
732
|
"default-src 'self'",
|
|
733
|
-
dir("script-src", ["'self'", ...nonce ? [`'nonce-${nonce}'`] : [], ...origins(sdkOrigins, ...pick("script"), options.extra?.script)]),
|
|
733
|
+
dir("script-src", ["'self'", ...(options.scriptHashes ?? []).filter((h) => /^'sha(256|384|512)-[A-Za-z0-9+/=]+'$/.test(h)), ...nonce ? [`'nonce-${nonce}'`] : [], ...origins(sdkOrigins, ...pick("script"), options.extra?.script)]),
|
|
734
734
|
dir("frame-src", origins(...pick("frame"), options.extra?.frame).length ? origins(...pick("frame"), options.extra?.frame) : ["'none'"]),
|
|
735
735
|
dir("connect-src", ["'self'", ...origins(...pick("connect"), options.extra?.connect)]),
|
|
736
|
-
dir("img-src", ["'self'", "data:", ...origins(...pick("img"), options.extra?.img)]),
|
|
736
|
+
dir("img-src", ["'self'", "data:", ...options.imgHttps ? ["https:"] : [], ...origins(...pick("img"), options.extra?.img)]),
|
|
737
737
|
"style-src 'self' 'unsafe-inline'",
|
|
738
738
|
dir("form-action", ["'self'", ...origins(...pick("form"), options.extra?.form)]),
|
|
739
739
|
"frame-ancestors 'none'",
|
|
@@ -746,21 +746,658 @@ function paymentCsp(clients, options = {}) {
|
|
|
746
746
|
function paymentCspHeaderName(reportOnly) {
|
|
747
747
|
return reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy";
|
|
748
748
|
}
|
|
749
|
+
function paymentCspMode(value, production) {
|
|
750
|
+
const raw = (value ?? "").trim().toLowerCase();
|
|
751
|
+
if (raw === "off" || raw === "report-only" || raw === "enforce") return raw;
|
|
752
|
+
return production ? "report-only" : "off";
|
|
753
|
+
}
|
|
754
|
+
function paymentNonce() {
|
|
755
|
+
const bytes = new Uint8Array(16);
|
|
756
|
+
crypto.getRandomValues(bytes);
|
|
757
|
+
let bin = "";
|
|
758
|
+
for (const b of bytes) bin += String.fromCharCode(b);
|
|
759
|
+
return btoa(bin);
|
|
760
|
+
}
|
|
761
|
+
function paymentCspHeaders(clients, options) {
|
|
762
|
+
if (options.mode === "off") return {};
|
|
763
|
+
return { [paymentCspHeaderName(options.mode === "report-only")]: paymentCsp(clients, options) };
|
|
764
|
+
}
|
|
765
|
+
function paymentNonceFromHeaders(headers) {
|
|
766
|
+
const csp = headers.get("Content-Security-Policy") ?? headers.get("Content-Security-Policy-Report-Only") ?? "";
|
|
767
|
+
return /'nonce-([A-Za-z0-9+/=_-]+)'/.exec(csp)?.[1];
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// src/payments/payment-method.messages.ts
|
|
771
|
+
var ES = {
|
|
772
|
+
legend: "M\xE9todo de pago",
|
|
773
|
+
pay: "Pagar",
|
|
774
|
+
placeOrder: "Realizar el pedido",
|
|
775
|
+
payRedirect: "Continuar al pago",
|
|
776
|
+
continue: "Continuar",
|
|
777
|
+
retryAddress: "Guardar direcci\xF3n y continuar",
|
|
778
|
+
processing: "Procesando\u2026",
|
|
779
|
+
redirectNote: "Te llevamos a la p\xE1gina del proveedor para terminar el pago y regresas aqu\xED.",
|
|
780
|
+
cashPoints: "Elige d\xF3nde pagar en efectivo",
|
|
781
|
+
cashMore: "Ver m\xE1s puntos de pago",
|
|
782
|
+
cashNote: "Al hacer el pedido te damos una ficha con la referencia y la fecha l\xEDmite. El pedido se confirma cuando pagas.",
|
|
783
|
+
secureCard: "Tus datos de tarjeta los captura directamente nuestro proveedor de pagos; la tienda nunca los ve.",
|
|
784
|
+
pickDeliveryFirst: "Elige primero la entrega para ver el total y pagar con tarjeta.",
|
|
785
|
+
updatingTotal: "Actualizando el total\u2026",
|
|
786
|
+
syncFailed: "No pudimos actualizar el total con tu entrega. Puedes continuar al sitio del proveedor para pagar con tarjeta.",
|
|
787
|
+
quoteChanged: "Las tarifas de env\xEDo se actualizaron. Revisa tu env\xEDo para ver el total.",
|
|
788
|
+
rebuildCart: "Volver a armar mi carrito",
|
|
789
|
+
noPaymentTitle: "Por ahora no hay formas de pago disponibles",
|
|
790
|
+
noPayment: "Intenta de nuevo en unos minutos o escr\xEDbenos para completar tu pedido.",
|
|
791
|
+
paymentNote: "El pago se procesa de forma segura con nuestro proveedor de pagos.",
|
|
792
|
+
options: {
|
|
793
|
+
card: "Tarjeta de cr\xE9dito o d\xE9bito",
|
|
794
|
+
cash: "Efectivo",
|
|
795
|
+
wallet: "Cuenta del proveedor de pagos",
|
|
796
|
+
credits: "Pagos sin tarjeta"
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
var EN = {
|
|
800
|
+
legend: "Payment method",
|
|
801
|
+
pay: "Pay",
|
|
802
|
+
placeOrder: "Place order",
|
|
803
|
+
payRedirect: "Continue to payment",
|
|
804
|
+
continue: "Continue",
|
|
805
|
+
retryAddress: "Save address and continue",
|
|
806
|
+
processing: "Processing\u2026",
|
|
807
|
+
redirectNote: "We'll take you to the provider's page to finish paying, then bring you back here.",
|
|
808
|
+
cashPoints: "Choose where to pay in cash",
|
|
809
|
+
cashMore: "Show more payment points",
|
|
810
|
+
cashNote: "When you place the order you get a slip with the reference and the deadline. The order is confirmed once you pay.",
|
|
811
|
+
secureCard: "Your card details are captured directly by our payment provider; the shop never sees them.",
|
|
812
|
+
pickDeliveryFirst: "Choose delivery first to see the total and pay by card.",
|
|
813
|
+
updatingTotal: "Updating the total\u2026",
|
|
814
|
+
syncFailed: "We couldn't update the total with your delivery. You can continue to the provider's site to pay by card.",
|
|
815
|
+
quoteChanged: "Shipping rates were updated. Check your delivery to see the total.",
|
|
816
|
+
rebuildCart: "Rebuild my cart",
|
|
817
|
+
noPaymentTitle: "No payment methods are available right now",
|
|
818
|
+
noPayment: "Try again in a few minutes or contact us to complete your order.",
|
|
819
|
+
paymentNote: "Payment is processed securely by our payment provider.",
|
|
820
|
+
options: {
|
|
821
|
+
card: "Credit or debit card",
|
|
822
|
+
cash: "Cash",
|
|
823
|
+
wallet: "Payment provider account",
|
|
824
|
+
credits: "Pay without a card"
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
function paymentMethodMessages(locale, overrides) {
|
|
828
|
+
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
|
|
829
|
+
if (!overrides) return base;
|
|
830
|
+
const { options, ...rest } = overrides;
|
|
831
|
+
return { ...base, ...rest, options: { ...base.options, ...options } };
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// src/checkout/brands.ts
|
|
835
|
+
var B = (key, name, kind, bg, fg, mark, shape) => ({
|
|
836
|
+
key,
|
|
837
|
+
name,
|
|
838
|
+
kind,
|
|
839
|
+
bg,
|
|
840
|
+
fg,
|
|
841
|
+
...mark ? { mark } : {},
|
|
842
|
+
...shape ? { shape } : {}
|
|
843
|
+
});
|
|
844
|
+
var LIST = [
|
|
845
|
+
// Parcel carriers (Mexico and global).
|
|
846
|
+
B("fedex", "FedEx", "carrier", "#4D148C", "#FFFFFF"),
|
|
847
|
+
B("dhl", "DHL", "carrier", "#FFCC00", "#B00410"),
|
|
848
|
+
B("estafeta", "Estafeta", "carrier", "#C8102E", "#FFFFFF"),
|
|
849
|
+
B("paquetexpress", "Paquetexpress", "carrier", "#0B4EA2", "#FFFFFF", "Paquet\nexpress"),
|
|
850
|
+
B("ups", "UPS", "carrier", "#351C15", "#FFB500"),
|
|
851
|
+
B("redpack", "Redpack", "carrier", "#C8102E", "#FFFFFF"),
|
|
852
|
+
B("99minutos", "99 Minutos", "carrier", "#00704A", "#FFFFFF", "99"),
|
|
853
|
+
B("jtexpress", "J&T Express", "carrier", "#C8102E", "#FFFFFF", "J&T"),
|
|
854
|
+
B("sendex", "Sendex", "carrier", "#003A70", "#FFFFFF"),
|
|
855
|
+
B("ampm", "AMPM", "carrier", "#1D1D1B", "#FFFFFF"),
|
|
856
|
+
B("tresguerras", "Tresguerras", "carrier", "#005BAC", "#FFFFFF", "3G"),
|
|
857
|
+
B("quiken", "Quiken", "carrier", "#1D1D1B", "#FFFFFF"),
|
|
858
|
+
B("imile", "iMile", "carrier", "#0057B8", "#FFFFFF"),
|
|
859
|
+
B("carssa", "Carssa", "carrier", "#00529B", "#FFFFFF"),
|
|
860
|
+
B("correosdemexico", "Correos de M\xE9xico", "carrier", "#7A1E3A", "#FFFFFF", "Correos\nM\xE9xico"),
|
|
861
|
+
B("usps", "USPS", "carrier", "#333366", "#FFFFFF"),
|
|
862
|
+
B("canadapost", "Canada Post", "carrier", "#DA291C", "#FFFFFF", "CPC"),
|
|
863
|
+
// Card networks.
|
|
864
|
+
B("visa", "Visa", "card", "#1A1F71", "#FFFFFF", "VISA"),
|
|
865
|
+
B("mastercard", "Mastercard", "card", "#FFFFFF", "#1D1D1B", "MC", "mastercard"),
|
|
866
|
+
B("amex", "American Express", "card", "#1F72CD", "#FFFFFF", "AMEX"),
|
|
867
|
+
B("carnet", "Carnet", "card", "#003B71", "#FFFFFF"),
|
|
868
|
+
// Wallets and payment providers.
|
|
869
|
+
B("mercadopago", "Mercado Pago", "wallet", "#00B1EA", "#0B1F4E", "mercado\npago"),
|
|
870
|
+
B("paypal", "PayPal", "wallet", "#003087", "#FFFFFF"),
|
|
871
|
+
B("clip", "Clip", "wallet", "#FC4C02", "#1D1D1B"),
|
|
872
|
+
B("applepay", "Apple Pay", "wallet", "#000000", "#FFFFFF", "Pay"),
|
|
873
|
+
B("googlepay", "Google Pay", "wallet", "#FFFFFF", "#3C4043", "G Pay"),
|
|
874
|
+
// Cash points and transfers (Mexico).
|
|
875
|
+
B("oxxo", "OXXO", "cash", "#E21E26", "#FFE600"),
|
|
876
|
+
B("spei", "SPEI", "bank", "#14365F", "#FFFFFF"),
|
|
877
|
+
B("stp", "STP", "bank", "#14365F", "#FFFFFF", "SPEI"),
|
|
878
|
+
B("7eleven", "7-Eleven", "cash", "#00704A", "#FFFFFF", "7-11"),
|
|
879
|
+
B("circlek", "Circle K", "cash", "#DA291C", "#FFFFFF", "K"),
|
|
880
|
+
B("soriana", "Soriana", "cash", "#C8102E", "#FFFFFF"),
|
|
881
|
+
B("extra", "Extra", "cash", "#E35205", "#FFFFFF"),
|
|
882
|
+
B("kiosko", "Kiosko", "cash", "#C8102E", "#FFFFFF"),
|
|
883
|
+
B("calimax", "Calimax", "cash", "#D52B1E", "#FFFFFF"),
|
|
884
|
+
B("farmaciasyza", "Farmacias Yza", "cash", "#0A5A9C", "#FFFFFF", "Yza"),
|
|
885
|
+
B("chedraui", "Chedraui", "cash", "#0047BB", "#FFFFFF"),
|
|
886
|
+
B("casaley", "Casa Ley", "cash", "#C8102E", "#FFFFFF", "Ley"),
|
|
887
|
+
B("telecomm", "Telecomm", "cash", "#6F1D46", "#FFFFFF"),
|
|
888
|
+
B("walmart", "Walmart", "cash", "#0071CE", "#FFFFFF"),
|
|
889
|
+
B("santander", "Santander", "bank", "#C00000", "#FFFFFF"),
|
|
890
|
+
B("bbva", "BBVA", "bank", "#004481", "#FFFFFF"),
|
|
891
|
+
B("citibanamex", "Citibanamex", "bank", "#004B8D", "#FFFFFF", "Citi"),
|
|
892
|
+
B("banorte", "Banorte", "bank", "#C8102E", "#FFFFFF")
|
|
893
|
+
];
|
|
894
|
+
var ALIASES = {
|
|
895
|
+
fedexmx: "fedex",
|
|
896
|
+
fedexexpress: "fedex",
|
|
897
|
+
dhlexpress: "dhl",
|
|
898
|
+
dhlmx: "dhl",
|
|
899
|
+
paquetexpres: "paquetexpress",
|
|
900
|
+
paqueteexpress: "paquetexpress",
|
|
901
|
+
jt: "jtexpress",
|
|
902
|
+
jandtexpress: "jtexpress",
|
|
903
|
+
noventaynueveminutos: "99minutos",
|
|
904
|
+
correos: "correosdemexico",
|
|
905
|
+
sepomex: "correosdemexico",
|
|
906
|
+
master: "mastercard",
|
|
907
|
+
americanexpress: "amex",
|
|
908
|
+
mercadopagomx: "mercadopago",
|
|
909
|
+
mp: "mercadopago",
|
|
910
|
+
clabe: "spei",
|
|
911
|
+
banktransfer: "spei",
|
|
912
|
+
seveneleven: "7eleven",
|
|
913
|
+
"711": "7eleven",
|
|
914
|
+
circulok: "circlek",
|
|
915
|
+
yza: "farmaciasyza",
|
|
916
|
+
bancomer: "bbva",
|
|
917
|
+
banamex: "citibanamex",
|
|
918
|
+
ley: "casaley"
|
|
919
|
+
};
|
|
920
|
+
var BY_KEY = new Map(LIST.map((b) => [b.key, b]));
|
|
921
|
+
function brandKey(raw) {
|
|
922
|
+
const flat = (raw ?? "").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]/g, "");
|
|
923
|
+
const noCountry = flat.endsWith("mexico") && flat !== "correosdemexico" ? flat.slice(0, -6) : flat;
|
|
924
|
+
return ALIASES[noCountry] ?? (BY_KEY.has(noCountry) ? noCountry : ALIASES[flat] ?? flat);
|
|
925
|
+
}
|
|
926
|
+
function findBrand(raw) {
|
|
927
|
+
return BY_KEY.get(brandKey(raw)) ?? null;
|
|
928
|
+
}
|
|
929
|
+
function brandName(raw) {
|
|
930
|
+
const brand = findBrand(raw);
|
|
931
|
+
if (brand) return brand.name;
|
|
932
|
+
const text = (raw ?? "").trim();
|
|
933
|
+
if (!text) return null;
|
|
934
|
+
if (text !== text.toLowerCase() && text !== text.toUpperCase()) return text;
|
|
935
|
+
return text.toLowerCase().split(/[\s_-]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
936
|
+
}
|
|
937
|
+
function safeLogo(url) {
|
|
938
|
+
if (!url) return null;
|
|
939
|
+
try {
|
|
940
|
+
return new URL(url).protocol === "https:" ? url : null;
|
|
941
|
+
} catch {
|
|
942
|
+
return null;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
function monogram(raw) {
|
|
946
|
+
const words = (brandName(raw) ?? raw).split(/\s+/).filter(Boolean);
|
|
947
|
+
const letters = words.length > 1 ? words.slice(0, 2).map((w) => w[0]) : [(words[0] ?? "?").slice(0, 2)];
|
|
948
|
+
return letters.join("").toUpperCase();
|
|
949
|
+
}
|
|
950
|
+
function BrandMark({ brand, logoUrl, size = 24, title, className }) {
|
|
951
|
+
const height = size;
|
|
952
|
+
const width = Math.round(size * 1.5);
|
|
953
|
+
const a11y = title ? { role: "img", "aria-label": title } : { "aria-hidden": true };
|
|
954
|
+
const logo = safeLogo(logoUrl);
|
|
955
|
+
const found = findBrand(brand);
|
|
956
|
+
const key = found?.key ?? "generic";
|
|
957
|
+
const style = { width, height, flex: "none" };
|
|
958
|
+
if (logo) {
|
|
959
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
960
|
+
"img",
|
|
961
|
+
{
|
|
962
|
+
src: logo,
|
|
963
|
+
alt: title ?? "",
|
|
964
|
+
width,
|
|
965
|
+
height,
|
|
966
|
+
loading: "lazy",
|
|
967
|
+
decoding: "async",
|
|
968
|
+
className,
|
|
969
|
+
style: { ...style, objectFit: "contain" },
|
|
970
|
+
"data-sf-brand-mark": key,
|
|
971
|
+
...title ? {} : { "aria-hidden": true }
|
|
972
|
+
}
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
const ring = "var(--sf-brand-mark-ring, rgb(127 127 127 / 0.35))";
|
|
976
|
+
if (found?.shape === "mastercard") {
|
|
977
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 48 32", width, height, className, style, "data-sf-brand-mark": key, focusable: "false", ...a11y, children: [
|
|
978
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "47", height: "31", rx: "5", fill: found.bg, stroke: ring }),
|
|
979
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "19", cy: "16", r: "9", fill: "#EB001B" }),
|
|
980
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "29", cy: "16", r: "9", fill: "#F79E1B" }),
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M24 8.52a9 9 0 0 1 0 14.96a9 9 0 0 1 0-14.96z", fill: "#FF5F00" })
|
|
982
|
+
] });
|
|
983
|
+
}
|
|
984
|
+
const text = found ? found.mark ?? found.name : monogram(brand ?? "");
|
|
985
|
+
const bg = found?.bg ?? "var(--sf-brand-mark-bg, #E7E9EE)";
|
|
986
|
+
const fg = found?.fg ?? "var(--sf-brand-mark-fg, #2B2F38)";
|
|
987
|
+
const lines = text.split("\n");
|
|
988
|
+
const longest = Math.max(...lines.map((l) => l.length));
|
|
989
|
+
const fontSize = lines.length > 1 ? longest <= 5 ? 11 : 9.5 : longest <= 2 ? 15 : longest <= 4 ? 12 : 10;
|
|
990
|
+
const fit = (l) => l.length > 5 ? { textLength: 40, lengthAdjust: "spacingAndGlyphs" } : {};
|
|
991
|
+
const italic = found?.key === "visa" || found?.key === "fedex" ? "italic" : void 0;
|
|
992
|
+
const common = {
|
|
993
|
+
textAnchor: "middle",
|
|
994
|
+
fill: fg,
|
|
995
|
+
fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif",
|
|
996
|
+
fontWeight: 800,
|
|
997
|
+
fontSize,
|
|
998
|
+
fontStyle: italic
|
|
999
|
+
};
|
|
1000
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 48 32", width, height, className, style, "data-sf-brand-mark": key, focusable: "false", ...a11y, children: [
|
|
1001
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "47", height: "31", rx: "5", fill: bg, stroke: ring }),
|
|
1002
|
+
lines.length > 1 ? lines.slice(0, 2).map((l, i) => /* @__PURE__ */ jsxRuntime.jsx("text", { x: "24", y: i === 0 ? 15 : 25.5, ...common, ...fit(l), children: l }, i)) : /* @__PURE__ */ jsxRuntime.jsx("text", { x: "24", y: "16", dominantBaseline: "central", letterSpacing: longest <= 4 ? 0.3 : 0, ...common, ...fit(text), children: text })
|
|
1003
|
+
] });
|
|
1004
|
+
}
|
|
1005
|
+
var PAYMENT_CHOICE_FIELD = "payment_choice";
|
|
1006
|
+
var CASH_POINT_FIELD = "cash_point";
|
|
1007
|
+
function formFields(form) {
|
|
1008
|
+
const out = {};
|
|
1009
|
+
if (!form) return out;
|
|
1010
|
+
for (const [k, v] of new FormData(form).entries()) if (typeof v === "string") out[k] = v;
|
|
1011
|
+
return out;
|
|
1012
|
+
}
|
|
1013
|
+
var useHydrated = () => react.useSyncExternalStore(
|
|
1014
|
+
() => () => {
|
|
1015
|
+
},
|
|
1016
|
+
() => true,
|
|
1017
|
+
() => false
|
|
1018
|
+
);
|
|
1019
|
+
function PaymentMethodSection(props) {
|
|
1020
|
+
const {
|
|
1021
|
+
choices,
|
|
1022
|
+
amount,
|
|
1023
|
+
scope,
|
|
1024
|
+
formRef,
|
|
1025
|
+
payUrl,
|
|
1026
|
+
statusUrl,
|
|
1027
|
+
delivery = "",
|
|
1028
|
+
deliveryReady = true,
|
|
1029
|
+
syncDelivery,
|
|
1030
|
+
addressFirst = false,
|
|
1031
|
+
retryAddress = false,
|
|
1032
|
+
blocked = false,
|
|
1033
|
+
busy = false,
|
|
1034
|
+
invalid,
|
|
1035
|
+
nonce,
|
|
1036
|
+
methodLabel,
|
|
1037
|
+
icons,
|
|
1038
|
+
brandMarks = true,
|
|
1039
|
+
cardBrands = [],
|
|
1040
|
+
renderAmount,
|
|
1041
|
+
rebuildHref,
|
|
1042
|
+
renderLink,
|
|
1043
|
+
onDone,
|
|
1044
|
+
onAmountChanged,
|
|
1045
|
+
onEvent,
|
|
1046
|
+
classNames: cx = {},
|
|
1047
|
+
testIds = {},
|
|
1048
|
+
hideSubmit,
|
|
1049
|
+
brickProps
|
|
1050
|
+
} = props;
|
|
1051
|
+
const locale = useResolvedLocale(props.locale);
|
|
1052
|
+
const m = react.useMemo(() => paymentMethodMessages(locale, props.messages), [locale, props.messages]);
|
|
1053
|
+
const hydrated = useHydrated();
|
|
1054
|
+
const [choiceValue2, setChoiceValue] = react.useState(props.defaultChoice ?? choices.defaultValue);
|
|
1055
|
+
const selected = choices.choices.find((c) => c.value === choiceValue2) ?? null;
|
|
1056
|
+
const noPayment = choices.choices.length === 0;
|
|
1057
|
+
const tid = (k) => testIds[k] ? { "data-testid": testIds[k] } : {};
|
|
1058
|
+
const [fallback, setFallback] = react.useState(false);
|
|
1059
|
+
const [ready, setReady] = react.useState(false);
|
|
1060
|
+
const [processing, setProcessing] = react.useState(false);
|
|
1061
|
+
const [expired, setExpired] = react.useState(false);
|
|
1062
|
+
const brick = react.useRef(null);
|
|
1063
|
+
const cardChosen = selected?.mode === "card" && !retryAddress && !addressFirst;
|
|
1064
|
+
const cardActive = hydrated && cardChosen && !fallback;
|
|
1065
|
+
const wantSync = hydrated && selected !== null && !addressFirst && !retryAddress && deliveryReady && Boolean(syncDelivery);
|
|
1066
|
+
const [sync, setSync] = react.useState(null);
|
|
1067
|
+
const syncRef = react.useRef(syncDelivery);
|
|
1068
|
+
syncRef.current = syncDelivery;
|
|
1069
|
+
react.useEffect(() => {
|
|
1070
|
+
if (!wantSync || !syncRef.current) return;
|
|
1071
|
+
if (sync?.key === delivery && sync.ok) return;
|
|
1072
|
+
let cancelled = false;
|
|
1073
|
+
syncRef.current(delivery).then(
|
|
1074
|
+
(ok) => !cancelled && setSync(ok === "requote" ? { key: delivery, ok: false, requote: true } : { key: delivery, ok }),
|
|
1075
|
+
() => !cancelled && setSync({ key: delivery, ok: false })
|
|
1076
|
+
);
|
|
1077
|
+
return () => {
|
|
1078
|
+
cancelled = true;
|
|
1079
|
+
};
|
|
1080
|
+
}, [wantSync, delivery]);
|
|
1081
|
+
const settled = sync?.key === delivery;
|
|
1082
|
+
const synced = !syncDelivery || settled && sync.ok;
|
|
1083
|
+
const requote = wantSync && settled && sync.requote === true;
|
|
1084
|
+
const syncFailed = wantSync && settled && !sync.ok && !requote;
|
|
1085
|
+
const brickReady = cardActive && deliveryReady && synced && !syncFailed;
|
|
1086
|
+
const transport = react.useMemo(
|
|
1087
|
+
() => props.transport ?? createFetchTransport(payUrl, {
|
|
1088
|
+
...statusUrl ? { refreshUrl: statusUrl } : {},
|
|
1089
|
+
buildBody: (request) => ({ ...request, fields: formFields(formRef.current) })
|
|
1090
|
+
}),
|
|
1091
|
+
[props.transport, payUrl, statusUrl, formRef]
|
|
1092
|
+
);
|
|
1093
|
+
const handleEvent = (e) => {
|
|
1094
|
+
if (e.type === "form_ready") setReady(true);
|
|
1095
|
+
if (e.type === "submit") setProcessing(true);
|
|
1096
|
+
if (e.type === "tokenize_error" || e.type === "retry") setProcessing(e.type === "retry");
|
|
1097
|
+
if (e.type === "result" && e.status === "rejected") setProcessing(false);
|
|
1098
|
+
if (e.type === "error") {
|
|
1099
|
+
setProcessing(false);
|
|
1100
|
+
if (e.kind === "price_mismatch") onAmountChanged?.();
|
|
1101
|
+
if (e.kind === "expired") setExpired(true);
|
|
1102
|
+
}
|
|
1103
|
+
onEvent?.(e);
|
|
1104
|
+
};
|
|
1105
|
+
const total = wantSync && (!settled || requote) ? null : renderAmount ? renderAmount(amount) : storefront.formatMoney(amount, locale);
|
|
1106
|
+
const label = retryAddress ? m.retryAddress : addressFirst ? m.continue : selected?.mode === "plain" || !selected ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1107
|
+
m.pay,
|
|
1108
|
+
total ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1109
|
+
" ",
|
|
1110
|
+
total
|
|
1111
|
+
] }) : null
|
|
1112
|
+
] }) : selected.mode === "redirect" || selected.mode === "card" && (fallback || syncFailed) ? m.payRedirect : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1113
|
+
m.placeOrder,
|
|
1114
|
+
total ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1115
|
+
" ",
|
|
1116
|
+
total
|
|
1117
|
+
] }) : null
|
|
1118
|
+
] });
|
|
1119
|
+
function onPayClick(event) {
|
|
1120
|
+
if (!cardActive || syncFailed) return;
|
|
1121
|
+
event.preventDefault();
|
|
1122
|
+
const form = formRef.current;
|
|
1123
|
+
if (form && !form.reportValidity()) return;
|
|
1124
|
+
if (brickReady) void brick.current?.submit();
|
|
1125
|
+
}
|
|
1126
|
+
const cardNotice = (k, node) => k === "syncFailed" ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: cx.alert, "data-sf-pay-notice": "sync-failed", ...tid("syncFailed"), children: node }) : /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: cx.status, "data-sf-pay-notice": k, ...k === "syncing" ? tid("syncing") : {}, children: node });
|
|
1127
|
+
const Link = renderLink ?? (({ href, className, children, testId }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, ...testId ? { "data-testid": testId } : {}, children }));
|
|
1128
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { id: "pago", className: cx.root, "data-sf-pay-method": true, children: [
|
|
1129
|
+
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: cx.legend, children: m.legend }),
|
|
1130
|
+
choices.choices.map((choice) => {
|
|
1131
|
+
const { label: rowLabel, hint } = rowText(choice, m, methodLabel);
|
|
1132
|
+
const checked = choice.value === choiceValue2;
|
|
1133
|
+
const slot = choice.option ?? "plain";
|
|
1134
|
+
const icon = icons?.[slot] ?? (brandMarks ? defaultIcon(choice) : null);
|
|
1135
|
+
const marks = brandMarks ? rowMarks(choice, cardBrands) : [];
|
|
1136
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.choice, "data-sf-pay-choice": true, children: [
|
|
1137
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: cx.radioLabel, children: [
|
|
1138
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1139
|
+
"input",
|
|
1140
|
+
{
|
|
1141
|
+
type: "radio",
|
|
1142
|
+
name: PAYMENT_CHOICE_FIELD,
|
|
1143
|
+
value: choice.value,
|
|
1144
|
+
checked,
|
|
1145
|
+
onChange: () => setChoiceValue(choice.value),
|
|
1146
|
+
"aria-invalid": invalid?.has("payment_method") || void 0,
|
|
1147
|
+
"data-mode": choice.mode,
|
|
1148
|
+
required: true,
|
|
1149
|
+
className: cx.radio,
|
|
1150
|
+
...tid("method")
|
|
1151
|
+
}
|
|
1152
|
+
),
|
|
1153
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.icon, "aria-hidden": "true", children: icon }) : null,
|
|
1154
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx.labelText, children: [
|
|
1155
|
+
rowLabel,
|
|
1156
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx.hint, children: [
|
|
1157
|
+
" ",
|
|
1158
|
+
hint
|
|
1159
|
+
] }) : null
|
|
1160
|
+
] }),
|
|
1161
|
+
marks.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.brands, "data-sf-pay-brands": choice.option ?? "plain", "aria-hidden": "true", children: marks.map((mk) => /* @__PURE__ */ jsxRuntime.jsx(BrandMark, { brand: mk.key, logoUrl: mk.logoUrl ?? null, size: 20 }, mk.key)) }) : null
|
|
1162
|
+
] }),
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChoicePanel, { choice, m, invalid, cx, tid, hidden: hydrated && !checked, marks: brandMarks })
|
|
1164
|
+
] }, choice.value);
|
|
1165
|
+
}),
|
|
1166
|
+
noPayment ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: cx.alert, "data-sf-pay-notice": "no-payment", ...tid("noPayment"), children: [
|
|
1167
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: m.noPaymentTitle }) }),
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: m.noPayment })
|
|
1169
|
+
] }) : null,
|
|
1170
|
+
cardChosen && hydrated && choices.cardClient ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.brickWrap, "data-sf-pay-card": true, ...tid("card"), children: [
|
|
1171
|
+
fallback ? null : !deliveryReady ? cardNotice("pickDelivery", m.pickDeliveryFirst) : syncFailed ? cardNotice("syncFailed", m.syncFailed) : requote ? cardNotice("requote", m.quoteChanged) : !synced ? cardNotice("syncing", m.updatingTotal) : null,
|
|
1172
|
+
brickReady || fallback ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1173
|
+
PaymentBrick,
|
|
1174
|
+
{
|
|
1175
|
+
...brickProps,
|
|
1176
|
+
ref: brick,
|
|
1177
|
+
client: choices.cardClient,
|
|
1178
|
+
amount,
|
|
1179
|
+
transport,
|
|
1180
|
+
...nonce ? { nonce } : {},
|
|
1181
|
+
locale,
|
|
1182
|
+
...scope ? { scope } : {},
|
|
1183
|
+
enabled: brickReady,
|
|
1184
|
+
...cx.brick ? { className: cx.brick } : {},
|
|
1185
|
+
onEvent: handleEvent,
|
|
1186
|
+
onFallback: () => setFallback(true),
|
|
1187
|
+
onResult: (o) => {
|
|
1188
|
+
if (o.kind === "approved" || o.kind === "in_review" || o.kind === "voucher") onDone(o);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
) : null,
|
|
1192
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, children: m.secureCard }),
|
|
1193
|
+
expired && rebuildHref ? Link({ href: rebuildHref, ...cx.rebuild ? { className: cx.rebuild } : {}, children: m.rebuildCart, ...testIds.rebuild ? { testId: testIds.rebuild } : {} }) : null
|
|
1194
|
+
] }) : null,
|
|
1195
|
+
noPayment || choices.choices.some((c) => c.option) ? null : /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, children: m.paymentNote }),
|
|
1196
|
+
hideSubmit ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1197
|
+
"button",
|
|
1198
|
+
{
|
|
1199
|
+
type: "submit",
|
|
1200
|
+
onClick: onPayClick,
|
|
1201
|
+
className: cx.submit,
|
|
1202
|
+
disabled: busy || blocked,
|
|
1203
|
+
"aria-disabled": blocked || brickReady && (!ready || processing) || void 0,
|
|
1204
|
+
"aria-busy": processing || void 0,
|
|
1205
|
+
"data-sf-pay-method-submit": true,
|
|
1206
|
+
...tid("submit"),
|
|
1207
|
+
children: busy || processing ? m.processing : label
|
|
1208
|
+
}
|
|
1209
|
+
)
|
|
1210
|
+
] });
|
|
1211
|
+
}
|
|
1212
|
+
function rowText(choice, m, methodLabel) {
|
|
1213
|
+
if (choice.mode === "plain") return methodLabel ? methodLabel(choice.methodKey) : { label: choice.methodKey };
|
|
1214
|
+
return { label: choice.label ?? (choice.option ? m.options[choice.option] : void 0) ?? choice.option ?? choice.methodKey };
|
|
1215
|
+
}
|
|
1216
|
+
function ChoicePanel({
|
|
1217
|
+
choice,
|
|
1218
|
+
m,
|
|
1219
|
+
invalid,
|
|
1220
|
+
cx,
|
|
1221
|
+
tid,
|
|
1222
|
+
hidden,
|
|
1223
|
+
marks = true
|
|
1224
|
+
}) {
|
|
1225
|
+
if (choice.mode === "redirect") {
|
|
1226
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.panel, hidden, "data-sf-pay-panel": "redirect", ...tid("redirectNote"), children: m.redirectNote });
|
|
1227
|
+
}
|
|
1228
|
+
if (choice.mode !== "cash") return null;
|
|
1229
|
+
const main = choice.points.filter((p) => p.group === "main");
|
|
1230
|
+
const more = choice.points.filter((p) => p.group !== "main");
|
|
1231
|
+
const row = (p, i, first) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cx.cashPoint, "data-sf-pay-point": true, children: [
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", { type: "radio", name: CASH_POINT_FIELD, value: p.id, defaultChecked: first && i === 0, className: cx.cashPointInput, "aria-invalid": invalid?.has("cash_point") || void 0 }),
|
|
1233
|
+
marks ? /* @__PURE__ */ jsxRuntime.jsx(BrandMark, { brand: p.payment_point || p.id, logoUrl: p.logo_url ?? null, size: 22 }) : null,
|
|
1234
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: p.label })
|
|
1235
|
+
] }, p.id);
|
|
1236
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.panel, hidden, "data-sf-pay-panel": "cash", ...tid("cash"), children: [
|
|
1237
|
+
/* @__PURE__ */ jsxRuntime.jsxs("fieldset", { children: [
|
|
1238
|
+
/* @__PURE__ */ jsxRuntime.jsx("legend", { children: m.cashPoints }),
|
|
1239
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-sf-pay-points": true, children: main.map((p, i) => row(p, i, true)) }),
|
|
1240
|
+
more.length ? /* @__PURE__ */ jsxRuntime.jsxs("details", { children: [
|
|
1241
|
+
/* @__PURE__ */ jsxRuntime.jsx("summary", { className: cx.cashMore, style: { minHeight: 44 }, children: m.cashMore }),
|
|
1242
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-sf-pay-points": true, children: more.map((p, i) => row(p, i, false)) })
|
|
1243
|
+
] }) : null
|
|
1244
|
+
] }),
|
|
1245
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, children: m.cashNote })
|
|
1246
|
+
] });
|
|
1247
|
+
}
|
|
1248
|
+
var glyph = (d) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "24", height: "24", fill: "none", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", strokeLinejoin: "round", focusable: "false", "data-sf-pay-glyph": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d }) });
|
|
1249
|
+
var CARD_GLYPH = "M3 6.5h18v11H3zM3 10h18M6.5 14.5h4";
|
|
1250
|
+
var CASH_GLYPH = "M3 7h18v10H3zM12 14.5a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5zM6 10v4M18 10v4";
|
|
1251
|
+
function defaultIcon(choice) {
|
|
1252
|
+
if (choice.option === "card") return glyph(CARD_GLYPH);
|
|
1253
|
+
if (choice.option === "cash") return glyph(CASH_GLYPH);
|
|
1254
|
+
return findBrand(choice.methodKey) ? /* @__PURE__ */ jsxRuntime.jsx(BrandMark, { brand: choice.methodKey, size: 24 }) : null;
|
|
1255
|
+
}
|
|
1256
|
+
function rowMarks(choice, cardBrands) {
|
|
1257
|
+
if (choice.option === "card") return cardBrands.map((key) => ({ key }));
|
|
1258
|
+
if (choice.option === "cash") {
|
|
1259
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1260
|
+
const out = [];
|
|
1261
|
+
for (const p of choice.points) {
|
|
1262
|
+
const key = p.payment_point || p.id;
|
|
1263
|
+
if (p.group !== "main" || seen.has(key)) continue;
|
|
1264
|
+
seen.add(key);
|
|
1265
|
+
out.push({ key, logoUrl: p.logo_url ?? null });
|
|
1266
|
+
if (out.length === 4) break;
|
|
1267
|
+
}
|
|
1268
|
+
return out;
|
|
1269
|
+
}
|
|
1270
|
+
return [];
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/payments/choices.ts
|
|
1274
|
+
var SEP = "|";
|
|
1275
|
+
function choiceValue(methodKey, option) {
|
|
1276
|
+
return option ? `${methodKey}${SEP}${option}` : methodKey;
|
|
1277
|
+
}
|
|
1278
|
+
function parseChoice(value) {
|
|
1279
|
+
const raw = (value ?? "").trim();
|
|
1280
|
+
if (!raw) return null;
|
|
1281
|
+
const i = raw.lastIndexOf(SEP);
|
|
1282
|
+
if (i === -1) return { methodKey: raw, option: null };
|
|
1283
|
+
const option = raw.slice(i + 1);
|
|
1284
|
+
if (option !== "card" && option !== "cash" && option !== "wallet" && option !== "credits") return null;
|
|
1285
|
+
return { methodKey: raw.slice(0, i), option };
|
|
1286
|
+
}
|
|
1287
|
+
function modeOf(option) {
|
|
1288
|
+
if (option.redirect || option.key === "wallet" || option.key === "credits") return "redirect";
|
|
1289
|
+
return option.key === "cash" ? "cash" : "card";
|
|
1290
|
+
}
|
|
1291
|
+
function buildPayChoices(methods, options = {}) {
|
|
1292
|
+
const hidden = new Set(options.hide ?? []);
|
|
1293
|
+
const choices = [];
|
|
1294
|
+
let cardClient = null;
|
|
1295
|
+
let defaultValue = null;
|
|
1296
|
+
for (const method of methods) {
|
|
1297
|
+
if (hidden.has(method.key)) continue;
|
|
1298
|
+
const opts = method.options ?? [];
|
|
1299
|
+
if (opts.length === 0) {
|
|
1300
|
+
const value = choiceValue(method.key, null);
|
|
1301
|
+
choices.push({ value, methodKey: method.key, option: null, mode: "plain", label: null, points: [], maxInstallments: null });
|
|
1302
|
+
if (method.default && !defaultValue) defaultValue = value;
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
opts.forEach((option, i) => {
|
|
1306
|
+
const mode = modeOf(option);
|
|
1307
|
+
const value = choiceValue(method.key, option.key);
|
|
1308
|
+
choices.push({
|
|
1309
|
+
value,
|
|
1310
|
+
methodKey: method.key,
|
|
1311
|
+
option: option.key,
|
|
1312
|
+
mode,
|
|
1313
|
+
label: option.label?.trim() || null,
|
|
1314
|
+
points: option.key === "cash" ? option.points ?? [] : [],
|
|
1315
|
+
maxInstallments: option.max_installments ?? null
|
|
1316
|
+
});
|
|
1317
|
+
if (mode === "card" && method.client && !cardClient) cardClient = method.client;
|
|
1318
|
+
if (method.default && i === 0 && !defaultValue) defaultValue = value;
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
const usable = choices.map((c) => c.mode === "card" && !cardClient ? { ...c, mode: "redirect" } : c);
|
|
1322
|
+
return { choices: usable, cardClient, defaultValue: defaultValue ?? usable[0]?.value ?? null };
|
|
1323
|
+
}
|
|
1324
|
+
function cashProviderData(points, pointId) {
|
|
1325
|
+
const point = points.find((p) => p.id === pointId) ?? (pointId ? null : points[0]);
|
|
1326
|
+
if (!point) return null;
|
|
1327
|
+
return {
|
|
1328
|
+
payment_method_id: point.payment_method_id,
|
|
1329
|
+
...point.payment_point ? { payment_point: point.payment_point } : {}
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
function checkoutToAttempt(result) {
|
|
1333
|
+
const { checkout, payment, order } = result;
|
|
1334
|
+
const action = payment.action ?? null;
|
|
1335
|
+
const base = { checkout, ...order ? { order } : {} };
|
|
1336
|
+
const status = (checkout.status ?? "").toLowerCase();
|
|
1337
|
+
if (status === "paid" || status === "converted") return { ...base, payment: { provider: payment.provider, status: "paid", outcome: "approved" } };
|
|
1338
|
+
if (status === "cancelled" || status === "canceled") return { ...base, payment: { provider: payment.provider, status: "cancelled" } };
|
|
1339
|
+
if (status === "expired") return { ...base, payment: { provider: payment.provider, status: "expired" } };
|
|
1340
|
+
if (status === "failed") {
|
|
1341
|
+
const decline = payment.decline_code ?? "declined";
|
|
1342
|
+
return { ...base, payment: { provider: payment.provider, status: "failed", outcome: "rejected", decline_code: decline, retryable: true } };
|
|
1343
|
+
}
|
|
1344
|
+
if (action?.type === "challenge") return { ...base, payment: { provider: payment.provider, status: "requires_action", outcome: "challenge", action } };
|
|
1345
|
+
return { ...base, payment: { provider: payment.provider, status: "pending", outcome: "pending", action: action ?? { type: "none" } } };
|
|
1346
|
+
}
|
|
1347
|
+
function payErrorResponse(err) {
|
|
1348
|
+
const status = typeof err.status === "number" && err.status >= 400 ? err.status : 503;
|
|
1349
|
+
let code = err.code ?? "server_error";
|
|
1350
|
+
if (status === 409 && err.field === "payment_in_progress") code = "payment_in_progress";
|
|
1351
|
+
if (status === 429) code = "too_many_attempts";
|
|
1352
|
+
if (status === 422 && err.field === "expected_total") code = "price_mismatch";
|
|
1353
|
+
return { status, body: { error: { code, message: err.message ?? "", ...err.details !== void 0 ? { details: err.details } : {} } } };
|
|
1354
|
+
}
|
|
1355
|
+
function voucherRows(voucher, labels, locale) {
|
|
1356
|
+
if (!voucher) return [];
|
|
1357
|
+
const rows = [];
|
|
1358
|
+
if (voucher.payment_point) rows.push([labels.point, String(voucher.payment_point).slice(0, 60)]);
|
|
1359
|
+
if (voucher.reference) rows.push([labels.reference, String(voucher.reference).slice(0, 80)]);
|
|
1360
|
+
if (voucher.clabe) rows.push([labels.clabe, String(voucher.clabe).slice(0, 40)]);
|
|
1361
|
+
if (voucher.barcode) rows.push([labels.barcode, String(voucher.barcode).slice(0, 80)]);
|
|
1362
|
+
if (voucher.expires_at) {
|
|
1363
|
+
const d = new Date(voucher.expires_at);
|
|
1364
|
+
if (!Number.isNaN(d.getTime())) {
|
|
1365
|
+
rows.push([labels.expires, new Intl.DateTimeFormat(locale, { dateStyle: "long", timeStyle: "short", timeZone: "UTC" }).format(d) + " UTC"]);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
return rows;
|
|
1369
|
+
}
|
|
749
1370
|
|
|
1371
|
+
exports.CASH_POINT_FIELD = CASH_POINT_FIELD;
|
|
750
1372
|
exports.MERCADOPAGO_BRICKS_KIND = MERCADOPAGO_BRICKS_KIND;
|
|
1373
|
+
exports.PAYMENT_CHOICE_FIELD = PAYMENT_CHOICE_FIELD;
|
|
751
1374
|
exports.PAYMENT_THEME_TOKENS = PAYMENT_THEME_TOKENS;
|
|
752
1375
|
exports.PaymentBrick = PaymentBrick;
|
|
753
1376
|
exports.PaymentChallenge = PaymentChallenge;
|
|
754
1377
|
exports.PaymentHttpError = PaymentHttpError;
|
|
1378
|
+
exports.PaymentMethodSection = PaymentMethodSection;
|
|
755
1379
|
exports.VoucherCard = VoucherCard;
|
|
1380
|
+
exports.buildPayChoices = buildPayChoices;
|
|
1381
|
+
exports.cashProviderData = cashProviderData;
|
|
1382
|
+
exports.checkoutToAttempt = checkoutToAttempt;
|
|
1383
|
+
exports.choiceValue = choiceValue;
|
|
756
1384
|
exports.createFetchTransport = createFetchTransport;
|
|
1385
|
+
exports.formFields = formFields;
|
|
757
1386
|
exports.loadPaymentSdk = loadPaymentSdk;
|
|
758
1387
|
exports.mercadoPagoBricksAdapter = mercadoPagoBricksAdapter;
|
|
1388
|
+
exports.parseChoice = parseChoice;
|
|
1389
|
+
exports.payErrorResponse = payErrorResponse;
|
|
759
1390
|
exports.paymentCsp = paymentCsp;
|
|
760
1391
|
exports.paymentCspHeaderName = paymentCspHeaderName;
|
|
1392
|
+
exports.paymentCspHeaders = paymentCspHeaders;
|
|
1393
|
+
exports.paymentCspMode = paymentCspMode;
|
|
1394
|
+
exports.paymentMethodMessages = paymentMethodMessages;
|
|
1395
|
+
exports.paymentNonce = paymentNonce;
|
|
1396
|
+
exports.paymentNonceFromHeaders = paymentNonceFromHeaders;
|
|
761
1397
|
exports.readPaymentTheme = readPaymentTheme;
|
|
762
1398
|
exports.resetPaymentSdkCache = resetPaymentSdkCache;
|
|
763
1399
|
exports.sanitizeMercadoPagoFormData = sanitizeMercadoPagoFormData;
|
|
764
1400
|
exports.useEmbeddedPayment = useEmbeddedPayment;
|
|
1401
|
+
exports.voucherRows = voucherRows;
|
|
765
1402
|
//# sourceMappingURL=payments.cjs.map
|
|
766
1403
|
//# sourceMappingURL=payments.cjs.map
|