@flopay/react 0.3.19 → 0.4.0

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.d.cts CHANGED
@@ -8,6 +8,12 @@ export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessi
8
8
  interface FloPayProviderProps {
9
9
  /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */
10
10
  flopay: Promise<FloPay> | FloPay;
11
+ /**
12
+ * Optional dedicated `FloPay` instance for PayPal, loaded with
13
+ * `gatewayData.paypalPublishableKey`. When omitted or `null`, PayPal is
14
+ * disabled (the button is not rendered).
15
+ */
16
+ paypalFlopay?: Promise<FloPay> | FloPay | null;
11
17
  /** Optional configuration applied when creating the elements group. */
12
18
  options?: {
13
19
  locale?: string;
@@ -35,7 +41,7 @@ interface FloPayProviderProps {
35
41
  * </FloPayProvider>
36
42
  * ```
37
43
  */
38
- declare function FloPayProvider({ flopay: floPayProp, options, children, }: FloPayProviderProps): React.ReactElement;
44
+ declare function FloPayProvider({ flopay: floPayProp, paypalFlopay: paypalFloPayProp, options, children, }: FloPayProviderProps): React.ReactElement;
39
45
 
40
46
  /** Props for the all-in-one `FloPayCheckout` wrapper. */
41
47
  interface FloPayCheckoutProps {
@@ -167,6 +173,14 @@ declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: creat
167
173
  * Must be called within a `<FloPayProvider>`.
168
174
  */
169
175
  declare function useFloPay(): FloPay | null;
176
+ /**
177
+ * Returns the dedicated PayPal `FloPay` instance (loaded with
178
+ * `gatewayData.paypalPublishableKey`), or `null` if PayPal is disabled
179
+ * for this session.
180
+ *
181
+ * Must be called within a `<FloPayProvider>`.
182
+ */
183
+ declare function usePayPalFloPay(): FloPay | null;
170
184
  /**
171
185
  * Returns the current `FloPayElements` instance, or `null` if the
172
186
  * provider is still loading.
@@ -507,4 +521,4 @@ interface PayPalButtonProps {
507
521
  */
508
522
  declare function PayPalButton({ sessionId, billingApiUrl, email, userId, firstName, lastName, chv, onTokenizedBody, onComplete, onErrorChange, isProcessing, }: PayPalButtonProps): React.ReactElement;
509
523
 
510
- export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, useCheckout, useElements, useFloPay };
524
+ export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, useCheckout, useElements, useFloPay, usePayPalFloPay };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,12 @@ export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessi
8
8
  interface FloPayProviderProps {
9
9
  /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */
10
10
  flopay: Promise<FloPay> | FloPay;
11
+ /**
12
+ * Optional dedicated `FloPay` instance for PayPal, loaded with
13
+ * `gatewayData.paypalPublishableKey`. When omitted or `null`, PayPal is
14
+ * disabled (the button is not rendered).
15
+ */
16
+ paypalFlopay?: Promise<FloPay> | FloPay | null;
11
17
  /** Optional configuration applied when creating the elements group. */
12
18
  options?: {
13
19
  locale?: string;
@@ -35,7 +41,7 @@ interface FloPayProviderProps {
35
41
  * </FloPayProvider>
36
42
  * ```
37
43
  */
38
- declare function FloPayProvider({ flopay: floPayProp, options, children, }: FloPayProviderProps): React.ReactElement;
44
+ declare function FloPayProvider({ flopay: floPayProp, paypalFlopay: paypalFloPayProp, options, children, }: FloPayProviderProps): React.ReactElement;
39
45
 
40
46
  /** Props for the all-in-one `FloPayCheckout` wrapper. */
41
47
  interface FloPayCheckoutProps {
@@ -167,6 +173,14 @@ declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: creat
167
173
  * Must be called within a `<FloPayProvider>`.
168
174
  */
169
175
  declare function useFloPay(): FloPay | null;
176
+ /**
177
+ * Returns the dedicated PayPal `FloPay` instance (loaded with
178
+ * `gatewayData.paypalPublishableKey`), or `null` if PayPal is disabled
179
+ * for this session.
180
+ *
181
+ * Must be called within a `<FloPayProvider>`.
182
+ */
183
+ declare function usePayPalFloPay(): FloPay | null;
170
184
  /**
171
185
  * Returns the current `FloPayElements` instance, or `null` if the
172
186
  * provider is still loading.
@@ -507,4 +521,4 @@ interface PayPalButtonProps {
507
521
  */
508
522
  declare function PayPalButton({ sessionId, billingApiUrl, email, userId, firstName, lastName, chv, onTokenizedBody, onComplete, onErrorChange, isProcessing, }: PayPalButtonProps): React.ReactElement;
509
523
 
510
- export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, useCheckout, useElements, useFloPay };
524
+ export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, type ElementComponentProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, useCheckout, useElements, useFloPay, usePayPalFloPay };
package/dist/index.mjs CHANGED
@@ -6,6 +6,7 @@ import { resolveBillingApiUrl } from "@flopay/shared";
6
6
  import { createContext } from "react";
7
7
  var FloPayContext = createContext({
8
8
  flopay: null,
9
+ paypalFlopay: null,
9
10
  elements: null,
10
11
  billingApiUrl: ""
11
12
  });
@@ -19,12 +20,16 @@ var CheckoutContext = createContext({
19
20
  import { jsx } from "react/jsx-runtime";
20
21
  function FloPayProvider({
21
22
  flopay: floPayProp,
23
+ paypalFlopay: paypalFloPayProp,
22
24
  options,
23
25
  children
24
26
  }) {
25
27
  const [flopay, setFloPay] = useState(
26
28
  floPayProp instanceof Promise ? null : floPayProp
27
29
  );
30
+ const [paypalFlopay, setPaypalFloPay] = useState(
31
+ paypalFloPayProp instanceof Promise || !paypalFloPayProp ? null : paypalFloPayProp
32
+ );
28
33
  const [elements, setElements] = useState(null);
29
34
  useEffect(() => {
30
35
  let cancelled = false;
@@ -41,6 +46,25 @@ function FloPayProvider({
41
46
  cancelled = true;
42
47
  };
43
48
  }, [floPayProp]);
49
+ useEffect(() => {
50
+ let cancelled = false;
51
+ if (!paypalFloPayProp) {
52
+ setPaypalFloPay(null);
53
+ return;
54
+ }
55
+ if (paypalFloPayProp instanceof Promise) {
56
+ paypalFloPayProp.then((instance) => {
57
+ if (!cancelled) {
58
+ setPaypalFloPay(instance);
59
+ }
60
+ });
61
+ } else {
62
+ setPaypalFloPay(paypalFloPayProp);
63
+ }
64
+ return () => {
65
+ cancelled = true;
66
+ };
67
+ }, [paypalFloPayProp]);
44
68
  useEffect(() => {
45
69
  if (!flopay) {
46
70
  setElements(null);
@@ -60,8 +84,8 @@ function FloPayProvider({
60
84
  }, [flopay, options?.appearance, options?.clientSecret, options?.amount, options?.currency]);
61
85
  const resolvedBillingApiUrl = resolveBillingApiUrl(options?.billingApiUrl);
62
86
  const value = useMemo(
63
- () => ({ flopay, elements, billingApiUrl: resolvedBillingApiUrl }),
64
- [flopay, elements, resolvedBillingApiUrl]
87
+ () => ({ flopay, paypalFlopay, elements, billingApiUrl: resolvedBillingApiUrl }),
88
+ [flopay, paypalFlopay, elements, resolvedBillingApiUrl]
65
89
  );
66
90
  return /* @__PURE__ */ jsx(FloPayContext.Provider, { value, children });
67
91
  }
@@ -215,6 +239,10 @@ function useFloPay() {
215
239
  const ctx = useContext2(FloPayContext);
216
240
  return ctx.flopay;
217
241
  }
242
+ function usePayPalFloPay() {
243
+ const ctx = useContext2(FloPayContext);
244
+ return ctx.paypalFlopay ?? null;
245
+ }
218
246
  function useElements() {
219
247
  const ctx = useContext2(FloPayContext);
220
248
  return ctx.elements;
@@ -601,7 +629,7 @@ function PayPalButtonInner({
601
629
  event.reject();
602
630
  return;
603
631
  }
604
- const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick("paypal", { deferInlineSessionPatch: true }) : { proceed: true };
632
+ const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick("paypal") : { proceed: true };
605
633
  if (!beforeClick.proceed) {
606
634
  beforeClickRef.current = null;
607
635
  event.reject();
@@ -609,7 +637,7 @@ function PayPalButtonInner({
609
637
  }
610
638
  beforeClickRef.current = {
611
639
  accountPatch: beforeClick.accountPatch,
612
- pendingInlinePatch: beforeClick.pendingInlinePatch
640
+ sessionId: beforeClick.sessionId
613
641
  };
614
642
  event.resolve();
615
643
  }, [isProcessing, runBeforeButtonClick, submitting]);
@@ -625,15 +653,10 @@ function PayPalButtonInner({
625
653
  }
626
654
  prepared = {
627
655
  accountPatch: beforeClick.accountPatch,
628
- pendingInlinePatch: beforeClick.pendingInlinePatch ?? Promise.resolve({ error: null, sessionId: beforeClick.sessionId ?? sessionId })
656
+ sessionId: beforeClick.sessionId
629
657
  };
630
658
  }
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;
659
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
637
660
  const effectiveEmail = prepared?.accountPatch?.email ?? email;
638
661
  onButtonClick?.("paypal");
639
662
  try {
@@ -757,16 +780,11 @@ function WalletButtonInner({
757
780
  }
758
781
  prepared = {
759
782
  accountPatch: beforeClick.accountPatch,
760
- pendingInlinePatch: beforeClick.pendingInlinePatch ?? Promise.resolve({ error: null, sessionId: beforeClick.sessionId ?? sessionId })
783
+ sessionId: beforeClick.sessionId
761
784
  };
762
785
  }
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
786
  const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
769
- const effectiveSessionId = patchResult.sessionId ?? sessionId;
787
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
770
788
  const effectiveEmail = prepared?.accountPatch?.email ?? email;
771
789
  onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
772
790
  try {
@@ -835,7 +853,7 @@ function WalletButtonInner({
835
853
  onLoadError: () => setLoadState("unavailable"),
836
854
  onClick: async (event) => {
837
855
  lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
838
- const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current, { deferInlineSessionPatch: true }) : { proceed: true };
856
+ const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current) : { proceed: true };
839
857
  if (!beforeClick.proceed) {
840
858
  beforeClickRef.current = null;
841
859
  event.reject();
@@ -843,7 +861,7 @@ function WalletButtonInner({
843
861
  }
844
862
  beforeClickRef.current = {
845
863
  accountPatch: beforeClick.accountPatch,
846
- pendingInlinePatch: beforeClick.pendingInlinePatch
864
+ sessionId: beforeClick.sessionId
847
865
  };
848
866
  event.resolve();
849
867
  },
@@ -913,6 +931,7 @@ function SplitCardFormInner({
913
931
  innerRef
914
932
  }) {
915
933
  const flopay = useFloPay();
934
+ const paypalFlopay = usePayPalFloPay();
916
935
  const elements = useElements();
917
936
  const checkout = useContext3(CheckoutContext);
918
937
  const contextBillingUrl = useBillingApiUrl();
@@ -976,6 +995,10 @@ function SplitCardFormInner({
976
995
  if (!flopay) return null;
977
996
  return flopay.getRawProvider();
978
997
  }, [flopay]);
998
+ const paypalStripeInstance = useMemo2(() => {
999
+ if (!paypalFlopay) return null;
1000
+ return paypalFlopay.getRawProvider();
1001
+ }, [paypalFlopay]);
979
1002
  const amountInCents = totalAmount || 100;
980
1003
  const walletOptions = useMemo2(() => ({
981
1004
  mode: "payment",
@@ -1028,7 +1051,7 @@ function SplitCardFormInner({
1028
1051
  },
1029
1052
  [checkout.applyInlineSessionPatch, onError, sessionId, updateError]
1030
1053
  );
1031
- const runBeforeButtonClick = useCallback(async (method, options) => {
1054
+ const runBeforeButtonClick = useCallback(async (method) => {
1032
1055
  if (!onBeforeButtonClick) return { proceed: true };
1033
1056
  try {
1034
1057
  const result = await onBeforeButtonClick({
@@ -1043,15 +1066,7 @@ function SplitCardFormInner({
1043
1066
  if (result.account) {
1044
1067
  setAccountPatch((prev) => ({ ...prev ?? {}, ...result.account }));
1045
1068
  }
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;
1069
+ const patchResult = await applyInlineSessionPatch(result, method);
1055
1070
  if (patchResult.error) {
1056
1071
  return {
1057
1072
  proceed: false,
@@ -1153,9 +1168,9 @@ function SplitCardFormInner({
1153
1168
  return;
1154
1169
  }
1155
1170
  try {
1156
- const stripeInstance2 = flopay.getRawProvider();
1157
- if (!stripeInstance2) {
1158
- updateError("Payment provider not available.");
1171
+ const paypalStripe = paypalFlopay?.getRawProvider();
1172
+ if (!paypalStripe) {
1173
+ updateError("PayPal is not available.");
1159
1174
  return;
1160
1175
  }
1161
1176
  const confirmParams = {
@@ -1164,7 +1179,7 @@ function SplitCardFormInner({
1164
1179
  if (savedPmId) {
1165
1180
  confirmParams["payment_method"] = savedPmId;
1166
1181
  }
1167
- const { error: confirmError } = await stripeInstance2.confirmPayment({
1182
+ const { error: confirmError } = await paypalStripe.confirmPayment({
1168
1183
  clientSecret: secret,
1169
1184
  confirmParams,
1170
1185
  redirect: "if_required"
@@ -1201,7 +1216,7 @@ function SplitCardFormInner({
1201
1216
  processingRef.current = false;
1202
1217
  }
1203
1218
  },
1204
- [baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, onComplete, onError, updateError, emitDecline]
1219
+ [baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline]
1205
1220
  );
1206
1221
  const dispatchTokenizedBody = useCallback(
1207
1222
  (tokenizedBody, overrides) => {
@@ -1651,7 +1666,7 @@ function SplitCardFormInner({
1651
1666
  ...!isButtonsView && !buttonsAnim ? { visibility: "hidden", position: "absolute", pointerEvents: "none", width: "100%" } : {},
1652
1667
  ...buttonsAnim ? { animation: buttonsAnim, pointerEvents: "none" } : {}
1653
1668
  }, children: [
1654
- showPayPal && stripeInstance ? /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx4(
1669
+ showPayPal && paypalStripeInstance && /* @__PURE__ */ jsx4(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx4(
1655
1670
  PayPalButtonInner,
1656
1671
  {
1657
1672
  sessionId,
@@ -1664,7 +1679,7 @@ function SplitCardFormInner({
1664
1679
  onDecline,
1665
1680
  runBeforeButtonClick
1666
1681
  }
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,
1682
+ ) }),
1668
1683
  showWallets && stripeInstance ? /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx4(
1669
1684
  WalletButtonInner,
1670
1685
  {
@@ -1763,7 +1778,7 @@ function SplitCardFormInner({
1763
1778
  onDecline
1764
1779
  }
1765
1780
  ) }),
1766
- showPayPal && stripeInstance && /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx4(
1781
+ showPayPal && paypalStripeInstance && /* @__PURE__ */ jsx4(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx4(
1767
1782
  PayPalButtonInner,
1768
1783
  {
1769
1784
  sessionId,
@@ -1775,7 +1790,7 @@ function SplitCardFormInner({
1775
1790
  onDecline
1776
1791
  }
1777
1792
  ) }),
1778
- (showWallets && stripeInstance || showPayPal && stripeInstance) && /* @__PURE__ */ jsxs2("div", { style: {
1793
+ (showWallets && stripeInstance || showPayPal && paypalStripeInstance) && /* @__PURE__ */ jsxs2("div", { style: {
1779
1794
  display: "flex",
1780
1795
  alignItems: "center",
1781
1796
  gap: "0.75rem",
@@ -1840,6 +1855,8 @@ function FloPayCheckout({
1840
1855
  const [unified, setUnified] = useState3(null);
1841
1856
  const [flopay, setFloPay] = useState3(null);
1842
1857
  const flopayRef = useRef3(null);
1858
+ const [paypalFlopay, setPaypalFloPay] = useState3(null);
1859
+ const paypalFlopayRef = useRef3(null);
1843
1860
  const [session, setSession] = useState3(null);
1844
1861
  const [resolvedSessionId, setResolvedSessionId] = useState3(sessionIdProp ?? "");
1845
1862
  const [isLoading, setIsLoading] = useState3(true);
@@ -1957,13 +1974,18 @@ function FloPayCheckout({
1957
1974
  return false;
1958
1975
  }
1959
1976
  if (redirectResult.type === "paypal_redirect_required") {
1977
+ const paypalStripe = paypalFlopayRef.current?.getRawProvider();
1978
+ if (!paypalStripe) {
1979
+ setModeError("PayPal is not available.");
1980
+ return false;
1981
+ }
1960
1982
  const confirmParams = {
1961
1983
  return_url: window.location.href
1962
1984
  };
1963
1985
  if (redirectResult.paymentMethodId) {
1964
1986
  confirmParams["payment_method"] = redirectResult.paymentMethodId;
1965
1987
  }
1966
- const { error } = await stripe.confirmPayment({
1988
+ const { error } = await paypalStripe.confirmPayment({
1967
1989
  clientSecret: redirectResult.threeDSecureToken,
1968
1990
  confirmParams,
1969
1991
  redirect: "if_required"
@@ -2072,8 +2094,10 @@ function FloPayCheckout({
2072
2094
  setResolvedSessionId(sid);
2073
2095
  }
2074
2096
  let publishableKey;
2097
+ let paypalPublishableKey;
2075
2098
  if (realResult.provider === "stripe") {
2076
2099
  publishableKey = realResult.data.stripe?.publishableKey;
2100
+ paypalPublishableKey = realResult.data.stripe?.paypalPublishableKey;
2077
2101
  }
2078
2102
  if (!publishableKey) publishableKey = fallbackPublishableKey;
2079
2103
  if (!publishableKey) {
@@ -2082,12 +2106,30 @@ function FloPayCheckout({
2082
2106
  "validation_error"
2083
2107
  );
2084
2108
  }
2085
- const instance = await loadFloPay(publishableKey, {
2086
- billingApiUrl: resolvedBillingUrl,
2087
- locale
2088
- });
2109
+ const needsSeparatePaypal = Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;
2110
+ const [instance, paypalInstanceOrError] = await Promise.all([
2111
+ loadFloPay(publishableKey, {
2112
+ billingApiUrl: resolvedBillingUrl,
2113
+ locale
2114
+ }),
2115
+ needsSeparatePaypal ? loadFloPay(paypalPublishableKey, {
2116
+ billingApiUrl: resolvedBillingUrl,
2117
+ locale
2118
+ }).catch((err) => {
2119
+ console.warn("[FloPay] Failed to load PayPal Stripe instance:", err);
2120
+ return null;
2121
+ }) : Promise.resolve(null)
2122
+ ]);
2089
2123
  flopayRef.current = instance;
2090
2124
  setFloPay(instance);
2125
+ if (paypalPublishableKey) {
2126
+ const paypalInstance = needsSeparatePaypal ? paypalInstanceOrError : instance;
2127
+ paypalFlopayRef.current = paypalInstance;
2128
+ setPaypalFloPay(paypalInstance);
2129
+ } else {
2130
+ paypalFlopayRef.current = null;
2131
+ setPaypalFloPay(null);
2132
+ }
2091
2133
  setIsLoading(false);
2092
2134
  } catch (err) {
2093
2135
  if (initializedHashRef.current === cacheKey) {
@@ -2200,8 +2242,10 @@ function FloPayCheckout({
2200
2242
  }
2201
2243
  async function initStripe(result) {
2202
2244
  let publishableKey;
2245
+ let paypalPublishableKey;
2203
2246
  if (result.provider === "stripe") {
2204
2247
  publishableKey = result.data.stripe?.publishableKey;
2248
+ paypalPublishableKey = result.data.stripe?.paypalPublishableKey;
2205
2249
  }
2206
2250
  if (!publishableKey) publishableKey = fallbackPublishableKey;
2207
2251
  if (!publishableKey) {
@@ -2210,12 +2254,30 @@ function FloPayCheckout({
2210
2254
  "validation_error"
2211
2255
  );
2212
2256
  }
2213
- const instance = await loadFloPay(publishableKey, {
2214
- billingApiUrl: resolvedBillingUrl,
2215
- locale
2216
- });
2257
+ const needsSeparatePaypal = Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;
2258
+ const [instance, paypalInstanceOrError] = await Promise.all([
2259
+ loadFloPay(publishableKey, {
2260
+ billingApiUrl: resolvedBillingUrl,
2261
+ locale
2262
+ }),
2263
+ needsSeparatePaypal ? loadFloPay(paypalPublishableKey, {
2264
+ billingApiUrl: resolvedBillingUrl,
2265
+ locale
2266
+ }).catch((err) => {
2267
+ console.warn("[FloPay] Failed to load PayPal Stripe instance:", err);
2268
+ return null;
2269
+ }) : Promise.resolve(null)
2270
+ ]);
2217
2271
  flopayRef.current = instance;
2218
2272
  setFloPay(instance);
2273
+ if (paypalPublishableKey) {
2274
+ const paypalInstance = needsSeparatePaypal ? paypalInstanceOrError : instance;
2275
+ paypalFlopayRef.current = paypalInstance;
2276
+ setPaypalFloPay(paypalInstance);
2277
+ } else {
2278
+ paypalFlopayRef.current = null;
2279
+ setPaypalFloPay(null);
2280
+ }
2219
2281
  }
2220
2282
  init();
2221
2283
  return () => {
@@ -2350,7 +2412,7 @@ function FloPayCheckout({
2350
2412
  }
2351
2413
  if (!flopay || !providerOptions) return /* @__PURE__ */ jsx5(Fragment3, {});
2352
2414
  if (currentMode === "confirm") {
2353
- return /* @__PURE__ */ jsx5(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx5(FloPayProvider, { flopay, options: providerOptions, children: /* @__PURE__ */ jsxs3("div", { className, children: [
2415
+ return /* @__PURE__ */ jsx5(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx5(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ jsxs3("div", { className, children: [
2354
2416
  modeError && /* @__PURE__ */ jsx5(
2355
2417
  "div",
2356
2418
  {
@@ -3181,6 +3243,7 @@ export {
3181
3243
  SplitCardForm,
3182
3244
  useCheckout,
3183
3245
  useElements,
3184
- useFloPay
3246
+ useFloPay,
3247
+ usePayPalFloPay
3185
3248
  };
3186
3249
  //# sourceMappingURL=index.mjs.map