@flopay/react 0.3.17 → 0.3.19
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 +208 -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 +208 -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,50 @@ 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", { deferInlineSessionPatch: true }) : { proceed: true };
|
|
605
|
+
if (!beforeClick.proceed) {
|
|
606
|
+
beforeClickRef.current = null;
|
|
607
|
+
event.reject();
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
beforeClickRef.current = {
|
|
611
|
+
accountPatch: beforeClick.accountPatch,
|
|
612
|
+
pendingInlinePatch: beforeClick.pendingInlinePatch
|
|
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
|
+
pendingInlinePatch: beforeClick.pendingInlinePatch ?? Promise.resolve({ error: null, sessionId: beforeClick.sessionId ?? sessionId })
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
const patchResult = prepared?.pendingInlinePatch ? await prepared.pendingInlinePatch : { error: null, sessionId };
|
|
632
|
+
if (patchResult.error) {
|
|
633
|
+
event.paymentFailed({ reason: "fail", message: patchResult.error.message });
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
const effectiveSessionId = patchResult.sessionId ?? sessionId;
|
|
637
|
+
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
580
638
|
onButtonClick?.("paypal");
|
|
581
639
|
try {
|
|
582
640
|
setSubmitting(true);
|
|
583
641
|
onErrorChange?.(null);
|
|
584
|
-
if (!
|
|
642
|
+
if (!effectiveSessionId || !effectiveEmail) {
|
|
585
643
|
throw new Error("Missing sessionId or email for PayPal payment");
|
|
586
644
|
}
|
|
587
645
|
const createPM = stripe.createPaymentMethod;
|
|
@@ -593,8 +651,8 @@ function PayPalButtonInner({
|
|
|
593
651
|
method: "POST",
|
|
594
652
|
headers: { "Content-Type": "application/json" },
|
|
595
653
|
body: JSON.stringify({
|
|
596
|
-
sessionId,
|
|
597
|
-
email,
|
|
654
|
+
sessionId: effectiveSessionId,
|
|
655
|
+
email: effectiveEmail,
|
|
598
656
|
paymentMethodType: paymentMethod?.id ?? "paypal",
|
|
599
657
|
isPaypal: "true"
|
|
600
658
|
})
|
|
@@ -628,21 +686,26 @@ function PayPalButtonInner({
|
|
|
628
686
|
type: "card",
|
|
629
687
|
threeDSecureActionResultTokenId: paymentIntent?.id,
|
|
630
688
|
isPaypal: true
|
|
689
|
+
}, {
|
|
690
|
+
accountPatch: prepared?.accountPatch,
|
|
691
|
+
sessionId: effectiveSessionId
|
|
631
692
|
});
|
|
632
693
|
} catch (err) {
|
|
633
694
|
onErrorChange?.(err instanceof Error ? err.message : "PayPal payment failed. Please try again.");
|
|
634
695
|
} finally {
|
|
635
696
|
setSubmitting(false);
|
|
636
697
|
}
|
|
637
|
-
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]);
|
|
698
|
+
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]);
|
|
638
699
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
639
700
|
/* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ jsx4(
|
|
640
701
|
ExpressCheckoutElement,
|
|
641
702
|
{
|
|
642
703
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
|
|
643
704
|
onLoadError: () => setLoadState("unavailable"),
|
|
705
|
+
onClick: handlePayPalClick,
|
|
644
706
|
onConfirm: handlePayPalConfirm,
|
|
645
707
|
onCancel: () => {
|
|
708
|
+
beforeClickRef.current = null;
|
|
646
709
|
onDecline?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
|
|
647
710
|
},
|
|
648
711
|
options: {
|
|
@@ -668,7 +731,8 @@ function WalletButtonInner({
|
|
|
668
731
|
onTokenizedBody,
|
|
669
732
|
onErrorChange,
|
|
670
733
|
onButtonClick,
|
|
671
|
-
onDecline
|
|
734
|
+
onDecline,
|
|
735
|
+
runBeforeButtonClick
|
|
672
736
|
}) {
|
|
673
737
|
const stripe = useStripeRaw();
|
|
674
738
|
const elements = useStripeElements();
|
|
@@ -676,10 +740,34 @@ function WalletButtonInner({
|
|
|
676
740
|
const [submitting, setSubmitting] = useState2(false);
|
|
677
741
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
678
742
|
const lastWalletMethodRef = useRef2("card");
|
|
743
|
+
const beforeClickRef = useRef2(null);
|
|
679
744
|
const handleWalletConfirm = useCallback(
|
|
680
|
-
async (
|
|
745
|
+
async (event) => {
|
|
681
746
|
if (!stripe || !elements) return;
|
|
682
|
-
const walletType =
|
|
747
|
+
const walletType = event.expressPaymentType;
|
|
748
|
+
let prepared = beforeClickRef.current;
|
|
749
|
+
beforeClickRef.current = null;
|
|
750
|
+
if (!prepared && runBeforeButtonClick) {
|
|
751
|
+
const beforeClick = await runBeforeButtonClick(
|
|
752
|
+
walletType === "apple_pay" ? "apple_pay" : "google_pay"
|
|
753
|
+
);
|
|
754
|
+
if (!beforeClick.proceed) {
|
|
755
|
+
event.paymentFailed({ reason: "fail", message: "Wallet checkout was cancelled." });
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
prepared = {
|
|
759
|
+
accountPatch: beforeClick.accountPatch,
|
|
760
|
+
pendingInlinePatch: beforeClick.pendingInlinePatch ?? Promise.resolve({ error: null, sessionId: beforeClick.sessionId ?? sessionId })
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
const patchResult = prepared?.pendingInlinePatch ? await prepared.pendingInlinePatch : { error: null, sessionId };
|
|
764
|
+
if (patchResult.error) {
|
|
765
|
+
event.paymentFailed({ reason: "fail", message: patchResult.error.message });
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
769
|
+
const effectiveSessionId = patchResult.sessionId ?? sessionId;
|
|
770
|
+
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
683
771
|
onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
|
|
684
772
|
try {
|
|
685
773
|
setSubmitting(true);
|
|
@@ -694,15 +782,15 @@ function WalletButtonInner({
|
|
|
694
782
|
onErrorChange?.(pmError?.message ?? "Failed to create payment method.");
|
|
695
783
|
return;
|
|
696
784
|
}
|
|
697
|
-
if (!
|
|
785
|
+
if (!effectiveSessionId || !effectiveEmail) {
|
|
698
786
|
throw new Error("Missing sessionId or email for wallet payment");
|
|
699
787
|
}
|
|
700
788
|
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
701
789
|
method: "POST",
|
|
702
790
|
headers: { "Content-Type": "application/json" },
|
|
703
791
|
body: JSON.stringify({
|
|
704
|
-
sessionId,
|
|
705
|
-
email,
|
|
792
|
+
sessionId: effectiveSessionId,
|
|
793
|
+
email: effectiveEmail,
|
|
706
794
|
paymentMethodType: paymentMethod.id,
|
|
707
795
|
isPaypal: false
|
|
708
796
|
})
|
|
@@ -716,7 +804,6 @@ function WalletButtonInner({
|
|
|
716
804
|
{ payment_method: paymentMethod.id }
|
|
717
805
|
);
|
|
718
806
|
if (confirmError) {
|
|
719
|
-
const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
720
807
|
const message = confirmError.message ?? "Wallet payment failed.";
|
|
721
808
|
onErrorChange?.(message);
|
|
722
809
|
onDecline?.(buildDeclineEvent(method, message, {
|
|
@@ -728,6 +815,9 @@ function WalletButtonInner({
|
|
|
728
815
|
id: paymentMethod.id,
|
|
729
816
|
type: "card",
|
|
730
817
|
threeDSecureActionResultTokenId: paymentIntent?.id
|
|
818
|
+
}, {
|
|
819
|
+
accountPatch: prepared?.accountPatch,
|
|
820
|
+
sessionId: effectiveSessionId
|
|
731
821
|
});
|
|
732
822
|
} catch (err) {
|
|
733
823
|
onErrorChange?.(err instanceof Error ? err.message : "Wallet payment failed. Please try again.");
|
|
@@ -735,7 +825,7 @@ function WalletButtonInner({
|
|
|
735
825
|
setSubmitting(false);
|
|
736
826
|
}
|
|
737
827
|
},
|
|
738
|
-
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]
|
|
828
|
+
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]
|
|
739
829
|
);
|
|
740
830
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
741
831
|
/* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ jsx4(
|
|
@@ -743,12 +833,23 @@ function WalletButtonInner({
|
|
|
743
833
|
{
|
|
744
834
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"])),
|
|
745
835
|
onLoadError: () => setLoadState("unavailable"),
|
|
746
|
-
onClick: (event) => {
|
|
836
|
+
onClick: async (event) => {
|
|
747
837
|
lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
838
|
+
const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current, { deferInlineSessionPatch: true }) : { proceed: true };
|
|
839
|
+
if (!beforeClick.proceed) {
|
|
840
|
+
beforeClickRef.current = null;
|
|
841
|
+
event.reject();
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
beforeClickRef.current = {
|
|
845
|
+
accountPatch: beforeClick.accountPatch,
|
|
846
|
+
pendingInlinePatch: beforeClick.pendingInlinePatch
|
|
847
|
+
};
|
|
748
848
|
event.resolve();
|
|
749
849
|
},
|
|
750
850
|
onConfirm: handleWalletConfirm,
|
|
751
851
|
onCancel: () => {
|
|
852
|
+
beforeClickRef.current = null;
|
|
752
853
|
onDecline?.(buildDeclineEvent(lastWalletMethodRef.current, "Wallet checkout was cancelled."));
|
|
753
854
|
},
|
|
754
855
|
options: {
|
|
@@ -910,55 +1011,91 @@ function SplitCardFormInner({
|
|
|
910
1011
|
onFirstNameChange?.(parts[0] ?? "");
|
|
911
1012
|
onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
|
|
912
1013
|
}, [onFullNameChange, onFirstNameChange, onLastNameChange]);
|
|
913
|
-
const
|
|
914
|
-
|
|
1014
|
+
const applyInlineSessionPatch = useCallback(
|
|
1015
|
+
(patch, method) => {
|
|
1016
|
+
if (!checkout.applyInlineSessionPatch) {
|
|
1017
|
+
return Promise.resolve({ error: null, sessionId });
|
|
1018
|
+
}
|
|
1019
|
+
return checkout.applyInlineSessionPatch(patch).then((result) => ({
|
|
1020
|
+
error: null,
|
|
1021
|
+
sessionId: result.sessionId || sessionId
|
|
1022
|
+
})).catch((err) => {
|
|
1023
|
+
const floPayErr = normalizeBeforeButtonClickError(method, err);
|
|
1024
|
+
updateError(floPayErr.message);
|
|
1025
|
+
onError?.(floPayErr);
|
|
1026
|
+
return { error: floPayErr, sessionId };
|
|
1027
|
+
});
|
|
1028
|
+
},
|
|
1029
|
+
[checkout.applyInlineSessionPatch, onError, sessionId, updateError]
|
|
1030
|
+
);
|
|
1031
|
+
const runBeforeButtonClick = useCallback(async (method, options) => {
|
|
1032
|
+
if (!onBeforeButtonClick) return { proceed: true };
|
|
915
1033
|
try {
|
|
916
1034
|
const result = await onBeforeButtonClick({
|
|
917
|
-
method
|
|
918
|
-
sessionId: sessionId || void 0
|
|
1035
|
+
method,
|
|
1036
|
+
sessionId: sessionId || void 0,
|
|
1037
|
+
createSession: checkout.inlineSessionDraft
|
|
919
1038
|
});
|
|
920
1039
|
if (result === false) {
|
|
921
|
-
return false;
|
|
1040
|
+
return { proceed: false };
|
|
922
1041
|
}
|
|
923
1042
|
if (result && typeof result === "object") {
|
|
924
|
-
await checkout.applyInlineSessionPatch?.(result);
|
|
925
1043
|
if (result.account) {
|
|
926
1044
|
setAccountPatch((prev) => ({ ...prev ?? {}, ...result.account }));
|
|
927
1045
|
}
|
|
1046
|
+
const pendingInlinePatch = applyInlineSessionPatch(result, method);
|
|
1047
|
+
if (options?.deferInlineSessionPatch) {
|
|
1048
|
+
return {
|
|
1049
|
+
proceed: true,
|
|
1050
|
+
accountPatch: result.account,
|
|
1051
|
+
pendingInlinePatch
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
const patchResult = await pendingInlinePatch;
|
|
1055
|
+
if (patchResult.error) {
|
|
1056
|
+
return {
|
|
1057
|
+
proceed: false,
|
|
1058
|
+
accountPatch: result.account
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
return {
|
|
1062
|
+
proceed: true,
|
|
1063
|
+
accountPatch: result.account,
|
|
1064
|
+
sessionId: patchResult.sessionId
|
|
1065
|
+
};
|
|
928
1066
|
}
|
|
929
|
-
return true;
|
|
1067
|
+
return { proceed: true };
|
|
930
1068
|
} catch (err) {
|
|
931
|
-
const floPayErr =
|
|
932
|
-
err instanceof Error ? err.message : "Card before-click hook failed.",
|
|
933
|
-
"validation_error"
|
|
934
|
-
);
|
|
1069
|
+
const floPayErr = normalizeBeforeButtonClickError(method, err);
|
|
935
1070
|
updateError(floPayErr.message);
|
|
936
1071
|
onError?.(floPayErr);
|
|
937
|
-
return false;
|
|
1072
|
+
return { proceed: false };
|
|
938
1073
|
}
|
|
939
|
-
}, [checkout.
|
|
1074
|
+
}, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
|
|
940
1075
|
const processPaymentInternal = useCallback(
|
|
941
|
-
async (tokenizedBody) => {
|
|
1076
|
+
async (tokenizedBody, overrides) => {
|
|
942
1077
|
if (processingRef.current) return;
|
|
943
1078
|
processingRef.current = true;
|
|
944
1079
|
setProcessing(true);
|
|
945
1080
|
setOverlayStatus("processing");
|
|
946
1081
|
updateError(null);
|
|
1082
|
+
const effectiveSessionId = overrides?.sessionId ?? sessionId;
|
|
1083
|
+
const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);
|
|
947
1084
|
try {
|
|
948
1085
|
const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
|
|
949
1086
|
method: "POST",
|
|
950
1087
|
headers: {
|
|
951
1088
|
"Content-Type": "application/json",
|
|
952
|
-
"x-user-id":
|
|
1089
|
+
"x-user-id": effectiveAccount.userId ?? ""
|
|
953
1090
|
},
|
|
954
1091
|
body: JSON.stringify({
|
|
955
|
-
sessionId,
|
|
1092
|
+
sessionId: effectiveSessionId,
|
|
956
1093
|
tokenizedData: tokenizedBody,
|
|
957
1094
|
accountData: {
|
|
958
|
-
userId:
|
|
959
|
-
email:
|
|
960
|
-
firstName:
|
|
961
|
-
lastName:
|
|
1095
|
+
userId: effectiveAccount.userId ?? "",
|
|
1096
|
+
email: effectiveAccount.email ?? "",
|
|
1097
|
+
firstName: effectiveAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
|
|
1098
|
+
lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
|
|
962
1099
|
...enableAVS ? { zip: zipCodeRef.current, country: selectedCountryRef.current } : {}
|
|
963
1100
|
},
|
|
964
1101
|
chv
|
|
@@ -1067,11 +1204,11 @@ function SplitCardFormInner({
|
|
|
1067
1204
|
[baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, onComplete, onError, updateError, emitDecline]
|
|
1068
1205
|
);
|
|
1069
1206
|
const dispatchTokenizedBody = useCallback(
|
|
1070
|
-
(tokenizedBody) => {
|
|
1207
|
+
(tokenizedBody, overrides) => {
|
|
1071
1208
|
if (onTokenizedBody) {
|
|
1072
1209
|
onTokenizedBody(tokenizedBody);
|
|
1073
1210
|
} else {
|
|
1074
|
-
processPaymentInternal(tokenizedBody);
|
|
1211
|
+
processPaymentInternal(tokenizedBody, overrides);
|
|
1075
1212
|
}
|
|
1076
1213
|
},
|
|
1077
1214
|
[onTokenizedBody, processPaymentInternal]
|
|
@@ -1498,6 +1635,7 @@ function SplitCardFormInner({
|
|
|
1498
1635
|
if (layout === "buttons") {
|
|
1499
1636
|
const isButtonsView = viewState === "buttons" || viewState === "expanding";
|
|
1500
1637
|
const isCardView = viewState === "expanding" || viewState === "card" || viewState === "collapsing";
|
|
1638
|
+
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
1501
1639
|
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
1640
|
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
1641
|
return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
@@ -1523,9 +1661,10 @@ function SplitCardFormInner({
|
|
|
1523
1661
|
onErrorChange: updateError,
|
|
1524
1662
|
isProcessing: isSubmitting,
|
|
1525
1663
|
onButtonClick,
|
|
1526
|
-
onDecline
|
|
1664
|
+
onDecline,
|
|
1665
|
+
runBeforeButtonClick
|
|
1527
1666
|
}
|
|
1528
|
-
) }) : showPayPal ? /* @__PURE__ */ jsx4("div", { style: { height:
|
|
1667
|
+
) }) : 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
1668
|
showWallets && stripeInstance ? /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx4(
|
|
1530
1669
|
WalletButtonInner,
|
|
1531
1670
|
{
|
|
@@ -1537,24 +1676,25 @@ function SplitCardFormInner({
|
|
|
1537
1676
|
onTokenizedBody: dispatchTokenizedBody,
|
|
1538
1677
|
onErrorChange: updateError,
|
|
1539
1678
|
onButtonClick,
|
|
1540
|
-
onDecline
|
|
1679
|
+
onDecline,
|
|
1680
|
+
runBeforeButtonClick
|
|
1541
1681
|
}
|
|
1542
|
-
) }) : showWallets ? /* @__PURE__ */ jsx4("div", { style: { height:
|
|
1682
|
+
) }) : 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
1683
|
/* @__PURE__ */ jsx4(
|
|
1544
1684
|
"button",
|
|
1545
1685
|
{
|
|
1546
1686
|
type: "button",
|
|
1547
1687
|
onClick: async () => {
|
|
1548
1688
|
if (isSubmitting) return;
|
|
1549
|
-
const
|
|
1550
|
-
if (!
|
|
1689
|
+
const beforeClick = await runBeforeButtonClick("card");
|
|
1690
|
+
if (!beforeClick.proceed) return;
|
|
1551
1691
|
onButtonClick?.("card");
|
|
1552
1692
|
expandToCard();
|
|
1553
1693
|
},
|
|
1554
1694
|
disabled: isSubmitting,
|
|
1555
1695
|
style: {
|
|
1556
1696
|
width: "100%",
|
|
1557
|
-
|
|
1697
|
+
...cardButtonSizing,
|
|
1558
1698
|
backgroundColor: "white",
|
|
1559
1699
|
color: "#262833",
|
|
1560
1700
|
border: "1px solid #d1d5db",
|
|
@@ -1653,6 +1793,7 @@ function SplitCardFormInner({
|
|
|
1653
1793
|
|
|
1654
1794
|
// src/flopay-checkout.tsx
|
|
1655
1795
|
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1796
|
+
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
1656
1797
|
function hasInlineSessionPatchData(patch) {
|
|
1657
1798
|
if (!patch) return false;
|
|
1658
1799
|
return Boolean(
|
|
@@ -1959,16 +2100,27 @@ function FloPayCheckout({
|
|
|
1959
2100
|
[fallbackPublishableKey, locale, resolvedBillingUrl]
|
|
1960
2101
|
);
|
|
1961
2102
|
const handleInlineSessionPatch = useCallback2(async (patch) => {
|
|
1962
|
-
if (!hasInlineSessionPatchData(patch) || cardBootstrapPending)
|
|
2103
|
+
if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
|
|
2104
|
+
return {
|
|
2105
|
+
sessionId: resolvedSessionId,
|
|
2106
|
+
session
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
1963
2109
|
setCardBootstrapPending(true);
|
|
1964
2110
|
try {
|
|
1965
|
-
await bootstrapInlineSession(patch);
|
|
2111
|
+
const resolved = await bootstrapInlineSession(patch);
|
|
2112
|
+
return {
|
|
2113
|
+
sessionId: resolved.sid,
|
|
2114
|
+
session: resolved.result.data.session ?? null
|
|
2115
|
+
};
|
|
1966
2116
|
} finally {
|
|
1967
2117
|
setCardBootstrapPending(false);
|
|
1968
2118
|
}
|
|
1969
2119
|
}, [
|
|
1970
2120
|
bootstrapInlineSession,
|
|
1971
|
-
cardBootstrapPending
|
|
2121
|
+
cardBootstrapPending,
|
|
2122
|
+
resolvedSessionId,
|
|
2123
|
+
session
|
|
1972
2124
|
]);
|
|
1973
2125
|
useEffect4(() => {
|
|
1974
2126
|
let cancelled = false;
|
|
@@ -2121,6 +2273,7 @@ function FloPayCheckout({
|
|
|
2121
2273
|
loading: isLoading,
|
|
2122
2274
|
error: loadError,
|
|
2123
2275
|
checkoutMode: currentMode,
|
|
2276
|
+
inlineSessionDraft: effectiveCreateSession,
|
|
2124
2277
|
applyInlineSessionPatch: shouldHandleInlineSessionPatch ? handleInlineSessionPatch : void 0,
|
|
2125
2278
|
inlineSessionPatchProcessing: cardBootstrapPending
|
|
2126
2279
|
}),
|
|
@@ -2129,6 +2282,7 @@ function FloPayCheckout({
|
|
|
2129
2282
|
isLoading,
|
|
2130
2283
|
loadError,
|
|
2131
2284
|
currentMode,
|
|
2285
|
+
effectiveCreateSession,
|
|
2132
2286
|
shouldHandleInlineSessionPatch,
|
|
2133
2287
|
handleInlineSessionPatch,
|
|
2134
2288
|
cardBootstrapPending
|
|
@@ -2145,9 +2299,9 @@ function FloPayCheckout({
|
|
|
2145
2299
|
animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
|
|
2146
2300
|
} });
|
|
2147
2301
|
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2148
|
-
showPayPal && skeletonBar(
|
|
2149
|
-
(showApplePay || showGooglePay) && skeletonBar(
|
|
2150
|
-
skeletonBar(
|
|
2302
|
+
showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2303
|
+
(showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2304
|
+
skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2151
2305
|
/* @__PURE__ */ jsx5("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
2152
2306
|
] });
|
|
2153
2307
|
}
|
|
@@ -2361,6 +2515,7 @@ function InterimButtonsView({
|
|
|
2361
2515
|
background: "#e5e7eb",
|
|
2362
2516
|
animation: "flopay-interim-pulse 1.5s ease-in-out infinite"
|
|
2363
2517
|
} });
|
|
2518
|
+
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
2364
2519
|
if (showCardForm) {
|
|
2365
2520
|
const inputBorder = bStyles.cardInputBorder ?? "#e5e7eb";
|
|
2366
2521
|
const inputBg = bStyles.cardInputBackground ?? "white";
|
|
@@ -2451,8 +2606,8 @@ function InterimButtonsView({
|
|
|
2451
2606
|
] });
|
|
2452
2607
|
}
|
|
2453
2608
|
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2454
|
-
showPayPal && skeleton(
|
|
2455
|
-
(showApplePay || showGooglePay) && skeleton(
|
|
2609
|
+
showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2610
|
+
(showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
2456
2611
|
/* @__PURE__ */ jsx5(
|
|
2457
2612
|
"button",
|
|
2458
2613
|
{
|
|
@@ -2469,7 +2624,7 @@ function InterimButtonsView({
|
|
|
2469
2624
|
disabled: cardLoading,
|
|
2470
2625
|
style: {
|
|
2471
2626
|
width: "100%",
|
|
2472
|
-
|
|
2627
|
+
...cardButtonSizing,
|
|
2473
2628
|
backgroundColor: "white",
|
|
2474
2629
|
color: "#262833",
|
|
2475
2630
|
border: "1px solid #d1d5db",
|