SDK error handling
Catch and react to Bridge SDK failures with TokeflowError and the full TokeflowErrorCode reference — switch on stable codes, surface friendly messages, and centralize logging with a global onError handler.
Every failure in the Bridge SDK is reported as a TokeflowError — a typed error with a stable, machine-readable code. Switch on code to drive your UI, show message to humans, and log requestId for support.
The SDK throws (or rejects promises with) TokeflowError for everything from a misconfigured key to an incomplete card field to a network timeout. Because the codes are stable, you can build your error handling once and rely on it across tokenization, checkout, and wallet flows.
For server-side API errors (the error envelope returned by https://api.tokeflow.com), see Errors. This page covers errors raised in the browser by the Bridge SDK.
The TokeflowError class
TokeflowError extends the native Error, so error.message and instanceof Error work as usual. It adds a code and optional transport context.
class TokeflowError extends Error {
code: TokeflowErrorCode; // stable machine-readable code — switch on this
message: string; // human-readable explanation (display-safe, may reword)
httpStatus?: number; // HTTP status, when the error came from an API call
requestId?: string; // request id (req_…) for support, when available
details?: unknown; // optional structured context about the failure
}| Property | Type | Always present | Description |
|---|---|---|---|
code | TokeflowErrorCode | Yes | Stable, machine-readable code. Switch on this. See the full table. |
message | string | Yes | Human-readable explanation. Display-safe, but may change wording over time — never parse it. |
httpStatus | number | No | Present when the error originated from an API request (e.g. 429, 500). |
requestId | string | No | Request identifier (req_…) for the underlying API call, when available. Log it. |
details | unknown | No | Optional structured context about the failure. |
Treat code as the stable contract and message as display-only. Always log requestId and httpStatus — they make support requests far faster to resolve.
How errors flow
A TokeflowError surfaces in two places: it rejects the promise of the call that failed (so you handle it with try/catch), and — if you configured one — it is also passed to the global onError handler.
Handling errors with try/catch
Wrap SDK calls in try/catch, narrow to TokeflowError with instanceof, then switch on error.code to map each failure to user-facing copy. Always keep a default branch.
import { TokeflowError, TokeflowErrorCode } from '@tokeflow_com/bridge-js';
try {
const token = await tokeflow.cards.tokenize({ card: cardElement });
// Send token.tokenId to your backend to create the transaction.
} catch (error) {
if (error instanceof TokeflowError) {
switch (error.code) {
case TokeflowErrorCode.ELEMENT_INCOMPLETE:
showError('Please complete all card fields.');
break;
case TokeflowErrorCode.INVALID_CARD:
showError('Please check your card number.');
break;
case TokeflowErrorCode.INVALID_CPF:
showError('Please check the CPF you entered.');
break;
case TokeflowErrorCode.EXPIRED_CARD:
showError('This card has expired.');
break;
case TokeflowErrorCode.UNSUPPORTED_CARD_BRAND:
showError('This card brand is not supported.');
break;
case TokeflowErrorCode.PAYMENT_METHOD_DISABLED:
showError('That payment method is not available right now.');
break;
case TokeflowErrorCode.SESSION_EXPIRED:
showError('Your session expired. Please refresh and try again.');
break;
case TokeflowErrorCode.RATE_LIMITED:
showError('Too many attempts. Please wait a moment and try again.');
break;
case TokeflowErrorCode.NETWORK_ERROR:
case TokeflowErrorCode.TIMEOUT:
showError('Network problem. Please try again.');
break;
default:
showError(error.message);
}
// Log the transport context for support and monitoring.
console.error('Tokeflow error', {
code: error.code,
httpStatus: error.httpStatus,
requestId: error.requestId,
details: error.details,
});
} else {
// Not a TokeflowError — rethrow or handle as a generic failure.
throw error;
}
}error.code is a value from the TokeflowErrorCode enum. Compare against the enum (e.g. TokeflowErrorCode.INVALID_CARD) rather than the raw string so a typo becomes a compile-time error in TypeScript.
Many input failures are avoidable before a round trip. Read an element's getState() ({ empty, valid, invalid, complete }) and keep your pay button disabled until state.complete && state.valid. This prevents most ELEMENT_INCOMPLETE and ELEMENT_INVALID errors. See Tokenization.
Global onError handler
Pass an onError callback in the SDK config to receive every TokeflowError in one place — ideal for centralized logging and monitoring. It complements try/catch; it does not replace it. Use onError for observability and your local catch for the user-facing reaction at the point of failure.
import { TokeflowBridge } from '@tokeflow_com/bridge-js';
const tokeflow = new TokeflowBridge({
publicKey: 'pk_live_mer_your_public_key',
onError: (error) => {
// Centralized logging — runs for every TokeflowError the SDK raises.
logToService({
code: error.code,
message: error.message,
httpStatus: error.httpStatus,
requestId: error.requestId,
});
},
});Keep onError side-effect-only (logging, metrics). Do not throw from inside it, and do not use it to control your checkout flow — drive the UI from the catch block at the call site, where you have local context.
In React, configure onError on the provider config, and read the current error from the useTokeflow() hook:
import { TokeflowProvider, useTokeflow } from '@tokeflow_com/bridge-js/react';
function App() {
return (
<TokeflowProvider
config={{
publicKey: 'pk_live_mer_your_public_key',
onError: (error) => logToService({ code: error.code, requestId: error.requestId }),
}}
>
<Checkout />
</TokeflowProvider>
);
}
function Checkout() {
const { isReady, error } = useTokeflow();
if (error) return <div role="alert">{error.message}</div>;
if (!isReady) return <div>Loading…</div>;
// render your payment form
}TokeflowErrorCode reference
Every error the SDK raises carries one of these codes. They are grouped here by lifecycle stage for readability; the enum itself is flat.
Configuration and initialization
| Code | Description |
|---|---|
INVALID_CONFIG | The SDK configuration is invalid (bad or conflicting options). |
INVALID_PUBLIC_KEY | The public key is missing or not a valid pk_… key. |
NOT_IN_BROWSER | The SDK was used outside a browser environment (e.g. during server-side rendering). |
NOT_INITIALIZED | An SDK method was called before init() resolved. |
Session lifecycle
| Code | Description |
|---|---|
SESSION_CREATION_FAILED | The SDK could not create a session during init(). |
SESSION_EXPIRED | The session has expired and was not refreshed. |
SESSION_REFRESH_FAILED | A background or manual session refresh failed. |
Elements and input validation
| Code | Description |
|---|---|
ELEMENT_NOT_MOUNTED | The operation requires an element that has not been mounted to the DOM. |
ELEMENT_INVALID | An element's value is invalid. |
ELEMENT_INCOMPLETE | An element's input is incomplete (a required field is not fully entered). |
VALIDATION_ERROR | Input validation failed. |
INVALID_CARD | The card number failed validation. |
INVALID_CPF | The CPF failed validation. |
EXPIRED_CARD | The card's expiry date is in the past. |
Tokenization
| Code | Description |
|---|---|
TOKENIZATION_FAILED | Tokenization could not be completed. |
TOKEN_REGISTRATION_FAILED | The token could not be registered with the backend. |
Checkout
| Code | Description |
|---|---|
NO_CHECKOUT_SESSION | A checkout call was made without a linked checkoutSessionId. |
CHECKOUT_CONTEXT_FETCH_FAILED | The checkout context could not be fetched. |
Payment and wallets
| Code | Description |
|---|---|
PAYMENT_METHOD_DISABLED | The payment method is not enabled for this merchant. |
UNSUPPORTED_CARD_BRAND | The card brand is not supported. |
PAYMENT_CANCELLED | The payment was cancelled (e.g. the Apple Pay or Google Pay sheet was dismissed). |
PAYMENT_FAILED | The payment failed. |
Transport
| Code | Description |
|---|---|
NETWORK_ERROR | A network request failed. |
TIMEOUT | A request timed out. |
RATE_LIMITED | Too many requests — the client is being rate limited. |
SERVER_ERROR | The server returned an error. |
RATE_LIMITED, SERVER_ERROR, NETWORK_ERROR, and TIMEOUT typically carry an httpStatus and a requestId. For transient transport failures, retry with exponential backoff rather than retrying immediately. See Idempotency and rate limits.
Recommended handling by category
Different categories call for different responses. Use this as a starting policy.
| Category | Example codes | What to do |
|---|---|---|
| Fix the integration | INVALID_CONFIG, INVALID_PUBLIC_KEY, NOT_IN_BROWSER, NOT_INITIALIZED | Bugs in your setup. Surface during development; do not show raw text to end users. |
| Ask the user to correct input | ELEMENT_INCOMPLETE, ELEMENT_INVALID, INVALID_CARD, INVALID_CPF, EXPIRED_CARD, VALIDATION_ERROR | Show a field-level, actionable message and let the user retry. |
| Recover the session | SESSION_EXPIRED, SESSION_REFRESH_FAILED, SESSION_CREATION_FAILED | Re-initialize the bridge or prompt the user to refresh, then retry. |
| Adjust the offer | PAYMENT_METHOD_DISABLED, UNSUPPORTED_CARD_BRAND | Offer a different payment method or card. |
| Expected user action | PAYMENT_CANCELLED | Treat as a benign cancellation — return the user to the payment step without an error banner. |
| Retry with backoff | NETWORK_ERROR, TIMEOUT, RATE_LIMITED, SERVER_ERROR | Retry transient failures with exponential backoff; show a non-alarming "try again" message. |
| Generic failure | TOKENIZATION_FAILED, TOKEN_REGISTRATION_FAILED, PAYMENT_FAILED, CHECKOUT_CONTEXT_FETCH_FAILED | Show a generic failure message, log the requestId, and let the user retry. |
Never display requestId, httpStatus, or raw details to end users. Log them for your own debugging and support, and show only a clean, friendly message (or your own copy) in the UI.
Next steps
- Tokenization — input shapes, options, and the token response.
- Bridge SDK overview — installation, lifecycle, and the public-key requirement.
- Errors — the server-side error envelope returned by the Tokeflow API.
- Idempotency and rate limits — retry safely and handle
429responses.