@pandait.tech/payment-nuvei 0.1.0 → 0.2.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/ui/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { useState, useEffect, useRef, useCallback } from 'react';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
3
  import { FaCheck, FaTrash, FaLock, FaExclamationTriangle, FaShieldAlt, FaPlus, FaInfoCircle, FaTimesCircle, FaRedo } from 'react-icons/fa';
3
4
  import Script from 'next/script';
4
5
 
@@ -510,8 +511,6 @@ var CARD_TYPE_NAMES = {
510
511
  prepaid: "Prepago",
511
512
  unknown: ""
512
513
  };
513
-
514
- // src/ui/CardVisual.tsx
515
514
  var BRAND_GRADIENT = {
516
515
  vi: { from: "#1a1f71", to: "#0d1240" },
517
516
  mc: { from: "#cc4d2e", to: "#561a0e" },
@@ -523,9 +522,12 @@ var BRAND_GRADIENT = {
523
522
  function BrandMark({ brand }) {
524
523
  const text = CARD_BRAND_NAMES[brand] || "CARD";
525
524
  if (brand === "mc") {
526
- return /* @__PURE__ */ React.createElement("div", { className: "flex items-center -space-x-2" }, /* @__PURE__ */ React.createElement("span", { className: "w-4 h-4 rounded-full bg-[#eb001b]" }), /* @__PURE__ */ React.createElement("span", { className: "w-4 h-4 rounded-full bg-[#f79e1b]/90 mix-blend-screen" }));
525
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center -space-x-2", children: [
526
+ /* @__PURE__ */ jsx("span", { className: "w-4 h-4 rounded-full bg-[#eb001b]" }),
527
+ /* @__PURE__ */ jsx("span", { className: "w-4 h-4 rounded-full bg-[#f79e1b]/90 mix-blend-screen" })
528
+ ] });
527
529
  }
528
- return /* @__PURE__ */ React.createElement("span", { className: "text-white text-[11px] font-bold tracking-wider uppercase italic" }, text);
530
+ return /* @__PURE__ */ jsx("span", { className: "text-white text-[11px] font-bold tracking-wider uppercase italic", children: text });
529
531
  }
530
532
  function CardVisual({
531
533
  bin,
@@ -564,29 +566,66 @@ function CardVisual({
564
566
  const cardType = binInfo?.type ? CARD_TYPE_NAMES[binInfo.type] || "" : "";
565
567
  const expiryShort = `${expiryMonth.padStart(2, "0")}/${String(expiryYear).slice(-2)}`;
566
568
  if (variant === "compact") {
567
- return /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React.createElement(
568
- "div",
569
- {
570
- style: gradientStyle,
571
- className: "shrink-0 relative w-22 h-14 rounded-md shadow-md overflow-hidden"
572
- },
573
- /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 bg-linear-to-br from-white/10 via-transparent to-black/20 pointer-events-none" }),
574
- /* @__PURE__ */ React.createElement("div", { className: "absolute top-2 left-2 w-3.5 h-2.5 rounded-sm bg-linear-to-br from-yellow-200/80 to-yellow-600/80 border border-yellow-700/40" }),
575
- /* @__PURE__ */ React.createElement("div", { className: "absolute top-1.5 right-2" }, /* @__PURE__ */ React.createElement(BrandMark, { brand })),
576
- /* @__PURE__ */ React.createElement("div", { className: "absolute bottom-1.5 left-2 right-2 flex justify-between items-end" }, /* @__PURE__ */ React.createElement("span", { className: "text-white/95 text-[11px] font-mono tracking-[0.05em] font-semibold drop-shadow" }, "\xB7\xB7\xB7\xB7", last4), /* @__PURE__ */ React.createElement("span", { className: "text-white/75 text-[8px] font-mono" }, expiryShort))
577
- ), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-semibold text-[var(--color-text-main)] truncate" }, bankName || CARD_BRAND_NAMES[brand] || "Tarjeta"), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-[var(--color-text-main)]/50 truncate" }, cardType ? `${cardType} \xB7 ` : "", holderName || "\u2014")));
569
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
570
+ /* @__PURE__ */ jsxs(
571
+ "div",
572
+ {
573
+ style: gradientStyle,
574
+ className: "shrink-0 relative w-22 h-14 rounded-md shadow-md overflow-hidden",
575
+ children: [
576
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-br from-white/10 via-transparent to-black/20 pointer-events-none" }),
577
+ /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 w-3.5 h-2.5 rounded-sm bg-linear-to-br from-yellow-200/80 to-yellow-600/80 border border-yellow-700/40" }),
578
+ /* @__PURE__ */ jsx("div", { className: "absolute top-1.5 right-2", children: /* @__PURE__ */ jsx(BrandMark, { brand }) }),
579
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-1.5 left-2 right-2 flex justify-between items-end", children: [
580
+ /* @__PURE__ */ jsxs("span", { className: "text-white/95 text-[11px] font-mono tracking-[0.05em] font-semibold drop-shadow", children: [
581
+ "\xB7\xB7\xB7\xB7",
582
+ last4
583
+ ] }),
584
+ /* @__PURE__ */ jsx("span", { className: "text-white/75 text-[8px] font-mono", children: expiryShort })
585
+ ] })
586
+ ]
587
+ }
588
+ ),
589
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
590
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-[var(--color-text-main)] truncate", children: bankName || CARD_BRAND_NAMES[brand] || "Tarjeta" }),
591
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-[var(--color-text-main)]/50 truncate", children: [
592
+ cardType ? `${cardType} \xB7 ` : "",
593
+ holderName || "\u2014"
594
+ ] })
595
+ ] })
596
+ ] });
578
597
  }
579
- return /* @__PURE__ */ React.createElement(
598
+ return /* @__PURE__ */ jsxs(
580
599
  "div",
581
600
  {
582
601
  style: gradientStyle,
583
- className: "relative overflow-hidden rounded-2xl shadow-xl p-5 aspect-[1.586/1] w-full max-w-sm"
584
- },
585
- /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 bg-linear-to-br from-white/10 via-transparent to-black/30 pointer-events-none" }),
586
- /* @__PURE__ */ React.createElement("div", { className: "relative flex justify-between items-start" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "text-[10px] font-medium tracking-[0.2em] uppercase text-white/50" }, cardType || "Tarjeta"), bankName && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-white/85 mt-0.5 font-medium" }, bankName)), /* @__PURE__ */ React.createElement(BrandMark, { brand })),
587
- /* @__PURE__ */ React.createElement("div", { className: "relative mt-6 w-9 h-7 rounded-md bg-linear-to-br from-yellow-200 to-yellow-600 border border-yellow-700/40 shadow-inner" }),
588
- /* @__PURE__ */ React.createElement("div", { className: "relative mt-4" }, /* @__PURE__ */ React.createElement("p", { className: "font-mono text-lg tracking-wider text-white drop-shadow" }, "\xB7\xB7\xB7\xB7 \xB7\xB7\xB7\xB7 \xB7\xB7\xB7\xB7 ", last4)),
589
- /* @__PURE__ */ React.createElement("div", { className: "relative mt-3 flex justify-between items-end" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("p", { className: "text-[9px] uppercase tracking-wider text-white/50" }, "Titular"), /* @__PURE__ */ React.createElement("p", { className: "text-white text-sm font-medium truncate uppercase" }, holderName || "\u2014")), /* @__PURE__ */ React.createElement("div", { className: "text-right" }, /* @__PURE__ */ React.createElement("p", { className: "text-[9px] uppercase tracking-wider text-white/50" }, "Expira"), /* @__PURE__ */ React.createElement("p", { className: "text-white text-sm font-mono font-medium" }, expiryShort)))
602
+ className: "relative overflow-hidden rounded-2xl shadow-xl p-5 aspect-[1.586/1] w-full max-w-sm",
603
+ children: [
604
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-br from-white/10 via-transparent to-black/30 pointer-events-none" }),
605
+ /* @__PURE__ */ jsxs("div", { className: "relative flex justify-between items-start", children: [
606
+ /* @__PURE__ */ jsxs("div", { children: [
607
+ /* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium tracking-[0.2em] uppercase text-white/50", children: cardType || "Tarjeta" }),
608
+ bankName && /* @__PURE__ */ jsx("p", { className: "text-xs text-white/85 mt-0.5 font-medium", children: bankName })
609
+ ] }),
610
+ /* @__PURE__ */ jsx(BrandMark, { brand })
611
+ ] }),
612
+ /* @__PURE__ */ jsx("div", { className: "relative mt-6 w-9 h-7 rounded-md bg-linear-to-br from-yellow-200 to-yellow-600 border border-yellow-700/40 shadow-inner" }),
613
+ /* @__PURE__ */ jsx("div", { className: "relative mt-4", children: /* @__PURE__ */ jsxs("p", { className: "font-mono text-lg tracking-wider text-white drop-shadow", children: [
614
+ "\xB7\xB7\xB7\xB7 \xB7\xB7\xB7\xB7 \xB7\xB7\xB7\xB7 ",
615
+ last4
616
+ ] }) }),
617
+ /* @__PURE__ */ jsxs("div", { className: "relative mt-3 flex justify-between items-end", children: [
618
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
619
+ /* @__PURE__ */ jsx("p", { className: "text-[9px] uppercase tracking-wider text-white/50", children: "Titular" }),
620
+ /* @__PURE__ */ jsx("p", { className: "text-white text-sm font-medium truncate uppercase", children: holderName || "\u2014" })
621
+ ] }),
622
+ /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
623
+ /* @__PURE__ */ jsx("p", { className: "text-[9px] uppercase tracking-wider text-white/50", children: "Expira" }),
624
+ /* @__PURE__ */ jsx("p", { className: "text-white text-sm font-mono font-medium", children: expiryShort })
625
+ ] })
626
+ ] })
627
+ ]
628
+ }
590
629
  );
591
630
  }
592
631
  function SavedCards({
@@ -691,173 +730,219 @@ function SavedCards({
691
730
  }
692
731
  }
693
732
  if (loading) {
694
- return /* @__PURE__ */ React.createElement("div", { className: "flex justify-center py-6" }, /* @__PURE__ */ React.createElement("div", { className: "w-12 h-12 rounded-full border-2 border-[var(--color-text-main)]/20 border-t-[var(--color-primary)] animate-spin" }));
733
+ return /* @__PURE__ */ jsx("div", { className: "flex justify-center py-6", children: /* @__PURE__ */ jsx("div", { className: "w-12 h-12 rounded-full border-2 border-[var(--color-text-main)]/20 border-t-[var(--color-primary)] animate-spin" }) });
695
734
  }
696
735
  const validCards = cards.filter((c) => c.status === "valid");
697
736
  const reviewCards = cards.filter(
698
737
  (c) => c.status === "review" || c.status === "pending"
699
738
  );
700
- return /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, validCards.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, validCards.map((card) => {
701
- const isSelected = selectedToken === card.token;
702
- const cvc = cvcValues[card.token] || "";
703
- const maxCvc = card.type === "ax" ? 4 : 3;
704
- return /* @__PURE__ */ React.createElement(
705
- "div",
706
- {
707
- key: card.token,
708
- onClick: () => {
709
- onSelectCard(card, cvc);
710
- if (!isSelected) {
711
- setCvcValues((prev) => ({ ...prev, [card.token]: "" }));
712
- }
713
- },
714
- className: `border rounded-lg cursor-pointer transition-all duration-200 ${isSelected ? "border-[var(--color-primary)] bg-[var(--color-primary)]/5 ring-1 ring-[var(--color-primary)]" : "border-[var(--color-border-default)] hover:border-[var(--color-border-strong)]"}`
715
- },
716
- /* @__PURE__ */ React.createElement("div", { className: "p-4 flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0 flex-1" }, /* @__PURE__ */ React.createElement(
717
- CardVisual,
718
- {
719
- bin: card.bin,
720
- brand: card.type,
721
- last4: card.number,
722
- holderName: card.holder_name,
723
- expiryMonth: card.expiry_month,
724
- expiryYear: card.expiry_year,
725
- binDatabaseEndpoint
726
- }
727
- ), isSelected && /* @__PURE__ */ React.createElement(FaCheck, { className: "w-3.5 h-3.5 text-[var(--color-primary)] shrink-0" })), /* @__PURE__ */ React.createElement(
728
- "button",
729
- {
730
- onClick: (e) => {
731
- e.stopPropagation();
732
- handleDelete(card.token);
733
- },
734
- disabled: deleting === card.token,
735
- className: "text-[var(--color-text-main)]/30 hover:text-[var(--color-error)] p-1 disabled:opacity-50 transition-colors cursor-pointer shrink-0",
736
- title: "Eliminar tarjeta"
737
- },
738
- /* @__PURE__ */ React.createElement(FaTrash, { className: "w-3 h-3" })
739
- )),
740
- isSelected && /* @__PURE__ */ React.createElement("div", { className: "px-4 pb-4 pt-0 border-t border-[var(--color-primary)]/15" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 pt-3" }, /* @__PURE__ */ React.createElement(FaLock, { className: "w-3 h-3 text-[var(--color-text-main)]/30 shrink-0" }), /* @__PURE__ */ React.createElement(
741
- "label",
742
- {
743
- htmlFor: `cvc-${card.token}`,
744
- className: "text-xs text-[var(--color-text-main)]/50 shrink-0"
745
- },
746
- "C\xF3digo de seguridad"
747
- ), /* @__PURE__ */ React.createElement(
748
- "input",
749
- {
750
- id: `cvc-${card.token}`,
751
- type: "text",
752
- inputMode: "numeric",
753
- maxLength: maxCvc,
754
- autoComplete: "cc-csc",
755
- placeholder: maxCvc === 4 ? "\xB7\xB7\xB7\xB7" : "\xB7\xB7\xB7",
756
- value: cvc,
757
- onClick: (e) => e.stopPropagation(),
758
- onChange: (e) => {
759
- const val = e.target.value.replace(/\D/g, "");
760
- setCvcValues((prev) => ({
761
- ...prev,
762
- [card.token]: val
763
- }));
764
- onSelectCard(card, val);
765
- },
766
- autoFocus: true,
767
- className: "w-16 text-center font-mono text-sm tracking-[0.25em] border border-[var(--color-border-default)] rounded-lg py-2 bg-[var(--color-background)] text-[var(--color-text-main)] placeholder:text-[var(--color-text-main)]/20 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/50 focus:border-[var(--color-primary)] transition-all"
768
- }
769
- )))
770
- );
771
- })), reviewCards.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, reviewCards.map((card) => {
772
- const isExpanded = verifyingToken === card.token;
773
- return /* @__PURE__ */ React.createElement(
774
- "div",
775
- {
776
- key: card.token,
777
- className: "border border-[var(--color-warning)]/30 bg-[var(--color-warning)]/5 rounded-lg overflow-hidden transition-all duration-200"
778
- },
779
- /* @__PURE__ */ React.createElement("div", { className: "p-4 flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0 flex-1" }, /* @__PURE__ */ React.createElement(
780
- CardVisual,
781
- {
782
- bin: card.bin,
783
- brand: card.type,
784
- last4: card.number,
785
- holderName: card.holder_name,
786
- expiryMonth: card.expiry_month,
787
- expiryYear: card.expiry_year,
788
- binDatabaseEndpoint
789
- }
790
- ), /* @__PURE__ */ React.createElement("span", { className: "text-[10px] font-medium uppercase tracking-wider bg-[var(--color-warning)]/15 text-[var(--color-warning)] px-1.5 py-0.5 rounded shrink-0 inline-flex items-center gap-1" }, /* @__PURE__ */ React.createElement(FaExclamationTriangle, { className: "w-2.5 h-2.5" }), "Verificar")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 shrink-0" }, !isExpanded && /* @__PURE__ */ React.createElement(
791
- "button",
739
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
740
+ validCards.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: validCards.map((card) => {
741
+ const isSelected = selectedToken === card.token;
742
+ const cvc = cvcValues[card.token] || "";
743
+ const maxCvc = card.type === "ax" ? 4 : 3;
744
+ return /* @__PURE__ */ jsxs(
745
+ "div",
792
746
  {
793
747
  onClick: () => {
794
- setVerifyingToken(card.token);
795
- setVerifyValue("");
796
- setVerifyError(null);
797
- },
798
- className: "text-xs font-medium text-[var(--color-primary)] hover:text-[var(--color-primary-hover)] underline underline-offset-2 transition-colors cursor-pointer"
799
- },
800
- "Verificar"
801
- ), /* @__PURE__ */ React.createElement(
802
- "button",
803
- {
804
- onClick: () => handleDelete(card.token),
805
- disabled: deleting === card.token,
806
- className: "text-[var(--color-text-main)]/30 hover:text-[var(--color-error)] p-1 disabled:opacity-50 transition-colors cursor-pointer",
807
- title: "Eliminar tarjeta"
808
- },
809
- /* @__PURE__ */ React.createElement(FaTrash, { className: "w-3 h-3" })
810
- ))),
811
- isExpanded && /* @__PURE__ */ React.createElement("div", { className: "px-4 pb-4 border-t border-[var(--color-warning)]/20" }, /* @__PURE__ */ React.createElement("div", { className: "pt-3 space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-2.5" }, /* @__PURE__ */ React.createElement(FaShieldAlt, { className: "w-3.5 h-3.5 text-[var(--color-primary)] mt-0.5 shrink-0" }), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-[var(--color-text-main)]/60 leading-relaxed" }, "Se realiz\xF3 un micro-cobro a tu tarjeta. Revisa tu estado de cuenta bancario e ingresa el monto exacto para verificarla.")), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "relative flex-1" }, /* @__PURE__ */ React.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-main)]/40 text-sm" }, "$"), /* @__PURE__ */ React.createElement(
812
- "input",
813
- {
814
- type: "text",
815
- inputMode: "decimal",
816
- value: verifyValue,
817
- onChange: (e) => {
818
- const val = e.target.value.replace(
819
- /[^0-9.]/g,
820
- ""
821
- );
822
- setVerifyValue(val);
748
+ onSelectCard(card, cvc);
749
+ if (!isSelected) {
750
+ setCvcValues((prev) => ({ ...prev, [card.token]: "" }));
751
+ }
823
752
  },
824
- placeholder: "0.00",
825
- className: "w-full pl-7 pr-3 py-2.5 text-sm border border-[var(--color-border-default)] rounded-lg bg-[var(--color-background)] text-[var(--color-text-main)] placeholder:text-[var(--color-text-main)]/30 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/50 focus:border-[var(--color-primary)] transition-all",
826
- autoFocus: true,
827
- onKeyDown: (e) => {
828
- if (e.key === "Enter") handleVerify(card);
829
- }
830
- }
831
- )), /* @__PURE__ */ React.createElement(
832
- "button",
833
- {
834
- onClick: () => handleVerify(card),
835
- disabled: verifySubmitting || !verifyValue.trim(),
836
- className: "px-4 py-2.5 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white text-sm font-medium rounded-lg transition-colors disabled:bg-[var(--color-surface-elevated)] disabled:text-[var(--color-text-main)]/30 cursor-pointer"
753
+ className: `border rounded-lg cursor-pointer transition-all duration-200 ${isSelected ? "border-[var(--color-primary)] bg-[var(--color-primary)]/5 ring-1 ring-[var(--color-primary)]" : "border-[var(--color-border-default)] hover:border-[var(--color-border-strong)]"}`,
754
+ children: [
755
+ /* @__PURE__ */ jsxs("div", { className: "p-4 flex items-center justify-between gap-3", children: [
756
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
757
+ /* @__PURE__ */ jsx(
758
+ CardVisual,
759
+ {
760
+ bin: card.bin,
761
+ brand: card.type,
762
+ last4: card.number,
763
+ holderName: card.holder_name,
764
+ expiryMonth: card.expiry_month,
765
+ expiryYear: card.expiry_year,
766
+ binDatabaseEndpoint
767
+ }
768
+ ),
769
+ isSelected && /* @__PURE__ */ jsx(FaCheck, { className: "w-3.5 h-3.5 text-[var(--color-primary)] shrink-0" })
770
+ ] }),
771
+ /* @__PURE__ */ jsx(
772
+ "button",
773
+ {
774
+ onClick: (e) => {
775
+ e.stopPropagation();
776
+ handleDelete(card.token);
777
+ },
778
+ disabled: deleting === card.token,
779
+ className: "text-[var(--color-text-main)]/30 hover:text-[var(--color-error)] p-1 disabled:opacity-50 transition-colors cursor-pointer shrink-0",
780
+ title: "Eliminar tarjeta",
781
+ children: /* @__PURE__ */ jsx(FaTrash, { className: "w-3 h-3" })
782
+ }
783
+ )
784
+ ] }),
785
+ isSelected && /* @__PURE__ */ jsx("div", { className: "px-4 pb-4 pt-0 border-t border-[var(--color-primary)]/15", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 pt-3", children: [
786
+ /* @__PURE__ */ jsx(FaLock, { className: "w-3 h-3 text-[var(--color-text-main)]/30 shrink-0" }),
787
+ /* @__PURE__ */ jsx(
788
+ "label",
789
+ {
790
+ htmlFor: `cvc-${card.token}`,
791
+ className: "text-xs text-[var(--color-text-main)]/50 shrink-0",
792
+ children: "C\xF3digo de seguridad"
793
+ }
794
+ ),
795
+ /* @__PURE__ */ jsx(
796
+ "input",
797
+ {
798
+ id: `cvc-${card.token}`,
799
+ type: "text",
800
+ inputMode: "numeric",
801
+ maxLength: maxCvc,
802
+ autoComplete: "cc-csc",
803
+ placeholder: maxCvc === 4 ? "\xB7\xB7\xB7\xB7" : "\xB7\xB7\xB7",
804
+ value: cvc,
805
+ onClick: (e) => e.stopPropagation(),
806
+ onChange: (e) => {
807
+ const val = e.target.value.replace(/\D/g, "");
808
+ setCvcValues((prev) => ({
809
+ ...prev,
810
+ [card.token]: val
811
+ }));
812
+ onSelectCard(card, val);
813
+ },
814
+ autoFocus: true,
815
+ className: "w-16 text-center font-mono text-sm tracking-[0.25em] border border-[var(--color-border-default)] rounded-lg py-2 bg-[var(--color-background)] text-[var(--color-text-main)] placeholder:text-[var(--color-text-main)]/20 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/50 focus:border-[var(--color-primary)] transition-all"
816
+ }
817
+ )
818
+ ] }) })
819
+ ]
837
820
  },
838
- verifySubmitting ? /* @__PURE__ */ React.createElement("div", { className: "w-4 h-4 rounded-full border-2 border-white border-b-transparent animate-spin" }) : "Verificar"
839
- )), verifyError && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-[var(--color-error)]" }, verifyError), /* @__PURE__ */ React.createElement(
840
- "button",
821
+ card.token
822
+ );
823
+ }) }),
824
+ reviewCards.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: reviewCards.map((card) => {
825
+ const isExpanded = verifyingToken === card.token;
826
+ return /* @__PURE__ */ jsxs(
827
+ "div",
841
828
  {
842
- onClick: () => {
843
- setVerifyingToken(null);
844
- setVerifyValue("");
845
- setVerifyError(null);
846
- },
847
- className: "text-xs text-[var(--color-text-main)]/40 hover:text-[var(--color-text-main)]/60 transition-colors cursor-pointer"
829
+ className: "border border-[var(--color-warning)]/30 bg-[var(--color-warning)]/5 rounded-lg overflow-hidden transition-all duration-200",
830
+ children: [
831
+ /* @__PURE__ */ jsxs("div", { className: "p-4 flex items-center justify-between gap-3", children: [
832
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
833
+ /* @__PURE__ */ jsx(
834
+ CardVisual,
835
+ {
836
+ bin: card.bin,
837
+ brand: card.type,
838
+ last4: card.number,
839
+ holderName: card.holder_name,
840
+ expiryMonth: card.expiry_month,
841
+ expiryYear: card.expiry_year,
842
+ binDatabaseEndpoint
843
+ }
844
+ ),
845
+ /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium uppercase tracking-wider bg-[var(--color-warning)]/15 text-[var(--color-warning)] px-1.5 py-0.5 rounded shrink-0 inline-flex items-center gap-1", children: [
846
+ /* @__PURE__ */ jsx(FaExclamationTriangle, { className: "w-2.5 h-2.5" }),
847
+ "Verificar"
848
+ ] })
849
+ ] }),
850
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
851
+ !isExpanded && /* @__PURE__ */ jsx(
852
+ "button",
853
+ {
854
+ onClick: () => {
855
+ setVerifyingToken(card.token);
856
+ setVerifyValue("");
857
+ setVerifyError(null);
858
+ },
859
+ className: "text-xs font-medium text-[var(--color-primary)] hover:text-[var(--color-primary-hover)] underline underline-offset-2 transition-colors cursor-pointer",
860
+ children: "Verificar"
861
+ }
862
+ ),
863
+ /* @__PURE__ */ jsx(
864
+ "button",
865
+ {
866
+ onClick: () => handleDelete(card.token),
867
+ disabled: deleting === card.token,
868
+ className: "text-[var(--color-text-main)]/30 hover:text-[var(--color-error)] p-1 disabled:opacity-50 transition-colors cursor-pointer",
869
+ title: "Eliminar tarjeta",
870
+ children: /* @__PURE__ */ jsx(FaTrash, { className: "w-3 h-3" })
871
+ }
872
+ )
873
+ ] })
874
+ ] }),
875
+ isExpanded && /* @__PURE__ */ jsx("div", { className: "px-4 pb-4 border-t border-[var(--color-warning)]/20", children: /* @__PURE__ */ jsxs("div", { className: "pt-3 space-y-3", children: [
876
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2.5", children: [
877
+ /* @__PURE__ */ jsx(FaShieldAlt, { className: "w-3.5 h-3.5 text-[var(--color-primary)] mt-0.5 shrink-0" }),
878
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-text-main)]/60 leading-relaxed", children: "Se realiz\xF3 un micro-cobro a tu tarjeta. Revisa tu estado de cuenta bancario e ingresa el monto exacto para verificarla." })
879
+ ] }),
880
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
881
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
882
+ /* @__PURE__ */ jsx("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-main)]/40 text-sm", children: "$" }),
883
+ /* @__PURE__ */ jsx(
884
+ "input",
885
+ {
886
+ type: "text",
887
+ inputMode: "decimal",
888
+ value: verifyValue,
889
+ onChange: (e) => {
890
+ const val = e.target.value.replace(
891
+ /[^0-9.]/g,
892
+ ""
893
+ );
894
+ setVerifyValue(val);
895
+ },
896
+ placeholder: "0.00",
897
+ className: "w-full pl-7 pr-3 py-2.5 text-sm border border-[var(--color-border-default)] rounded-lg bg-[var(--color-background)] text-[var(--color-text-main)] placeholder:text-[var(--color-text-main)]/30 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/50 focus:border-[var(--color-primary)] transition-all",
898
+ autoFocus: true,
899
+ onKeyDown: (e) => {
900
+ if (e.key === "Enter") handleVerify(card);
901
+ }
902
+ }
903
+ )
904
+ ] }),
905
+ /* @__PURE__ */ jsx(
906
+ "button",
907
+ {
908
+ onClick: () => handleVerify(card),
909
+ disabled: verifySubmitting || !verifyValue.trim(),
910
+ className: "px-4 py-2.5 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white text-sm font-medium rounded-lg transition-colors disabled:bg-[var(--color-surface-elevated)] disabled:text-[var(--color-text-main)]/30 cursor-pointer",
911
+ children: verifySubmitting ? /* @__PURE__ */ jsx("div", { className: "w-4 h-4 rounded-full border-2 border-white border-b-transparent animate-spin" }) : "Verificar"
912
+ }
913
+ )
914
+ ] }),
915
+ verifyError && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-error)]", children: verifyError }),
916
+ /* @__PURE__ */ jsx(
917
+ "button",
918
+ {
919
+ onClick: () => {
920
+ setVerifyingToken(null);
921
+ setVerifyValue("");
922
+ setVerifyError(null);
923
+ },
924
+ className: "text-xs text-[var(--color-text-main)]/40 hover:text-[var(--color-text-main)]/60 transition-colors cursor-pointer",
925
+ children: "Cancelar"
926
+ }
927
+ )
928
+ ] }) })
929
+ ]
848
930
  },
849
- "Cancelar"
850
- )))
851
- );
852
- })), /* @__PURE__ */ React.createElement(
853
- "button",
854
- {
855
- onClick: onAddNewCard,
856
- className: "w-full flex items-center justify-center gap-2 p-3 border-2 border-dashed border-[var(--color-border-default)] rounded-lg text-sm text-[var(--color-text-main)]/50 hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors cursor-pointer"
857
- },
858
- /* @__PURE__ */ React.createElement(FaPlus, { className: "w-3 h-3" }),
859
- cards.length > 0 ? "Usar otra tarjeta" : "Agregar tarjeta"
860
- ));
931
+ card.token
932
+ );
933
+ }) }),
934
+ /* @__PURE__ */ jsxs(
935
+ "button",
936
+ {
937
+ onClick: onAddNewCard,
938
+ className: "w-full flex items-center justify-center gap-2 p-3 border-2 border-dashed border-[var(--color-border-default)] rounded-lg text-sm text-[var(--color-text-main)]/50 hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors cursor-pointer",
939
+ children: [
940
+ /* @__PURE__ */ jsx(FaPlus, { className: "w-3 h-3" }),
941
+ cards.length > 0 ? "Usar otra tarjeta" : "Agregar tarjeta"
942
+ ]
943
+ }
944
+ )
945
+ ] });
861
946
  }
862
947
  var SDK_URL = "https://cdn.paymentez.com/ccapi/sdk/payment_sdk_stable.min.js";
863
948
  var CONTAINER_ID = "nuvei-tokenize-container";
@@ -1100,121 +1185,164 @@ function NuveiPaymentForm({
1100
1185
  exclusiveCardTypes,
1101
1186
  iconColor
1102
1187
  ]);
1103
- return /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement(
1104
- Script,
1105
- {
1106
- src: SDK_URL,
1107
- strategy: "afterInteractive",
1108
- onReady: handleScriptReady
1109
- }
1110
- ), error && error.variant !== "incomplete" ? /* @__PURE__ */ React.createElement(
1111
- "div",
1112
- {
1113
- className: `rounded-xl border p-5 text-sm ${error.variant === "duplicate" ? "bg-[var(--color-primary)]/5 border-[var(--color-primary)]/20" : "bg-[var(--color-error)]/5 border-[var(--color-error)]/20"}`
1114
- },
1115
- /* @__PURE__ */ React.createElement("div", { className: "flex gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "shrink-0 mt-0.5" }, error.variant === "duplicate" ? /* @__PURE__ */ React.createElement(FaInfoCircle, { className: "w-4 h-4 text-[var(--color-primary)]" }) : /* @__PURE__ */ React.createElement(FaTimesCircle, { className: "w-4 h-4 text-[var(--color-error)]" })), /* @__PURE__ */ React.createElement("div", { className: "grow space-y-1" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-[var(--color-text-main)]" }, error.title), /* @__PURE__ */ React.createElement("p", { className: "text-[var(--color-text-main)]/60 leading-relaxed" }, error.message))),
1116
- /* @__PURE__ */ React.createElement("div", { className: "flex gap-3 mt-4 pt-3 border-t border-[var(--color-border-subtle)]" }, error.variant === "duplicate" && error.duplicateToken ? /* @__PURE__ */ React.createElement(
1117
- "button",
1188
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1189
+ /* @__PURE__ */ jsx(
1190
+ Script,
1118
1191
  {
1119
- type: "button",
1120
- disabled: isDeletingDuplicate,
1121
- onClick: async () => {
1122
- setIsDeletingDuplicate(true);
1123
- try {
1124
- const res = await fetch("/api/nuvei/cards", {
1125
- method: "DELETE",
1126
- headers: { "Content-Type": "application/json" },
1127
- body: JSON.stringify({
1128
- token: error.duplicateToken
1129
- })
1130
- });
1131
- const data = await res.json().catch(() => ({}));
1132
- if (process.env.NODE_ENV !== "production") {
1133
- console.log(
1134
- "[NuveiPaymentForm] Delete response:",
1135
- res.status,
1136
- JSON.stringify(data)
1137
- );
1192
+ src: SDK_URL,
1193
+ strategy: "afterInteractive",
1194
+ onReady: handleScriptReady
1195
+ }
1196
+ ),
1197
+ error && error.variant !== "incomplete" ? /* @__PURE__ */ jsxs(
1198
+ "div",
1199
+ {
1200
+ className: `rounded-xl border p-5 text-sm ${error.variant === "duplicate" ? "bg-[var(--color-primary)]/5 border-[var(--color-primary)]/20" : "bg-[var(--color-error)]/5 border-[var(--color-error)]/20"}`,
1201
+ children: [
1202
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
1203
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-0.5", children: error.variant === "duplicate" ? /* @__PURE__ */ jsx(FaInfoCircle, { className: "w-4 h-4 text-[var(--color-primary)]" }) : /* @__PURE__ */ jsx(FaTimesCircle, { className: "w-4 h-4 text-[var(--color-error)]" }) }),
1204
+ /* @__PURE__ */ jsxs("div", { className: "grow space-y-1", children: [
1205
+ /* @__PURE__ */ jsx("p", { className: "font-semibold text-[var(--color-text-main)]", children: error.title }),
1206
+ /* @__PURE__ */ jsx("p", { className: "text-[var(--color-text-main)]/60 leading-relaxed", children: error.message })
1207
+ ] })
1208
+ ] }),
1209
+ /* @__PURE__ */ jsx("div", { className: "flex gap-3 mt-4 pt-3 border-t border-[var(--color-border-subtle)]", children: error.variant === "duplicate" && error.duplicateToken ? /* @__PURE__ */ jsx(
1210
+ "button",
1211
+ {
1212
+ type: "button",
1213
+ disabled: isDeletingDuplicate,
1214
+ onClick: async () => {
1215
+ setIsDeletingDuplicate(true);
1216
+ try {
1217
+ const res = await fetch("/api/nuvei/cards", {
1218
+ method: "DELETE",
1219
+ headers: { "Content-Type": "application/json" },
1220
+ body: JSON.stringify({
1221
+ token: error.duplicateToken
1222
+ })
1223
+ });
1224
+ const data = await res.json().catch(() => ({}));
1225
+ if (process.env.NODE_ENV !== "production") {
1226
+ console.log(
1227
+ "[NuveiPaymentForm] Delete response:",
1228
+ res.status,
1229
+ JSON.stringify(data)
1230
+ );
1231
+ }
1232
+ if (res.ok && !data.error) {
1233
+ setError(null);
1234
+ sdkInitRef.current = false;
1235
+ setSdkReady(false);
1236
+ setTimeout(() => handleScriptReady(), 100);
1237
+ } else {
1238
+ setError({
1239
+ variant: "rejected",
1240
+ title: "No se pudo eliminar",
1241
+ message: "El procesador de pagos no permiti\xF3 eliminar esta tarjeta. Intenta con otra tarjeta o contacta a tu banco."
1242
+ });
1243
+ }
1244
+ } catch {
1245
+ setError({
1246
+ variant: "system",
1247
+ title: "Error de conexi\xF3n",
1248
+ message: "No se pudo conectar al servidor. Intenta de nuevo."
1249
+ });
1250
+ } finally {
1251
+ setIsDeletingDuplicate(false);
1252
+ }
1253
+ },
1254
+ className: "flex-1 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-2.5 px-4 rounded-lg transition-colors text-sm cursor-pointer inline-flex items-center justify-center gap-2 disabled:opacity-50",
1255
+ children: isDeletingDuplicate ? "Eliminando..." : "Eliminar y reintentar"
1138
1256
  }
1139
- if (res.ok && !data.error) {
1140
- setError(null);
1141
- sdkInitRef.current = false;
1142
- setSdkReady(false);
1143
- setTimeout(() => handleScriptReady(), 100);
1144
- } else {
1145
- setError({
1146
- variant: "rejected",
1147
- title: "No se pudo eliminar",
1148
- message: "El procesador de pagos no permiti\xF3 eliminar esta tarjeta. Intenta con otra tarjeta o contacta a tu banco."
1149
- });
1257
+ ) : /* @__PURE__ */ jsxs(
1258
+ "button",
1259
+ {
1260
+ type: "button",
1261
+ onClick: () => {
1262
+ setError(null);
1263
+ const container = document.getElementById(CONTAINER_ID);
1264
+ if (container) container.innerHTML = "";
1265
+ sdkInitRef.current = false;
1266
+ setSdkReady(false);
1267
+ setTimeout(() => handleScriptReady(), 100);
1268
+ },
1269
+ className: "flex-1 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-2.5 px-4 rounded-lg transition-colors text-sm cursor-pointer inline-flex items-center justify-center gap-2",
1270
+ children: [
1271
+ /* @__PURE__ */ jsx(FaRedo, { className: "w-3 h-3" }),
1272
+ "Intentar con otra tarjeta"
1273
+ ]
1150
1274
  }
1151
- } catch {
1152
- setError({
1153
- variant: "system",
1154
- title: "Error de conexi\xF3n",
1155
- message: "No se pudo conectar al servidor. Intenta de nuevo."
1156
- });
1157
- } finally {
1158
- setIsDeletingDuplicate(false);
1159
- }
1160
- },
1161
- className: "flex-1 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-2.5 px-4 rounded-lg transition-colors text-sm cursor-pointer inline-flex items-center justify-center gap-2 disabled:opacity-50"
1162
- },
1163
- isDeletingDuplicate ? "Eliminando..." : "Eliminar y reintentar"
1164
- ) : /* @__PURE__ */ React.createElement(
1165
- "button",
1166
- {
1167
- type: "button",
1168
- onClick: () => {
1169
- setError(null);
1170
- const container = document.getElementById(CONTAINER_ID);
1171
- if (container) container.innerHTML = "";
1172
- sdkInitRef.current = false;
1173
- setSdkReady(false);
1174
- setTimeout(() => handleScriptReady(), 100);
1175
- },
1176
- className: "flex-1 bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-2.5 px-4 rounded-lg transition-colors text-sm cursor-pointer inline-flex items-center justify-center gap-2"
1177
- },
1178
- /* @__PURE__ */ React.createElement(FaRedo, { className: "w-3 h-3" }),
1179
- "Intentar con otra tarjeta"
1180
- ))
1181
- ) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { id: CONTAINER_ID, className: "min-h-16" }), error && /* @__PURE__ */ React.createElement(
1182
- "div",
1183
- {
1184
- className: `rounded-xl border p-4 text-sm ${error.variant === "incomplete" ? "bg-[var(--color-warning)]/5 border-[var(--color-warning)]/20" : "bg-[var(--color-surface-elevated)] border-[var(--color-border-subtle)]"}`
1185
- },
1186
- /* @__PURE__ */ React.createElement("div", { className: "flex gap-3" }, /* @__PURE__ */ React.createElement(
1187
- FaExclamationTriangle,
1188
- {
1189
- className: `w-4 h-4 shrink-0 mt-0.5 ${error.variant === "incomplete" ? "text-[var(--color-warning)]" : "text-[var(--color-text-main)]/40"}`
1275
+ ) })
1276
+ ]
1190
1277
  }
1191
- ), /* @__PURE__ */ React.createElement("div", { className: "grow" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-[var(--color-text-main)]" }, error.title), /* @__PURE__ */ React.createElement("p", { className: "text-[var(--color-text-main)]/60 leading-relaxed" }, error.message)))
1192
- ), sdkReady && /* @__PURE__ */ React.createElement(React.Fragment, null, showSaveCardCheckbox && /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2.5 cursor-pointer select-none" }, /* @__PURE__ */ React.createElement(
1193
- "input",
1194
- {
1195
- type: "checkbox",
1196
- checked: saveCard,
1197
- onChange: (e) => setSaveCard(e.target.checked),
1198
- className: "w-4 h-4 rounded border-[var(--color-border-default)] text-[var(--color-primary)] focus:ring-[var(--color-primary)]/30 cursor-pointer accent-[var(--color-primary)]"
1199
- }
1200
- ), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-[var(--color-text-main)]/60" }, "Guardar tarjeta para futuras compras")), /* @__PURE__ */ React.createElement(
1201
- "button",
1202
- {
1203
- type: "button",
1204
- onClick: handlePay,
1205
- disabled: isProcessing || disabled,
1206
- className: "w-full bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-3 px-4 rounded-lg transition-all duration-200 disabled:bg-[var(--color-surface-elevated)] disabled:text-[var(--color-text-main)]/30 disabled:cursor-not-allowed flex items-center justify-center gap-2 active:scale-[0.97] cursor-pointer"
1207
- },
1208
- isProcessing ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "w-5 h-5 rounded-full border-2 border-white border-b-transparent animate-spin" }), processingLabel) : buttonLabel ?? (saveCard ? "Agregar Tarjeta" : "Continuar con pago")
1209
- ))), !sdkReady && /* @__PURE__ */ React.createElement("div", { className: "flex flex-col items-center py-4 gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "w-12 h-12 rounded-full border-2 border-[var(--color-text-main)]/20 border-t-[var(--color-primary)] animate-spin" }), sdkTimedOut && /* @__PURE__ */ React.createElement("div", { className: "text-center space-y-2" }, /* @__PURE__ */ React.createElement("p", { className: "text-xs text-[var(--color-text-main)]/50" }, "El sistema de pagos est\xE1 tardando en cargar."), /* @__PURE__ */ React.createElement(
1210
- "button",
1211
- {
1212
- type: "button",
1213
- onClick: () => window.location.reload(),
1214
- className: "text-xs font-semibold text-[var(--color-primary)] hover:text-[var(--color-primary-hover)] underline underline-offset-2 transition-colors"
1215
- },
1216
- "Recargar p\xE1gina"
1217
- ))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-center gap-2 text-[var(--color-text-main)]/30 text-xs" }, /* @__PURE__ */ React.createElement(FaLock, { className: "w-3 h-3" }), /* @__PURE__ */ React.createElement("span", null, "Pago 100% seguro \xB7 Tokenizaci\xF3n PCI Compliant")));
1278
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
1279
+ /* @__PURE__ */ jsx("div", { id: CONTAINER_ID, className: "min-h-16" }),
1280
+ error && /* @__PURE__ */ jsx(
1281
+ "div",
1282
+ {
1283
+ className: `rounded-xl border p-4 text-sm ${error.variant === "incomplete" ? "bg-[var(--color-warning)]/5 border-[var(--color-warning)]/20" : "bg-[var(--color-surface-elevated)] border-[var(--color-border-subtle)]"}`,
1284
+ children: /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
1285
+ /* @__PURE__ */ jsx(
1286
+ FaExclamationTriangle,
1287
+ {
1288
+ className: `w-4 h-4 shrink-0 mt-0.5 ${error.variant === "incomplete" ? "text-[var(--color-warning)]" : "text-[var(--color-text-main)]/40"}`
1289
+ }
1290
+ ),
1291
+ /* @__PURE__ */ jsxs("div", { className: "grow", children: [
1292
+ /* @__PURE__ */ jsx("p", { className: "font-semibold text-[var(--color-text-main)]", children: error.title }),
1293
+ /* @__PURE__ */ jsx("p", { className: "text-[var(--color-text-main)]/60 leading-relaxed", children: error.message })
1294
+ ] })
1295
+ ] })
1296
+ }
1297
+ ),
1298
+ sdkReady && /* @__PURE__ */ jsxs(Fragment, { children: [
1299
+ showSaveCardCheckbox && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2.5 cursor-pointer select-none", children: [
1300
+ /* @__PURE__ */ jsx(
1301
+ "input",
1302
+ {
1303
+ type: "checkbox",
1304
+ checked: saveCard,
1305
+ onChange: (e) => setSaveCard(e.target.checked),
1306
+ className: "w-4 h-4 rounded border-[var(--color-border-default)] text-[var(--color-primary)] focus:ring-[var(--color-primary)]/30 cursor-pointer accent-[var(--color-primary)]"
1307
+ }
1308
+ ),
1309
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--color-text-main)]/60", children: "Guardar tarjeta para futuras compras" })
1310
+ ] }),
1311
+ /* @__PURE__ */ jsx(
1312
+ "button",
1313
+ {
1314
+ type: "button",
1315
+ onClick: handlePay,
1316
+ disabled: isProcessing || disabled,
1317
+ className: "w-full bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white font-semibold py-3 px-4 rounded-lg transition-all duration-200 disabled:bg-[var(--color-surface-elevated)] disabled:text-[var(--color-text-main)]/30 disabled:cursor-not-allowed flex items-center justify-center gap-2 active:scale-[0.97] cursor-pointer",
1318
+ children: isProcessing ? /* @__PURE__ */ jsxs(Fragment, { children: [
1319
+ /* @__PURE__ */ jsx("div", { className: "w-5 h-5 rounded-full border-2 border-white border-b-transparent animate-spin" }),
1320
+ processingLabel
1321
+ ] }) : buttonLabel ?? (saveCard ? "Agregar Tarjeta" : "Continuar con pago")
1322
+ }
1323
+ )
1324
+ ] })
1325
+ ] }),
1326
+ !sdkReady && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center py-4 gap-3", children: [
1327
+ /* @__PURE__ */ jsx("div", { className: "w-12 h-12 rounded-full border-2 border-[var(--color-text-main)]/20 border-t-[var(--color-primary)] animate-spin" }),
1328
+ sdkTimedOut && /* @__PURE__ */ jsxs("div", { className: "text-center space-y-2", children: [
1329
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-text-main)]/50", children: "El sistema de pagos est\xE1 tardando en cargar." }),
1330
+ /* @__PURE__ */ jsx(
1331
+ "button",
1332
+ {
1333
+ type: "button",
1334
+ onClick: () => window.location.reload(),
1335
+ className: "text-xs font-semibold text-[var(--color-primary)] hover:text-[var(--color-primary-hover)] underline underline-offset-2 transition-colors",
1336
+ children: "Recargar p\xE1gina"
1337
+ }
1338
+ )
1339
+ ] })
1340
+ ] }),
1341
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 text-[var(--color-text-main)]/30 text-xs", children: [
1342
+ /* @__PURE__ */ jsx(FaLock, { className: "w-3 h-3" }),
1343
+ /* @__PURE__ */ jsx("span", { children: "Pago 100% seguro \xB7 Tokenizaci\xF3n PCI Compliant" })
1344
+ ] })
1345
+ ] });
1218
1346
  }
1219
1347
 
1220
1348
  export { CARD_BRAND_NAMES, CARD_TYPE_NAMES, CardVisual, NuveiPaymentForm, SavedCards, getBinDatabase, lookupBankPalette, lookupBin, lookupBinSync };