@flopay/react 0.5.17 → 0.5.18

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 CHANGED
@@ -154,7 +154,7 @@ function FloPayProvider({
154
154
 
155
155
  // src/flopay-checkout.tsx
156
156
  var import_react9 = __toESM(require("react"), 1);
157
- var import_js2 = require("@flopay/js");
157
+ var import_js3 = require("@flopay/js");
158
158
  var import_shared7 = require("@flopay/shared");
159
159
 
160
160
  // src/card-button-content.tsx
@@ -287,6 +287,7 @@ var AddressElement = createElementComponent("address", "AddressElement");
287
287
  // src/split-card-form.tsx
288
288
  var import_react_stripe_js = require("@stripe/react-stripe-js");
289
289
  var import_shared4 = require("@flopay/shared");
290
+ var import_js = require("@flopay/js");
290
291
  var import_react8 = require("react");
291
292
 
292
293
  // src/hooks.ts
@@ -1488,53 +1489,47 @@ function SplitCardFormInner({
1488
1489
  const resolvedCompletionPaymentMethodId = overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
1489
1490
  const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
1490
1491
  try {
1491
- const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
1492
- method: "POST",
1493
- headers: {
1494
- "Content-Type": "application/json",
1495
- "x-user-id": effectiveAccount.userId ?? ""
1492
+ const api = new import_js.PaymentAPI(baseUrl);
1493
+ const response = await api.processPayment(effectiveAccount.userId ?? "", {
1494
+ sessionId: effectiveSessionId,
1495
+ tokenizedData: requestTokenizedBody,
1496
+ accountData: {
1497
+ userId: effectiveAccount.userId ?? "",
1498
+ email: effectiveAccount.email ?? "",
1499
+ firstName: effectiveAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
1500
+ lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
1501
+ ...avsConfig ? (() => {
1502
+ const c = selectedCountryRef.current;
1503
+ const stateVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.state, c);
1504
+ const line1Visible = (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, c);
1505
+ const zipVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, c);
1506
+ const derivedState = line1Visible && !stateVisible && zipVisible ? (0, import_shared4.getStateFromPostalCode)(c, zipCodeRef.current ?? "") : null;
1507
+ const stateValue2 = stateVisible ? stateRef.current : derivedState;
1508
+ return {
1509
+ country: c,
1510
+ ...zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {},
1511
+ ...(0, import_shared4.isAVSFieldVisible)(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {},
1512
+ ...stateValue2 ? { state: stateValue2 } : {},
1513
+ ...line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {},
1514
+ ...(0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}
1515
+ };
1516
+ })() : {}
1496
1517
  },
1497
- body: JSON.stringify({
1498
- sessionId: effectiveSessionId,
1499
- tokenizedData: requestTokenizedBody,
1500
- accountData: {
1501
- userId: effectiveAccount.userId ?? "",
1502
- email: effectiveAccount.email ?? "",
1503
- firstName: effectiveAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
1504
- lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
1505
- ...avsConfig ? (() => {
1506
- const c = selectedCountryRef.current;
1507
- const stateVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.state, c);
1508
- const line1Visible = (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, c);
1509
- const zipVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, c);
1510
- const derivedState = line1Visible && !stateVisible && zipVisible ? (0, import_shared4.getStateFromPostalCode)(c, zipCodeRef.current ?? "") : null;
1511
- const stateValue2 = stateVisible ? stateRef.current : derivedState;
1512
- return {
1513
- country: c,
1514
- ...zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {},
1515
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {},
1516
- ...stateValue2 ? { state: stateValue2 } : {},
1517
- ...line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {},
1518
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}
1519
- };
1520
- })() : {}
1521
- },
1522
- chv,
1523
- // Checkout analytics metadata
1524
- avsCheck: avsCheckProp ?? false,
1525
- checkoutType: checkoutTypeProp,
1526
- checkoutLayout: checkoutLayoutProp,
1527
- // Resolved exposure: which fields were actually shown for the active country.
1528
- // Country-scoped rules (e.g. ['US', 'CA']) are flattened to booleans here.
1529
- avsConfig: avsConfig ? {
1530
- country: (0, import_shared4.isAVSFieldVisible)(avsConfig.country, selectedCountryRef.current),
1531
- postal_code: (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, selectedCountryRef.current),
1532
- address_line_1: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, selectedCountryRef.current),
1533
- address_line_2: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, selectedCountryRef.current),
1534
- city: (0, import_shared4.isAVSFieldVisible)(avsConfig.city, selectedCountryRef.current),
1535
- state: (0, import_shared4.isAVSFieldVisible)(avsConfig.state, selectedCountryRef.current)
1536
- } : void 0
1537
- })
1518
+ chv,
1519
+ // Checkout analytics metadata
1520
+ avsCheck: avsCheckProp ?? false,
1521
+ checkoutType: checkoutTypeProp,
1522
+ checkoutLayout: checkoutLayoutProp,
1523
+ // Resolved exposure: which fields were actually shown for the active country.
1524
+ // Country-scoped rules (e.g. ['US', 'CA']) are flattened to booleans here.
1525
+ avsConfig: avsConfig ? {
1526
+ country: (0, import_shared4.isAVSFieldVisible)(avsConfig.country, selectedCountryRef.current),
1527
+ postal_code: (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, selectedCountryRef.current),
1528
+ address_line_1: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, selectedCountryRef.current),
1529
+ address_line_2: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, selectedCountryRef.current),
1530
+ city: (0, import_shared4.isAVSFieldVisible)(avsConfig.city, selectedCountryRef.current),
1531
+ state: (0, import_shared4.isAVSFieldVisible)(avsConfig.state, selectedCountryRef.current)
1532
+ } : void 0
1538
1533
  });
1539
1534
  if (response.ok) {
1540
1535
  markSessionRecentlyCompleted(effectiveSessionId);
@@ -2437,7 +2432,7 @@ function SplitCardFormInner({
2437
2432
  }
2438
2433
 
2439
2434
  // src/saved-payment-flow.ts
2440
- var import_js = require("@flopay/js");
2435
+ var import_js2 = require("@flopay/js");
2441
2436
  var import_shared6 = require("@flopay/shared");
2442
2437
  var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
2443
2438
  function getRedirectResultFromCheckoutProcessError(error) {
@@ -2545,7 +2540,7 @@ async function recover3DSRedirectResult({
2545
2540
  return null;
2546
2541
  }
2547
2542
  try {
2548
- const api = new import_js.PaymentAPI(billingApiUrl);
2543
+ const api = new import_js2.PaymentAPI(billingApiUrl);
2549
2544
  const unified = await api.getUnifiedCheckoutSession(sessionId);
2550
2545
  const refreshedToken = unified.provider === "stripe" ? unified.data.stripe?.clientSecret : void 0;
2551
2546
  if (isStripePaymentIntentClientSecret(refreshedToken)) {
@@ -2573,25 +2568,19 @@ async function processSavedPaymentForMode({
2573
2568
  const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? "";
2574
2569
  const country = session.customer?.country ?? session.accountData?.country ?? void 0;
2575
2570
  const zip = session.customer?.zip ?? session.accountData?.zip ?? void 0;
2576
- const response = await retryOnceOnFetchFailure(() => fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
2577
- method: "POST",
2578
- headers: {
2579
- "Content-Type": "application/json",
2580
- "x-user-id": customerId
2571
+ const api = new import_js2.PaymentAPI(baseUrl);
2572
+ const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {
2573
+ sessionId: resolvedSessionId,
2574
+ tokenizedData,
2575
+ accountData: {
2576
+ userId: customerId,
2577
+ email: customerEmail,
2578
+ firstName,
2579
+ lastName,
2580
+ country,
2581
+ zip
2581
2582
  },
2582
- body: JSON.stringify({
2583
- sessionId: resolvedSessionId,
2584
- tokenizedData,
2585
- accountData: {
2586
- userId: customerId,
2587
- email: customerEmail,
2588
- firstName,
2589
- lastName,
2590
- country,
2591
- zip
2592
- },
2593
- returnUrl: returnUrl ?? resolveSavedPaymentReturnUrl(session)
2594
- })
2583
+ returnUrl: returnUrl ?? resolveSavedPaymentReturnUrl(session)
2595
2584
  }));
2596
2585
  if (response.ok) {
2597
2586
  return {
@@ -2664,7 +2653,7 @@ async function processSavedPaymentWithIntent({
2664
2653
  { checkoutMethod: "card" }
2665
2654
  );
2666
2655
  }
2667
- const api = new import_js.PaymentAPI(billingApiUrl);
2656
+ const api = new import_js2.PaymentAPI(billingApiUrl);
2668
2657
  const intentResponse = await retryOnceOnFetchFailure(() => api.createPaymentIntent(
2669
2658
  sessionId,
2670
2659
  customerEmail,
@@ -2950,11 +2939,11 @@ async function loadSavedPaymentProviders({
2950
2939
  }) {
2951
2940
  const needsSeparatePaypal = Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;
2952
2941
  const [instance, paypalInstanceOrError] = await Promise.all([
2953
- (0, import_js.loadFloPay)(publishableKey, {
2942
+ (0, import_js2.loadFloPay)(publishableKey, {
2954
2943
  billingApiUrl,
2955
2944
  locale
2956
2945
  }),
2957
- needsSeparatePaypal ? (0, import_js.loadFloPay)(paypalPublishableKey, {
2946
+ needsSeparatePaypal ? (0, import_js2.loadFloPay)(paypalPublishableKey, {
2958
2947
  billingApiUrl,
2959
2948
  locale
2960
2949
  }).catch((err) => {
@@ -3171,6 +3160,17 @@ function FloPayCheckout({
3171
3160
  if (redirectResult.type === "paypal_redirect_required") {
3172
3161
  clearPayPalResumeState();
3173
3162
  }
3163
+ } else if (options?.initialAutoProcessingPending) {
3164
+ const api = new import_js3.PaymentAPI(resolvedBillingUrl);
3165
+ const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {
3166
+ initialDelayMs: options.initialAutoProcessingPending.retryAfterMs
3167
+ });
3168
+ if (completed.data.session?.status !== "complete") {
3169
+ throw new import_shared7.FloPayError("Automatic payment failed. Please try again.", "api_error", {
3170
+ code: completed.data.session?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
3171
+ });
3172
+ }
3173
+ paymentResult = { status: "succeeded" };
3174
3174
  } else if (options?.initialAutoProcessingError) {
3175
3175
  throw checkoutProcessErrorToFloPayError(
3176
3176
  options.initialAutoProcessingError,
@@ -3313,7 +3313,7 @@ function FloPayCheckout({
3313
3313
  const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
3314
3314
  let finalResultStatus = resultStatus;
3315
3315
  if (resumeState.sessionId) {
3316
- const resumeApi = new import_js2.PaymentAPI(resolvedBillingUrl);
3316
+ const resumeApi = new import_js3.PaymentAPI(resolvedBillingUrl);
3317
3317
  const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
3318
3318
  const resumeSession = resumeSessionResult.data.session;
3319
3319
  if (resumeSession && resumeSession.status !== "complete") {
@@ -3407,7 +3407,7 @@ function FloPayCheckout({
3407
3407
  setModeOverlayStatus(null);
3408
3408
  }, [createSessionHash, initialErrorMessage, sessionIdProp]);
3409
3409
  async function resolveInlineSession(params, cacheKey) {
3410
- const api = new import_js2.PaymentAPI(resolvedBillingUrl);
3410
+ const api = new import_js3.PaymentAPI(resolvedBillingUrl);
3411
3411
  let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
3412
3412
  let realResult = null;
3413
3413
  if (sid) {
@@ -3559,6 +3559,7 @@ function FloPayCheckout({
3559
3559
  fallbackToFull: true,
3560
3560
  fromCreateSession: true,
3561
3561
  initialAutoProcessingError: resolved.result.autoProcessingError,
3562
+ initialAutoProcessingPending: resolved.result.autoProcessingPending,
3562
3563
  autoProcessingAttempted: resolved.result.autoProcessingAttempted,
3563
3564
  sessionId: resolved.sid || resolvedSession.id
3564
3565
  });
@@ -3597,7 +3598,7 @@ function FloPayCheckout({
3597
3598
  setIsLoading(true);
3598
3599
  async function init() {
3599
3600
  try {
3600
- const api = new import_js2.PaymentAPI(resolvedBillingUrl);
3601
+ const api = new import_js3.PaymentAPI(resolvedBillingUrl);
3601
3602
  const result = await api.getUnifiedCheckoutSession(activeSessionId);
3602
3603
  if (cancelled) return;
3603
3604
  setUnified(result);
@@ -4163,6 +4164,7 @@ function InterimButtonsView({
4163
4164
  }
4164
4165
 
4165
4166
  // src/checkout-form.tsx
4167
+ var import_js4 = require("@flopay/js");
4166
4168
  var import_shared8 = require("@flopay/shared");
4167
4169
  var import_react10 = require("react");
4168
4170
  var import_jsx_runtime8 = require("react/jsx-runtime");
@@ -4225,23 +4227,17 @@ function CheckoutFormInner({
4225
4227
  const resolvedCompletionPaymentMethodId = completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
4226
4228
  const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
4227
4229
  try {
4228
- const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
4229
- method: "POST",
4230
- headers: {
4231
- "Content-Type": "application/json",
4232
- "x-user-id": userId ?? ""
4230
+ const api = new import_js4.PaymentAPI(baseUrl);
4231
+ const response = await api.processPayment(userId ?? "", {
4232
+ sessionId,
4233
+ tokenizedData: requestTokenizedBody,
4234
+ accountData: {
4235
+ userId: userId ?? "",
4236
+ email: email ?? "",
4237
+ firstName: firstName ?? "",
4238
+ lastName: lastName ?? ""
4233
4239
  },
4234
- body: JSON.stringify({
4235
- sessionId,
4236
- tokenizedData: requestTokenizedBody,
4237
- accountData: {
4238
- userId: userId ?? "",
4239
- email: email ?? "",
4240
- firstName: firstName ?? "",
4241
- lastName: lastName ?? ""
4242
- },
4243
- chv
4244
- })
4240
+ chv
4245
4241
  });
4246
4242
  if (response.ok) {
4247
4243
  onComplete?.({
@@ -4509,6 +4505,7 @@ function CheckoutFormInner({
4509
4505
  }
4510
4506
 
4511
4507
  // src/paypal-button.tsx
4508
+ var import_js5 = require("@flopay/js");
4512
4509
  var import_shared9 = require("@flopay/shared");
4513
4510
  var import_react11 = require("react");
4514
4511
  var import_jsx_runtime9 = require("react/jsx-runtime");
@@ -4535,23 +4532,17 @@ function PayPalButton({
4535
4532
  const processPaymentInternal = (0, import_react11.useCallback)(
4536
4533
  async (tokenizedBody) => {
4537
4534
  try {
4538
- const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
4539
- method: "POST",
4540
- headers: {
4541
- "Content-Type": "application/json",
4542
- "x-user-id": userId ?? ""
4535
+ const api = new import_js5.PaymentAPI(baseUrl);
4536
+ const response = await api.processPayment(userId ?? "", {
4537
+ sessionId,
4538
+ tokenizedData: tokenizedBody,
4539
+ accountData: {
4540
+ userId: userId ?? "",
4541
+ email: email ?? "",
4542
+ firstName: firstName ?? "",
4543
+ lastName: lastName ?? ""
4543
4544
  },
4544
- body: JSON.stringify({
4545
- sessionId,
4546
- tokenizedData: tokenizedBody,
4547
- accountData: {
4548
- userId: userId ?? "",
4549
- email: email ?? "",
4550
- firstName: firstName ?? "",
4551
- lastName: lastName ?? ""
4552
- },
4553
- chv
4554
- })
4545
+ chv
4555
4546
  });
4556
4547
  if (response.ok) {
4557
4548
  onComplete?.();
@@ -4703,7 +4694,7 @@ function PayPalButton({
4703
4694
 
4704
4695
  // src/automatic-payment-button.tsx
4705
4696
  var import_react12 = require("react");
4706
- var import_js3 = require("@flopay/js");
4697
+ var import_js6 = require("@flopay/js");
4707
4698
  var import_shared10 = require("@flopay/shared");
4708
4699
  var import_jsx_runtime10 = require("react/jsx-runtime");
4709
4700
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
@@ -4950,6 +4941,29 @@ function FloPayAutomaticPaymentButton({
4950
4941
  const redirectResult = getRedirectResultFromCheckoutProcessError(apiResult.autoProcessingError);
4951
4942
  const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && (apiResult.autoProcessingAttempted === true || !!apiResult.autoProcessingError || !!redirectResult);
4952
4943
  const shouldRetryPayPalClientSide = checkoutMethod === "paypal" && automaticPaymentToken?.isPaypal === true && options?.fromCreateSession === true;
4944
+ if (apiResult.autoProcessingPending) {
4945
+ const api = new import_js6.PaymentAPI(resolvedBillingUrl);
4946
+ const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {
4947
+ initialDelayMs: apiResult.autoProcessingPending.retryAfterMs
4948
+ });
4949
+ const completedSession = completed.data.session;
4950
+ if (!completedSession || completedSession.status !== "complete") {
4951
+ throw new import_shared10.FloPayError("Automatic payment failed. Please try again.", "api_error", {
4952
+ code: completedSession?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
4953
+ });
4954
+ }
4955
+ await showSuccess({
4956
+ result: {
4957
+ status: "succeeded",
4958
+ paymentMethodId: paymentMethodId ?? void 0,
4959
+ checkoutMethod
4960
+ },
4961
+ session: completedSession,
4962
+ sessionId: completedSession.id || resolvedSessionId,
4963
+ autoCompleted: false
4964
+ });
4965
+ return;
4966
+ }
4953
4967
  if (redirectResult) {
4954
4968
  const {
4955
4969
  publishableKey,
@@ -5160,7 +5174,7 @@ function FloPayAutomaticPaymentButton({
5160
5174
  setOverlayError(null);
5161
5175
  setOverlayStatus("processing");
5162
5176
  try {
5163
- const api = new import_js3.PaymentAPI(resolvedBillingUrl);
5177
+ const api = new import_js6.PaymentAPI(resolvedBillingUrl);
5164
5178
  if (sessionId) {
5165
5179
  const result = await api.getUnifiedCheckoutSession(sessionId);
5166
5180
  await processResolvedSession(result, sessionId);
@@ -5290,7 +5304,7 @@ function FloPayAutomaticPaymentButton({
5290
5304
  { checkoutMethod: "paypal" }
5291
5305
  );
5292
5306
  }
5293
- const api = new import_js3.PaymentAPI(resolvedBillingUrl);
5307
+ const api = new import_js6.PaymentAPI(resolvedBillingUrl);
5294
5308
  const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
5295
5309
  let resumeSession = sessionResult.data.session;
5296
5310
  if (!resumeSession) {