PayPal via Stripe (Fallback)
The Stripe-rendered PayPal path. Used when a client has not provisioned a direct PayPal gateway.
PayPal via Stripe
This page covers the Stripe-rendered PayPal fallback — PayPal mounted through Stripe's ExpressCheckoutElement. It is the path FloPay uses when the checkout session response does not include a gateways.paypal entry.
Looking for the primary PayPal flow? See the Direct PayPal guide. Direct PayPal is required for checkouts opened inside Facebook, Meta, and Instagram in-app browsers, where the Stripe-rendered PayPal flow does not work reliably. For an overview of when each path is used, see the PayPal overview.
When This Path Is Used
The SDK picks the PayPal path from the checkout session's gateways map:
gateways.paypalis present → direct PayPal renders.gateways.paypalisnullor missing → the Stripe-rendered PayPal button described on this page renders, usinggateways.stripe.publishableKey.
PayPal never renders twice. The two paths are mutually exclusive per session.
Architecture
PayPal in this path has a specific Stripe Elements requirement: it needs its own Stripe Elements instance without paymentMethodCreation: 'manual'. Card tokenization needs paymentMethodCreation: 'manual'. Those two requirements are mutually exclusive on the same <Elements> instance, so FloPay mounts two Elements groups side by side.
Using FloPayCheckout (Recommended)
The simplest way to offer the Stripe-rendered PayPal flow is through FloPayCheckout, which fetches the session, picks the PayPal path from the gateways map, and handles the dual-Elements architecture automatically:
<FloPayCheckout
sessionId="sess_abc123"
onComplete={handleComplete}
/>Under the hood, FloPayCheckout renders a SplitCardForm that creates two Elements instances:
- Card Elements -- with
paymentMethodCreation: 'manual'for card tokenization - PayPal Elements -- a separate Stripe
<Elements>wrapper withoutpaymentMethodCreationfor theExpressCheckoutElement
The amount and currency for the PayPal Elements instance are read from the session automatically — no extra props required.
Need full control over provider setup? See the SplitCardForm reference for the lower-level API that lets you mount SplitCardForm inside your own FloPayProvider.
PayPal Payment Flow
The Stripe-rendered PayPal flow differs from the card flow:
- User clicks the PayPal button (rendered by
ExpressCheckoutElement) - Stripe opens the PayPal approval window
- The
confirmPayPalPaymentmethod on theFloPayinstance is called:- Creates a payment intent via the billing API
- Confirms the PayPal payment with Stripe
- Handles any redirect if needed
- On return from PayPal redirect,
resumePayPalPaymentpicks up the flow - Payment is processed via the billing API
// This is handled internally by SplitCardForm, shown for reference:
const result = await flopay.confirmPayPalPayment({
billingApiUrl: 'https://billing.example.com',
sessionId: 'sess_abc123',
email: 'user@example.com',
returnUrl: window.location.href,
});Wallet Resume Across Redirects
PayPal payments may redirect the user away from your site and back. FloPayCheckout (and the underlying SplitCardForm / CheckoutForm components) persist payment state to localStorage under the key flopay_wallet_resume before the redirect, then automatically resume the flow when the user returns.
Why Separate Elements?
Stripe's ExpressCheckoutElement (which renders PayPal, Apple Pay, Google Pay) requires an Elements instance configured with mode, amount, and currency. Card-based flows that use paymentMethodCreation: 'manual' are incompatible with this configuration. SplitCardForm solves this by mounting the PayPal button in its own <Elements> wrapper while keeping card fields in the parent provider's context.
In-App Browser Limitation
The Stripe-rendered PayPal path does not work reliably inside Facebook, Meta, and Instagram in-app browsers. The PayPal popup either fails to open or fails to return to the originating tab. Clients running paid social funnels (Meta Ads, Instagram Ads) should provision a direct PayPal gateway so the SDK switches to the direct PayPal path automatically for those buyers.
Migration
Existing clients that use only the Stripe-rendered PayPal flow stay on this path with no action required. Opting into direct PayPal is a per-gateway provisioning step (see Setup). Once a provider_type=paypal gateway record exists for a client, FloPay starts populating gateways.paypal on that client's sessions and the SDK switches automatically.