@flopay/react 1.2.7 → 1.2.8
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 +82 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.mjs +85 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,6 @@ import { FloPay, FloPayElements } from '@flopay/js';
|
|
|
3
3
|
import * as _flopay_shared from '@flopay/shared';
|
|
4
4
|
import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
|
|
5
5
|
export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessionDraft, InlineSessionPatch } from '@flopay/shared';
|
|
6
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
6
|
|
|
8
7
|
/** Props for the `FloPayProvider` component. */
|
|
9
8
|
interface FloPayProviderProps {
|
|
@@ -867,6 +866,6 @@ interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttribu
|
|
|
867
866
|
onDecline?: (decline: DeclineEvent) => void;
|
|
868
867
|
children?: React.ReactNode;
|
|
869
868
|
}
|
|
870
|
-
declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps):
|
|
869
|
+
declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
|
|
871
870
|
|
|
872
871
|
export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, 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
|
@@ -3,7 +3,6 @@ import { FloPay, FloPayElements } from '@flopay/js';
|
|
|
3
3
|
import * as _flopay_shared from '@flopay/shared';
|
|
4
4
|
import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
|
|
5
5
|
export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessionDraft, InlineSessionPatch } from '@flopay/shared';
|
|
6
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
6
|
|
|
8
7
|
/** Props for the `FloPayProvider` component. */
|
|
9
8
|
interface FloPayProviderProps {
|
|
@@ -867,6 +866,6 @@ interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttribu
|
|
|
867
866
|
onDecline?: (decline: DeclineEvent) => void;
|
|
868
867
|
children?: React.ReactNode;
|
|
869
868
|
}
|
|
870
|
-
declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps):
|
|
869
|
+
declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
|
|
871
870
|
|
|
872
871
|
export { AddressElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, CheckoutForm, type CheckoutFormProps, type CheckoutFormRef, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, SplitCardForm, type SplitCardFormProps, type SplitCardFormRef, useCheckout, useElements, useFloPay, usePayPalFloPay };
|
package/dist/index.mjs
CHANGED
|
@@ -436,7 +436,7 @@ function ProcessingOverlay({
|
|
|
436
436
|
}
|
|
437
437
|
|
|
438
438
|
// src/checkout-utils.ts
|
|
439
|
-
import { FloPayError } from "@flopay/shared";
|
|
439
|
+
import { FloPayError, isSetupIntentClientSecret } from "@flopay/shared";
|
|
440
440
|
function mergeInlineSessionPatches(base, patch) {
|
|
441
441
|
if (!patch) return base;
|
|
442
442
|
if (!base) return patch;
|
|
@@ -605,6 +605,18 @@ function resolvePaymentIntentPaymentMethodId(paymentIntent) {
|
|
|
605
605
|
}
|
|
606
606
|
async function retrievePaymentIntentFromProvider(provider, clientSecret) {
|
|
607
607
|
const retriever = provider;
|
|
608
|
+
if (isSetupIntentClientSecret(clientSecret)) {
|
|
609
|
+
if (!retriever?.retrieveSetupIntent) {
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
const { setupIntent, error: error2 } = await retriever.retrieveSetupIntent(clientSecret);
|
|
613
|
+
if (error2) {
|
|
614
|
+
throw new FloPayError(error2.message ?? "Failed to retrieve setup intent.", "api_error", {
|
|
615
|
+
...error2.code ? { code: error2.code } : {}
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
return setupIntent ?? null;
|
|
619
|
+
}
|
|
608
620
|
if (!retriever?.retrievePaymentIntent) {
|
|
609
621
|
return null;
|
|
610
622
|
}
|
|
@@ -616,6 +628,12 @@ async function retrievePaymentIntentFromProvider(provider, clientSecret) {
|
|
|
616
628
|
}
|
|
617
629
|
return paymentIntent ?? null;
|
|
618
630
|
}
|
|
631
|
+
function resolveWalletElementsMode(amountInMinorUnits) {
|
|
632
|
+
if (typeof amountInMinorUnits !== "number" || !Number.isFinite(amountInMinorUnits) || amountInMinorUnits <= 0) {
|
|
633
|
+
return { mode: "setup" };
|
|
634
|
+
}
|
|
635
|
+
return { mode: "payment", amount: amountInMinorUnits };
|
|
636
|
+
}
|
|
619
637
|
function resolveTokenizedPaymentMethodId(tokenizedBody) {
|
|
620
638
|
const candidates = [
|
|
621
639
|
tokenizedBody?.id,
|
|
@@ -1240,7 +1258,7 @@ ${debugLines.join("\n")}`
|
|
|
1240
1258
|
}
|
|
1241
1259
|
|
|
1242
1260
|
// src/split-card-form.tsx
|
|
1243
|
-
import { FloPayError as FloPayError3, resolveTheme } from "@flopay/shared";
|
|
1261
|
+
import { FloPayError as FloPayError3, isSetupIntentClientSecret as isSetupIntentClientSecret2, resolveTheme } from "@flopay/shared";
|
|
1244
1262
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1245
1263
|
var STRIPE_RESUME_KEY = "flopay_stripe_resume";
|
|
1246
1264
|
var LEGACY_WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
@@ -1733,10 +1751,7 @@ function WalletButtonInner({
|
|
|
1733
1751
|
const intentJson = await intentResponse.json();
|
|
1734
1752
|
const intentClientSecret = intentJson.data?.id;
|
|
1735
1753
|
if (!intentClientSecret) throw new Error("No client_secret in payment intent response");
|
|
1736
|
-
const { error: confirmError,
|
|
1737
|
-
intentClientSecret,
|
|
1738
|
-
{ payment_method: paymentMethod.id }
|
|
1739
|
-
);
|
|
1754
|
+
const { error: confirmError, intentId } = isSetupIntentClientSecret2(intentClientSecret) ? await stripe.confirmCardSetup(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.setupIntent?.id })) : await stripe.confirmCardPayment(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.paymentIntent?.id }));
|
|
1740
1755
|
if (confirmError) {
|
|
1741
1756
|
const message = confirmError.message ?? "Wallet payment failed.";
|
|
1742
1757
|
onErrorChange?.(message);
|
|
@@ -1748,7 +1763,7 @@ function WalletButtonInner({
|
|
|
1748
1763
|
onTokenizedBody({
|
|
1749
1764
|
id: paymentMethod.id,
|
|
1750
1765
|
type: "card",
|
|
1751
|
-
threeDSecureActionResultTokenId:
|
|
1766
|
+
threeDSecureActionResultTokenId: intentId
|
|
1752
1767
|
}, {
|
|
1753
1768
|
accountPatch: prepared?.accountPatch,
|
|
1754
1769
|
sessionId: effectiveSessionId,
|
|
@@ -2611,14 +2626,17 @@ function SplitCardFormInner({
|
|
|
2611
2626
|
}
|
|
2612
2627
|
};
|
|
2613
2628
|
}, [appearance]);
|
|
2614
|
-
const walletOptions = useMemo3(() =>
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2629
|
+
const walletOptions = useMemo3(() => {
|
|
2630
|
+
const modeOptions = resolveWalletElementsMode(totalAmount);
|
|
2631
|
+
return {
|
|
2632
|
+
...modeOptions,
|
|
2633
|
+
currency: currency.toLowerCase(),
|
|
2634
|
+
paymentMethodCreation: "manual",
|
|
2635
|
+
// captureMethod only applies to payment mode; Stripe rejects it in setup.
|
|
2636
|
+
...modeOptions.mode === "payment" ? { captureMethod: "manual" } : {},
|
|
2637
|
+
...stripeAppearanceProp
|
|
2638
|
+
};
|
|
2639
|
+
}, [totalAmount, currency, stripeAppearanceProp]);
|
|
2622
2640
|
const paypalOptions = useMemo3(() => ({
|
|
2623
2641
|
mode: "payment",
|
|
2624
2642
|
amount: amountInCents,
|
|
@@ -4288,8 +4306,28 @@ function SplitCardFormInner({
|
|
|
4288
4306
|
|
|
4289
4307
|
// src/saved-payment-flow.ts
|
|
4290
4308
|
import { loadFloPay, PaymentAPI as PaymentAPI3 } from "@flopay/js";
|
|
4291
|
-
import { FloPayError as FloPayError4 } from "@flopay/shared";
|
|
4309
|
+
import { FloPayError as FloPayError4, isSetupIntentClientSecret as isSetupIntentClientSecret3 } from "@flopay/shared";
|
|
4292
4310
|
var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
|
|
4311
|
+
async function retrieveResumeIntent(stripe, clientSecret, isSetupIntent) {
|
|
4312
|
+
if (isSetupIntent) {
|
|
4313
|
+
if (typeof stripe.retrieveSetupIntent !== "function") return null;
|
|
4314
|
+
const { setupIntent, error: error2 } = await stripe.retrieveSetupIntent(clientSecret);
|
|
4315
|
+
return { error: error2, intent: setupIntent ?? null };
|
|
4316
|
+
}
|
|
4317
|
+
if (typeof stripe.retrievePaymentIntent !== "function") return null;
|
|
4318
|
+
const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);
|
|
4319
|
+
return { error, intent: paymentIntent ?? null };
|
|
4320
|
+
}
|
|
4321
|
+
async function confirmResumeIntent(stripe, clientSecret, data, isSetupIntent) {
|
|
4322
|
+
if (isSetupIntent) {
|
|
4323
|
+
if (typeof stripe.confirmCardSetup !== "function") return null;
|
|
4324
|
+
const { setupIntent, error: error2 } = await stripe.confirmCardSetup(clientSecret, data);
|
|
4325
|
+
return { error: error2, intent: setupIntent ?? null };
|
|
4326
|
+
}
|
|
4327
|
+
if (typeof stripe.confirmCardPayment !== "function") return null;
|
|
4328
|
+
const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);
|
|
4329
|
+
return { error, intent: paymentIntent ?? null };
|
|
4330
|
+
}
|
|
4293
4331
|
function getRedirectResultFromCheckoutProcessError(error) {
|
|
4294
4332
|
if (!error?.type || !error.threeDSecureToken) {
|
|
4295
4333
|
return null;
|
|
@@ -4525,64 +4563,66 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
4525
4563
|
{ checkoutMethod: "card" }
|
|
4526
4564
|
);
|
|
4527
4565
|
}
|
|
4566
|
+
const isSetupIntent = isSetupIntentClientSecret3(redirectResult.threeDSecureToken);
|
|
4528
4567
|
let paymentIntent = null;
|
|
4529
4568
|
let savedPaymentMethodId = redirectResult.paymentMethodId;
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
);
|
|
4534
|
-
if (retrieveError) {
|
|
4569
|
+
const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);
|
|
4570
|
+
if (retrieved) {
|
|
4571
|
+
if (retrieved.error) {
|
|
4535
4572
|
throw Object.assign(
|
|
4536
4573
|
new FloPayError4(
|
|
4537
|
-
|
|
4574
|
+
retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? "setup" : "payment"} status.`,
|
|
4538
4575
|
"api_error",
|
|
4539
|
-
{ code:
|
|
4576
|
+
{ code: retrieved.error.code }
|
|
4540
4577
|
),
|
|
4541
4578
|
{ checkoutMethod: "card" }
|
|
4542
4579
|
);
|
|
4543
4580
|
}
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4581
|
+
const existingIntent = retrieved.intent;
|
|
4582
|
+
if (!savedPaymentMethodId && existingIntent?.payment_method) {
|
|
4583
|
+
if (typeof existingIntent.payment_method === "string") {
|
|
4584
|
+
savedPaymentMethodId = existingIntent.payment_method;
|
|
4585
|
+
} else if ("id" in existingIntent.payment_method) {
|
|
4586
|
+
savedPaymentMethodId = existingIntent.payment_method.id ?? void 0;
|
|
4549
4587
|
}
|
|
4550
4588
|
}
|
|
4551
4589
|
}
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4590
|
+
const confirmed = savedPaymentMethodId ? await confirmResumeIntent(
|
|
4591
|
+
stripe,
|
|
4592
|
+
redirectResult.threeDSecureToken,
|
|
4593
|
+
{
|
|
4594
|
+
payment_method: savedPaymentMethodId,
|
|
4595
|
+
return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href
|
|
4596
|
+
},
|
|
4597
|
+
isSetupIntent
|
|
4598
|
+
) : null;
|
|
4599
|
+
if (confirmed) {
|
|
4600
|
+
if (confirmed.error) {
|
|
4561
4601
|
throw Object.assign(
|
|
4562
4602
|
new FloPayError4(
|
|
4563
|
-
|
|
4603
|
+
confirmed.error.message ?? "3DS authentication failed.",
|
|
4564
4604
|
"api_error",
|
|
4565
|
-
{ code:
|
|
4605
|
+
{ code: confirmed.error.code }
|
|
4566
4606
|
),
|
|
4567
4607
|
{ checkoutMethod: "card" }
|
|
4568
4608
|
);
|
|
4569
4609
|
}
|
|
4570
|
-
paymentIntent =
|
|
4610
|
+
paymentIntent = confirmed.intent;
|
|
4571
4611
|
} else {
|
|
4572
|
-
const
|
|
4612
|
+
const nextAction = await stripe.handleNextAction({
|
|
4573
4613
|
clientSecret: redirectResult.threeDSecureToken
|
|
4574
4614
|
});
|
|
4575
|
-
if (
|
|
4615
|
+
if (nextAction.error) {
|
|
4576
4616
|
throw Object.assign(
|
|
4577
4617
|
new FloPayError4(
|
|
4578
|
-
|
|
4618
|
+
nextAction.error.message ?? "3DS authentication failed.",
|
|
4579
4619
|
"api_error",
|
|
4580
|
-
{ code:
|
|
4620
|
+
{ code: nextAction.error.code }
|
|
4581
4621
|
),
|
|
4582
4622
|
{ checkoutMethod: "card" }
|
|
4583
4623
|
);
|
|
4584
4624
|
}
|
|
4585
|
-
paymentIntent =
|
|
4625
|
+
paymentIntent = (isSetupIntent ? nextAction.setupIntent : nextAction.paymentIntent) ?? null;
|
|
4586
4626
|
}
|
|
4587
4627
|
if (paymentIntent && (paymentIntent.status === "requires_capture" || paymentIntent.status === "succeeded" || paymentIntent.status === "processing")) {
|
|
4588
4628
|
const followUp = await processSavedPaymentForMode({
|