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
| Type | Description |
|---|---|
validation_error | A required field is missing or invalid (e.g., no publishable key) |
api_error | The upstream provider or billing API returned an error |
authentication_error | Invalid API key or credentials |
rate_limit_error | Too many requests |
network_error | Network 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 FloPayCheckout and FloPayAutomaticPaymentButton accept an onError callback:
<FloPayCheckout
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.