@flopay/react 0.5.13 → 0.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +45 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -9
- package/dist/index.d.ts +38 -9
- package/dist/index.mjs +74 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -579,8 +579,10 @@ declare function FloPayAutomaticPaymentButton({ sessionId, createSession, paymen
|
|
|
579
579
|
interface InAppBrowserNoticeProps {
|
|
580
580
|
/** Custom message override. Defaults to a generic, non-platform-specific copy. */
|
|
581
581
|
message?: React.ReactNode;
|
|
582
|
-
/** Custom button label.
|
|
582
|
+
/** Custom button label. Default depends on the detected environment:
|
|
583
|
+
* in-app browser → "Copy link"; other → "Open in browser". */
|
|
583
584
|
openButtonLabel?: string;
|
|
585
|
+
/** Custom copied-state button label. Default depends on environment. */
|
|
584
586
|
copiedButtonLabel?: string;
|
|
585
587
|
/** Custom CSS overrides for the container, message, and button. */
|
|
586
588
|
containerStyle?: React.CSSProperties;
|
|
@@ -596,16 +598,43 @@ interface InAppBrowserNoticeProps {
|
|
|
596
598
|
* — typically because the buyer is in an in-app browser (Instagram, Facebook,
|
|
597
599
|
* TikTok, etc.) or behind an ad-blocker. The card form remains fully
|
|
598
600
|
* functional; this notice just informs the buyer about the unavailable
|
|
599
|
-
* methods and
|
|
601
|
+
* methods and gives them a way to escape to a real browser.
|
|
600
602
|
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
* - Falls back to copying the URL to clipboard so the buyer can paste it
|
|
604
|
-
* into Safari/Chrome themselves.
|
|
603
|
+
* Action behavior is environment-dependent because `window.open` is a known
|
|
604
|
+
* liar inside in-app WebViews:
|
|
605
605
|
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
606
|
+
* - **Detected in-app browser** (Facebook/Instagram/TikTok/etc. via UA):
|
|
607
|
+
* skip `window.open` entirely. It returns a non-null window but the new
|
|
608
|
+
* page opens *inside the same WebView*, which defeats the entire point
|
|
609
|
+
* and makes us mis-report `opened: true` to `onOpenInBrowser`. Instead,
|
|
610
|
+
* copy the URL to clipboard and surface clear paste-in-Safari/Chrome
|
|
611
|
+
* messaging. There is no reliable cross-platform JS API to force a
|
|
612
|
+
* WebView to defer to the system browser; the buyer must use the host
|
|
613
|
+
* app's "..." / "⋮" menu.
|
|
614
|
+
* - **Other environments** (desktop with ad-blocker, unknown UA):
|
|
615
|
+
* `window.open` may genuinely succeed — try it, fall back to clipboard.
|
|
608
616
|
*/
|
|
609
617
|
declare function InAppBrowserNotice({ message, openButtonLabel, copiedButtonLabel, containerStyle, buttonStyle, onOpenInBrowser, }: InAppBrowserNoticeProps): react_jsx_runtime.JSX.Element;
|
|
610
618
|
|
|
611
|
-
|
|
619
|
+
/**
|
|
620
|
+
* Heuristic detector for in-app browser / WebView environments where PayPal
|
|
621
|
+
* and digital wallets often fail to initialize.
|
|
622
|
+
*
|
|
623
|
+
* Pairs with the load-state classifier in `SplitCardForm`: this gives us a
|
|
624
|
+
* proactive signal (we know we're in a hostile environment before Stripe
|
|
625
|
+
* even tries), while load state covers the long tail (ad-blockers, new
|
|
626
|
+
* WebViews we haven't seen, account-misconfig surfacing as `unavailable`).
|
|
627
|
+
*
|
|
628
|
+
* Tradeoffs:
|
|
629
|
+
* - False positives possible. Some modern WebViews (iOS SFSafariViewController
|
|
630
|
+
* on recent iOS, Chrome Custom Tabs) handle PayPal fine but match these
|
|
631
|
+
* patterns. The notice is non-disruptive — card form keeps working — so we
|
|
632
|
+
* accept it.
|
|
633
|
+
* - False negatives possible. New social-app WebViews ship without us knowing.
|
|
634
|
+
* That's why we also keep the reactive load-state signal.
|
|
635
|
+
*
|
|
636
|
+
* SSR-safe: returns `false` when `navigator` is undefined.
|
|
637
|
+
*/
|
|
638
|
+
declare function isInAppBrowser(userAgent?: string): boolean;
|
|
639
|
+
|
|
640
|
+
export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, InAppBrowserNotice, type InAppBrowserNoticeProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, isInAppBrowser, useCheckout, useElements, useFloPay, usePayPalFloPay };
|
package/dist/index.d.ts
CHANGED
|
@@ -579,8 +579,10 @@ declare function FloPayAutomaticPaymentButton({ sessionId, createSession, paymen
|
|
|
579
579
|
interface InAppBrowserNoticeProps {
|
|
580
580
|
/** Custom message override. Defaults to a generic, non-platform-specific copy. */
|
|
581
581
|
message?: React.ReactNode;
|
|
582
|
-
/** Custom button label.
|
|
582
|
+
/** Custom button label. Default depends on the detected environment:
|
|
583
|
+
* in-app browser → "Copy link"; other → "Open in browser". */
|
|
583
584
|
openButtonLabel?: string;
|
|
585
|
+
/** Custom copied-state button label. Default depends on environment. */
|
|
584
586
|
copiedButtonLabel?: string;
|
|
585
587
|
/** Custom CSS overrides for the container, message, and button. */
|
|
586
588
|
containerStyle?: React.CSSProperties;
|
|
@@ -596,16 +598,43 @@ interface InAppBrowserNoticeProps {
|
|
|
596
598
|
* — typically because the buyer is in an in-app browser (Instagram, Facebook,
|
|
597
599
|
* TikTok, etc.) or behind an ad-blocker. The card form remains fully
|
|
598
600
|
* functional; this notice just informs the buyer about the unavailable
|
|
599
|
-
* methods and
|
|
601
|
+
* methods and gives them a way to escape to a real browser.
|
|
600
602
|
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
* - Falls back to copying the URL to clipboard so the buyer can paste it
|
|
604
|
-
* into Safari/Chrome themselves.
|
|
603
|
+
* Action behavior is environment-dependent because `window.open` is a known
|
|
604
|
+
* liar inside in-app WebViews:
|
|
605
605
|
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
606
|
+
* - **Detected in-app browser** (Facebook/Instagram/TikTok/etc. via UA):
|
|
607
|
+
* skip `window.open` entirely. It returns a non-null window but the new
|
|
608
|
+
* page opens *inside the same WebView*, which defeats the entire point
|
|
609
|
+
* and makes us mis-report `opened: true` to `onOpenInBrowser`. Instead,
|
|
610
|
+
* copy the URL to clipboard and surface clear paste-in-Safari/Chrome
|
|
611
|
+
* messaging. There is no reliable cross-platform JS API to force a
|
|
612
|
+
* WebView to defer to the system browser; the buyer must use the host
|
|
613
|
+
* app's "..." / "⋮" menu.
|
|
614
|
+
* - **Other environments** (desktop with ad-blocker, unknown UA):
|
|
615
|
+
* `window.open` may genuinely succeed — try it, fall back to clipboard.
|
|
608
616
|
*/
|
|
609
617
|
declare function InAppBrowserNotice({ message, openButtonLabel, copiedButtonLabel, containerStyle, buttonStyle, onOpenInBrowser, }: InAppBrowserNoticeProps): react_jsx_runtime.JSX.Element;
|
|
610
618
|
|
|
611
|
-
|
|
619
|
+
/**
|
|
620
|
+
* Heuristic detector for in-app browser / WebView environments where PayPal
|
|
621
|
+
* and digital wallets often fail to initialize.
|
|
622
|
+
*
|
|
623
|
+
* Pairs with the load-state classifier in `SplitCardForm`: this gives us a
|
|
624
|
+
* proactive signal (we know we're in a hostile environment before Stripe
|
|
625
|
+
* even tries), while load state covers the long tail (ad-blockers, new
|
|
626
|
+
* WebViews we haven't seen, account-misconfig surfacing as `unavailable`).
|
|
627
|
+
*
|
|
628
|
+
* Tradeoffs:
|
|
629
|
+
* - False positives possible. Some modern WebViews (iOS SFSafariViewController
|
|
630
|
+
* on recent iOS, Chrome Custom Tabs) handle PayPal fine but match these
|
|
631
|
+
* patterns. The notice is non-disruptive — card form keeps working — so we
|
|
632
|
+
* accept it.
|
|
633
|
+
* - False negatives possible. New social-app WebViews ship without us knowing.
|
|
634
|
+
* That's why we also keep the reactive load-state signal.
|
|
635
|
+
*
|
|
636
|
+
* SSR-safe: returns `false` when `navigator` is undefined.
|
|
637
|
+
*/
|
|
638
|
+
declare function isInAppBrowser(userAgent?: string): boolean;
|
|
639
|
+
|
|
640
|
+
export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, InAppBrowserNotice, type InAppBrowserNoticeProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, isInAppBrowser, useCheckout, useElements, useFloPay, usePayPalFloPay };
|
package/dist/index.mjs
CHANGED
|
@@ -100,7 +100,7 @@ function FloPayProvider({
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// src/flopay-checkout.tsx
|
|
103
|
-
import React7, { useCallback as useCallback3, useEffect as
|
|
103
|
+
import React7, { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
104
104
|
import { PaymentAPI as PaymentAPI2 } from "@flopay/js";
|
|
105
105
|
import { SDK_VERSION, FloPayError as FloPayError4, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2 } from "@flopay/shared";
|
|
106
106
|
|
|
@@ -248,7 +248,7 @@ import {
|
|
|
248
248
|
isAVSFieldVisible,
|
|
249
249
|
getStateFromPostalCode
|
|
250
250
|
} from "@flopay/shared";
|
|
251
|
-
import { forwardRef, useCallback as useCallback2, useContext as useContext3, useEffect as
|
|
251
|
+
import { forwardRef, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
|
|
252
252
|
|
|
253
253
|
// src/hooks.ts
|
|
254
254
|
import { useContext as useContext2 } from "react";
|
|
@@ -622,27 +622,54 @@ function wasSessionRecentlyCompleted(sessionId) {
|
|
|
622
622
|
}
|
|
623
623
|
|
|
624
624
|
// src/in-app-browser-notice.tsx
|
|
625
|
-
import { useCallback, useState as useState2 } from "react";
|
|
625
|
+
import { useCallback, useEffect as useEffect3, useState as useState2 } from "react";
|
|
626
|
+
|
|
627
|
+
// src/in-app-browser.ts
|
|
628
|
+
function isInAppBrowser(userAgent) {
|
|
629
|
+
const ua = userAgent ?? (typeof navigator !== "undefined" ? navigator.userAgent : "");
|
|
630
|
+
if (!ua) return false;
|
|
631
|
+
if (/FBAN|FBAV|FB_IAB|FBIOS|Instagram|musical_ly|BytedanceWebview|TikTok/i.test(ua)) {
|
|
632
|
+
return true;
|
|
633
|
+
}
|
|
634
|
+
if (/Twitter|Snapchat|Pinterest|LinkedInApp|Line\/|MicroMessenger|GSA\//i.test(ua)) {
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
if (/Android.*;\s?wv\)/.test(ua)) return true;
|
|
638
|
+
if (/(iPhone|iPad|iPod).*AppleWebKit(?!.*Safari)/.test(ua)) return true;
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// src/in-app-browser-notice.tsx
|
|
626
643
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
627
644
|
var DEFAULT_MESSAGE = "PayPal and some digital wallets aren't supported in this browser. Open this page in your device's browser to use them.";
|
|
628
645
|
function InAppBrowserNotice({
|
|
629
646
|
message,
|
|
630
|
-
openButtonLabel
|
|
631
|
-
copiedButtonLabel
|
|
647
|
+
openButtonLabel,
|
|
648
|
+
copiedButtonLabel,
|
|
632
649
|
containerStyle,
|
|
633
650
|
buttonStyle,
|
|
634
651
|
onOpenInBrowser
|
|
635
652
|
}) {
|
|
636
653
|
const [copied, setCopied] = useState2(false);
|
|
654
|
+
const [inAppBrowser, setInAppBrowser] = useState2(false);
|
|
655
|
+
useEffect3(() => {
|
|
656
|
+
setInAppBrowser(isInAppBrowser());
|
|
657
|
+
}, []);
|
|
658
|
+
const defaultOpenLabel = inAppBrowser ? "Copy link" : "Open in browser";
|
|
659
|
+
const defaultCopiedLabel = inAppBrowser ? "Link copied \u2014 open Safari/Chrome and paste" : "Link copied \u2014 paste in your browser";
|
|
660
|
+
const effectiveOpenLabel = openButtonLabel ?? defaultOpenLabel;
|
|
661
|
+
const effectiveCopiedLabel = copiedButtonLabel ?? defaultCopiedLabel;
|
|
637
662
|
const handleClick = useCallback(async () => {
|
|
638
663
|
if (typeof window === "undefined") return;
|
|
639
664
|
const url = window.location.href;
|
|
640
665
|
let opened = false;
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
666
|
+
if (!inAppBrowser) {
|
|
667
|
+
try {
|
|
668
|
+
const win = window.open(url, "_blank");
|
|
669
|
+
opened = !!win;
|
|
670
|
+
} catch {
|
|
671
|
+
opened = false;
|
|
672
|
+
}
|
|
646
673
|
}
|
|
647
674
|
let didCopy = false;
|
|
648
675
|
if (!opened) {
|
|
@@ -657,13 +684,14 @@ function InAppBrowserNotice({
|
|
|
657
684
|
}
|
|
658
685
|
}
|
|
659
686
|
onOpenInBrowser?.({ opened, copied: didCopy });
|
|
660
|
-
}, [onOpenInBrowser]);
|
|
687
|
+
}, [inAppBrowser, onOpenInBrowser]);
|
|
661
688
|
return /* @__PURE__ */ jsxs3(
|
|
662
689
|
"div",
|
|
663
690
|
{
|
|
664
691
|
role: "status",
|
|
665
692
|
"data-testid": "flopay-in-app-browser-notice",
|
|
666
693
|
style: {
|
|
694
|
+
marginTop: "0.75rem",
|
|
667
695
|
padding: "0.75rem 0.875rem",
|
|
668
696
|
background: "#FFFBEB",
|
|
669
697
|
border: "1px solid #FDE68A",
|
|
@@ -695,7 +723,7 @@ function InAppBrowserNotice({
|
|
|
695
723
|
cursor: "pointer",
|
|
696
724
|
...buttonStyle
|
|
697
725
|
},
|
|
698
|
-
children: copied ?
|
|
726
|
+
children: copied ? effectiveCopiedLabel : effectiveOpenLabel
|
|
699
727
|
}
|
|
700
728
|
)
|
|
701
729
|
]
|
|
@@ -824,17 +852,17 @@ function PayPalButtonInner({
|
|
|
824
852
|
const elements = useStripeElements();
|
|
825
853
|
const [loadState, setLoadState] = useState3("loading");
|
|
826
854
|
const onLoadStateChangeRef = useRef2(onLoadStateChange);
|
|
827
|
-
|
|
855
|
+
useEffect4(() => {
|
|
828
856
|
onLoadStateChangeRef.current = onLoadStateChange;
|
|
829
857
|
}, [onLoadStateChange]);
|
|
830
|
-
|
|
858
|
+
useEffect4(() => {
|
|
831
859
|
onLoadStateChangeRef.current?.(loadState);
|
|
832
860
|
}, [loadState]);
|
|
833
861
|
const [submitting, setSubmitting] = useState3(false);
|
|
834
862
|
const paypalResumeAttempted = useRef2(false);
|
|
835
863
|
const beforeClickRef = useRef2(null);
|
|
836
864
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
837
|
-
|
|
865
|
+
useEffect4(() => {
|
|
838
866
|
if (!stripe || paypalResumeAttempted.current) return;
|
|
839
867
|
const params = new URLSearchParams(window.location.search);
|
|
840
868
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -1037,10 +1065,10 @@ function WalletButtonInner({
|
|
|
1037
1065
|
const elements = useStripeElements();
|
|
1038
1066
|
const [loadState, setLoadState] = useState3("loading");
|
|
1039
1067
|
const onLoadStateChangeRef = useRef2(onLoadStateChange);
|
|
1040
|
-
|
|
1068
|
+
useEffect4(() => {
|
|
1041
1069
|
onLoadStateChangeRef.current = onLoadStateChange;
|
|
1042
1070
|
}, [onLoadStateChange]);
|
|
1043
|
-
|
|
1071
|
+
useEffect4(() => {
|
|
1044
1072
|
onLoadStateChangeRef.current?.(loadState);
|
|
1045
1073
|
}, [loadState]);
|
|
1046
1074
|
const [submitting, setSubmitting] = useState3(false);
|
|
@@ -1264,7 +1292,7 @@ function SplitCardFormInner({
|
|
|
1264
1292
|
setViewState("collapsing");
|
|
1265
1293
|
setTimeout(() => setViewState("buttons"), TRANSITION_MS);
|
|
1266
1294
|
}, []);
|
|
1267
|
-
|
|
1295
|
+
useEffect4(() => {
|
|
1268
1296
|
if (layout === "buttons" && initialCardOpen) {
|
|
1269
1297
|
setViewState("card");
|
|
1270
1298
|
}
|
|
@@ -1340,11 +1368,15 @@ function SplitCardFormInner({
|
|
|
1340
1368
|
const showWallets = showApplePay || showGooglePay;
|
|
1341
1369
|
const [paypalLoadState, setPaypalLoadState] = useState3("loading");
|
|
1342
1370
|
const [walletLoadState, setWalletLoadState] = useState3("loading");
|
|
1371
|
+
const [inAppBrowserDetected, setInAppBrowserDetected] = useState3(false);
|
|
1372
|
+
useEffect4(() => {
|
|
1373
|
+
setInAppBrowserDetected(isInAppBrowser());
|
|
1374
|
+
}, []);
|
|
1343
1375
|
const expectedPayPal = showPayPal && !!paypalStripeInstance;
|
|
1344
1376
|
const expectedWallets = showWallets && !!stripeInstance;
|
|
1345
|
-
const paypalLoadFailed = expectedPayPal && paypalLoadState === "load_error";
|
|
1377
|
+
const paypalLoadFailed = expectedPayPal && (paypalLoadState === "load_error" || paypalLoadState === "unavailable");
|
|
1346
1378
|
const walletsLoadFailed = expectedWallets && walletLoadState === "load_error";
|
|
1347
|
-
const showInAppBrowserNotice = (expectedPayPal || expectedWallets) && (
|
|
1379
|
+
const showInAppBrowserNotice = (expectedPayPal || expectedWallets) && (inAppBrowserDetected || paypalLoadFailed || walletsLoadFailed);
|
|
1348
1380
|
const handleNameChange = useCallback2((value) => {
|
|
1349
1381
|
setFullName(value);
|
|
1350
1382
|
onFullNameChange?.(value);
|
|
@@ -1632,7 +1664,7 @@ function SplitCardFormInner({
|
|
|
1632
1664
|
}
|
|
1633
1665
|
}
|
|
1634
1666
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
1635
|
-
|
|
1667
|
+
useEffect4(() => {
|
|
1636
1668
|
if (typeof window === "undefined") return;
|
|
1637
1669
|
const stored = localStorage.getItem(WALLET_RESUME_KEY);
|
|
1638
1670
|
if (!stored) return;
|
|
@@ -3031,7 +3063,7 @@ function FloPayCheckout({
|
|
|
3031
3063
|
onDeclineRef.current = onDecline;
|
|
3032
3064
|
const onSessionCompletedRef = useRef3(onSessionCompleted);
|
|
3033
3065
|
onSessionCompletedRef.current = onSessionCompleted;
|
|
3034
|
-
|
|
3066
|
+
useEffect5(() => {
|
|
3035
3067
|
console.info("[FloPay] Checkout initialized", {
|
|
3036
3068
|
sdk_version: SDK_VERSION,
|
|
3037
3069
|
checkout_type: checkoutType,
|
|
@@ -3059,11 +3091,11 @@ function FloPayCheckout({
|
|
|
3059
3091
|
} : void 0,
|
|
3060
3092
|
[effectiveCreateSessionBase, effectiveCreateSessionMode]
|
|
3061
3093
|
);
|
|
3062
|
-
|
|
3094
|
+
useEffect5(() => {
|
|
3063
3095
|
setCreateSessionPatch(void 0);
|
|
3064
3096
|
setCreateSessionPatchBaseHash(baseCreateSessionHash);
|
|
3065
3097
|
}, [baseCreateSessionHash]);
|
|
3066
|
-
|
|
3098
|
+
useEffect5(() => {
|
|
3067
3099
|
setModeError(initialErrorMessage);
|
|
3068
3100
|
}, [initialErrorMessage]);
|
|
3069
3101
|
const emitDecline = useCallback3(
|
|
@@ -3179,7 +3211,7 @@ function FloPayCheckout({
|
|
|
3179
3211
|
resolvedBillingUrl
|
|
3180
3212
|
]
|
|
3181
3213
|
);
|
|
3182
|
-
|
|
3214
|
+
useEffect5(() => {
|
|
3183
3215
|
if (typeof window === "undefined" || paypalResumeAttempted.current) {
|
|
3184
3216
|
return;
|
|
3185
3217
|
}
|
|
@@ -3326,10 +3358,10 @@ function FloPayCheckout({
|
|
|
3326
3358
|
);
|
|
3327
3359
|
const createSessionParamsRef = useRef3(effectiveCreateSession);
|
|
3328
3360
|
createSessionParamsRef.current = effectiveCreateSession;
|
|
3329
|
-
|
|
3361
|
+
useEffect5(() => {
|
|
3330
3362
|
setResolvedSessionId(sessionIdProp ?? "");
|
|
3331
3363
|
}, [sessionIdProp]);
|
|
3332
|
-
|
|
3364
|
+
useEffect5(() => {
|
|
3333
3365
|
autoCheckoutAttempted.current = false;
|
|
3334
3366
|
setModeError(initialErrorMessage);
|
|
3335
3367
|
setModeOverlayError(null);
|
|
@@ -3456,7 +3488,7 @@ function FloPayCheckout({
|
|
|
3456
3488
|
resolvedSessionId,
|
|
3457
3489
|
session
|
|
3458
3490
|
]);
|
|
3459
|
-
|
|
3491
|
+
useEffect5(() => {
|
|
3460
3492
|
let cancelled = false;
|
|
3461
3493
|
setLoadError(null);
|
|
3462
3494
|
if (createSessionHash) {
|
|
@@ -3902,7 +3934,7 @@ function InterimButtonsView({
|
|
|
3902
3934
|
}) {
|
|
3903
3935
|
const [showCardForm, setShowCardForm] = useState4(false);
|
|
3904
3936
|
const isCardOpenControlled = typeof cardOpen === "boolean";
|
|
3905
|
-
|
|
3937
|
+
useEffect5(() => {
|
|
3906
3938
|
if (isCardOpenControlled) {
|
|
3907
3939
|
setShowCardForm(cardOpen);
|
|
3908
3940
|
}
|
|
@@ -4086,7 +4118,7 @@ function InterimButtonsView({
|
|
|
4086
4118
|
|
|
4087
4119
|
// src/checkout-form.tsx
|
|
4088
4120
|
import { FloPayError as FloPayError5 } from "@flopay/shared";
|
|
4089
|
-
import { forwardRef as forwardRef2, useCallback as useCallback4, useEffect as
|
|
4121
|
+
import { forwardRef as forwardRef2, useCallback as useCallback4, useEffect as useEffect6, useImperativeHandle as useImperativeHandle2, useState as useState5 } from "react";
|
|
4090
4122
|
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4091
4123
|
var WALLET_RESUME_KEY2 = "flopay_wallet_resume";
|
|
4092
4124
|
var CheckoutForm = forwardRef2(
|
|
@@ -4294,7 +4326,7 @@ function CheckoutFormInner({
|
|
|
4294
4326
|
}
|
|
4295
4327
|
}
|
|
4296
4328
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
4297
|
-
|
|
4329
|
+
useEffect6(() => {
|
|
4298
4330
|
if (typeof window === "undefined") return;
|
|
4299
4331
|
const stored = localStorage.getItem(WALLET_RESUME_KEY2);
|
|
4300
4332
|
if (!stored) return;
|
|
@@ -4432,7 +4464,7 @@ function CheckoutFormInner({
|
|
|
4432
4464
|
|
|
4433
4465
|
// src/paypal-button.tsx
|
|
4434
4466
|
import { FloPayError as FloPayError6 } from "@flopay/shared";
|
|
4435
|
-
import { useCallback as useCallback5, useEffect as
|
|
4467
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef4, useState as useState6 } from "react";
|
|
4436
4468
|
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4437
4469
|
function PayPalButton({
|
|
4438
4470
|
sessionId,
|
|
@@ -4497,7 +4529,7 @@ function PayPalButton({
|
|
|
4497
4529
|
},
|
|
4498
4530
|
[onTokenizedBody, processPaymentInternal]
|
|
4499
4531
|
);
|
|
4500
|
-
|
|
4532
|
+
useEffect7(() => {
|
|
4501
4533
|
if (!flopay || paypalResumeAttempted.current) return;
|
|
4502
4534
|
const params = new URLSearchParams(window.location.search);
|
|
4503
4535
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -4624,7 +4656,7 @@ function PayPalButton({
|
|
|
4624
4656
|
}
|
|
4625
4657
|
|
|
4626
4658
|
// src/automatic-payment-button.tsx
|
|
4627
|
-
import { useCallback as useCallback6, useEffect as
|
|
4659
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
|
|
4628
4660
|
import { PaymentAPI as PaymentAPI3 } from "@flopay/js";
|
|
4629
4661
|
import { FloPayError as FloPayError7, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3 } from "@flopay/shared";
|
|
4630
4662
|
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -4792,25 +4824,25 @@ function FloPayAutomaticPaymentButton({
|
|
|
4792
4824
|
const onSuccessRef = useRef5(onSuccess);
|
|
4793
4825
|
const onErrorRef = useRef5(onError);
|
|
4794
4826
|
const onDeclineRef = useRef5(onDecline);
|
|
4795
|
-
|
|
4827
|
+
useEffect8(() => {
|
|
4796
4828
|
fallbackSessionRef.current = fallbackSession;
|
|
4797
4829
|
}, [fallbackSession]);
|
|
4798
|
-
|
|
4830
|
+
useEffect8(() => {
|
|
4799
4831
|
onSuccessRef.current = onSuccess;
|
|
4800
4832
|
}, [onSuccess]);
|
|
4801
|
-
|
|
4833
|
+
useEffect8(() => {
|
|
4802
4834
|
onErrorRef.current = onError;
|
|
4803
4835
|
}, [onError]);
|
|
4804
|
-
|
|
4836
|
+
useEffect8(() => {
|
|
4805
4837
|
onDeclineRef.current = onDecline;
|
|
4806
4838
|
}, [onDecline]);
|
|
4807
|
-
|
|
4839
|
+
useEffect8(() => {
|
|
4808
4840
|
isMountedRef.current = true;
|
|
4809
4841
|
return () => {
|
|
4810
4842
|
isMountedRef.current = false;
|
|
4811
4843
|
};
|
|
4812
4844
|
}, []);
|
|
4813
|
-
|
|
4845
|
+
useEffect8(() => {
|
|
4814
4846
|
if (!fallbackSession || typeof window === "undefined") {
|
|
4815
4847
|
return;
|
|
4816
4848
|
}
|
|
@@ -5141,7 +5173,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5141
5173
|
const handleFallbackDecline = useCallback6((decline) => {
|
|
5142
5174
|
onDeclineRef.current?.(decline);
|
|
5143
5175
|
}, []);
|
|
5144
|
-
|
|
5176
|
+
useEffect8(() => {
|
|
5145
5177
|
if (typeof window === "undefined" || resumeAttemptedRef.current) {
|
|
5146
5178
|
return;
|
|
5147
5179
|
}
|
|
@@ -5405,6 +5437,7 @@ export {
|
|
|
5405
5437
|
PayPalButton,
|
|
5406
5438
|
PaymentElement,
|
|
5407
5439
|
SplitCardForm,
|
|
5440
|
+
isInAppBrowser,
|
|
5408
5441
|
useCheckout,
|
|
5409
5442
|
useElements,
|
|
5410
5443
|
useFloPay,
|