@fayz-ai/storefront 0.15.0 → 0.16.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/{chunk-AEV2QRRH.js → chunk-STL6MATQ.js} +264 -20
- package/dist/chunk-STL6MATQ.js.map +1 -0
- package/dist/components/cart/CartDrawer.d.ts.map +1 -1
- package/dist/components/checkout/CardBrick.d.ts +64 -0
- package/dist/components/checkout/CardBrick.d.ts.map +1 -0
- package/dist/components/checkout/CheckoutPayment.d.ts +10 -1
- package/dist/components/checkout/CheckoutPayment.d.ts.map +1 -1
- package/dist/hooks/use-checkout.d.ts.map +1 -1
- package/dist/hooks/use-discount-validator.d.ts +2 -0
- package/dist/hooks/use-discount-validator.d.ts.map +1 -1
- package/dist/hooks/use-shipping.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/render.js +1 -1
- package/dist/stores/cart.store.d.ts +12 -3
- package/dist/stores/cart.store.d.ts.map +1 -1
- package/dist/views/CheckoutPage.d.ts.map +1 -1
- package/dist/workflows/checkout.d.ts +1 -1
- package/dist/workflows/checkout.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-AEV2QRRH.js.map +0 -1
|
@@ -329,6 +329,7 @@ var useCartStore = create()(
|
|
|
329
329
|
lines: [],
|
|
330
330
|
discountCode: null,
|
|
331
331
|
discountPercent: 0,
|
|
332
|
+
discountFreeShipping: false,
|
|
332
333
|
isOpen: false,
|
|
333
334
|
justAddedLineId: null,
|
|
334
335
|
addItem: (product, qty = 1, options) => set((state) => {
|
|
@@ -384,9 +385,13 @@ var useCartStore = create()(
|
|
|
384
385
|
};
|
|
385
386
|
}),
|
|
386
387
|
removeItem: (lineId) => set((state) => ({ lines: state.lines.filter((l) => (l.lineId ?? l.productId) !== lineId) })),
|
|
387
|
-
applyDiscount: (code, percent) => set({
|
|
388
|
-
|
|
389
|
-
|
|
388
|
+
applyDiscount: (code, percent, options) => set({
|
|
389
|
+
discountCode: code,
|
|
390
|
+
discountPercent: percent,
|
|
391
|
+
discountFreeShipping: options?.freeShipping === true
|
|
392
|
+
}),
|
|
393
|
+
clearDiscount: () => set({ discountCode: null, discountPercent: 0, discountFreeShipping: false }),
|
|
394
|
+
clear: () => set({ lines: [], discountCode: null, discountPercent: 0, discountFreeShipping: false }),
|
|
390
395
|
openDrawer: () => set({ isOpen: true }),
|
|
391
396
|
closeDrawer: () => set({ isOpen: false, justAddedLineId: null }),
|
|
392
397
|
reconcile: async (resolve) => {
|
|
@@ -404,7 +409,8 @@ var useCartStore = create()(
|
|
|
404
409
|
partialize: (state) => ({
|
|
405
410
|
lines: state.lines,
|
|
406
411
|
discountCode: state.discountCode,
|
|
407
|
-
discountPercent: state.discountPercent
|
|
412
|
+
discountPercent: state.discountPercent,
|
|
413
|
+
discountFreeShipping: state.discountFreeShipping
|
|
408
414
|
})
|
|
409
415
|
}
|
|
410
416
|
)
|
|
@@ -416,6 +422,7 @@ var selectRequiresShipping = (s2) => s2.lines.some((l) => l.requiresShipping !==
|
|
|
416
422
|
var selectShipping = (s2, cfg) => {
|
|
417
423
|
if (s2.lines.length === 0) return 0;
|
|
418
424
|
if (!selectRequiresShipping(s2)) return 0;
|
|
425
|
+
if (s2.discountFreeShipping) return 0;
|
|
419
426
|
const subtotal = selectSubtotal(s2);
|
|
420
427
|
const quoted = selectQuotedShipping(useDeliveryStore.getState(), subtotal);
|
|
421
428
|
if (quoted != null) return quoted;
|
|
@@ -6909,6 +6916,9 @@ var REASON_MESSAGE = {
|
|
|
6909
6916
|
rules_not_matched: "Este cupom n\xE3o se aplica ao seu carrinho.",
|
|
6910
6917
|
unsupported: "Este cupom n\xE3o \xE9 suportado na loja."
|
|
6911
6918
|
};
|
|
6919
|
+
function cartSubtotal() {
|
|
6920
|
+
return selectSubtotal({ lines: useCartStore.getState().lines });
|
|
6921
|
+
}
|
|
6912
6922
|
function cartSnapshot() {
|
|
6913
6923
|
const lines = useCartStore.getState().lines;
|
|
6914
6924
|
return {
|
|
@@ -6930,15 +6940,21 @@ function useDiscountValidator() {
|
|
|
6930
6940
|
...(config.discounts ?? []).map(storefrontDiscountToPromotion)
|
|
6931
6941
|
];
|
|
6932
6942
|
const localPreview = previewCouponPercent(local, normalized, cartSnapshot());
|
|
6933
|
-
if (localPreview.valid)
|
|
6943
|
+
if (localPreview.valid) {
|
|
6944
|
+
return { valid: true, percent: localPreview.percent, freeShipping: localPreview.freeShipping };
|
|
6945
|
+
}
|
|
6934
6946
|
if (localPreview.reason !== "not_found") {
|
|
6935
6947
|
return { valid: false, percent: 0, message: REASON_MESSAGE[localPreview.reason ?? "not_found"] ?? "Cupom inv\xE1lido." };
|
|
6936
6948
|
}
|
|
6937
|
-
const validation = await validateDiscount({ code: normalized });
|
|
6949
|
+
const validation = await validateDiscount({ code: normalized, subtotal: cartSubtotal() });
|
|
6938
6950
|
if (!validation.valid) {
|
|
6951
|
+
if (validation.reason === "min_subtotal" && validation.minSubtotal != null) {
|
|
6952
|
+
const missing = formatMoney(validation.minSubtotal, config.currency, config.locale);
|
|
6953
|
+
return { valid: false, percent: 0, message: `Este cupom vale em pedidos a partir de ${missing}.` };
|
|
6954
|
+
}
|
|
6939
6955
|
return { valid: false, percent: 0, message: REASON_MESSAGE[validation.reason ?? "not_found"] ?? "Cupom inv\xE1lido ou expirado." };
|
|
6940
6956
|
}
|
|
6941
|
-
if (validation.type !== "percentage") {
|
|
6957
|
+
if (validation.type !== "percentage" && validation.type !== "free_shipping") {
|
|
6942
6958
|
return { valid: false, percent: 0, message: REASON_MESSAGE.unsupported };
|
|
6943
6959
|
}
|
|
6944
6960
|
const promotion = discountToPromotion({
|
|
@@ -6946,7 +6962,7 @@ function useDiscountValidator() {
|
|
|
6946
6962
|
tenantId: "storefront",
|
|
6947
6963
|
title: normalized,
|
|
6948
6964
|
code: validation.code ?? normalized,
|
|
6949
|
-
type:
|
|
6965
|
+
type: validation.type,
|
|
6950
6966
|
method: "code",
|
|
6951
6967
|
value: validation.value,
|
|
6952
6968
|
usageLimit: null,
|
|
@@ -6966,7 +6982,7 @@ function useDiscountValidator() {
|
|
|
6966
6982
|
if (!preview?.valid) {
|
|
6967
6983
|
return { valid: false, percent: 0, message: REASON_MESSAGE[preview?.reason ?? "not_found"] ?? "Cupom inv\xE1lido." };
|
|
6968
6984
|
}
|
|
6969
|
-
return { valid: true, percent: preview.percent };
|
|
6985
|
+
return { valid: true, percent: preview.percent, freeShipping: preview.freeShipping };
|
|
6970
6986
|
}, [config.discounts, config.promotions]);
|
|
6971
6987
|
}
|
|
6972
6988
|
var seq = 0;
|
|
@@ -7037,9 +7053,10 @@ function CartDrawer() {
|
|
|
7037
7053
|
const result = await validate(code);
|
|
7038
7054
|
if (result.valid) {
|
|
7039
7055
|
const applied = code.trim().toUpperCase();
|
|
7040
|
-
cart.applyDiscount(applied, result.percent);
|
|
7056
|
+
cart.applyDiscount(applied, result.percent, { freeShipping: result.freeShipping });
|
|
7041
7057
|
setCode("");
|
|
7042
|
-
|
|
7058
|
+
const effect = result.freeShipping ? "frete gr\xE1tis" : `${result.percent}% de desconto`;
|
|
7059
|
+
toast.success("Cupom aplicado!", `${applied} \u2022 ${effect}`);
|
|
7043
7060
|
} else {
|
|
7044
7061
|
setDiscountError(result.message ?? "Cupom inv\xE1lido.");
|
|
7045
7062
|
toast.error("Cupom inv\xE1lido", result.message ?? "Verifique o c\xF3digo e tente novamente.");
|
|
@@ -7233,12 +7250,25 @@ function CartDrawer() {
|
|
|
7233
7250
|
] })
|
|
7234
7251
|
] }),
|
|
7235
7252
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
7236
|
-
/* @__PURE__ */ jsxs("dt", { className: "text-muted-foreground", children: [
|
|
7253
|
+
/* @__PURE__ */ jsxs("dt", { className: cart.discountFreeShipping ? "text-emerald-700" : "text-muted-foreground", children: [
|
|
7237
7254
|
"Frete",
|
|
7238
7255
|
delivery.status === "served" && delivery.postalCode && /* @__PURE__ */ jsxs("span", { className: "ml-1 text-xs", children: [
|
|
7239
7256
|
"\xB7 ",
|
|
7240
7257
|
formatPostalCode(delivery.postalCode)
|
|
7241
|
-
] })
|
|
7258
|
+
] }),
|
|
7259
|
+
cart.discountFreeShipping && /* @__PURE__ */ jsxs(
|
|
7260
|
+
"button",
|
|
7261
|
+
{
|
|
7262
|
+
type: "button",
|
|
7263
|
+
onClick: cart.clearDiscount,
|
|
7264
|
+
className: "ml-1 py-1 text-xs text-muted-foreground underline",
|
|
7265
|
+
children: [
|
|
7266
|
+
"(",
|
|
7267
|
+
cart.discountCode,
|
|
7268
|
+
" \u2715)"
|
|
7269
|
+
]
|
|
7270
|
+
}
|
|
7271
|
+
)
|
|
7242
7272
|
] }),
|
|
7243
7273
|
/* @__PURE__ */ jsx("dd", { "data-testid": TID.cartShipping, "data-price": shipping.toFixed(2), children: shipping === 0 ? "Gr\xE1tis" : money(shipping) })
|
|
7244
7274
|
] }),
|
|
@@ -7689,6 +7719,128 @@ function PulseDot({ className = "" }) {
|
|
|
7689
7719
|
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2.5 w-2.5 rounded-full bg-current" })
|
|
7690
7720
|
] });
|
|
7691
7721
|
}
|
|
7722
|
+
var SDK_URL = "https://sdk.mercadopago.com/js/v2";
|
|
7723
|
+
var CONTAINER_ID = "fayz-mp-card-brick";
|
|
7724
|
+
var DEVICE_SCRIPT_URL = "https://www.mercadopago.com/v2/security.js";
|
|
7725
|
+
var DEVICE_VIEW = "checkout";
|
|
7726
|
+
function loadDeviceScript() {
|
|
7727
|
+
if (typeof document === "undefined") return;
|
|
7728
|
+
if (document.querySelector(`script[src="${DEVICE_SCRIPT_URL}"]`)) return;
|
|
7729
|
+
const script = document.createElement("script");
|
|
7730
|
+
script.src = DEVICE_SCRIPT_URL;
|
|
7731
|
+
script.setAttribute("view", DEVICE_VIEW);
|
|
7732
|
+
script.async = true;
|
|
7733
|
+
document.body.appendChild(script);
|
|
7734
|
+
}
|
|
7735
|
+
function deviceSessionId() {
|
|
7736
|
+
if (typeof window === "undefined") return null;
|
|
7737
|
+
const id = window.MP_DEVICE_SESSION_ID;
|
|
7738
|
+
return typeof id === "string" && id.trim() ? id.trim() : null;
|
|
7739
|
+
}
|
|
7740
|
+
var sdkPromise = null;
|
|
7741
|
+
function loadSdk() {
|
|
7742
|
+
if (typeof window === "undefined") return Promise.reject(new Error("no window"));
|
|
7743
|
+
if (window.MercadoPago) return Promise.resolve();
|
|
7744
|
+
if (sdkPromise) return sdkPromise;
|
|
7745
|
+
sdkPromise = new Promise((resolve, reject) => {
|
|
7746
|
+
const existing = document.querySelector(`script[src="${SDK_URL}"]`);
|
|
7747
|
+
const script = existing ?? document.createElement("script");
|
|
7748
|
+
script.src = SDK_URL;
|
|
7749
|
+
script.async = true;
|
|
7750
|
+
script.addEventListener("load", () => resolve());
|
|
7751
|
+
script.addEventListener("error", () => {
|
|
7752
|
+
sdkPromise = null;
|
|
7753
|
+
reject(new Error("N\xE3o conseguimos carregar o pagamento com cart\xE3o."));
|
|
7754
|
+
});
|
|
7755
|
+
if (!existing) document.body.appendChild(script);
|
|
7756
|
+
});
|
|
7757
|
+
return sdkPromise;
|
|
7758
|
+
}
|
|
7759
|
+
function CardBrick({ publicKey, amount, email, onSubmit, onError }) {
|
|
7760
|
+
const [ready, setReady] = useState(false);
|
|
7761
|
+
const [failed, setFailed] = useState(null);
|
|
7762
|
+
const mounted = useRef(false);
|
|
7763
|
+
const controller = useRef(null);
|
|
7764
|
+
const submitRef = useRef(onSubmit);
|
|
7765
|
+
submitRef.current = onSubmit;
|
|
7766
|
+
useEffect(() => {
|
|
7767
|
+
if (mounted.current) return;
|
|
7768
|
+
mounted.current = true;
|
|
7769
|
+
let cancelled = false;
|
|
7770
|
+
loadDeviceScript();
|
|
7771
|
+
void (async () => {
|
|
7772
|
+
try {
|
|
7773
|
+
await loadSdk();
|
|
7774
|
+
if (cancelled || !window.MercadoPago) return;
|
|
7775
|
+
const mp = new window.MercadoPago(publicKey, { locale: "pt-BR" });
|
|
7776
|
+
const builder = mp.bricks();
|
|
7777
|
+
controller.current = await builder.create("cardPayment", CONTAINER_ID, {
|
|
7778
|
+
initialization: {
|
|
7779
|
+
amount,
|
|
7780
|
+
...email ? { payer: { email } } : {}
|
|
7781
|
+
},
|
|
7782
|
+
customization: {
|
|
7783
|
+
visual: { style: { theme: "default" } },
|
|
7784
|
+
paymentMethods: { maxInstallments: 12 }
|
|
7785
|
+
},
|
|
7786
|
+
callbacks: {
|
|
7787
|
+
onReady: () => {
|
|
7788
|
+
if (!cancelled) setReady(true);
|
|
7789
|
+
},
|
|
7790
|
+
onSubmit: (formData) => (
|
|
7791
|
+
// Their contract: resolve when the payment is handled, reject to
|
|
7792
|
+
// keep the form up. Rejecting is what lets a declined card be
|
|
7793
|
+
// corrected in place instead of re-typed from scratch.
|
|
7794
|
+
submitRef.current({
|
|
7795
|
+
token: String(formData?.token ?? ""),
|
|
7796
|
+
paymentMethodId: formData?.payment_method_id ?? null,
|
|
7797
|
+
issuerId: formData?.issuer_id == null ? null : String(formData.issuer_id),
|
|
7798
|
+
installments: Number(formData?.installments) || 1,
|
|
7799
|
+
email: formData?.payer?.email ?? null,
|
|
7800
|
+
document: formData?.payer?.identification?.number ? {
|
|
7801
|
+
type: String(formData.payer.identification.type ?? "CPF"),
|
|
7802
|
+
number: String(formData.payer.identification.number)
|
|
7803
|
+
} : null
|
|
7804
|
+
})
|
|
7805
|
+
),
|
|
7806
|
+
onError: (brickError) => {
|
|
7807
|
+
const message = brickError?.message ?? "N\xE3o conseguimos carregar o formul\xE1rio do cart\xE3o.";
|
|
7808
|
+
if (!cancelled) onError?.(message);
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
});
|
|
7812
|
+
} catch (err) {
|
|
7813
|
+
if (cancelled) return;
|
|
7814
|
+
const message = err instanceof Error ? err.message : "N\xE3o conseguimos carregar o pagamento com cart\xE3o.";
|
|
7815
|
+
setFailed(message);
|
|
7816
|
+
onError?.(message);
|
|
7817
|
+
}
|
|
7818
|
+
})();
|
|
7819
|
+
return () => {
|
|
7820
|
+
cancelled = true;
|
|
7821
|
+
try {
|
|
7822
|
+
controller.current?.unmount();
|
|
7823
|
+
} catch {
|
|
7824
|
+
}
|
|
7825
|
+
controller.current = null;
|
|
7826
|
+
mounted.current = false;
|
|
7827
|
+
};
|
|
7828
|
+
}, []);
|
|
7829
|
+
if (failed) {
|
|
7830
|
+
return /* @__PURE__ */ jsx("p", { className: "rounded-lg border border-destructive/40 bg-destructive/5 p-4 text-sm text-destructive", children: failed });
|
|
7831
|
+
}
|
|
7832
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
7833
|
+
!ready && /* @__PURE__ */ jsxs(SkeletonGroup, { label: "Carregando o formul\xE1rio do cart\xE3o", className: "space-y-3", children: [
|
|
7834
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-11 w-full rounded-lg" }),
|
|
7835
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
7836
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-11 w-full rounded-lg" }),
|
|
7837
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-11 w-full rounded-lg" })
|
|
7838
|
+
] }),
|
|
7839
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-11 w-full rounded-lg" })
|
|
7840
|
+
] }),
|
|
7841
|
+
/* @__PURE__ */ jsx("div", { id: CONTAINER_ID, className: ready ? "" : "hidden" })
|
|
7842
|
+
] });
|
|
7843
|
+
}
|
|
7692
7844
|
var POLL_MS = 3e3;
|
|
7693
7845
|
var RESUME_KEY = "fz.checkout.resume";
|
|
7694
7846
|
function useExpiry(expiresAt) {
|
|
@@ -7751,12 +7903,13 @@ function recallSessionProvider(sessionId) {
|
|
|
7751
7903
|
return null;
|
|
7752
7904
|
}
|
|
7753
7905
|
}
|
|
7754
|
-
function CheckoutPayment({ input, onPaid, onBack, money, onUnavailable, resume }) {
|
|
7906
|
+
function CheckoutPayment({ input, onPaid, onBack, money, onUnavailable, resume, amount }) {
|
|
7755
7907
|
const [phase, setPhase] = useState("opening");
|
|
7756
7908
|
const [charge, setCharge] = useState(null);
|
|
7757
7909
|
const expiry = useExpiry(charge?.expiresAt);
|
|
7758
7910
|
const [total, setTotal] = useState(null);
|
|
7759
7911
|
const [redirectUrl, setRedirectUrl] = useState(null);
|
|
7912
|
+
const [brickKey, setBrickKey] = useState(null);
|
|
7760
7913
|
const [sessionId, setSessionId] = useState(resume?.sessionId ?? null);
|
|
7761
7914
|
const [provider, setProvider] = useState(resume?.provider ?? null);
|
|
7762
7915
|
const [error, setError] = useState(null);
|
|
@@ -7774,6 +7927,16 @@ function CheckoutPayment({ input, onPaid, onBack, money, onUnavailable, resume }
|
|
|
7774
7927
|
setPhase("opening");
|
|
7775
7928
|
setError(null);
|
|
7776
7929
|
try {
|
|
7930
|
+
if (input.paymentMethod === "credit_card" && shop.paymentPublicKey) {
|
|
7931
|
+
const providerSlug = input.provider ?? null;
|
|
7932
|
+
const publicKey = providerSlug ? await shop.paymentPublicKey(providerSlug) : null;
|
|
7933
|
+
if (publicKey) {
|
|
7934
|
+
setProvider(providerSlug);
|
|
7935
|
+
setBrickKey(publicKey);
|
|
7936
|
+
setPhase("card");
|
|
7937
|
+
return;
|
|
7938
|
+
}
|
|
7939
|
+
}
|
|
7777
7940
|
const session = await shop.openCheckoutSession({
|
|
7778
7941
|
...input,
|
|
7779
7942
|
// Para onde o adquirente devolve o comprador. É esta página, com o id da
|
|
@@ -7860,6 +8023,70 @@ function CheckoutPayment({ input, onPaid, onBack, money, onUnavailable, resume }
|
|
|
7860
8023
|
}
|
|
7861
8024
|
toast.error("Copie o c\xF3digo manualmente");
|
|
7862
8025
|
}
|
|
8026
|
+
if (phase === "card" && brickKey) {
|
|
8027
|
+
const acquirer = gatewayLabel(provider);
|
|
8028
|
+
return /* @__PURE__ */ jsxs("div", { "data-testid": TID.checkoutPayment, className: "space-y-4 rounded-xl border bg-card p-6", children: [
|
|
8029
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8030
|
+
/* @__PURE__ */ jsx(CreditCard, { className: "h-5 w-5 text-primary" }),
|
|
8031
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Pague com cart\xE3o sem sair da loja" })
|
|
8032
|
+
] }),
|
|
8033
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: acquirer ? `Os campos do cart\xE3o s\xE3o da ${acquirer} e o n\xFAmero n\xE3o passa por esta loja. Seu pedido \xE9 criado assim que o pagamento for aprovado.` : "O n\xFAmero do cart\xE3o n\xE3o passa por esta loja. Seu pedido \xE9 criado assim que o pagamento for aprovado." }),
|
|
8034
|
+
(total ?? amount) != null && /* @__PURE__ */ jsxs("p", { className: "text-sm", children: [
|
|
8035
|
+
"Valor: ",
|
|
8036
|
+
/* @__PURE__ */ jsx("strong", { "data-testid": TID.checkoutPaymentTotal, children: money(total ?? amount) })
|
|
8037
|
+
] }),
|
|
8038
|
+
/* @__PURE__ */ jsx(
|
|
8039
|
+
CardBrick,
|
|
8040
|
+
{
|
|
8041
|
+
publicKey: brickKey,
|
|
8042
|
+
amount: total ?? amount ?? 0,
|
|
8043
|
+
email: input.customer?.email ?? null,
|
|
8044
|
+
onError: (message) => setError(message),
|
|
8045
|
+
onSubmit: async (result) => {
|
|
8046
|
+
const shop = getShopProvider();
|
|
8047
|
+
if (!shop.openCheckoutSession) throw new Error("sem gateway");
|
|
8048
|
+
try {
|
|
8049
|
+
const session = await shop.openCheckoutSession({
|
|
8050
|
+
...input,
|
|
8051
|
+
cardToken: result.token,
|
|
8052
|
+
installments: result.installments,
|
|
8053
|
+
paymentMethodId: result.paymentMethodId,
|
|
8054
|
+
issuerId: result.issuerId,
|
|
8055
|
+
// Their anti-fraud reads this, and a card charged without it is
|
|
8056
|
+
// declined more often for no visible reason.
|
|
8057
|
+
deviceId: deviceSessionId()
|
|
8058
|
+
});
|
|
8059
|
+
setSessionId(session.sessionId);
|
|
8060
|
+
setProvider(session.provider ?? input.provider ?? null);
|
|
8061
|
+
setTotal(session.total);
|
|
8062
|
+
const orderId = session.orderId ?? null;
|
|
8063
|
+
if (orderId) {
|
|
8064
|
+
settled.current = true;
|
|
8065
|
+
setPhase("settling");
|
|
8066
|
+
onPaid(orderId);
|
|
8067
|
+
return;
|
|
8068
|
+
}
|
|
8069
|
+
setPhase("waiting");
|
|
8070
|
+
} catch (err) {
|
|
8071
|
+
const message = err instanceof Error ? err.message : "O pagamento n\xE3o foi aprovado.";
|
|
8072
|
+
setError(message);
|
|
8073
|
+
throw err;
|
|
8074
|
+
}
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
),
|
|
8078
|
+
error && /* @__PURE__ */ jsx("p", { className: "rounded-lg border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive", children: error }),
|
|
8079
|
+
/* @__PURE__ */ jsx(
|
|
8080
|
+
"button",
|
|
8081
|
+
{
|
|
8082
|
+
type: "button",
|
|
8083
|
+
onClick: onBack,
|
|
8084
|
+
className: "inline-flex min-h-11 items-center rounded-lg border px-4 py-2.5 text-sm font-medium transition hover:bg-muted",
|
|
8085
|
+
children: "Voltar"
|
|
8086
|
+
}
|
|
8087
|
+
)
|
|
8088
|
+
] });
|
|
8089
|
+
}
|
|
7863
8090
|
if (phase === "redirect" && redirectUrl) {
|
|
7864
8091
|
const acquirer = gatewayLabel(provider);
|
|
7865
8092
|
return /* @__PURE__ */ jsxs("div", { "data-testid": TID.checkoutPayment, className: "space-y-4 rounded-xl border bg-card p-6", children: [
|
|
@@ -8375,10 +8602,11 @@ function CheckoutPage() {
|
|
|
8375
8602
|
const appliedCode = discountCode.trim().toUpperCase();
|
|
8376
8603
|
const result = await validateDiscount2(discountCode);
|
|
8377
8604
|
if (result.valid) {
|
|
8378
|
-
cart.applyDiscount(appliedCode, result.percent);
|
|
8605
|
+
cart.applyDiscount(appliedCode, result.percent, { freeShipping: result.freeShipping });
|
|
8379
8606
|
setDiscountCode(appliedCode);
|
|
8380
|
-
|
|
8381
|
-
|
|
8607
|
+
const effect = result.freeShipping ? "frete gr\xE1tis" : `${result.percent}% de desconto`;
|
|
8608
|
+
setDiscountSuccess(`${appliedCode} aplicado: ${effect}.`);
|
|
8609
|
+
toast.success("Cupom aplicado!", `${appliedCode} \u2022 ${effect}`);
|
|
8382
8610
|
} else {
|
|
8383
8611
|
setDiscountError(result.message ?? "Cupom inv\xE1lido.");
|
|
8384
8612
|
toast.error("Cupom inv\xE1lido", result.message ?? "Verifique o c\xF3digo e tente novamente.");
|
|
@@ -8833,6 +9061,7 @@ function CheckoutPage() {
|
|
|
8833
9061
|
{
|
|
8834
9062
|
input: checkoutSessionInput,
|
|
8835
9063
|
money,
|
|
9064
|
+
amount: total,
|
|
8836
9065
|
onBack: () => goToStep(2),
|
|
8837
9066
|
resume,
|
|
8838
9067
|
onUnavailable: () => setUnavailable((list) => list.includes(method) ? list : [...list, method]),
|
|
@@ -8986,7 +9215,22 @@ function CheckoutPage() {
|
|
|
8986
9215
|
] })
|
|
8987
9216
|
] }),
|
|
8988
9217
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
8989
|
-
/* @__PURE__ */
|
|
9218
|
+
/* @__PURE__ */ jsxs("dt", { className: cart.discountFreeShipping ? "text-emerald-700" : "text-muted-foreground", children: [
|
|
9219
|
+
"Entrega",
|
|
9220
|
+
cart.discountFreeShipping && /* @__PURE__ */ jsxs(
|
|
9221
|
+
"button",
|
|
9222
|
+
{
|
|
9223
|
+
type: "button",
|
|
9224
|
+
onClick: clearDiscountCode,
|
|
9225
|
+
className: "ml-1 text-xs text-muted-foreground underline",
|
|
9226
|
+
children: [
|
|
9227
|
+
"(",
|
|
9228
|
+
cart.discountCode,
|
|
9229
|
+
" \xD7)"
|
|
9230
|
+
]
|
|
9231
|
+
}
|
|
9232
|
+
)
|
|
9233
|
+
] }),
|
|
8990
9234
|
/* @__PURE__ */ jsx("dd", { "data-price": shipping.toFixed(2), children: shipping === 0 ? "Gr\xE1tis" : money(shipping) })
|
|
8991
9235
|
] }),
|
|
8992
9236
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between border-t pt-5 text-lg font-bold", children: [
|
|
@@ -11417,5 +11661,5 @@ ${formatErrors(report.errors)}`;
|
|
|
11417
11661
|
}
|
|
11418
11662
|
|
|
11419
11663
|
export { BEFORE_PLACE_ORDER_VALVE, BLOCK_STRUCTURAL_KEYS, BenefitsRow, BlockDataError, CART_LINE_ANNOTATION_POINT, CATALOG_BODY_BLOCK, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, CollectionCta, CollectionHero, ContentPage, CountdownBand, EmailConfirmationRequiredError, EntityListBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, Link, ManifestoBlock, MediaCarousel, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_BODY_BLOCK, PRODUCT_CARD_BADGE_POINT, PageDataScope, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_COMPONENT_KEYS, STOREFRONT_PAGE_KINDS, STOREFRONT_SLOTS, STORE_BACKEND_PROVIDERS, STORE_COMMERCE_MODES, STORE_DOCUMENT_KIND, STORE_PAYMENT_METHOD_KINDS, STORE_PAYMENT_MODES, STORE_ROUTE_CHROMES, STORE_ROUTE_KINDS, STORE_SECTIONS, STORE_SECTION_NAMES, SealsBand, SearchOverlay, Slot, SmoothImage, StepsSection, StorefrontConfigHost, StorefrontConfigProvider, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontRouterProvider, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyStoreSettings, bannerPlaceholder, blockInstanceId, buildEnquiryFromForm, checkPageBlocks, collectDataNeeds, collectOrderMetadata, contentPagePath, createStorefront, createStorefrontApp, currentStaticRenderPass, defaultPageBlocks, entityListBlockMeta, establishCustomerSession, exportStore, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydrateStoreDocument, hydratedEntriesFor, initStorefrontRuntime, isJsonValue, isKnownPath, isNestedBlockRef, isPublicPath, isRecord, listSlots, matchContentPage, matchPath, matchesFacets, mergeCollectionFacet, mergePageTheme, navigateTo, nextMilestone, normalizeProductOptionSelection, orderGalleryImages, overrideComponent, overrideProps, pageSeo, pageThemeSelector, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, primaryImageUrl, productCardComponentContract, productJsonLd, productOptionSelectionKey, productPlaceholder, productSeo, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveConfig, resolveDataParams, resolveOverride, resolvePageData, resolvePageDataNeed, resolvePaymentTerms, resolveStorefrontProvider, resolveStorefrontRoute, resolveVariantForSelection, roundCents, routePathParams, runBeforePlaceOrderValve, sectionToJsonSchema, sectionsToBlocks, selectCount, selectDiscountTotal, selectRequiresShipping, selectShipping, selectSubtotal, selectTotal, selectionPrice, serializePageData, shellRouterAdapter, signInByEmail, signOutCustomer, signUpCustomer, slugifyStoreName, storefrontComponentContracts, storefrontPaths, themeToCss, toBlockNodes, toFacetMap, useBlockData, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useHashPath, useInView, useLoader, useMyOrders, useNavigate, usePopOnChange, useProduct, useProducts, useRoutePath, useRouterAdapter, useScrollToTopOnNavigate, useScrolled, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontConfig, useStorefrontConfigOptional, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, usedSlots, validateStore, withFacet, withStaticRenderPass };
|
|
11420
|
-
//# sourceMappingURL=chunk-
|
|
11421
|
-
//# sourceMappingURL=chunk-
|
|
11664
|
+
//# sourceMappingURL=chunk-STL6MATQ.js.map
|
|
11665
|
+
//# sourceMappingURL=chunk-STL6MATQ.js.map
|