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