@ecomiq/storefront 2.1.4 → 3.0.1
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/LICENSE +21 -0
- package/README.md +377 -76
- package/dist/account-Dx4e3syi.js +258 -0
- package/dist/account-forms-AVk71ko7.js +39 -0
- package/dist/account-forms.d.ts +13 -0
- package/dist/account.d.ts +240 -0
- package/dist/address-defaults-BqjRhS82.js +14 -0
- package/dist/address-defaults.d.ts +11 -0
- package/dist/analytics/analytics-CG1Qagwl.js +148 -0
- package/dist/analytics/analytics.d.ts +1 -0
- package/dist/analytics/config-DJr-GRhs.js +62 -0
- package/dist/analytics/config.d.ts +22 -0
- package/dist/analytics/consent-B13rBpBs.js +57 -0
- package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
- package/dist/analytics/consent-banner.d.ts +20 -0
- package/dist/analytics/cookies-pLozllyB.js +100 -0
- package/dist/analytics/cookies.d.ts +6 -0
- package/dist/analytics/destinations-iECrlLIr.js +144 -0
- package/dist/analytics/events-Dt81tIp1.js +102 -0
- package/dist/analytics/events.d.ts +51 -0
- package/dist/analytics/tracker-p4yaoOyk.js +51 -0
- package/dist/api-cache-DsuIn5hX.js +159 -0
- package/dist/bank-accounts-DlEczQQ5.js +81 -0
- package/dist/bank-accounts.d.ts +4 -0
- package/dist/captcha-DAqaIx8m.js +117 -0
- package/dist/captcha.d.ts +34 -0
- package/dist/cart-D7DxZ2lD.js +30 -0
- package/dist/cart-actions-Bsub_FFG.js +116 -0
- package/dist/cart-actions.d.ts +15 -0
- package/dist/cart-drawer-B7PPsR69.js +22 -0
- package/dist/cart-drawer.d.ts +9 -0
- package/dist/cart-form-y9P1r_EX.js +81 -0
- package/dist/cart-form.d.ts +24 -0
- package/dist/cart-summary-ur2VWKr-.js +89 -0
- package/dist/cart-summary.d.ts +31 -0
- package/dist/cart.d.ts +4 -0
- package/dist/catalog-7gJ-l5hW.js +67 -0
- package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
- package/dist/catalog-hooks.d.ts +111 -0
- package/dist/catalog.d.ts +5 -0
- package/dist/checkout-DVWSXANi.js +474 -0
- package/dist/checkout-form-CbOIdENC.js +131 -0
- package/dist/checkout-form.d.ts +20 -0
- package/dist/checkout.d.ts +86 -0
- package/dist/complaint-book-BvwLvfx0.js +117 -0
- package/dist/complaint-book.d.ts +62 -0
- package/dist/culqi-authentication-BGr20vAJ.js +204 -0
- package/dist/culqi-authentication.d.ts +15 -0
- package/dist/culqi-checkout-CTXpKgp_.js +55 -0
- package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
- package/dist/culqi-three-ds.d.ts +29 -0
- package/dist/customer-avatar-CJXSDroK.js +12 -0
- package/dist/customer-avatar.d.ts +5 -0
- package/dist/customer-cookies-DHOgFAMV.js +45 -0
- package/dist/customer-csrf-C1oDX-Py.js +17 -0
- package/dist/customer-csrf.d.ts +3 -0
- package/dist/customer-document-fields-C1K-_DAD.js +70 -0
- package/dist/customer-document-fields.d.ts +9 -0
- package/dist/customer-login-form-C7AC6vXd.js +144 -0
- package/dist/customer-login-form.d.ts +17 -0
- package/dist/customer-registration-form-BEm_NEfP.js +93 -0
- package/dist/customer-registration-form.d.ts +8 -0
- package/dist/document-url-CGsAl5Tf.js +9 -0
- package/dist/documents-T1mzc_j8.js +38 -0
- package/dist/documents.d.ts +16 -0
- package/dist/entries/account.d.ts +11 -0
- package/dist/entries/account.js +10 -0
- package/dist/entries/analytics.d.ts +6 -0
- package/dist/entries/analytics.js +5 -0
- package/dist/entries/cart.d.ts +8 -0
- package/dist/entries/cart.js +7 -0
- package/dist/entries/checkout.d.ts +12 -0
- package/dist/entries/checkout.js +11 -0
- package/dist/entries/order.d.ts +11 -0
- package/dist/entries/order.js +11 -0
- package/dist/favicon-YpyhVJ9H.js +28 -0
- package/dist/favicon.d.ts +4 -0
- package/dist/form-BtQcbXlJ.js +18 -0
- package/dist/form-contracts-BNpHaTGJ.js +166 -0
- package/dist/form-contracts.d.ts +42 -0
- package/dist/form.d.ts +3 -0
- package/dist/hidden-CCWtOWKR.js +3 -0
- package/dist/hidden.d.ts +4 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +50 -0
- package/dist/invoice-fields-BG0HjL6T.js +103 -0
- package/dist/invoice-fields.d.ts +39 -0
- package/dist/links-kFxBZfdb.js +96 -0
- package/dist/links.d.ts +21 -0
- package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
- package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
- package/dist/mercadopago-dialog.d.ts +21 -0
- package/dist/money-DtGOtDri.js +32 -0
- package/dist/money.d.ts +1 -0
- package/dist/optimistic-cart-BveVOHuh.js +53 -0
- package/dist/optimistic-cart.d.ts +16 -0
- package/dist/order-display-DTt5WBbc.js +112 -0
- package/dist/order-display.d.ts +20 -0
- package/dist/order-draft-DxV1Uhm3.js +38 -0
- package/dist/order-draft.d.ts +16 -0
- package/dist/order-pages-Dm6l5m0m.js +38 -0
- package/dist/order-pages.d.ts +12 -0
- package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
- package/dist/order-payment-continuation.d.ts +10 -0
- package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
- package/dist/order-payment-in-review.d.ts +5 -0
- package/dist/order-status-BJXLJwxq.js +162 -0
- package/dist/order-status.d.ts +89 -0
- package/dist/order-view-9IlBg5AF.js +62 -0
- package/dist/order-view.d.ts +12 -0
- package/dist/page-action-Ctkf4xC6.js +7 -0
- package/dist/page-seo-a5FJl8x5.js +262 -0
- package/dist/page-seo.d.ts +34 -0
- package/dist/pages-Ca_Gt6mq.js +150 -0
- package/dist/pages.d.ts +45 -0
- package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
- package/dist/payment-logo-BoPaGJc_.js +46 -0
- package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
- package/dist/payment-logo.d.ts +11 -0
- package/dist/payment-logos-BYvdwYyJ.js +23 -0
- package/dist/payment-methods-B8ocTgFZ.js +73 -0
- package/dist/payment-methods.d.ts +58 -0
- package/dist/payment-return-5cjypwIw.js +7 -0
- package/dist/place-CmW4hBWY.js +13 -0
- package/dist/place.d.ts +4 -0
- package/dist/preview-BiIBif3C.js +427 -0
- package/dist/preview-address-Cf0sJ-9p.js +21 -0
- package/dist/preview-cart-Dg2CVktS.js +376 -0
- package/dist/product-preview-BspMAecJ.js +51 -0
- package/dist/product-preview.d.ts +5 -0
- package/dist/product-variants-BNDHvs1y.js +46 -0
- package/dist/product-variants.d.ts +12 -0
- package/dist/public-pages-XtwlaLwt.js +194 -0
- package/dist/public-pages.d.ts +67 -0
- package/dist/registration-CpDcv8ql.js +91 -0
- package/dist/registration.d.ts +12 -0
- package/dist/request-security-CRsRMgwj.js +76 -0
- package/dist/rich-text-M-Ju8RL4.js +9 -0
- package/dist/rich-text.d.ts +5 -0
- package/dist/route-text-DcJw2SsK.js +9 -0
- package/dist/route-text.d.ts +4 -0
- package/dist/section-preview-CmsMl3yu.js +83 -0
- package/dist/section-preview.d.ts +12 -0
- package/dist/sections/account-addresses.d.ts +18 -0
- package/dist/sections/account-addresses.js +375 -0
- package/dist/sections/account-order.d.ts +12 -0
- package/dist/sections/account-order.js +592 -0
- package/dist/sections/account-orders.d.ts +8 -0
- package/dist/sections/account-orders.js +359 -0
- package/dist/sections/account-profile.d.ts +16 -0
- package/dist/sections/account-profile.js +123 -0
- package/dist/sections/checkout.d.ts +24 -0
- package/dist/sections/checkout.js +963 -0
- package/dist/sections/complaint-book.d.ts +8 -0
- package/dist/sections/complaint-book.js +538 -0
- package/dist/sections/design-system.d.ts +1 -0
- package/dist/sections/design-system.js +310 -0
- package/dist/sections/draft-invoice.d.ts +20 -0
- package/dist/sections/draft-invoice.js +158 -0
- package/dist/sections/order-tracking.d.ts +19 -0
- package/dist/sections/order-tracking.js +141 -0
- package/dist/sections-CNUMWTF_.js +77 -0
- package/dist/sections.d.ts +19 -0
- package/dist/seo-GpDRhAAA.js +78 -0
- package/dist/session-CKvmFJyg.js +379 -0
- package/dist/session.d.ts +24 -0
- package/dist/settings-B0NO2A6Y.js +78 -0
- package/dist/settings.d.ts +51 -0
- package/dist/source-marker-DhqSkW7n.js +4 -0
- package/dist/sources-B-3JFJfb.js +46 -0
- package/dist/sources.d.ts +7 -0
- package/dist/store-8Q-_LFrQ.js +152 -0
- package/dist/store-contact--hY6CoFb.js +19 -0
- package/dist/store-contact.d.ts +6 -0
- package/dist/store.d.ts +17 -0
- package/dist/storefront-language-DrMjVbmk.js +29 -0
- package/dist/storefront-language.d.ts +14 -0
- package/dist/storefront-text-D25ae1qf.js +11 -0
- package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
- package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
- package/dist/storefront-text.d.ts +4 -0
- package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
- package/dist/stripe-dialog.d.ts +30 -0
- package/dist/telemetry-HuZXWBPi.js +114 -0
- package/dist/telemetry.d.ts +10 -0
- package/dist/templates-CAqoNyTW.js +40 -0
- package/dist/templates.d.ts +15 -0
- package/dist/urls-CpGQPxvf.js +71 -0
- package/dist/urls.d.ts +18 -0
- package/dist/use-checkout-CZcxXJXi.js +42 -0
- package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
- package/dist/use-checkout-payment.d.ts +18 -0
- package/dist/use-checkout.d.ts +36 -0
- package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
- package/dist/use-order-payment-BKIz_IO0.js +45 -0
- package/dist/use-order-payment.d.ts +18 -0
- package/dist/use-payment-token-CErx-tN-.js +105 -0
- package/dist/vite-payment-logos-kziu7wKb.js +27 -0
- package/dist/vite-payment-logos.d.ts +24 -0
- package/dist/vite-public-assets-DW2fgtVb.js +209 -0
- package/dist/vite-public-assets.d.ts +29 -0
- package/dist/vite-sections-DTBr0-Kg.js +464 -0
- package/dist/vite-sections.d.ts +21 -0
- package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
- package/dist/vite-theme-ui.d.ts +10 -0
- package/dist/vite.d.ts +36 -0
- package/dist/vite.js +127 -0
- package/dist/voucher-payment-CVFDZ1L8.js +66 -0
- package/dist/worker-CNi-gzCu.js +86 -0
- package/dist/worker.d.ts +27 -0
- package/package.json +100 -76
- package/src/sections/account-addresses.tsx +215 -0
- package/src/sections/account-order.tsx +424 -0
- package/src/sections/account-orders.tsx +259 -0
- package/src/sections/account-profile.tsx +70 -0
- package/src/sections/checkout.tsx +586 -0
- package/src/sections/complaint-book.tsx +325 -0
- package/src/sections/design-system.tsx +146 -0
- package/src/sections/draft-invoice.tsx +105 -0
- package/src/sections/order-tracking.tsx +81 -0
- package/src/vite-client.d.ts +4 -0
- package/bin/ecomiq.mjs +0 -179
- package/public/design-bridge.js +0 -318
- package/src/api-proxy.ts +0 -194
- package/src/auth/create-storefront-auth.ts +0 -94
- package/src/auth/ecomiq-oauth-password-client.ts +0 -26
- package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
- package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
- package/src/auth/ecomiq-oauth-password-types.ts +0 -24
- package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
- package/src/auth/env.ts +0 -7
- package/src/auth/secure-cookies.ts +0 -23
- package/src/auth/storefront-auth-base-url.ts +0 -117
- package/src/auth/storefront-auth.ts +0 -7
- package/src/cart-session.ts +0 -239
- package/src/client.ts +0 -48
- package/src/codegen.mjs +0 -801
- package/src/components/account/customer-addresses-panel.tsx +0 -678
- package/src/components/account/customer-order-detail-panel.tsx +0 -285
- package/src/components/account/customer-orders-panel.tsx +0 -192
- package/src/components/account/customer-profile-panel.tsx +0 -379
- package/src/components/checkout/cart-sync.ts +0 -143
- package/src/components/checkout/checkout-contact-section.tsx +0 -76
- package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
- package/src/components/checkout/checkout-form-controls.tsx +0 -139
- package/src/components/checkout/checkout-line-items.tsx +0 -43
- package/src/components/checkout/checkout-order-summary.tsx +0 -165
- package/src/components/checkout/checkout-payment-section.tsx +0 -212
- package/src/components/checkout/checkout-session-view.tsx +0 -564
- package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
- package/src/components/checkout/checkout-shipping-section.tsx +0 -98
- package/src/components/checkout/checkout-states.tsx +0 -73
- package/src/components/checkout/checkout-step-card.tsx +0 -101
- package/src/components/checkout/checkout-steps.ts +0 -111
- package/src/components/checkout/form-schema.ts +0 -281
- package/src/components/checkout/format.ts +0 -15
- package/src/components/checkout/index.ts +0 -5
- package/src/components/checkout/map-customer-to-checkout.ts +0 -188
- package/src/components/checkout/types.ts +0 -41
- package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
- package/src/components/checkout/use-checkout-geo.ts +0 -50
- package/src/components/checkout/use-checkout-session.ts +0 -640
- package/src/components/hero.tsx +0 -291
- package/src/config.d.ts +0 -94
- package/src/config.mjs +0 -146
- package/src/format-money.ts +0 -31
- package/src/health.ts +0 -90
- package/src/hooks/index.ts +0 -9
- package/src/hooks/recently-viewed.ts +0 -125
- package/src/index.ts +0 -349
- package/src/link.tsx +0 -2
- package/src/pages/account/account-page-skeleton.tsx +0 -69
- package/src/pages/account/account-page-view.tsx +0 -270
- package/src/pages/account/account-shell.tsx +0 -101
- package/src/pages/account/parse-account-route.ts +0 -36
- package/src/pages/account.tsx +0 -16
- package/src/pages/api.$.ts +0 -20
- package/src/pages/api.auth.$.ts +0 -16
- package/src/pages/checkout.$checkoutId.tsx +0 -60
- package/src/pages/checkout.tsx +0 -31
- package/src/pages/pages.$pageSlug.tsx +0 -74
- package/src/pages/thank-you.tsx +0 -53
- package/src/providers/auth.tsx +0 -96
- package/src/providers/cart.tsx +0 -275
- package/src/providers/ecomiq.ts +0 -137
- package/src/providers/index.ts +0 -26
- package/src/proxy-api.ts +0 -20
- package/src/public-config.ts +0 -24
- package/src/review-submission.ts +0 -89
- package/src/runtime/context.ts +0 -2
- package/src/runtime/default-layout.tsx +0 -64
- package/src/runtime/head.ts +0 -149
- package/src/runtime/page.tsx +0 -143
- package/src/runtime/postcss-browser-stub.mjs +0 -5
- package/src/server-config-store.ts +0 -35
- package/src/server.ts +0 -286
- package/src/styles.css +0 -76
- package/src/ui/badge.tsx +0 -32
- package/src/ui/button.tsx +0 -31
- package/src/ui/card.tsx +0 -31
- package/src/ui/carousel.tsx +0 -218
- package/src/ui/cn.ts +0 -6
- package/src/ui/index.ts +0 -8
- package/src/ui/separator.tsx +0 -6
- package/src/ui/skeleton.tsx +0 -6
- package/src/ui/storefront-error.tsx +0 -49
- package/src/utils.ts +0 -36
- package/src/vite-inline.mjs +0 -263
- package/templates/__root.tsx +0 -83
- package/templates/router.tsx +0 -19
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { useStorefrontText } from "./storefront-language-DrMjVbmk.js";
|
|
2
|
+
import { VoucherPayment } from "./voucher-payment-CVFDZ1L8.js";
|
|
3
|
+
import { useCulqiCheckout } from "./use-culqi-checkout-CrjLAipU.js";
|
|
4
|
+
import { CulqiAuthentication } from "./culqi-authentication-BGr20vAJ.js";
|
|
5
|
+
import { useRevalidator } from "react-router";
|
|
6
|
+
import { useEffect, useRef, useState } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
// src/order-payment-continuation.tsx
|
|
9
|
+
function OrderPaymentContinuation({ payment, source = null, orderStatusUrl, email, result }) {
|
|
10
|
+
const storefrontTranslate = useStorefrontText();
|
|
11
|
+
const revalidator = useRevalidator();
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (payment.isCaptured) return;
|
|
14
|
+
const timer = window.setInterval(() => {
|
|
15
|
+
revalidator.revalidate();
|
|
16
|
+
}, 1e4);
|
|
17
|
+
return () => window.clearInterval(timer);
|
|
18
|
+
}, [payment.isCaptured, revalidator.revalidate]);
|
|
19
|
+
if (payment.actionKind === "threeDS" && payment.providerId === "culqi" && orderStatusUrl && email) return /* @__PURE__ */ jsx(CulqiAuthentication, {
|
|
20
|
+
payment,
|
|
21
|
+
source,
|
|
22
|
+
orderStatusUrl,
|
|
23
|
+
email,
|
|
24
|
+
result
|
|
25
|
+
});
|
|
26
|
+
if (payment.actionKind === "embedded" && payment.providerId === "stripe") return /* @__PURE__ */ jsx(StripeOrderPayment, { payment });
|
|
27
|
+
if (payment.actionKind === "voucher" && payment.providerId === "culqi" && payment.externalId) return /* @__PURE__ */ jsx(CulqiOrderPayment, { payment });
|
|
28
|
+
if (payment.actionKind === "voucher") return /* @__PURE__ */ jsx(VoucherPayment, { payment });
|
|
29
|
+
if (payment.actionKind === "qrCode" && payment.qrCode) return /* @__PURE__ */ jsx(OrderPaymentQr, { code: payment.qrCode });
|
|
30
|
+
return /* @__PURE__ */ jsxs("p", {
|
|
31
|
+
role: "alert",
|
|
32
|
+
children: [storefrontTranslate("No pudimos abrir este medio de pago. Escríbenos para completar tu pedido."), " "]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function CulqiOrderPayment({ payment }) {
|
|
36
|
+
const storefrontTranslate = useStorefrontText();
|
|
37
|
+
const culqi = useCulqiCheckout();
|
|
38
|
+
const revalidator = useRevalidator();
|
|
39
|
+
const open = useRef(() => {});
|
|
40
|
+
open.current = () => {
|
|
41
|
+
if (payment.externalId === null || payment.paymentMethodCode === null || payment.amount === null || payment.currencyCode === null) return;
|
|
42
|
+
culqi.openOrder({
|
|
43
|
+
orderId: payment.externalId,
|
|
44
|
+
methodCode: payment.paymentMethodCode,
|
|
45
|
+
publicKey: payment.publicConfiguration.publicKey,
|
|
46
|
+
title: storefrontTranslate("Completa tu pago"),
|
|
47
|
+
currency: payment.currencyCode,
|
|
48
|
+
amount: payment.amount,
|
|
49
|
+
email: null
|
|
50
|
+
}, () => {
|
|
51
|
+
revalidator.revalidate();
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
open.current();
|
|
56
|
+
}, [payment.externalId]);
|
|
57
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: "flex flex-col gap-4",
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsx(VoucherPayment, { payment }),
|
|
61
|
+
culqi.error ? /* @__PURE__ */ jsx("p", {
|
|
62
|
+
role: "alert",
|
|
63
|
+
children: culqi.error
|
|
64
|
+
}) : null,
|
|
65
|
+
/* @__PURE__ */ jsx("button", {
|
|
66
|
+
type: "button",
|
|
67
|
+
disabled: culqi.loading,
|
|
68
|
+
onClick: () => open.current(),
|
|
69
|
+
className: "rounded-md bg-primary px-4 py-3 font-medium text-primary-foreground disabled:opacity-50",
|
|
70
|
+
children: culqi.loading ? storefrontTranslate("Cargando el pago…") : storefrontTranslate("Abrir instrucciones de pago")
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function OrderPaymentQr({ code }) {
|
|
76
|
+
const storefrontTranslate = useStorefrontText();
|
|
77
|
+
const [image, setImage] = useState(null);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
let disposed = false;
|
|
80
|
+
import("qrcode-generator").then(({ default: qrcode }) => {
|
|
81
|
+
if (disposed) return;
|
|
82
|
+
const qr = qrcode(0, "M");
|
|
83
|
+
qr.addData(code);
|
|
84
|
+
qr.make();
|
|
85
|
+
setImage(qr.createDataURL(5, 10));
|
|
86
|
+
});
|
|
87
|
+
return () => {
|
|
88
|
+
disposed = true;
|
|
89
|
+
};
|
|
90
|
+
}, [code]);
|
|
91
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
92
|
+
className: "flex flex-col items-center gap-4 rounded-lg border p-6",
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx("p", { children: storefrontTranslate("Escanea el QR para completar tu pago.") }),
|
|
95
|
+
image === null ? /* @__PURE__ */ jsx("span", {
|
|
96
|
+
className: "size-60",
|
|
97
|
+
"aria-hidden": "true"
|
|
98
|
+
}) : /* @__PURE__ */ jsx("img", {
|
|
99
|
+
src: image,
|
|
100
|
+
alt: storefrontTranslate("Código QR de pago"),
|
|
101
|
+
width: 240,
|
|
102
|
+
height: 240,
|
|
103
|
+
className: "size-60"
|
|
104
|
+
}),
|
|
105
|
+
/* @__PURE__ */ jsx("p", {
|
|
106
|
+
className: "text-sm text-muted-foreground",
|
|
107
|
+
role: "status",
|
|
108
|
+
children: storefrontTranslate("Confirmaremos tu pago al recibirlo.")
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function StripeOrderPayment({ payment }) {
|
|
114
|
+
const storefrontTranslate = useStorefrontText();
|
|
115
|
+
const container = useRef(null);
|
|
116
|
+
const stripe = useRef(null);
|
|
117
|
+
const elements = useRef(null);
|
|
118
|
+
const [ready, setReady] = useState(false);
|
|
119
|
+
const [busy, setBusy] = useState(false);
|
|
120
|
+
const [error, setError] = useState(null);
|
|
121
|
+
const [submitted, setSubmitted] = useState(false);
|
|
122
|
+
const [attempt, setAttempt] = useState(0);
|
|
123
|
+
const revalidator = useRevalidator();
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
let disposed = false;
|
|
126
|
+
let element;
|
|
127
|
+
setReady(false);
|
|
128
|
+
setError(null);
|
|
129
|
+
async function mount() {
|
|
130
|
+
const key = payment.publicConfiguration.publishableKey;
|
|
131
|
+
if (!key || !payment.clientSecret) throw new Error("El pago con tarjeta no está disponible. Escríbenos para completar tu pedido.");
|
|
132
|
+
const { loadStripe } = await import("@stripe/stripe-js/pure");
|
|
133
|
+
const client = await loadStripe(key);
|
|
134
|
+
if (disposed) return;
|
|
135
|
+
if (!client || !container.current) throw new Error("No pudimos cargar el pago con tarjeta.");
|
|
136
|
+
stripe.current = client;
|
|
137
|
+
elements.current = client.elements({ clientSecret: payment.clientSecret });
|
|
138
|
+
element = elements.current.create("payment");
|
|
139
|
+
element.on("ready", () => {
|
|
140
|
+
if (!disposed) setReady(true);
|
|
141
|
+
});
|
|
142
|
+
element.on("loaderror", () => {
|
|
143
|
+
if (!disposed) setError("No pudimos cargar el formulario. Revisa tu conexión e intenta de nuevo.");
|
|
144
|
+
});
|
|
145
|
+
element.mount(container.current);
|
|
146
|
+
}
|
|
147
|
+
mount().catch((error) => {
|
|
148
|
+
if (!disposed) setError(error instanceof Error ? error.message : "No pudimos cargar el pago con tarjeta.");
|
|
149
|
+
});
|
|
150
|
+
return () => {
|
|
151
|
+
disposed = true;
|
|
152
|
+
element?.destroy();
|
|
153
|
+
stripe.current = null;
|
|
154
|
+
elements.current = null;
|
|
155
|
+
};
|
|
156
|
+
}, [
|
|
157
|
+
payment.clientSecret,
|
|
158
|
+
payment.publicConfiguration.publishableKey,
|
|
159
|
+
attempt
|
|
160
|
+
]);
|
|
161
|
+
async function pay() {
|
|
162
|
+
if (!stripe.current || !elements.current || busy) return;
|
|
163
|
+
setBusy(true);
|
|
164
|
+
setError(null);
|
|
165
|
+
try {
|
|
166
|
+
const result = await stripe.current.confirmPayment({
|
|
167
|
+
elements: elements.current,
|
|
168
|
+
confirmParams: { return_url: window.location.href },
|
|
169
|
+
redirect: "if_required"
|
|
170
|
+
});
|
|
171
|
+
if (result.error) setError(result.error.message ?? "No pudimos procesar el pago. Revisa los datos de la tarjeta.");
|
|
172
|
+
else {
|
|
173
|
+
setSubmitted(true);
|
|
174
|
+
await revalidator.revalidate();
|
|
175
|
+
}
|
|
176
|
+
} catch {
|
|
177
|
+
setError("No pudimos confirmar el pago. Revisa su estado antes de intentar de nuevo.");
|
|
178
|
+
} finally {
|
|
179
|
+
setBusy(false);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
183
|
+
className: "flex flex-col gap-4 rounded-lg border p-6",
|
|
184
|
+
children: [
|
|
185
|
+
/* @__PURE__ */ jsx("div", { ref: container }),
|
|
186
|
+
error ? /* @__PURE__ */ jsx("p", {
|
|
187
|
+
role: "alert",
|
|
188
|
+
className: "text-sm text-destructive",
|
|
189
|
+
children: error
|
|
190
|
+
}) : null,
|
|
191
|
+
submitted ? /* @__PURE__ */ jsx("p", {
|
|
192
|
+
role: "status",
|
|
193
|
+
children: storefrontTranslate("Estamos confirmando tu pago.")
|
|
194
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
195
|
+
type: "button",
|
|
196
|
+
onClick: () => {
|
|
197
|
+
pay();
|
|
198
|
+
},
|
|
199
|
+
disabled: !ready || busy,
|
|
200
|
+
className: "rounded-md bg-primary px-4 py-3 font-medium text-primary-foreground disabled:opacity-50",
|
|
201
|
+
children: busy ? storefrontTranslate("Procesando…") : "Confirmar pago"
|
|
202
|
+
}),
|
|
203
|
+
error && !ready ? /* @__PURE__ */ jsxs("button", {
|
|
204
|
+
type: "button",
|
|
205
|
+
onClick: () => setAttempt((value) => value + 1),
|
|
206
|
+
className: "underline",
|
|
207
|
+
children: [storefrontTranslate("Reintentar"), " "]
|
|
208
|
+
}) : null
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
export { OrderPaymentContinuation };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CulqiPaymentSource } from "./culqi-three-ds.js";
|
|
2
|
+
import { OrderPaymentActionData } from "./order-status.js";
|
|
3
|
+
import { OrderPaymentStart } from "@ecomiq/core";
|
|
4
|
+
export declare function OrderPaymentContinuation({ payment, source, orderStatusUrl, email, result }: {
|
|
5
|
+
payment: OrderPaymentStart;
|
|
6
|
+
source?: CulqiPaymentSource | null;
|
|
7
|
+
orderStatusUrl?: string;
|
|
8
|
+
email?: string | null;
|
|
9
|
+
result?: OrderPaymentActionData;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { money } from "./money-DtGOtDri.js";
|
|
2
|
+
import { useStorefrontLocale, useStorefrontText } from "./storefront-language-DrMjVbmk.js";
|
|
3
|
+
import { Link, useLocation, useRevalidator } from "react-router";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
// src/order-payment-in-review.tsx
|
|
7
|
+
const CONFIRMATION_POLL_MS = 3e3;
|
|
8
|
+
const CONFIRMATION_TIMEOUT_MS = 6e4;
|
|
9
|
+
const MESSAGES = {
|
|
10
|
+
awaitingProvider: "Estamos confirmando tu pago de {value0}. Esto puede tardar unos segundos.",
|
|
11
|
+
awaitingCapture: "Recibimos tu pago de {value0}. La tienda lo confirmará en breve.",
|
|
12
|
+
receiptInReview: "Recibimos tu comprobante por {value0}. La tienda lo revisará en breve."
|
|
13
|
+
};
|
|
14
|
+
function OrderPaymentInReview({ payment, currency }) {
|
|
15
|
+
const storefrontTranslate = useStorefrontText();
|
|
16
|
+
const { locale } = useStorefrontLocale();
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
18
|
+
className: "flex flex-col gap-2 rounded-lg border p-5",
|
|
19
|
+
role: "status",
|
|
20
|
+
children: [
|
|
21
|
+
/* @__PURE__ */ jsx("p", {
|
|
22
|
+
className: "font-medium",
|
|
23
|
+
children: storefrontTranslate("Pago en confirmación")
|
|
24
|
+
}),
|
|
25
|
+
/* @__PURE__ */ jsx("p", {
|
|
26
|
+
className: "text-sm text-muted-foreground",
|
|
27
|
+
children: storefrontTranslate(MESSAGES[payment.kind], { value0: money(payment.amount, currency, locale) })
|
|
28
|
+
}),
|
|
29
|
+
payment.kind === "awaitingProvider" ? /* @__PURE__ */ jsx(ProviderConfirmation, {}) : null
|
|
30
|
+
]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function ProviderConfirmation() {
|
|
34
|
+
const storefrontTranslate = useStorefrontText();
|
|
35
|
+
const revalidator = useRevalidator();
|
|
36
|
+
const location = useLocation();
|
|
37
|
+
const [timedOut, setTimedOut] = useState(false);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const poll = window.setInterval(() => {
|
|
40
|
+
revalidator.revalidate();
|
|
41
|
+
}, CONFIRMATION_POLL_MS);
|
|
42
|
+
const timeout = window.setTimeout(() => {
|
|
43
|
+
window.clearInterval(poll);
|
|
44
|
+
setTimedOut(true);
|
|
45
|
+
}, CONFIRMATION_TIMEOUT_MS);
|
|
46
|
+
return () => {
|
|
47
|
+
window.clearInterval(poll);
|
|
48
|
+
window.clearTimeout(timeout);
|
|
49
|
+
};
|
|
50
|
+
}, [revalidator.revalidate]);
|
|
51
|
+
if (!timedOut) return null;
|
|
52
|
+
return /* @__PURE__ */ jsxs("p", {
|
|
53
|
+
className: "text-sm",
|
|
54
|
+
children: [
|
|
55
|
+
storefrontTranslate("Aún no recibimos la confirmación. Si ya completaste el pago, no lo repitas: te avisaremos cuando se confirme."),
|
|
56
|
+
" ",
|
|
57
|
+
/* @__PURE__ */ jsx(Link, {
|
|
58
|
+
to: location.pathname,
|
|
59
|
+
className: "underline",
|
|
60
|
+
children: storefrontTranslate("Ver opciones de pago")
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export { OrderPaymentInReview };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { orderAnalytics } from "./analytics/events-Dt81tIp1.js";
|
|
2
|
+
import { text } from "./form-BtQcbXlJ.js";
|
|
3
|
+
import { found, store } from "./store-8Q-_LFrQ.js";
|
|
4
|
+
import { worker } from "./worker-CNi-gzCu.js";
|
|
5
|
+
import { PAYMENT_RETURN_CONFIRMING, PAYMENT_RETURN_PARAM } from "./payment-return-5cjypwIw.js";
|
|
6
|
+
import { data, redirect } from "react-router";
|
|
7
|
+
import { ApiError, AuthenticateOrderPaymentInputSchema } from "@ecomiq/core";
|
|
8
|
+
// src/order-status.ts
|
|
9
|
+
function hasOrderPaymentContinuation(payment) {
|
|
10
|
+
return payment !== void 0 && payment !== null && !payment.isCaptured && payment.providerId !== "manual" && payment.actionKind !== "none";
|
|
11
|
+
}
|
|
12
|
+
const PROGRESS = [
|
|
13
|
+
{
|
|
14
|
+
key: "confirmed",
|
|
15
|
+
label: "Confirmado"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
key: "shipped",
|
|
19
|
+
label: "Enviado"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: "outForDelivery",
|
|
23
|
+
label: "En reparto"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: "delivered",
|
|
27
|
+
label: "Entregado"
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
const TITLES = {
|
|
31
|
+
pending: "Pedido recibido",
|
|
32
|
+
confirmed: "Pedido confirmado",
|
|
33
|
+
shipped: "Pedido enviado",
|
|
34
|
+
outForDelivery: "En reparto",
|
|
35
|
+
delivered: "Pedido entregado",
|
|
36
|
+
cancelled: "Pedido cancelado"
|
|
37
|
+
};
|
|
38
|
+
function orderProgress(step) {
|
|
39
|
+
const current = PROGRESS.findIndex((item) => item.key === step);
|
|
40
|
+
return PROGRESS.map((item, index) => ({
|
|
41
|
+
...item,
|
|
42
|
+
done: index <= current,
|
|
43
|
+
current: index === current
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
function orderStepTitle(step) {
|
|
47
|
+
return TITLES[step];
|
|
48
|
+
}
|
|
49
|
+
function returnsFromPaymentProvider(context) {
|
|
50
|
+
const { requestUrl } = context.get(worker);
|
|
51
|
+
if (requestUrl === void 0) return false;
|
|
52
|
+
return new URL(requestUrl).searchParams.get(PAYMENT_RETURN_PARAM) === PAYMENT_RETURN_CONFIRMING;
|
|
53
|
+
}
|
|
54
|
+
async function loadOrderStatus(context, token) {
|
|
55
|
+
const status = await found(store(context).getOrderStatus(token), (code) => code < 500);
|
|
56
|
+
const methods = status.paymentMethods.filter((method) => method.isActive).sort((a, b) => a.sortOrder - b.sortOrder);
|
|
57
|
+
const settings = await store(context).getSettings();
|
|
58
|
+
let paymentInReview = status.paymentInReview;
|
|
59
|
+
if (paymentInReview === null && status.balanceDue > 0 && returnsFromPaymentProvider(context)) paymentInReview = {
|
|
60
|
+
kind: "awaitingProvider",
|
|
61
|
+
amount: status.balanceDue
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
token,
|
|
65
|
+
order: status.order,
|
|
66
|
+
step: status.step,
|
|
67
|
+
balanceDue: status.balanceDue,
|
|
68
|
+
methods,
|
|
69
|
+
pendingPayment: status.pendingPayment,
|
|
70
|
+
paymentInReview,
|
|
71
|
+
timeZone: settings.store.timeZone,
|
|
72
|
+
locale: `${settings.store.language}-${settings.store.countryCode}`,
|
|
73
|
+
analytics: orderAnalytics(status.order, status.balanceDue <= 0 && status.step !== "cancelled")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function failure(message) {
|
|
77
|
+
return data({
|
|
78
|
+
ok: false,
|
|
79
|
+
message
|
|
80
|
+
}, { status: 400 });
|
|
81
|
+
}
|
|
82
|
+
const ORDER_PAYMENT_CONFLICTS = {
|
|
83
|
+
"Payments.ProviderOperationInProgress": "Ya iniciaste un pago para este pedido. Complétalo con el mismo medio de pago o espera a que venza para elegir otro.",
|
|
84
|
+
"Payments.ProviderOutcomePending": "Ya iniciaste un pago para este pedido. Complétalo con el mismo medio de pago o espera a que venza para elegir otro.",
|
|
85
|
+
"Payments.PaymentProjectionPending": "Estamos registrando un pago anterior de este pedido. Actualiza la página en unos minutos.",
|
|
86
|
+
"Orders.NoBalanceDue": "Este pedido ya no tiene saldo pendiente."
|
|
87
|
+
};
|
|
88
|
+
async function orderPaymentAction(request, context, token) {
|
|
89
|
+
const form = await request.formData();
|
|
90
|
+
if (text(form, "intent") === "authenticate") {
|
|
91
|
+
let authentication3DS;
|
|
92
|
+
try {
|
|
93
|
+
authentication3DS = JSON.parse(text(form, "authentication3DS"));
|
|
94
|
+
} catch {
|
|
95
|
+
return failure("No pudimos validar la autenticación del pago.");
|
|
96
|
+
}
|
|
97
|
+
const input = AuthenticateOrderPaymentInputSchema.safeParse({
|
|
98
|
+
token: text(form, "token"),
|
|
99
|
+
deviceSessionId: text(form, "deviceSessionId"),
|
|
100
|
+
authentication3DS
|
|
101
|
+
});
|
|
102
|
+
const transactionId = text(form, "transactionId");
|
|
103
|
+
if (!input.success || !transactionId) return failure("No pudimos validar la autenticación del pago.");
|
|
104
|
+
try {
|
|
105
|
+
const payment = await store(context).authenticateOrderPayment(token, transactionId, input.data);
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
message: payment.isCaptured ? "Recibimos tu pago." : "Estamos confirmando tu pago.",
|
|
109
|
+
payment,
|
|
110
|
+
authenticatedTransactionId: payment.actionKind === "threeDS" ? void 0 : transactionId
|
|
111
|
+
};
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error instanceof ApiError && error.status === 404) throw data(null, { status: 404 });
|
|
114
|
+
return failure("No pudimos confirmar la autenticación. Consulta el estado del pedido antes de intentar nuevamente.");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const method = text(form, "method");
|
|
118
|
+
if (!method) return failure("Elige un medio de pago.");
|
|
119
|
+
try {
|
|
120
|
+
const file = form.get("receipt") ?? form.get("file");
|
|
121
|
+
const client = store(context);
|
|
122
|
+
let payment;
|
|
123
|
+
if (file instanceof File && file.size > 0) {
|
|
124
|
+
if (file.size > 5242880) return failure("El comprobante debe pesar como máximo 5 MB.");
|
|
125
|
+
if (![
|
|
126
|
+
"image/jpeg",
|
|
127
|
+
"image/png",
|
|
128
|
+
"image/webp"
|
|
129
|
+
].includes(file.type)) return failure("Adjunta un comprobante JPG, PNG o WebP.");
|
|
130
|
+
payment = await client.uploadOrderPaymentReceipt(token, {
|
|
131
|
+
paymentMethodCode: method,
|
|
132
|
+
file
|
|
133
|
+
});
|
|
134
|
+
} else payment = await client.startOrderPayment(token, {
|
|
135
|
+
paymentMethodCode: method,
|
|
136
|
+
token: text(form, "token") || void 0,
|
|
137
|
+
providerPaymentMethodId: text(form, "providerPaymentMethodId") || void 0,
|
|
138
|
+
deviceSessionId: text(form, "deviceSessionId") || void 0
|
|
139
|
+
});
|
|
140
|
+
if (payment.actionKind === "redirect" && payment.actionUrl) return redirect(payment.actionUrl);
|
|
141
|
+
let message = "Continúa para completar el pago.";
|
|
142
|
+
if (payment.isCaptured) message = "Recibimos tu pago.";
|
|
143
|
+
else if (payment.receiptUrl) message = "Recibimos tu comprobante. Te avisaremos cuando confirmemos el pago.";
|
|
144
|
+
else if (payment.providerId === "manual" || payment.actionKind === "none") message = "Registramos tu pago. Te avisaremos cuando lo confirmemos.";
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
message,
|
|
148
|
+
payment,
|
|
149
|
+
method
|
|
150
|
+
};
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof ApiError && error.status === 404) throw data(null, { status: 404 });
|
|
153
|
+
if (error instanceof ApiError && error.status === 409) {
|
|
154
|
+
let message = "Ya hay un pago registrado para este pedido.";
|
|
155
|
+
if (error.code !== void 0) message = ORDER_PAYMENT_CONFLICTS[error.code] ?? message;
|
|
156
|
+
return failure(message);
|
|
157
|
+
}
|
|
158
|
+
if (error instanceof ApiError && error.status >= 400 && error.status < 500) return failure(error.message);
|
|
159
|
+
return failure("No pudimos iniciar el pago. Intenta de nuevo.");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export { hasOrderPaymentContinuation, loadOrderStatus, orderPaymentAction, orderProgress, orderStepTitle };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { PageAnalytics } from "./analytics/events.js";
|
|
2
|
+
import { RouterContextProvider } from "react-router";
|
|
3
|
+
import { CustomerOrderDetail, OrderPaymentInReview, OrderPaymentMethod, OrderPaymentStart, OrderStep } from "@ecomiq/core";
|
|
4
|
+
export type OrderPaymentReview = OrderPaymentInReview | {
|
|
5
|
+
kind: "awaitingProvider";
|
|
6
|
+
amount: number;
|
|
7
|
+
};
|
|
8
|
+
export type OrderStatusData = {
|
|
9
|
+
token: string;
|
|
10
|
+
order: CustomerOrderDetail;
|
|
11
|
+
step: OrderStep;
|
|
12
|
+
balanceDue: number;
|
|
13
|
+
methods: OrderPaymentMethod[];
|
|
14
|
+
pendingPayment: OrderPaymentStart | null;
|
|
15
|
+
paymentInReview: OrderPaymentReview | null;
|
|
16
|
+
timeZone: string;
|
|
17
|
+
locale: string;
|
|
18
|
+
analytics: PageAnalytics;
|
|
19
|
+
};
|
|
20
|
+
export type OrderPaymentActionData = {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
message: string;
|
|
23
|
+
payment?: OrderPaymentStart;
|
|
24
|
+
method?: string;
|
|
25
|
+
authenticatedTransactionId?: string;
|
|
26
|
+
};
|
|
27
|
+
export type OrderProgressStep = {
|
|
28
|
+
key: OrderStep;
|
|
29
|
+
label: string;
|
|
30
|
+
done: boolean;
|
|
31
|
+
current: boolean;
|
|
32
|
+
};
|
|
33
|
+
export declare function hasOrderPaymentContinuation(payment: OrderPaymentStart | null | undefined): payment is OrderPaymentStart;
|
|
34
|
+
export declare function orderProgress(step: OrderStep): OrderProgressStep[];
|
|
35
|
+
export declare function orderStepTitle(step: OrderStep): string;
|
|
36
|
+
export declare function loadOrderStatus(context: Readonly<RouterContextProvider>, token: string): Promise<OrderStatusData>;
|
|
37
|
+
export declare function orderPaymentAction(request: Request, context: Readonly<RouterContextProvider>, token: string): Promise<import("react-router").UNSAFE_DataWithResponseInit<OrderPaymentActionData> | Response | {
|
|
38
|
+
ok: true;
|
|
39
|
+
message: string;
|
|
40
|
+
payment: {
|
|
41
|
+
actionUrl: string | null;
|
|
42
|
+
isCaptured: boolean;
|
|
43
|
+
transactionId: string | null;
|
|
44
|
+
externalId: string | null;
|
|
45
|
+
actionKind: "embedded" | "none" | "qrCode" | "redirect" | "threeDS" | "voucher";
|
|
46
|
+
providerId: string | null;
|
|
47
|
+
publicConfiguration: {
|
|
48
|
+
publishableKey?: string | undefined;
|
|
49
|
+
publicKey?: string | undefined;
|
|
50
|
+
};
|
|
51
|
+
clientSecret: string | null;
|
|
52
|
+
qrCode: string | null;
|
|
53
|
+
receiptUrl: string | null;
|
|
54
|
+
expiresAt: string | null;
|
|
55
|
+
paymentMethodCode: string | null;
|
|
56
|
+
amount: number | null;
|
|
57
|
+
currencyCode: string | null;
|
|
58
|
+
voucherCode: string | null;
|
|
59
|
+
qrImageUrl: string | null;
|
|
60
|
+
};
|
|
61
|
+
authenticatedTransactionId: string | undefined;
|
|
62
|
+
method?: undefined;
|
|
63
|
+
} | {
|
|
64
|
+
authenticatedTransactionId?: undefined;
|
|
65
|
+
ok: true;
|
|
66
|
+
message: string;
|
|
67
|
+
payment: {
|
|
68
|
+
actionUrl: string | null;
|
|
69
|
+
isCaptured: boolean;
|
|
70
|
+
transactionId: string | null;
|
|
71
|
+
externalId: string | null;
|
|
72
|
+
actionKind: "embedded" | "none" | "qrCode" | "redirect" | "threeDS" | "voucher";
|
|
73
|
+
providerId: string | null;
|
|
74
|
+
publicConfiguration: {
|
|
75
|
+
publishableKey?: string | undefined;
|
|
76
|
+
publicKey?: string | undefined;
|
|
77
|
+
};
|
|
78
|
+
clientSecret: string | null;
|
|
79
|
+
qrCode: string | null;
|
|
80
|
+
receiptUrl: string | null;
|
|
81
|
+
expiresAt: string | null;
|
|
82
|
+
paymentMethodCode: string | null;
|
|
83
|
+
amount: number | null;
|
|
84
|
+
currencyCode: string | null;
|
|
85
|
+
voucherCode: string | null;
|
|
86
|
+
qrImageUrl: string | null;
|
|
87
|
+
};
|
|
88
|
+
method: string;
|
|
89
|
+
}>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/order-view.ts
|
|
2
|
+
const STEP_LABELS = {
|
|
3
|
+
pending: "Recibido",
|
|
4
|
+
confirmed: "Confirmado",
|
|
5
|
+
shipped: "Enviado",
|
|
6
|
+
outForDelivery: "En reparto",
|
|
7
|
+
delivered: "Entregado",
|
|
8
|
+
cancelled: "Cancelado"
|
|
9
|
+
};
|
|
10
|
+
const STATUS_STEPS = {
|
|
11
|
+
new: "pending",
|
|
12
|
+
pendingToConfirm: "pending",
|
|
13
|
+
none: "pending",
|
|
14
|
+
confirmed: "confirmed",
|
|
15
|
+
inProgress: "confirmed",
|
|
16
|
+
invoiced: "confirmed",
|
|
17
|
+
readyToPickUp: "confirmed",
|
|
18
|
+
inTransit: "shipped",
|
|
19
|
+
pendingToDeliveredToClient: "outForDelivery",
|
|
20
|
+
delivered: "delivered",
|
|
21
|
+
partialDelivered: "delivered",
|
|
22
|
+
returned: "delivered",
|
|
23
|
+
partialReturned: "delivered",
|
|
24
|
+
closed: "delivered",
|
|
25
|
+
cancelled: "cancelled",
|
|
26
|
+
partialCancelled: "cancelled",
|
|
27
|
+
invalid: "cancelled"
|
|
28
|
+
};
|
|
29
|
+
const PAYMENT_STATUS_LABELS = {
|
|
30
|
+
pending: "Pendiente",
|
|
31
|
+
authorized: "Autorizado",
|
|
32
|
+
captured: "Pagado",
|
|
33
|
+
failed: "Rechazado",
|
|
34
|
+
cancelled: "Anulado",
|
|
35
|
+
refunded: "Reembolsado"
|
|
36
|
+
};
|
|
37
|
+
function camel(value) {
|
|
38
|
+
return value.charAt(0).toLowerCase() + value.slice(1);
|
|
39
|
+
}
|
|
40
|
+
/** The step the buyer sees for an order or item; an older API sends only the status. */
|
|
41
|
+
function orderStepOf(value) {
|
|
42
|
+
return value.step ?? STATUS_STEPS[camel(value.status.trim())] ?? "pending";
|
|
43
|
+
}
|
|
44
|
+
function orderStepLabel(step) {
|
|
45
|
+
return STEP_LABELS[step];
|
|
46
|
+
}
|
|
47
|
+
/** "Visa •••• 4242" for cards, otherwise the payment method name. */
|
|
48
|
+
function paymentLabel(payment) {
|
|
49
|
+
const brand = payment.cardBrand?.trim() ?? "";
|
|
50
|
+
const last4 = payment.cardLast4?.trim() ?? "";
|
|
51
|
+
if (last4 !== "") return `${brand || payment.paymentMethod} •••• ${last4}`;
|
|
52
|
+
return brand || payment.paymentMethod;
|
|
53
|
+
}
|
|
54
|
+
function paymentStatusLabel(payment) {
|
|
55
|
+
if (payment.paymentStatus === null) return null;
|
|
56
|
+
return PAYMENT_STATUS_LABELS[camel(payment.paymentStatus)] ?? null;
|
|
57
|
+
}
|
|
58
|
+
/** The payment to preview in a list: the first one that went through, else the latest. */
|
|
59
|
+
function mainPayment(payments) {
|
|
60
|
+
return payments.find((payment) => payment.paymentStatus !== null && ["captured", "authorized"].includes(camel(payment.paymentStatus))) ?? payments.at(-1) ?? null;
|
|
61
|
+
}
|
|
62
|
+
export { mainPayment, orderStepLabel, orderStepOf, paymentLabel, paymentStatusLabel };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CustomerOrderPayment, OrderStep } from "@ecomiq/core";
|
|
2
|
+
/** The step the buyer sees for an order or item; an older API sends only the status. */
|
|
3
|
+
export declare function orderStepOf(value: {
|
|
4
|
+
step?: OrderStep;
|
|
5
|
+
status: string;
|
|
6
|
+
}): OrderStep;
|
|
7
|
+
export declare function orderStepLabel(step: OrderStep): string;
|
|
8
|
+
/** "Visa •••• 4242" for cards, otherwise the payment method name. */
|
|
9
|
+
export declare function paymentLabel(payment: CustomerOrderPayment): string;
|
|
10
|
+
export declare function paymentStatusLabel(payment: CustomerOrderPayment): string | null;
|
|
11
|
+
/** The payment to preview in a list: the first one that went through, else the latest. */
|
|
12
|
+
export declare function mainPayment(payments: CustomerOrderPayment[]): CustomerOrderPayment | null;
|