FloPay
Guides

PayPal Integration

Add PayPal as a payment method alongside card payments.

PayPal Integration

FloPay supports PayPal payments through Stripe's ExpressCheckoutElement. PayPal has a specific architectural requirement: it needs its own Stripe Elements instance without paymentMethodCreation: 'manual'.

The simplest way to offer PayPal is through SplitCardForm, which handles the dual-Elements architecture automatically:

<FloPayProvider flopay={flopayPromise} options={{ paymentMethodCreation: 'manual' }}>
  <SplitCardForm
    sessionId="sess_abc123"
    billingApiUrl="https://billing.example.com"
    email="user@example.com"
    totalAmount={49.99}
    currency="usd"
    showPayPal={true}
    onComplete={handleComplete}
  />
</FloPayProvider>

The component internally creates two Elements instances:

  1. Card Elements -- uses the parent FloPayProvider with paymentMethodCreation: 'manual' for card tokenization
  2. PayPal Elements -- creates a separate Stripe <Elements> wrapper without paymentMethodCreation for the ExpressCheckoutElement

When showPayPal is enabled, you must provide totalAmount (in dollars) and currency. These are used to configure the PayPal Elements instance with the correct amount (converted to cents) and currency values.

PayPal Payment Flow

The PayPal flow differs from the card flow:

  1. User clicks the PayPal button (rendered by ExpressCheckoutElement)
  2. Stripe opens the PayPal approval window
  3. The confirmPayPalPayment method on the FloPay instance is called:
    • Creates a payment intent via the billing API
    • Confirms the PayPal payment with Stripe
    • Handles any redirect if needed
  4. On return from PayPal redirect, resumePayPalPayment picks up the flow
  5. 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. SplitCardForm and CheckoutForm 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.

On this page