FloPay
Guides

Error Handling

Handle payment errors with FloPayError types and factory functions.

Error Handling

All errors in the FloPay SDK use the FloPayError class from @flopay/shared. It extends Error with structured fields that mirror Stripe-style error responses.

FloPayError

class FloPayError extends Error {
  readonly type: FloPayErrorType;
  readonly code?: string;
  readonly declineCode?: string;
  readonly param?: string;
}

Error Types

TypeDescription
validation_errorA required field is missing or invalid (e.g., no publishable key)
api_errorThe upstream provider or billing API returned an error
authentication_errorInvalid API key or credentials
rate_limit_errorToo many requests
network_errorNetwork connectivity failure (fetch failed)

Additional Fields

  • code -- Provider-specific error code (e.g., card_declined)
  • declineCode -- Card decline reason (e.g., insufficient_funds, lost_card)
  • param -- The parameter that caused the error (e.g., publishableKey, sessionId)

Factory Functions

@flopay/shared exports factory functions for creating errors:

import {
  validationError,
  apiError,
  authenticationError,
  rateLimitError,
  networkError,
} from '@flopay/shared';
 
// Missing required field
throw validationError('sessionId is required', 'sessionId');
 
// Provider returned an error
throw apiError('Card was declined', 'card_declined');
 
// Bad credentials
throw authenticationError('Invalid publishable key');
 
// Too many requests
throw rateLimitError('Rate limit exceeded, retry after 30s');
 
// Fetch failed
throw networkError('Failed to reach billing API');

Handling Errors in Components

Both CheckoutForm and SplitCardForm accept an onError callback:

<CheckoutForm
  sessionId="sess_abc123"
  billingApiUrl="https://billing.example.com"
  onError={(error) => {
    switch (error.type) {
      case 'validation_error':
        // show field-level validation message
        console.error(`Validation: ${error.param} - ${error.message}`);
        break;
      case 'api_error':
        if (error.declineCode) {
          // card was declined
          console.error(`Declined: ${error.declineCode}`);
        } else {
          console.error(`API error: ${error.message}`);
        }
        break;
      case 'network_error':
        // suggest retry
        console.error('Network issue, please try again');
        break;
      default:
        console.error(error.message);
    }
  }}
  onComplete={handleComplete}
/>

Catching Errors from loadFloPay

loadFloPay throws a FloPayError if the publishable key is missing:

import { loadFloPay } from '@flopay/js';
import { FloPayError } from '@flopay/shared';
 
try {
  const flopay = await loadFloPay(publishableKey);
} catch (err) {
  if (err instanceof FloPayError) {
    console.error(err.type, err.param, err.message);
  }
}

FloPayError restores the prototype chain with Object.setPrototypeOf, so instanceof checks work correctly even in environments that transpile class inheritance.

On this page