@sikka/aps 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -3
- package/dist/react/index.d.mts +147 -29
- package/dist/react/index.d.ts +147 -29
- package/dist/react/index.js +454 -136
- package/dist/react/index.mjs +454 -136
- package/package.json +1 -3
package/dist/react/index.js
CHANGED
|
@@ -456,23 +456,50 @@ var defaultStyles = {
|
|
|
456
456
|
borderRadius: "8px",
|
|
457
457
|
fontSize: "13px",
|
|
458
458
|
color: "#065F46"
|
|
459
|
+
},
|
|
460
|
+
errorMessage: {
|
|
461
|
+
color: "#EF4444",
|
|
462
|
+
fontSize: "12px"
|
|
463
|
+
},
|
|
464
|
+
helperText: {
|
|
465
|
+
fontSize: "12px",
|
|
466
|
+
color: "#6B7280"
|
|
459
467
|
}
|
|
460
468
|
};
|
|
469
|
+
var defaultFieldConfig = {
|
|
470
|
+
cardNumber: { visible: true, required: true },
|
|
471
|
+
cardHolder: { visible: true, required: true },
|
|
472
|
+
customerEmail: { visible: true, required: false },
|
|
473
|
+
expiryDate: { visible: true, required: true },
|
|
474
|
+
cvv: { visible: true, required: true }
|
|
475
|
+
};
|
|
461
476
|
var TokenizationForm = ({
|
|
462
477
|
actionUrl,
|
|
463
478
|
formParams,
|
|
464
479
|
customerEmail = "",
|
|
465
480
|
onSuccess: _onSuccess,
|
|
466
|
-
// Success is handled via returnUrl redirect
|
|
467
481
|
onError,
|
|
468
482
|
styles = {},
|
|
469
483
|
icons = {},
|
|
484
|
+
fields = {},
|
|
485
|
+
layout = { type: "vertical" },
|
|
470
486
|
labels = {},
|
|
471
487
|
placeholders = {},
|
|
472
488
|
disableFormatting = false,
|
|
473
489
|
showCardIcons = true,
|
|
474
490
|
showSecurityNotice = true,
|
|
475
|
-
|
|
491
|
+
securityNotice,
|
|
492
|
+
submitButton,
|
|
493
|
+
className = {},
|
|
494
|
+
errorMessages = {},
|
|
495
|
+
fieldOrder = ["cardNumber", "cardHolder", "customerEmail", "expiryDate", "cvv"],
|
|
496
|
+
beforeForm,
|
|
497
|
+
afterForm,
|
|
498
|
+
beforeSubmit,
|
|
499
|
+
afterSubmit,
|
|
500
|
+
nativeSubmission = true,
|
|
501
|
+
onChange,
|
|
502
|
+
onValidSubmit
|
|
476
503
|
}) => {
|
|
477
504
|
const [cardNumber, setCardNumber] = (0, import_react4.useState)("");
|
|
478
505
|
const [expiryDate, setExpiryDate] = (0, import_react4.useState)("");
|
|
@@ -490,6 +517,13 @@ var TokenizationForm = ({
|
|
|
490
517
|
...DefaultIcons,
|
|
491
518
|
...icons
|
|
492
519
|
};
|
|
520
|
+
const mergedFields = {
|
|
521
|
+
cardNumber: { ...defaultFieldConfig.cardNumber, ...fields.cardNumber },
|
|
522
|
+
cardHolder: { ...defaultFieldConfig.cardHolder, ...fields.cardHolder },
|
|
523
|
+
customerEmail: { ...defaultFieldConfig.customerEmail, ...fields.customerEmail },
|
|
524
|
+
expiryDate: { ...defaultFieldConfig.expiryDate, ...fields.expiryDate },
|
|
525
|
+
cvv: { ...defaultFieldConfig.cvv, ...fields.cvv }
|
|
526
|
+
};
|
|
493
527
|
const mergedLabels = {
|
|
494
528
|
cardNumber: "Card Number",
|
|
495
529
|
cardHolder: "Card Holder Name",
|
|
@@ -508,6 +542,16 @@ var TokenizationForm = ({
|
|
|
508
542
|
cvv: "123",
|
|
509
543
|
...placeholders
|
|
510
544
|
};
|
|
545
|
+
const mergedErrorMessages = {
|
|
546
|
+
cardNumber: "Invalid card number",
|
|
547
|
+
cardHolder: "Card holder name is required",
|
|
548
|
+
customerEmail: "Invalid email address",
|
|
549
|
+
expiryDate: "Invalid expiry date",
|
|
550
|
+
cvv: "Invalid CVV",
|
|
551
|
+
required: "This field is required",
|
|
552
|
+
invalidEmail: "Invalid email address",
|
|
553
|
+
...errorMessages
|
|
554
|
+
};
|
|
511
555
|
const formatCardNumber = (value) => {
|
|
512
556
|
if (disableFormatting) return value;
|
|
513
557
|
const v = value.replace(/\s+/g, "").replace(/[^0-9]/gi, "");
|
|
@@ -530,24 +574,75 @@ var TokenizationForm = ({
|
|
|
530
574
|
}
|
|
531
575
|
return v;
|
|
532
576
|
};
|
|
533
|
-
const
|
|
577
|
+
const isValidExpiryDate = (value) => {
|
|
578
|
+
if (!value || value.length !== 5) return false;
|
|
579
|
+
const [month, year] = value.split("/");
|
|
580
|
+
if (!month || !year) return false;
|
|
581
|
+
const mm = parseInt(month, 10);
|
|
582
|
+
const yy = parseInt(year, 10);
|
|
583
|
+
if (mm < 1 || mm > 12) return false;
|
|
584
|
+
if (yy < 0 || yy > 99) return false;
|
|
585
|
+
const now = /* @__PURE__ */ new Date();
|
|
586
|
+
const currentYear = now.getFullYear() % 100;
|
|
587
|
+
const currentMonth = now.getMonth() + 1;
|
|
588
|
+
if (yy < currentYear) return false;
|
|
589
|
+
if (yy === currentYear && mm < currentMonth) return false;
|
|
590
|
+
return true;
|
|
591
|
+
};
|
|
592
|
+
const getFormData = () => ({
|
|
593
|
+
cardNumber,
|
|
594
|
+
cardHolderName,
|
|
595
|
+
email,
|
|
596
|
+
expiryDate,
|
|
597
|
+
cvv,
|
|
598
|
+
cardBrand,
|
|
599
|
+
isValid: validateForm(false)
|
|
600
|
+
});
|
|
601
|
+
const validateForm = (updateErrors = true) => {
|
|
534
602
|
const newErrors = {};
|
|
535
|
-
if (
|
|
536
|
-
|
|
603
|
+
if (mergedFields.cardNumber?.visible && mergedFields.cardNumber?.required !== false) {
|
|
604
|
+
const customError = mergedFields.cardNumber?.validate?.(cardNumber);
|
|
605
|
+
if (customError) {
|
|
606
|
+
newErrors.cardNumber = customError;
|
|
607
|
+
} else if (!cardNumber || cardNumber.replace(/\s/g, "").length < 13) {
|
|
608
|
+
newErrors.cardNumber = mergedErrorMessages.cardNumber;
|
|
609
|
+
}
|
|
537
610
|
}
|
|
538
|
-
if (
|
|
539
|
-
|
|
611
|
+
if (mergedFields.cardHolder?.visible && mergedFields.cardHolder?.required !== false) {
|
|
612
|
+
const customError = mergedFields.cardHolder?.validate?.(cardHolderName);
|
|
613
|
+
if (customError) {
|
|
614
|
+
newErrors.cardHolder = customError;
|
|
615
|
+
} else if (!cardHolderName || cardHolderName.length < 2) {
|
|
616
|
+
newErrors.cardHolder = mergedErrorMessages.cardHolder;
|
|
617
|
+
}
|
|
540
618
|
}
|
|
541
|
-
if (
|
|
542
|
-
|
|
619
|
+
if (mergedFields.customerEmail?.visible && email) {
|
|
620
|
+
const customError = mergedFields.customerEmail?.validate?.(email);
|
|
621
|
+
if (customError) {
|
|
622
|
+
newErrors.email = customError;
|
|
623
|
+
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
624
|
+
newErrors.email = mergedErrorMessages.customerEmail;
|
|
625
|
+
}
|
|
543
626
|
}
|
|
544
|
-
if (
|
|
545
|
-
|
|
627
|
+
if (mergedFields.expiryDate?.visible && mergedFields.expiryDate?.required !== false) {
|
|
628
|
+
const customError = mergedFields.expiryDate?.validate?.(expiryDate);
|
|
629
|
+
if (customError) {
|
|
630
|
+
newErrors.expiryDate = customError;
|
|
631
|
+
} else if (!expiryDate || !isValidExpiryDate(expiryDate)) {
|
|
632
|
+
newErrors.expiryDate = mergedErrorMessages.expiryDate;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
if (mergedFields.cvv?.visible && mergedFields.cvv?.required !== false) {
|
|
636
|
+
const customError = mergedFields.cvv?.validate?.(cvv);
|
|
637
|
+
if (customError) {
|
|
638
|
+
newErrors.cvv = customError;
|
|
639
|
+
} else if (!cvv || cvv.length < 3) {
|
|
640
|
+
newErrors.cvv = mergedErrorMessages.cvv;
|
|
641
|
+
}
|
|
546
642
|
}
|
|
547
|
-
if (
|
|
548
|
-
newErrors
|
|
643
|
+
if (updateErrors) {
|
|
644
|
+
setErrors(newErrors);
|
|
549
645
|
}
|
|
550
|
-
setErrors(newErrors);
|
|
551
646
|
return Object.keys(newErrors).length === 0;
|
|
552
647
|
};
|
|
553
648
|
const handleSubmit = (e) => {
|
|
@@ -556,6 +651,14 @@ var TokenizationForm = ({
|
|
|
556
651
|
onError?.("Please fill in all required fields correctly");
|
|
557
652
|
return;
|
|
558
653
|
}
|
|
654
|
+
const formData = getFormData();
|
|
655
|
+
if (onValidSubmit) {
|
|
656
|
+
onValidSubmit(formData);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
if (!nativeSubmission) {
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
559
662
|
setLoading(true);
|
|
560
663
|
const form = document.createElement("form");
|
|
561
664
|
form.method = "POST";
|
|
@@ -576,7 +679,10 @@ var TokenizationForm = ({
|
|
|
576
679
|
form.appendChild(input);
|
|
577
680
|
};
|
|
578
681
|
const cleanCardNumber = cardNumber.replace(/\s/g, "");
|
|
579
|
-
const
|
|
682
|
+
const cleanExpiry = expiryDate.replace(/\//g, "");
|
|
683
|
+
const mm = cleanExpiry.substring(0, 2);
|
|
684
|
+
const yy = cleanExpiry.substring(2, 4);
|
|
685
|
+
const cleanExpiryDate = yy + mm;
|
|
580
686
|
addHiddenInput("card_number", cleanCardNumber);
|
|
581
687
|
addHiddenInput("expiry_date", cleanExpiryDate);
|
|
582
688
|
addHiddenInput("card_security_code", cvv);
|
|
@@ -585,156 +691,342 @@ var TokenizationForm = ({
|
|
|
585
691
|
form.submit();
|
|
586
692
|
setLoading(false);
|
|
587
693
|
};
|
|
588
|
-
const handleCardNumberChange = (
|
|
589
|
-
const formatted = formatCardNumber(
|
|
694
|
+
const handleCardNumberChange = (value) => {
|
|
695
|
+
const formatted = formatCardNumber(value);
|
|
590
696
|
setCardNumber(formatted);
|
|
591
697
|
setCardBrand(detectCardBrand(formatted));
|
|
592
698
|
if (errors.cardNumber) {
|
|
593
699
|
setErrors({ ...errors, cardNumber: "" });
|
|
594
700
|
}
|
|
701
|
+
onChange?.(getFormData());
|
|
595
702
|
};
|
|
596
|
-
const handleExpiryDateChange = (
|
|
597
|
-
const formatted = formatExpiryDate(
|
|
703
|
+
const handleExpiryDateChange = (value) => {
|
|
704
|
+
const formatted = formatExpiryDate(value);
|
|
598
705
|
setExpiryDate(formatted);
|
|
599
706
|
if (errors.expiryDate) {
|
|
600
707
|
setErrors({ ...errors, expiryDate: "" });
|
|
601
708
|
}
|
|
709
|
+
onChange?.(getFormData());
|
|
602
710
|
};
|
|
603
|
-
const handleCvvChange = (
|
|
604
|
-
const
|
|
605
|
-
setCvv(
|
|
711
|
+
const handleCvvChange = (value) => {
|
|
712
|
+
const cleaned = value.replace(/\D/g, "");
|
|
713
|
+
setCvv(cleaned);
|
|
606
714
|
if (errors.cvv) {
|
|
607
715
|
setErrors({ ...errors, cvv: "" });
|
|
608
716
|
}
|
|
717
|
+
onChange?.(getFormData());
|
|
609
718
|
};
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
719
|
+
const handleCardHolderChange = (value) => {
|
|
720
|
+
setCardHolderName(value);
|
|
721
|
+
if (errors.cardHolder) {
|
|
722
|
+
setErrors({ ...errors, cardHolder: "" });
|
|
723
|
+
}
|
|
724
|
+
onChange?.(getFormData());
|
|
725
|
+
};
|
|
726
|
+
const handleEmailChange = (value) => {
|
|
727
|
+
setEmail(value);
|
|
728
|
+
if (errors.email) {
|
|
729
|
+
setErrors({ ...errors, email: "" });
|
|
730
|
+
}
|
|
731
|
+
onChange?.(getFormData());
|
|
732
|
+
};
|
|
733
|
+
const renderField = (fieldName) => {
|
|
734
|
+
const config = mergedFields[fieldName];
|
|
735
|
+
if (!config?.visible) return null;
|
|
736
|
+
const fieldRenderers = {
|
|
737
|
+
cardNumber: () => {
|
|
738
|
+
const label = config.label || mergedLabels.cardNumber;
|
|
739
|
+
const placeholder = config.placeholder || mergedPlaceholders.cardNumber;
|
|
740
|
+
const error = errors.cardNumber;
|
|
741
|
+
if (config.render) {
|
|
742
|
+
return config.render({
|
|
618
743
|
value: cardNumber,
|
|
619
744
|
onChange: handleCardNumberChange,
|
|
620
|
-
|
|
621
|
-
maxLength: 19,
|
|
622
|
-
required: true,
|
|
623
|
-
style: {
|
|
624
|
-
...mergedStyles.input,
|
|
625
|
-
...errors.cardNumber ? mergedStyles.inputError : {},
|
|
626
|
-
paddingRight: showCardIcons ? "60px" : "16px"
|
|
745
|
+
onBlur: () => {
|
|
627
746
|
},
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
747
|
+
error,
|
|
748
|
+
placeholder,
|
|
749
|
+
label,
|
|
750
|
+
required: config.required !== false,
|
|
751
|
+
disabled: loading,
|
|
752
|
+
name: "card_number"
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
632
756
|
"div",
|
|
633
757
|
{
|
|
634
|
-
style: {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
758
|
+
style: { ...mergedStyles.inputGroup, ...config.style },
|
|
759
|
+
className: config.className || className.inputGroup,
|
|
760
|
+
children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label, children: label }),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative" }, children: [
|
|
763
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
764
|
+
"input",
|
|
765
|
+
{
|
|
766
|
+
type: "text",
|
|
767
|
+
value: cardNumber,
|
|
768
|
+
onChange: (e) => handleCardNumberChange(e.target.value),
|
|
769
|
+
placeholder,
|
|
770
|
+
maxLength: 19,
|
|
771
|
+
required: config.required !== false,
|
|
772
|
+
disabled: loading,
|
|
773
|
+
name: "card_number",
|
|
774
|
+
style: {
|
|
775
|
+
...mergedStyles.input,
|
|
776
|
+
...error ? mergedStyles.inputError : {},
|
|
777
|
+
paddingRight: showCardIcons ? "60px" : "16px"
|
|
778
|
+
},
|
|
779
|
+
className: className.input
|
|
780
|
+
}
|
|
781
|
+
),
|
|
782
|
+
showCardIcons && cardBrand !== "unknown" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
783
|
+
"div",
|
|
784
|
+
{
|
|
785
|
+
style: {
|
|
786
|
+
position: "absolute",
|
|
787
|
+
right: "12px",
|
|
788
|
+
top: "50%",
|
|
789
|
+
transform: "translateY(-50%)"
|
|
790
|
+
},
|
|
791
|
+
children: mergedIcons[cardBrand]
|
|
792
|
+
}
|
|
793
|
+
)
|
|
794
|
+
] }),
|
|
795
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.errorMessage, children: error })
|
|
796
|
+
]
|
|
641
797
|
}
|
|
642
|
-
)
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
style: {
|
|
662
|
-
...mergedStyles.input,
|
|
663
|
-
...errors.cardHolder ? mergedStyles.inputError : {}
|
|
664
|
-
},
|
|
665
|
-
className: className.input || ""
|
|
798
|
+
);
|
|
799
|
+
},
|
|
800
|
+
cardHolder: () => {
|
|
801
|
+
const label = config.label || mergedLabels.cardHolder;
|
|
802
|
+
const placeholder = config.placeholder || mergedPlaceholders.cardHolder;
|
|
803
|
+
const error = errors.cardHolder;
|
|
804
|
+
if (config.render) {
|
|
805
|
+
return config.render({
|
|
806
|
+
value: cardHolderName,
|
|
807
|
+
onChange: handleCardHolderChange,
|
|
808
|
+
onBlur: () => {
|
|
809
|
+
},
|
|
810
|
+
error,
|
|
811
|
+
placeholder,
|
|
812
|
+
label,
|
|
813
|
+
required: config.required !== false,
|
|
814
|
+
disabled: loading,
|
|
815
|
+
name: "card_holder_name"
|
|
816
|
+
});
|
|
666
817
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
819
|
+
"div",
|
|
820
|
+
{
|
|
821
|
+
style: { ...mergedStyles.inputGroup, ...config.style },
|
|
822
|
+
className: config.className || className.inputGroup,
|
|
823
|
+
children: [
|
|
824
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label, children: label }),
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
826
|
+
"input",
|
|
827
|
+
{
|
|
828
|
+
type: "text",
|
|
829
|
+
value: cardHolderName,
|
|
830
|
+
onChange: (e) => handleCardHolderChange(e.target.value),
|
|
831
|
+
placeholder,
|
|
832
|
+
required: config.required !== false,
|
|
833
|
+
disabled: loading,
|
|
834
|
+
name: "card_holder_name",
|
|
835
|
+
style: {
|
|
836
|
+
...mergedStyles.input,
|
|
837
|
+
...error ? mergedStyles.inputError : {}
|
|
838
|
+
},
|
|
839
|
+
className: className.input
|
|
840
|
+
}
|
|
841
|
+
),
|
|
842
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.errorMessage, children: error })
|
|
843
|
+
]
|
|
844
|
+
}
|
|
845
|
+
);
|
|
846
|
+
},
|
|
847
|
+
customerEmail: () => {
|
|
848
|
+
const label = config.label || mergedLabels.customerEmail;
|
|
849
|
+
const placeholder = config.placeholder || mergedPlaceholders.customerEmail;
|
|
850
|
+
const error = errors.email;
|
|
851
|
+
if (config.render) {
|
|
852
|
+
return config.render({
|
|
853
|
+
value: email,
|
|
854
|
+
onChange: handleEmailChange,
|
|
855
|
+
onBlur: () => {
|
|
856
|
+
},
|
|
857
|
+
error,
|
|
858
|
+
placeholder,
|
|
859
|
+
label,
|
|
860
|
+
required: config.required === true,
|
|
861
|
+
disabled: loading,
|
|
862
|
+
name: "customer_email"
|
|
863
|
+
});
|
|
689
864
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "12px", color: "#6B7280" }, children: "Used to associate the saved card with the customer" })
|
|
693
|
-
] }),
|
|
694
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: mergedStyles.row, children: [
|
|
695
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: mergedStyles.inputGroup, className: className.inputGroup || "", children: [
|
|
696
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label || "", children: mergedLabels.expiryDate }),
|
|
697
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
698
|
-
"input",
|
|
865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
866
|
+
"div",
|
|
699
867
|
{
|
|
700
|
-
|
|
868
|
+
style: { ...mergedStyles.inputGroup, ...config.style },
|
|
869
|
+
className: config.className || className.inputGroup,
|
|
870
|
+
children: [
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label, children: label }),
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
873
|
+
"input",
|
|
874
|
+
{
|
|
875
|
+
type: "email",
|
|
876
|
+
value: email,
|
|
877
|
+
onChange: (e) => handleEmailChange(e.target.value),
|
|
878
|
+
placeholder,
|
|
879
|
+
required: config.required === true,
|
|
880
|
+
disabled: loading,
|
|
881
|
+
name: "customer_email",
|
|
882
|
+
style: {
|
|
883
|
+
...mergedStyles.input,
|
|
884
|
+
...error ? mergedStyles.inputError : {}
|
|
885
|
+
},
|
|
886
|
+
className: className.input
|
|
887
|
+
}
|
|
888
|
+
),
|
|
889
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.errorMessage, children: error }),
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.helperText, children: "Used to associate the saved card with the customer" })
|
|
891
|
+
]
|
|
892
|
+
}
|
|
893
|
+
);
|
|
894
|
+
},
|
|
895
|
+
expiryDate: () => {
|
|
896
|
+
const label = config.label || mergedLabels.expiryDate;
|
|
897
|
+
const placeholder = config.placeholder || mergedPlaceholders.expiryDate;
|
|
898
|
+
const error = errors.expiryDate;
|
|
899
|
+
if (config.render) {
|
|
900
|
+
return config.render({
|
|
701
901
|
value: expiryDate,
|
|
702
902
|
onChange: handleExpiryDateChange,
|
|
703
|
-
|
|
704
|
-
maxLength: 5,
|
|
705
|
-
required: true,
|
|
706
|
-
style: {
|
|
707
|
-
...mergedStyles.input,
|
|
708
|
-
...errors.expiryDate ? mergedStyles.inputError : {}
|
|
903
|
+
onBlur: () => {
|
|
709
904
|
},
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
905
|
+
error,
|
|
906
|
+
placeholder,
|
|
907
|
+
label,
|
|
908
|
+
required: config.required !== false,
|
|
909
|
+
disabled: loading,
|
|
910
|
+
name: "expiry_date"
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
914
|
+
"div",
|
|
719
915
|
{
|
|
720
|
-
|
|
916
|
+
style: { ...mergedStyles.inputGroup, ...config.style },
|
|
917
|
+
className: config.className || className.inputGroup,
|
|
918
|
+
children: [
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label, children: label }),
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
921
|
+
"input",
|
|
922
|
+
{
|
|
923
|
+
type: "text",
|
|
924
|
+
value: expiryDate,
|
|
925
|
+
onChange: (e) => handleExpiryDateChange(e.target.value),
|
|
926
|
+
placeholder,
|
|
927
|
+
maxLength: 5,
|
|
928
|
+
required: config.required !== false,
|
|
929
|
+
disabled: loading,
|
|
930
|
+
name: "expiry_date",
|
|
931
|
+
style: {
|
|
932
|
+
...mergedStyles.input,
|
|
933
|
+
...error ? mergedStyles.inputError : {}
|
|
934
|
+
},
|
|
935
|
+
className: className.input
|
|
936
|
+
}
|
|
937
|
+
),
|
|
938
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.errorMessage, children: error })
|
|
939
|
+
]
|
|
940
|
+
}
|
|
941
|
+
);
|
|
942
|
+
},
|
|
943
|
+
cvv: () => {
|
|
944
|
+
const label = config.label || mergedLabels.cvv;
|
|
945
|
+
const placeholder = config.placeholder || mergedPlaceholders.cvv;
|
|
946
|
+
const error = errors.cvv;
|
|
947
|
+
if (config.render) {
|
|
948
|
+
return config.render({
|
|
721
949
|
value: cvv,
|
|
722
950
|
onChange: handleCvvChange,
|
|
723
|
-
|
|
724
|
-
maxLength: 4,
|
|
725
|
-
required: true,
|
|
726
|
-
style: {
|
|
727
|
-
...mergedStyles.input,
|
|
728
|
-
...errors.cvv ? mergedStyles.inputError : {}
|
|
951
|
+
onBlur: () => {
|
|
729
952
|
},
|
|
730
|
-
|
|
953
|
+
error,
|
|
954
|
+
placeholder,
|
|
955
|
+
label,
|
|
956
|
+
required: config.required !== false,
|
|
957
|
+
disabled: loading,
|
|
958
|
+
name: "cvv"
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
962
|
+
"div",
|
|
963
|
+
{
|
|
964
|
+
style: { ...mergedStyles.inputGroup, ...config.style },
|
|
965
|
+
className: config.className || className.inputGroup,
|
|
966
|
+
children: [
|
|
967
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: mergedStyles.label, className: className.label, children: label }),
|
|
968
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
969
|
+
"input",
|
|
970
|
+
{
|
|
971
|
+
type: "text",
|
|
972
|
+
value: cvv,
|
|
973
|
+
onChange: (e) => handleCvvChange(e.target.value),
|
|
974
|
+
placeholder,
|
|
975
|
+
maxLength: 4,
|
|
976
|
+
required: config.required !== false,
|
|
977
|
+
disabled: loading,
|
|
978
|
+
name: "cvv",
|
|
979
|
+
style: {
|
|
980
|
+
...mergedStyles.input,
|
|
981
|
+
...error ? mergedStyles.inputError : {}
|
|
982
|
+
},
|
|
983
|
+
className: className.input
|
|
984
|
+
}
|
|
985
|
+
),
|
|
986
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: mergedStyles.errorMessage, children: error })
|
|
987
|
+
]
|
|
731
988
|
}
|
|
732
|
-
)
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
]
|
|
736
|
-
|
|
737
|
-
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
return fieldRenderers[fieldName]?.() || null;
|
|
993
|
+
};
|
|
994
|
+
const getFormStyle = () => {
|
|
995
|
+
const baseStyle = mergedStyles.form || {};
|
|
996
|
+
switch (layout.type) {
|
|
997
|
+
case "horizontal":
|
|
998
|
+
return {
|
|
999
|
+
...baseStyle,
|
|
1000
|
+
flexDirection: "row",
|
|
1001
|
+
flexWrap: "wrap",
|
|
1002
|
+
gap: layout.gap || "12px"
|
|
1003
|
+
};
|
|
1004
|
+
case "grid":
|
|
1005
|
+
return {
|
|
1006
|
+
...baseStyle,
|
|
1007
|
+
display: "grid",
|
|
1008
|
+
gridTemplateColumns: layout.gridTemplateColumns || `repeat(${layout.columns || 2}, 1fr)`,
|
|
1009
|
+
...layout.gridTemplateAreas ? { gridTemplateAreas: layout.gridTemplateAreas } : {},
|
|
1010
|
+
gap: layout.gap || "12px"
|
|
1011
|
+
};
|
|
1012
|
+
case "custom":
|
|
1013
|
+
return {
|
|
1014
|
+
...baseStyle,
|
|
1015
|
+
...styles?.form || {}
|
|
1016
|
+
};
|
|
1017
|
+
default:
|
|
1018
|
+
return baseStyle;
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
const renderSubmitButton = () => {
|
|
1022
|
+
if (submitButton) {
|
|
1023
|
+
if (typeof submitButton === "function") {
|
|
1024
|
+
return submitButton({ loading, onClick: () => {
|
|
1025
|
+
} });
|
|
1026
|
+
}
|
|
1027
|
+
return submitButton;
|
|
1028
|
+
}
|
|
1029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
738
1030
|
"button",
|
|
739
1031
|
{
|
|
740
1032
|
type: "submit",
|
|
@@ -743,11 +1035,37 @@ var TokenizationForm = ({
|
|
|
743
1035
|
...mergedStyles.button,
|
|
744
1036
|
...loading ? mergedStyles.buttonDisabled : {}
|
|
745
1037
|
},
|
|
746
|
-
className: className.button
|
|
1038
|
+
className: className.button,
|
|
747
1039
|
children: loading ? mergedLabels.processing : mergedLabels.submitButton
|
|
748
1040
|
}
|
|
749
|
-
)
|
|
750
|
-
|
|
1041
|
+
);
|
|
1042
|
+
};
|
|
1043
|
+
const renderSecurityNotice = () => {
|
|
1044
|
+
if (!showSecurityNotice) return null;
|
|
1045
|
+
if (securityNotice) {
|
|
1046
|
+
return securityNotice;
|
|
1047
|
+
}
|
|
1048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: mergedStyles.securityNotice, children: "\u{1F512} Your card details are securely processed by Amazon Payment Services. We never store your card information." });
|
|
1049
|
+
};
|
|
1050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: mergedStyles.container, className: className.container, children: [
|
|
1051
|
+
beforeForm,
|
|
1052
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1053
|
+
"form",
|
|
1054
|
+
{
|
|
1055
|
+
onSubmit: handleSubmit,
|
|
1056
|
+
style: getFormStyle(),
|
|
1057
|
+
className: className.form,
|
|
1058
|
+
children: [
|
|
1059
|
+
fieldOrder.map((fieldName) => renderField(fieldName)),
|
|
1060
|
+
renderSecurityNotice(),
|
|
1061
|
+
beforeSubmit,
|
|
1062
|
+
renderSubmitButton(),
|
|
1063
|
+
afterSubmit
|
|
1064
|
+
]
|
|
1065
|
+
}
|
|
1066
|
+
),
|
|
1067
|
+
afterForm
|
|
1068
|
+
] });
|
|
751
1069
|
};
|
|
752
1070
|
|
|
753
1071
|
// src/constants.ts
|