@flopay/react 0.3.17 → 0.3.20
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 +8 -4
- package/dist/index.cjs +190 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +190 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -102,10 +102,10 @@ interface FloPayCheckoutProps {
|
|
|
102
102
|
*/
|
|
103
103
|
onButtonClick?: (method: CheckoutButtonMethod) => void;
|
|
104
104
|
/**
|
|
105
|
-
* Called before
|
|
106
|
-
*
|
|
105
|
+
* Called before a payment button continues in `layout="buttons"`.
|
|
106
|
+
* Runs for card, PayPal, Apple Pay, and Google Pay.
|
|
107
107
|
* In `layout="buttons"` with `createSession`, the returned patch is merged
|
|
108
|
-
* into the inline session params before the
|
|
108
|
+
* into the inline session params before the selected flow continues.
|
|
109
109
|
*/
|
|
110
110
|
onBeforeButtonClick?: (event: BeforeButtonClickEvent) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;
|
|
111
111
|
/**
|
|
@@ -417,8 +417,8 @@ interface SplitCardFormProps {
|
|
|
417
417
|
*/
|
|
418
418
|
onButtonClick?: (method: CheckoutButtonMethod) => void;
|
|
419
419
|
/**
|
|
420
|
-
* Called before
|
|
421
|
-
*
|
|
420
|
+
* Called before a payment button continues in `layout="buttons"`.
|
|
421
|
+
* Runs for card, PayPal, Apple Pay, and Google Pay.
|
|
422
422
|
*/
|
|
423
423
|
onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<void | false | InlineSessionPatch>;
|
|
424
424
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -102,10 +102,10 @@ interface FloPayCheckoutProps {
|
|
|
102
102
|
*/
|
|
103
103
|
onButtonClick?: (method: CheckoutButtonMethod) => void;
|
|
104
104
|
/**
|
|
105
|
-
* Called before
|
|
106
|
-
*
|
|
105
|
+
* Called before a payment button continues in `layout="buttons"`.
|
|
106
|
+
* Runs for card, PayPal, Apple Pay, and Google Pay.
|
|
107
107
|
* In `layout="buttons"` with `createSession`, the returned patch is merged
|
|
108
|
-
* into the inline session params before the
|
|
108
|
+
* into the inline session params before the selected flow continues.
|
|
109
109
|
*/
|
|
110
110
|
onBeforeButtonClick?: (event: BeforeButtonClickEvent) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;
|
|
111
111
|
/**
|
|
@@ -417,8 +417,8 @@ interface SplitCardFormProps {
|
|
|
417
417
|
*/
|
|
418
418
|
onButtonClick?: (method: CheckoutButtonMethod) => void;
|
|
419
419
|
/**
|
|
420
|
-
* Called before
|
|
421
|
-
*
|
|
420
|
+
* Called before a payment button continues in `layout="buttons"`.
|
|
421
|
+
* Runs for card, PayPal, Apple Pay, and Google Pay.
|
|
422
422
|
*/
|
|
423
423
|
onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<void | false | InlineSessionPatch>;
|
|
424
424
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -350,6 +350,25 @@ var FLOPAY_KEYFRAMES = `
|
|
|
350
350
|
100% { opacity: 0; transform: translateX(16px) scale(0.97); }
|
|
351
351
|
}
|
|
352
352
|
`;
|
|
353
|
+
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;
|
|
354
|
+
function getButtonMethodLabel(method) {
|
|
355
|
+
switch (method) {
|
|
356
|
+
case "paypal":
|
|
357
|
+
return "PayPal";
|
|
358
|
+
case "apple_pay":
|
|
359
|
+
return "Apple Pay";
|
|
360
|
+
case "google_pay":
|
|
361
|
+
return "Google Pay";
|
|
362
|
+
default:
|
|
363
|
+
return "Card";
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function normalizeBeforeButtonClickError(method, err) {
|
|
367
|
+
return err instanceof FloPayError2 ? err : new FloPayError2(
|
|
368
|
+
err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,
|
|
369
|
+
"validation_error"
|
|
370
|
+
);
|
|
371
|
+
}
|
|
353
372
|
function FloPayKeyframes() {
|
|
354
373
|
return /* @__PURE__ */ jsx4("style", { children: FLOPAY_KEYFRAMES });
|
|
355
374
|
}
|
|
@@ -520,13 +539,15 @@ function PayPalButtonInner({
|
|
|
520
539
|
onErrorChange,
|
|
521
540
|
isProcessing = false,
|
|
522
541
|
onButtonClick,
|
|
523
|
-
onDecline
|
|
542
|
+
onDecline,
|
|
543
|
+
runBeforeButtonClick
|
|
524
544
|
}) {
|
|
525
545
|
const stripe = useStripeRaw();
|
|
526
546
|
const elements = useStripeElements();
|
|
527
547
|
const [loadState, setLoadState] = useState2("loading");
|
|
528
548
|
const [submitting, setSubmitting] = useState2(false);
|
|
529
549
|
const paypalResumeAttempted = useRef2(false);
|
|
550
|
+
const beforeClickRef = useRef2(null);
|
|
530
551
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
531
552
|
useEffect3(() => {
|
|
532
553
|
if (!stripe || paypalResumeAttempted.current) return;
|
|
@@ -575,13 +596,45 @@ function PayPalButtonInner({
|
|
|
575
596
|
}
|
|
576
597
|
})();
|
|
577
598
|
}, [stripe, onTokenizedBody, onErrorChange, onDecline]);
|
|
578
|
-
const
|
|
599
|
+
const handlePayPalClick = useCallback(async (event) => {
|
|
600
|
+
if (isProcessing || submitting) {
|
|
601
|
+
event.reject();
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick("paypal") : { proceed: true };
|
|
605
|
+
if (!beforeClick.proceed) {
|
|
606
|
+
beforeClickRef.current = null;
|
|
607
|
+
event.reject();
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
beforeClickRef.current = {
|
|
611
|
+
accountPatch: beforeClick.accountPatch,
|
|
612
|
+
sessionId: beforeClick.sessionId
|
|
613
|
+
};
|
|
614
|
+
event.resolve();
|
|
615
|
+
}, [isProcessing, runBeforeButtonClick, submitting]);
|
|
616
|
+
const handlePayPalConfirm = useCallback(async (event) => {
|
|
579
617
|
if (!stripe || !elements) return;
|
|
618
|
+
let prepared = beforeClickRef.current;
|
|
619
|
+
beforeClickRef.current = null;
|
|
620
|
+
if (!prepared && runBeforeButtonClick) {
|
|
621
|
+
const beforeClick = await runBeforeButtonClick("paypal");
|
|
622
|
+
if (!beforeClick.proceed) {
|
|
623
|
+
event.paymentFailed({ reason: "fail", message: "PayPal checkout was cancelled." });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
prepared = {
|
|
627
|
+
accountPatch: beforeClick.accountPatch,
|
|
628
|
+
sessionId: beforeClick.sessionId
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
632
|
+
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
580
633
|
onButtonClick?.("paypal");
|
|
581
634
|
try {
|
|
582
635
|
setSubmitting(true);
|
|
583
636
|
onErrorChange?.(null);
|
|
584
|
-
if (!
|
|
637
|
+
if (!effectiveSessionId || !effectiveEmail) {
|
|
585
638
|
throw new Error("Missing sessionId or email for PayPal payment");
|
|
586
639
|
}
|
|
587
640
|
const createPM = stripe.createPaymentMethod;
|
|
@@ -593,8 +646,8 @@ function PayPalButtonInner({
|
|
|
593
646
|
method: "POST",
|
|
594
647
|
headers: { "Content-Type": "application/json" },
|
|
595
648
|
body: JSON.stringify({
|
|
596
|
-
sessionId,
|
|
597
|
-
email,
|
|
649
|
+
sessionId: effectiveSessionId,
|
|
650
|
+
email: effectiveEmail,
|
|
598
651
|
paymentMethodType: paymentMethod?.id ?? "paypal",
|
|
599
652
|
isPaypal: "true"
|
|
600
653
|
})
|
|
@@ -628,21 +681,26 @@ function PayPalButtonInner({
|
|
|
628
681
|
type: "card",
|
|
629
682
|
threeDSecureActionResultTokenId: paymentIntent?.id,
|
|
630
683
|
isPaypal: true
|
|
684
|
+
}, {
|
|
685
|
+
accountPatch: prepared?.accountPatch,
|
|
686
|
+
sessionId: effectiveSessionId
|
|
631
687
|
});
|
|
632
688
|
} catch (err) {
|
|
633
689
|
onErrorChange?.(err instanceof Error ? err.message : "PayPal payment failed. Please try again.");
|
|
634
690
|
} finally {
|
|
635
691
|
setSubmitting(false);
|
|
636
692
|
}
|
|
637
|
-
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]);
|
|
693
|
+
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]);
|
|
638
694
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
639
695
|
/* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ jsx4(
|
|
640
696
|
ExpressCheckoutElement,
|
|
641
697
|
{
|
|
642
698
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
|
|
643
699
|
onLoadError: () => setLoadState("unavailable"),
|
|
700
|
+
onClick: handlePayPalClick,
|
|
644
701
|
onConfirm: handlePayPalConfirm,
|
|
645
702
|
onCancel: () => {
|
|
703
|
+
beforeClickRef.current = null;
|
|
646
704
|
onDecline?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
|
|
647
705
|
},
|
|
648
706
|
options: {
|
|
@@ -668,7 +726,8 @@ function WalletButtonInner({
|
|
|
668
726
|
onTokenizedBody,
|
|
669
727
|
onErrorChange,
|
|
670
728
|
onButtonClick,
|
|
671
|
-
onDecline
|
|
729
|
+
onDecline,
|
|
730
|
+
runBeforeButtonClick
|
|
672
731
|
}) {
|
|
673
732
|
const stripe = useStripeRaw();
|
|
674
733
|
const elements = useStripeElements();
|
|
@@ -676,10 +735,29 @@ function WalletButtonInner({
|
|
|
676
735
|
const [submitting, setSubmitting] = useState2(false);
|
|
677
736
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
678
737
|
const lastWalletMethodRef = useRef2("card");
|
|
738
|
+
const beforeClickRef = useRef2(null);
|
|
679
739
|
const handleWalletConfirm = useCallback(
|
|
680
|
-
async (
|
|
740
|
+
async (event) => {
|
|
681
741
|
if (!stripe || !elements) return;
|
|
682
|
-
const walletType =
|
|
742
|
+
const walletType = event.expressPaymentType;
|
|
743
|
+
let prepared = beforeClickRef.current;
|
|
744
|
+
beforeClickRef.current = null;
|
|
745
|
+
if (!prepared && runBeforeButtonClick) {
|
|
746
|
+
const beforeClick = await runBeforeButtonClick(
|
|
747
|
+
walletType === "apple_pay" ? "apple_pay" : "google_pay"
|
|
748
|
+
);
|
|
749
|
+
if (!beforeClick.proceed) {
|
|
750
|
+
event.paymentFailed({ reason: "fail", message: "Wallet checkout was cancelled." });
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
prepared = {
|
|
754
|
+
accountPatch: beforeClick.accountPatch,
|
|
755
|
+
sessionId: beforeClick.sessionId
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
759
|
+
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
760
|
+
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
683
761
|
onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
|
|
684
762
|
try {
|
|
685
763
|
setSubmitting(true);
|
|
@@ -694,15 +772,15 @@ function WalletButtonInner({
|
|
|
694
772
|
onErrorChange?.(pmError?.message ?? "Failed to create payment method.");
|
|
695
773
|
return;
|
|
696
774
|
}
|
|
697
|
-
if (!
|
|
775
|
+
if (!effectiveSessionId || !effectiveEmail) {
|
|
698
776
|
throw new Error("Missing sessionId or email for wallet payment");
|
|
699
777
|
}
|
|
700
778
|
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
701
779
|
method: "POST",
|
|
702
780
|
headers: { "Content-Type": "application/json" },
|
|
703
781
|
body: JSON.stringify({
|
|
704
|
-
sessionId,
|
|
705
|
-
email,
|
|
782
|
+
sessionId: effectiveSessionId,
|
|
783
|
+
email: effectiveEmail,
|
|
706
784
|
paymentMethodType: paymentMethod.id,
|
|
707
785
|
isPaypal: false
|
|
708
786
|
})
|
|
@@ -716,7 +794,6 @@ function WalletButtonInner({
|
|
|
716
794
|
{ payment_method: paymentMethod.id }
|
|
717
795
|
);
|
|
718
796
|
if (confirmError) {
|
|
719
|
-
const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
720
797
|
const message = confirmError.message ?? "Wallet payment failed.";
|
|
721
798
|
onErrorChange?.(message);
|
|
722
799
|
onDecline?.(buildDeclineEvent(method, message, {
|
|
@@ -728,6 +805,9 @@ function WalletButtonInner({
|
|
|
728
805
|
id: paymentMethod.id,
|
|
729
806
|
type: "card",
|
|
730
807
|
threeDSecureActionResultTokenId: paymentIntent?.id
|
|
808
|
+
}, {
|
|
809
|
+
accountPatch: prepared?.accountPatch,
|
|
810
|
+
sessionId: effectiveSessionId
|
|
731
811
|
});
|
|
732
812
|
} catch (err) {
|
|
733
813
|
onErrorChange?.(err instanceof Error ? err.message : "Wallet payment failed. Please try again.");
|
|
@@ -735,7 +815,7 @@ function WalletButtonInner({
|
|
|
735
815
|
setSubmitting(false);
|
|
736
816
|
}
|
|
737
817
|
},
|
|
738
|
-
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]
|
|
818
|
+
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]
|
|
739
819
|
);
|
|
740
820
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
741
821
|
/* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ jsx4(
|
|
@@ -743,12 +823,23 @@ function WalletButtonInner({
|
|
|
743
823
|
{
|
|
744
824
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"])),
|
|
745
825
|
onLoadError: () => setLoadState("unavailable"),
|
|
746
|
-
onClick: (event) => {
|
|
826
|
+
onClick: async (event) => {
|
|
747
827
|
lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
828
|
+
const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current) : { proceed: true };
|
|
829
|
+
if (!beforeClick.proceed) {
|
|
830
|
+
beforeClickRef.current = null;
|
|
831
|
+
event.reject();
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
beforeClickRef.current = {
|
|
835
|
+
accountPatch: beforeClick.accountPatch,
|
|
836
|
+
sessionId: beforeClick.sessionId
|
|
837
|
+
};
|
|
748
838
|
event.resolve();
|
|
749
839
|
},
|
|
750
840
|
onConfirm: handleWalletConfirm,
|
|
751
841
|
onCancel: () => {
|
|
842
|
+
beforeClickRef.current = null;
|
|
752
843
|
onDecline?.(buildDeclineEvent(lastWalletMethodRef.current, "Wallet checkout was cancelled."));
|
|
753
844
|
},
|
|
754
845
|
options: {
|
|
@@ -910,55 +1001,83 @@ function SplitCardFormInner({
|
|
|
910
1001
|
onFirstNameChange?.(parts[0] ?? "");
|
|
911
1002
|
onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
|
|
912
1003
|
}, [onFullNameChange, onFirstNameChange, onLastNameChange]);
|
|
913
|
-
const
|
|
914
|
-
|
|
1004
|
+
const applyInlineSessionPatch = useCallback(
|
|
1005
|
+
(patch, method) => {
|
|
1006
|
+
if (!checkout.applyInlineSessionPatch) {
|
|
1007
|
+
return Promise.resolve({ error: null, sessionId });
|
|
1008
|
+
}
|
|
1009
|
+
return checkout.applyInlineSessionPatch(patch).then((result) => ({
|
|
1010
|
+
error: null,
|
|
1011
|
+
sessionId: result.sessionId || sessionId
|
|
1012
|
+
})).catch((err) => {
|
|
1013
|
+
const floPayErr = normalizeBeforeButtonClickError(method, err);
|
|
1014
|
+
updateError(floPayErr.message);
|
|
1015
|
+
onError?.(floPayErr);
|
|
1016
|
+
return { error: floPayErr, sessionId };
|
|
1017
|
+
});
|
|
1018
|
+
},
|
|
1019
|
+
[checkout.applyInlineSessionPatch, onError, sessionId, updateError]
|
|
1020
|
+
);
|
|
1021
|
+
const runBeforeButtonClick = useCallback(async (method) => {
|
|
1022
|
+
if (!onBeforeButtonClick) return { proceed: true };
|
|
915
1023
|
try {
|
|
916
1024
|
const result = await onBeforeButtonClick({
|
|
917
|
-
method
|
|
918
|
-
sessionId: sessionId || void 0
|
|
1025
|
+
method,
|
|
1026
|
+
sessionId: sessionId || void 0,
|
|
1027
|
+
createSession: checkout.inlineSessionDraft
|
|
919
1028
|
});
|
|
920
1029
|
if (result === false) {
|
|
921
|
-
return false;
|
|
1030
|
+
return { proceed: false };
|
|
922
1031
|
}
|
|
923
1032
|
if (result && typeof result === "object") {
|
|
924
|
-
await checkout.applyInlineSessionPatch?.(result);
|
|
925
1033
|
if (result.account) {
|
|
926
1034
|
setAccountPatch((prev) => ({ ...prev ?? {}, ...result.account }));
|
|
927
1035
|
}
|
|
1036
|
+
const patchResult = await applyInlineSessionPatch(result, method);
|
|
1037
|
+
if (patchResult.error) {
|
|
1038
|
+
return {
|
|
1039
|
+
proceed: false,
|
|
1040
|
+
accountPatch: result.account
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
return {
|
|
1044
|
+
proceed: true,
|
|
1045
|
+
accountPatch: result.account,
|
|
1046
|
+
sessionId: patchResult.sessionId
|
|
1047
|
+
};
|
|
928
1048
|
}
|
|
929
|
-
return true;
|
|
1049
|
+
return { proceed: true };
|
|
930
1050
|
} catch (err) {
|
|
931
|
-
const floPayErr =
|
|
932
|
-
err instanceof Error ? err.message : "Card before-click hook failed.",
|
|
933
|
-
"validation_error"
|
|
934
|
-
);
|
|
1051
|
+
const floPayErr = normalizeBeforeButtonClickError(method, err);
|
|
935
1052
|
updateError(floPayErr.message);
|
|
936
1053
|
onError?.(floPayErr);
|
|
937
|
-
return false;
|
|
1054
|
+
return { proceed: false };
|
|
938
1055
|
}
|
|
939
|
-
}, [checkout.
|
|
1056
|
+
}, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
|
|
940
1057
|
const processPaymentInternal = useCallback(
|
|
941
|
-
async (tokenizedBody) => {
|
|
1058
|
+
async (tokenizedBody, overrides) => {
|
|
942
1059
|
if (processingRef.current) return;
|
|
943
1060
|
processingRef.current = true;
|
|
944
1061
|
setProcessing(true);
|
|
945
1062
|
setOverlayStatus("processing");
|
|
946
1063
|
updateError(null);
|
|
1064
|
+
const effectiveSessionId = overrides?.sessionId ?? sessionId;
|
|
1065
|
+
const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);
|
|
947
1066
|
try {
|
|
948
1067
|
const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
|
|
949
1068
|
method: "POST",
|
|
950
1069
|
headers: {
|
|
951
1070
|
"Content-Type": "application/json",
|
|
952
|
-
"x-user-id":
|
|
1071
|
+
"x-user-id": effectiveAccount.userId ?? ""
|
|
953
1072
|
},
|
|
954
1073
|
body: JSON.stringify({
|
|
955
|
-
sessionId,
|
|
1074
|
+
sessionId: effectiveSessionId,
|
|
956
1075
|
tokenizedData: tokenizedBody,
|
|
957
1076
|
accountData: {
|
|
958
|
-
userId:
|
|
959
|
-
email:
|
|
960
|
-
firstName:
|
|
961
|
-
lastName:
|
|
1077
|
+
userId: effectiveAccount.userId ?? "",
|
|
1078
|
+
email: effectiveAccount.email ?? "",
|
|
1079
|
+
firstName: effectiveAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
|
|
1080
|
+
lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
|
|
962
1081
|
...enableAVS ? { zip: zipCodeRef.current, country: selectedCountryRef.current } : {}
|
|
963
1082
|
},
|
|
964
1083
|
chv
|
|
@@ -1067,11 +1186,11 @@ function SplitCardFormInner({
|
|
|
1067
1186
|
[baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, onComplete, onError, updateError, emitDecline]
|
|
1068
1187
|
);
|
|
1069
1188
|
const dispatchTokenizedBody = useCallback(
|
|
1070
|
-
(tokenizedBody) => {
|
|
1189
|
+
(tokenizedBody, overrides) => {
|
|
1071
1190
|
if (onTokenizedBody) {
|
|
1072
1191
|
onTokenizedBody(tokenizedBody);
|
|
1073
1192
|
} else {
|
|
1074
|
-
processPaymentInternal(tokenizedBody);
|
|
1193
|
+
processPaymentInternal(tokenizedBody, overrides);
|
|
1075
1194
|
}
|
|
1076
1195
|
},
|
|
1077
1196
|
[onTokenizedBody, processPaymentInternal]
|
|
@@ -1498,6 +1617,7 @@ function SplitCardFormInner({
|
|
|
1498
1617
|
if (layout === "buttons") {
|
|
1499
1618
|
const isButtonsView = viewState === "buttons" || viewState === "expanding";
|
|
1500
1619
|
const isCardView = viewState === "expanding" || viewState === "card" || viewState === "collapsing";
|
|
1620
|
+
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
1501
1621
|
const buttonsAnim = viewState === "expanding" ? `flopay-buttons-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both` : viewState === "collapsing" ? `flopay-buttons-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both` : void 0;
|
|
1502
1622
|
const cardAnim = viewState === "expanding" ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both` : viewState === "collapsing" ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both` : void 0;
|
|
1503
1623
|
return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
@@ -1523,9 +1643,10 @@ function SplitCardFormInner({
|
|
|
1523
1643
|
onErrorChange: updateError,
|
|
1524
1644
|
isProcessing: isSubmitting,
|
|
1525
1645
|
onButtonClick,
|
|
1526
|
-
onDecline
|
|
1646
|
+
onDecline,
|
|
1647
|
+
runBeforeButtonClick
|
|
1527
1648
|
}
|
|
1528
|
-
) }) : showPayPal ? /* @__PURE__ */ jsx4("div", { style: { height:
|
|
1649
|
+
) }) : showPayPal ? /* @__PURE__ */ jsx4("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
1529
1650
|
showWallets && stripeInstance ? /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx4(
|
|
1530
1651
|
WalletButtonInner,
|
|
1531
1652
|
{
|
|
@@ -1537,24 +1658,25 @@ function SplitCardFormInner({
|
|
|
1537
1658
|
onTokenizedBody: dispatchTokenizedBody,
|
|
1538
1659
|
onErrorChange: updateError,
|
|
1539
1660
|
onButtonClick,
|
|
1540
|
-
onDecline
|
|
1661
|
+
onDecline,
|
|
1662
|
+
runBeforeButtonClick
|
|
1541
1663
|
}
|
|
1542
|
-
) }) : showWallets ? /* @__PURE__ */ jsx4("div", { style: { height:
|
|
1664
|
+
) }) : showWallets ? /* @__PURE__ */ jsx4("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
1543
1665
|
/* @__PURE__ */ jsx4(
|
|
1544
1666
|
"button",
|
|
1545
1667
|
{
|
|
1546
1668
|
type: "button",
|
|
1547
1669
|
onClick: async () => {
|
|
1548
1670
|
if (isSubmitting) return;
|
|
1549
|
-
const
|
|
1550
|
-
if (!
|
|
1671
|
+
const beforeClick = await runBeforeButtonClick("card");
|
|
1672
|
+
if (!beforeClick.proceed) return;
|
|
1551
1673
|
onButtonClick?.("card");
|
|
1552
1674
|
expandToCard();
|
|
1553
1675
|
},
|
|
1554
1676
|
disabled: isSubmitting,
|
|
1555
1677
|
style: {
|
|
1556
1678
|
width: "100%",
|
|
1557
|
-
|
|
1679
|
+
...cardButtonSizing,
|
|
1558
1680
|
backgroundColor: "white",
|
|
1559
1681
|
color: "#262833",
|
|
1560
1682
|
border: "1px solid #d1d5db",
|
|
@@ -1653,6 +1775,7 @@ function SplitCardFormInner({
|
|
|
1653
1775
|
|
|
1654
1776
|
// src/flopay-checkout.tsx
|
|
1655
1777
|
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1778
|
+
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
1656
1779
|
function hasInlineSessionPatchData(patch) {
|
|
1657
1780
|
if (!patch) return false;
|
|
1658
1781
|
return Boolean(
|
|
@@ -1959,16 +2082,27 @@ function FloPayCheckout({
|
|
|
1959
2082
|
[fallbackPublishableKey, locale, resolvedBillingUrl]
|
|
1960
2083
|
);
|
|
1961
2084
|
const handleInlineSessionPatch = useCallback2(async (patch) => {
|
|
1962
|
-
if (!hasInlineSessionPatchData(patch) || cardBootstrapPending)
|
|
2085
|
+
if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
|
|
2086
|
+
return {
|
|
2087
|
+
sessionId: resolvedSessionId,
|
|
2088
|
+
session
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
1963
2091
|
setCardBootstrapPending(true);
|
|
1964
2092
|
try {
|
|
1965
|
-
await bootstrapInlineSession(patch);
|
|
2093
|
+
const resolved = await bootstrapInlineSession(patch);
|
|
2094
|
+
return {
|
|
2095
|
+
sessionId: resolved.sid,
|
|
2096
|
+
session: resolved.result.data.session ?? null
|
|
2097
|
+
};
|
|
1966
2098
|
} finally {
|
|
1967
2099
|
setCardBootstrapPending(false);
|
|
1968
2100
|
}
|
|
1969
2101
|
}, [
|
|
1970
2102
|
bootstrapInlineSession,
|
|
1971
|
-
cardBootstrapPending
|
|
2103
|
+
cardBootstrapPending,
|
|
2104
|
+
resolvedSessionId,
|
|
2105
|
+
session
|
|
1972
2106
|
]);
|
|
1973
2107
|
useEffect4(() => {
|
|
1974
2108
|
let cancelled = false;
|
|
@@ -2121,6 +2255,7 @@ function FloPayCheckout({
|
|
|
2121
2255
|
loading: isLoading,
|
|
2122
2256
|
error: loadError,
|
|
2123
2257
|
checkoutMode: currentMode,
|
|
2258
|
+
inlineSessionDraft: effectiveCreateSession,
|
|
2124
2259
|
applyInlineSessionPatch: shouldHandleInlineSessionPatch ? handleInlineSessionPatch : void 0,
|
|
2125
2260
|
inlineSessionPatchProcessing: cardBootstrapPending
|
|
2126
2261
|
}),
|
|
@@ -2129,6 +2264,7 @@ function FloPayCheckout({
|
|
|
2129
2264
|
isLoading,
|
|
2130
2265
|
loadError,
|
|
2131
2266
|
currentMode,
|
|
2267
|
+
effectiveCreateSession,
|
|
2132
2268
|
shouldHandleInlineSessionPatch,
|
|
2133
2269
|
handleInlineSessionPatch,
|
|
2134
2270
|
cardBootstrapPending
|
|
@@ -2145,9 +2281,9 @@ function FloPayCheckout({
|
|
|
2145
2281
|
animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
|
|
2146
2282
|
} });
|
|
2147
2283
|
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2148
|
-
showPayPal && skeletonBar(
|
|
2149
|
-
(showApplePay || showGooglePay) && skeletonBar(
|
|
2150
|
-
skeletonBar(
|
|
2284
|
+
showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2285
|
+
(showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2286
|
+
skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2151
2287
|
/* @__PURE__ */ jsx5("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
2152
2288
|
] });
|
|
2153
2289
|
}
|
|
@@ -2361,6 +2497,7 @@ function InterimButtonsView({
|
|
|
2361
2497
|
background: "#e5e7eb",
|
|
2362
2498
|
animation: "flopay-interim-pulse 1.5s ease-in-out infinite"
|
|
2363
2499
|
} });
|
|
2500
|
+
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
2364
2501
|
if (showCardForm) {
|
|
2365
2502
|
const inputBorder = bStyles.cardInputBorder ?? "#e5e7eb";
|
|
2366
2503
|
const inputBg = bStyles.cardInputBackground ?? "white";
|
|
@@ -2451,8 +2588,8 @@ function InterimButtonsView({
|
|
|
2451
2588
|
] });
|
|
2452
2589
|
}
|
|
2453
2590
|
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2454
|
-
showPayPal && skeleton(
|
|
2455
|
-
(showApplePay || showGooglePay) && skeleton(
|
|
2591
|
+
showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2592
|
+
(showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2456
2593
|
/* @__PURE__ */ jsx5(
|
|
2457
2594
|
"button",
|
|
2458
2595
|
{
|
|
@@ -2469,7 +2606,7 @@ function InterimButtonsView({
|
|
|
2469
2606
|
disabled: cardLoading,
|
|
2470
2607
|
style: {
|
|
2471
2608
|
width: "100%",
|
|
2472
|
-
|
|
2609
|
+
...cardButtonSizing,
|
|
2473
2610
|
backgroundColor: "white",
|
|
2474
2611
|
color: "#262833",
|
|
2475
2612
|
border: "1px solid #d1d5db",
|