Skip to content

API Reference

The main entry point for the SDK. Create an instance before mounting any card elements.

import { ZatlasCardCapture } from '@zatlas/card-capture';
const zatlas = new ZatlasCardCapture({
publishableKey: 'pk_sandbox_your_key',
locale: 'es-MX',
});
ParameterTypeRequiredDefaultDescription
publishableKeystringYesYour publishable key. Starts with pk_sandbox_ in sandbox or pk_live_ in production. Identifies your account and determines the environment.
localestringNo'es-MX'BCP 47 locale for labels, placeholders, error messages, and the CTA button. Supported: 'es-MX', 'es-ES', 'en-US', 'en-GB', 'pt-BR'.
themeobjectNodefaultThemeTheme object to customize the card form appearance. See Themes and the Theming Guide.

If you prefer a functional style, the named export Zatlas returns the same instance:

import { Zatlas } from '@zatlas/card-capture';
const zatlas = Zatlas({
publishableKey: 'pk_sandbox_your_key',
});

Zatlas(options) is equivalent to new ZatlasCardCapture(options).


Creates a card element that can be mounted into the DOM. The element renders a secure iframe containing the card form (number, expiry, CVC, and cardholder name).

const card = zatlas.create('card', {
mode: 'checkout', // or 'tokenize'
showCardholderName: true,
showPostalCode: false,
});
OptionTypeRequiredDefaultDescription
mode'checkout' | 'tokenize'YesDetermines the CTA label and SDK behavior. 'checkout' shows “Continuar” and expects a checkout() call. 'tokenize' shows “Guardar metodo” and expects a createToken() call.
showCardholderNamebooleanNotrueShow the cardholder name field inside the iframe.
showPostalCodebooleanNofalseShow a postal code field inside the iframe. Required by some acquirers for US-issued cards.

Returns a MountedElement.


The object returned by create(). Use it to mount the card form into the DOM, listen for events, and clean up when done.

Pass a CSS selector or an HTMLElement:

// CSS selector
card.mount('#card-element');
// Direct element reference
const container = document.getElementById('card-element');
card.mount(container);

The SDK injects an iframe into the target element. The iframe auto-resizes to fit its contents.

Always unmount when navigating away or destroying the component to avoid memory leaks:

card.unmount();

In React, this is handled automatically by <CardElement /> (see React).

MethodSignatureDescription
mountmount(target: string | HTMLElement): voidInjects the iframe into the given DOM element. Throws if the element is not found.
unmountunmount(): voidRemoves the iframe from the DOM and tears down internal listeners. Safe to call multiple times.
onon(event: string, handler: Function): voidSubscribes to an event.
offoff(event: string, handler: Function): voidUnsubscribes a previously registered handler.
destroydestroy(): voidAlias for unmount(). Removes iframe and cleans up.
focusfocus(): voidProgrammatically focuses the card number field inside the iframe.
blurblur(): voidProgrammatically blurs the currently focused field inside the iframe.
clearclear(): voidClears all fields inside the iframe and resets validation state.

Subscribe to events with card.on(event, handler). All events are emitted from the MountedElement instance.

Fired once the iframe has loaded and the card form is interactive. Use this to hide a loading spinner or enable surrounding UI.

card.on('ready', () => {
document.getElementById('spinner').style.display = 'none';
document.getElementById('pay-section').style.opacity = '1';
});

Fired whenever the guest types or the validation state changes. The handler receives a payload describing the current form state.

card.on('change', (event) => {
console.log(event.complete); // true when all fields are valid
console.log(event.error); // validation error, if any
console.log(event.brand); // detected card brand
});

Payload fields:

FieldTypeDescription
completebooleantrue when all fields pass validation and the form is ready to submit.
emptybooleantrue when all fields are empty.
brandstring | nullDetected card brand: 'visa', 'mastercard', 'amex', 'discover', or null if not yet identified.
error{ code: string, message: string } | nullCurrent validation error, or null if the form is valid. See Validation errors.

Fired when the guest clicks the CTA button inside the iframe (“Continuar” in checkout mode, “Guardar metodo” in tokenize mode). This is where you call checkout() or createToken().

// 1. Get a fresh access token from your server
const { accessToken } = await fetch('/api/payment-token').then(r => r.json());
card.on('cta_clicked', async () => {
// 2. Process the payment
const { payment, error } = await zatlas.checkout({
accessToken,
amount: 25000,
currency: 'mxn',
reservationId: 'RES-456',
});
// 3. Handle the result
if (payment) {
showConfirmation(payment.id);
} else {
console.error(`Payment failed: ${error.code} - ${error.message}`);
}
});

The SDK automatically shows a loading spinner inside the iframe while your async handler is running.

Fired when any field inside the iframe receives focus.

card.on('focus', (event) => {
console.log(`Field focused: ${event.field}`);
// event.field is 'cardNumber', 'expiry', 'cvc', or 'cardholderName'
});

Fired when any field inside the iframe loses focus. Useful for triggering your own validation UI.

card.on('blur', (event) => {
console.log(`Field blurred: ${event.field}`);
if (!event.complete) {
highlightContainer('warning');
}
});

Fired when a non-recoverable error occurs inside the iframe (e.g. network failure loading the form). This is different from validation errors in the change event.

card.on('error', (event) => {
console.error('Iframe error:', event.code, event.message);
showFallbackUI();
});

Processes a full payment using the card data captured in the iframe. The SDK tokenizes the card, creates the payment, handles installment selection (MSI) and 3D Secure automatically, and polls for the final result.

const { accessToken } = await fetch('/api/payment-token').then(r => r.json());
card.on('cta_clicked', async () => {
const { payment, error } = await zatlas.checkout({
accessToken,
amount: 50000,
currency: 'mxn',
reservationId: 'RES-789',
description: 'Suite Deluxe - 2 nights',
installments: { required: true },
metadata: { bookingRef: 'BK-001' },
});
if (payment) {
// payment.id — 'pay_...'
// payment.status — 'succeeded'
// payment.amount — 50000
window.location.href = `/confirmation?payment=${payment.id}`;
} else {
console.error(error.code, error.message);
}
});
OptionTypeRequiredDefaultDescription
accessTokenstringYesOAuth2 access token from your server. Short-lived (1 hour).
amountnumberYesPayment amount in currency units (e.g. 12000 = $12,000.00 MXN).
currencystringYesThree-letter ISO 4217 currency code, lowercase. Example: 'mxn', 'usd'.
reservationIdstringYesYour reservation or booking identifier. Used for reconciliation.
descriptionstringNoundefinedHuman-readable description shown on the guest’s card statement (if supported by the acquirer).
installments{ required: boolean }NoundefinedPass { required: true } to show the installment (MSI) picker inside the iframe. The guest selects 3, 6, 9, 12, 18, or 24 months. Omit or set to undefined for single payment.
metadataRecord<string, string>NoundefinedArbitrary key-value pairs attached to the payment. Useful for internal references. Max 20 keys, 500 chars per value.
// On success
type CheckoutSuccess = {
payment: {
id: string; // 'pay_...'
methodId: string; // 'mth_...' — reusable for future charges
status: 'succeeded';
amount: number;
currency: string;
installments?: { count: number; perInstallment: number }; // null if single payment
card: {
brand: string; // 'visa', 'mastercard', etc.
last4: string; // '4242'
expMonth: number; // 12
expYear: number; // 2030
};
createdAt: string; // ISO 8601
};
error: null;
};
// On failure
type CheckoutFailure = {
payment: null;
error: {
code: string; // e.g. 'card_declined', 'insufficient_funds'
message: string; // human-readable, localized
declineCode?: string; // raw decline code from the acquirer, if available
};
};
type CheckoutResult = CheckoutSuccess | CheckoutFailure;

Tokenizes the card data captured in the iframe and returns a reusable mth_* payment method token. Your server stores this token and charges later via the Payments API.

const { accessToken } = await fetch('/api/payment-token').then(r => r.json());
card.on('cta_clicked', async () => {
const { token, error } = await zatlas.createToken({
accessToken,
currency: 'mxn',
metadata: { guestId: 'G-42' },
});
if (token) {
// token.id — 'mth_...'
// token.card — { brand, last4, expMonth, expYear }
await fetch('/api/save-method', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
methodId: token.id,
brand: token.card.brand,
last4: token.card.last4,
}),
});
showSuccess('Card saved');
} else {
console.error(error.code, error.message);
}
});
OptionTypeRequiredDefaultDescription
accessTokenstringYesOAuth2 access token from your server.
currencystringYesThree-letter ISO 4217 currency code. Used to validate the card against the correct acquirer.
metadataRecord<string, string>NoundefinedArbitrary key-value pairs attached to the payment method. Max 20 keys, 500 chars per value.
// On success
type TokenSuccess = {
token: {
id: string; // 'mth_...'
card: {
brand: string; // 'visa', 'mastercard', etc.
last4: string; // '4242'
expMonth: number; // 12
expYear: number; // 2030
};
createdAt: string; // ISO 8601
};
error: null;
};
// On failure
type TokenFailure = {
token: null;
error: {
code: string; // e.g. 'card_declined', 'invalid_card_number'
message: string; // human-readable, localized
};
};
type TokenResult = TokenSuccess | TokenFailure;

Changes the visual theme of the card form at runtime without remounting. Useful for toggling between light and dark modes.

// Switch to dark theme
import { darkTheme } from '@zatlas/card-capture';
zatlas.updateTheme(darkTheme);
// Switch back to default
import { defaultTheme } from '@zatlas/card-capture';
zatlas.updateTheme(defaultTheme);

You can also pass a partial theme object — only the properties you include are updated:

zatlas.updateTheme({
colors: {
primary: '#1a73e8',
borderFocus: '#1a73e8',
background: '#f9fafb',
},
borders: {
radius: '12px',
},
});

See the Theming Guide for the full list of customizable properties.


Errors returned by checkout() and createToken() fall into three categories.

Returned when the card issuer or acquirer rejects the transaction. These are shown to the guest inside the iframe automatically.

CodeDescriptionRecoverable
card_declinedGeneric decline. The issuer did not provide a reason.Yes
insufficient_fundsThe card does not have enough balance.Yes
expired_cardThe card has expired.No
incorrect_cvcThe CVC does not match.Yes
incorrect_numberThe card number is wrong.Yes
lost_cardThe card has been reported lost.No
stolen_cardThe card has been reported stolen.No
pickup_cardThe issuer requests the card be retained.No
do_not_honorThe issuer declined without a specific reason.Yes
fraudulentThe issuer flagged this as a fraudulent transaction.No
processing_errorA transient error at the acquirer.Yes
try_again_laterThe issuer is temporarily unavailable.Yes

Recoverable = Yes means the guest can retry with different card details or after contacting their bank.

Returned when the SDK cannot complete the request due to network or server issues. These are not caused by the card data itself.

CodeDescriptionWhat to do
network_errorCould not reach the Zatlas API. The guest may be offline.Show a retry button. Check the guest’s connection.
timeoutThe request timed out waiting for a response.Retry once. If it persists, contact support.
server_errorZatlas API returned an unexpected error (5xx).Retry after a brief delay. If it persists, contact the Zatlas team.
authentication_errorThe access token is invalid, expired, or missing.Fetch a new access token from your server and retry.
rate_limit_exceededToo many requests from this publishable key.Back off and retry after a few seconds.
invalid_requestThe request parameters are malformed (e.g. missing amount).Check the parameters passed to checkout() or createToken(). This is a code bug, not a guest error.

Returned in the change event payload when the guest’s input fails client-side validation. These are shown inline next to the field inside the iframe.

CodeDescriptionTrigger
incomplete_numberThe card number is too short.Guest has not finished typing the full card number.
invalid_numberThe card number fails the Luhn check.Guest entered an impossible card number.
incomplete_expiryThe expiry date is incomplete.Guest typed only the month or left the field blank.
invalid_expiry_pastThe expiry date is in the past.Guest entered a month/year that has already passed.
incomplete_cvcThe CVC is too short.Guest entered fewer digits than required (3 for Visa/MC, 4 for Amex).
invalid_cvcThe CVC contains non-numeric characters.Guest typed letters or symbols in the CVC field.
invalid_holder_nameThe cardholder name is too short.Guest typed less than 2 characters (name field is optional — empty is valid).

The SDK ships React bindings for seamless integration with React and Next.js projects.

Wraps your app (or the payment section) with the SDK instance. Create the ZatlasCardCapture instance first, then pass it to the provider.

import { ZatlasCardCapture } from '@zatlas/card-capture';
import { ZatlasProvider } from '@zatlas/card-capture/react';
const zatlas = new ZatlasCardCapture({
publishableKey: 'pk_sandbox_your_key',
locale: 'es-MX',
});
function App() {
return (
<ZatlasProvider zatlas={zatlas}>
<PaymentPage />
</ZatlasProvider>
);
}

Hook that returns the ZatlasCardCapture instance from the nearest ZatlasProvider. Use it to call checkout() or createToken().

import { useZatlas } from '@zatlas/card-capture/react';
function PaymentPage() {
const zatlas = useZatlas();
// Use zatlas.checkout() or zatlas.createToken() in event handlers
}

Renders the card form iframe. Handles mounting, unmounting, and event binding automatically. The cta_clicked event is handled via card.on() on the vanilla instance — use useZatlas() to access it.

import { CardElement, useZatlas } from '@zatlas/card-capture/react';
function PaymentForm() {
const zatlas = useZatlas();
return (
<CardElement
options={{ mode: 'checkout' }}
onReady={() => console.log('Card form ready')}
onChange={(e) => console.log('Valid:', e.complete)}
onFocus={() => console.log('Focused')}
onBlur={() => console.log('Blurred')}
onError={(e) => console.error('Error:', e.code)}
/>
);
}

To handle the CTA button click and trigger checkout, use the vanilla API alongside the React component:

import { useEffect, useRef } from 'react';
import { ZatlasCardCapture } from '@zatlas/card-capture';
function CheckoutForm({ amount, reservationId }) {
const cardRef = useRef(null);
useEffect(() => {
const zatlas = new ZatlasCardCapture({
publishableKey: 'pk_sandbox_your_key',
locale: 'es-MX',
});
const card = zatlas.create('card', { mode: 'checkout' });
card.mount(cardRef.current);
const { accessToken } = await fetch('/api/payment-token').then(r => r.json());
card.on('cta_clicked', async () => {
const { payment, error } = await zatlas.checkout({
accessToken,
amount,
currency: 'mxn',
reservationId,
});
if (payment) window.location.href = `/success?id=${payment.id}`;
});
return () => card.unmount();
}, [amount, reservationId]);
return <div ref={cardRef} />;
}

CardElement Props:

PropTypeRequiredDescription
optionsCardElementOptionsNoOptions object with mode, showCardholderName, showPostalCode.
onReady() => voidNoCalled when the iframe is loaded and interactive.
onChange(event: ChangeEvent) => voidNoCalled on every input change. See change event.
onFocus() => voidNoCalled when a field receives focus.
onBlur() => voidNoCalled when a field loses focus.
onError(error: FieldError) => voidNoCalled on non-recoverable iframe errors.
classNamestringNoCSS class applied to the outer <div> wrapper.
idstringNoID applied to the outer <div> wrapper.

The SDK ships with built-in themes. Import them by name or pass a custom theme object to the constructor or updateTheme().

import { darkTheme, mergeTheme } from '@zatlas/card-capture';
// Built-in dark theme
const zatlas = new ZatlasCardCapture({
publishableKey: 'pk_sandbox_your_key',
theme: darkTheme,
});
// Custom overrides (deep-merged with default theme)
const zatlas = new ZatlasCardCapture({
publishableKey: 'pk_sandbox_your_key',
theme: {
colors: {
primary: '#1a73e8',
borderFocus: '#1a73e8',
background: '#f9fafb',
text: '#111827',
error: '#ef4444',
},
borders: {
radius: '12px',
},
},
});

Built-in themes: defaultTheme (light, teal accents) and darkTheme (dark background, lighter accents). Use mergeTheme() to extend either one.

For the full list of theme properties and visual examples, see the Theming Guide.