> For a complete page index, fetch https://docs.transak.com/llms.txt
# Headless Cards
**Headless Cards** is a lightweight, embeddable UI module that allows partners to offer credit/debit card payments directly within their own application without loading any widget.
#### [Saved Cards](#check-for-saved-cards-using-backend-only)
Retrieve a user's previously saved cards, enabling one step checkout without re entering payment details.
#### [Add New Card](#create-a-transaction-session-using-backend-only)
Renders the card payment UI via the Transak SDK for users paying with a new credit or debit card.
#### [Delete Saved Card](/api/headless-cards/delete-saved-cards)
Allows users to delete a saved credit or debit card at any time.
## Problem Statement
Currently, Transak requires loading the full widget for card payments, which forces users to go through multiple screens before reaching the payment form. This creates friction and limits partner control over the payment experience.
Here are some of the **key challenges** with the current approach:
|
**Full widget required**
Partners must load the entire Transak widget to accept card payments.
|
|
**Multiple screens before payment**
Users navigate through several Transak screens before they ever see the card form, increasing drop-off risk.
|
|
**Disconnected payment experience**
The payment flow feels separate from the partner's own UI, breaking the continuity.
|
|
**Limited partner control**
Partners have no control over when or where the card form appears — placement and styling are determined by the widget.
|
## Our Solution
Headless Cards exposes just the card payment form as a standalone, embeddable component. Partners control where it sits, how it looks, and what happens after payment. Transak handles all the payment infrastructure in the background.
Here are some of the **key benefits** of the Headless Cards solution:
|
**Just the card form**
Embed only the card payment form — no full widget required.
|
|
**Fewer steps to payment**
Users see the card form immediately within the partner UI, reducing drop-off.
|
|
**Seamless checkout integration**
The card form sits inside the partner's own checkout UI, keeping the experience continuous.
|
|
**Full partner control**
Partners decide where the form appears, how it looks, and what happens after payment.
|
## **How does it work?**

## Current Limitations
|
Limitation
|
Details
|
|
**Headless Cards APIs\
([Transaction Session API](/api/headless-cards/transaction-session-api), [Create Order (with New Card) API](/api/headless-cards/create-order-with-new-card), [Get Saved Cards API](/api/headless-cards/get-saved-cards), [Create Order (with Saved Card) API](/api/headless-cards/create-order-with-saved-card), [Delete Saved Cards API](/api/headless-cards/delete-saved-cards), [Transaction Request Status API](/api/headless-cards/transaction-request-status-api))**
|
APIs are to be called only from the partner backend and subjected to the whitelisting of partner IP addresses. We don't support API calls from the frontend due to security restrictions.
|
|
**Supported for JS, React, and React Native integrations**
|
The Transak UI SDK is available for JS, React, and React Native integrations.
|
|
**Card payment availability**
|
Card payments are only supported if the [Get Fiat Currencies API](/api/whitelabel/lookup/get-fiat-currencies) response includes payment method `credit_debit_card` for that particular fiat currency.
|
## How to integrate?
#### Whitelist Your API Key & Enable Headless Cards
| Action |
| ---------------------------------------------------------------------------------------------------------------------- |
| Follow the steps in the [Need help in Integration](/getting-started/help-and-support#need-help-in-integration) section |
| Request **API key whitelisting** and ask to **enable Headless Cards** for your API key |
| Share your public IP addresses with Transak for whitelisting to use our APIs in your backend |
#### User Authentication
You can use either of the following authentication options:
| Option | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **White-label Auth** | Use the standard Transak authentication flow to generate a user access token. Partners can do this by calling the [Send User OTP API](/api/whitelabel/user/send-user-otp) followed by the [Verify User API](/api/whitelabel/user/verify-user-otp) to generate the access token. Learn more |
| **Auth Reliance** | Use [Auth Reliance](/features/auth-reliance) by passing these headers with every request: `x-user-identifier` and `x-access-token` |
Please refer to the tutorial on [how to create partner access token](/guides/how-to-create-partner-access-token).
#### User KYC
KYC is a mandatory step in compliance with regulatory requirements. Each user should be
KYC Approved
. You can use either of the following KYC options:
| Option | Description |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **White label KYC** | Partners can collect the required KYC information on their end and then forward it to Transak for review and approval. Learn more: [Whitelabel KYC](/integration/api#kyc) |
| **KYC Reliance via Sumsub** | Partners can share their KYC data from their platform with Transak using Sumsub. Learn more: [KYC Reliance Guide](/features/kyc-reliance#using-sumsub) |
#### Generate a quote using the Quote API
Call the [Get Quote API](https://docs.transak.com/api/whitelabel/lookup/get-quote) to get a quote for the transaction. Pass the apiKey, fiat amount, fiat currency, crypto currency, network, and order type.
Set `paymentMethod` to `credit_debit_card` while creating a quote.
A successful response returns a `quoteId`.
#### Check for saved cards (using Backend only)
Call the [Get Saved Cards API](/api/headless-cards/get-saved-cards) to check whether the user has any previously saved credit/debit cards. A successful response returns a `cards` array.
| Case | Next step |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| No saved cards | Go to [Create a transaction session](#create-a-transaction-session-using-backend-only) to let the user add a new card |
| Saved card(s) found | Go to [Place order using the saved card](#place-order-using-the-saved-card-using-backend-only) |
#### Place order using the saved card (using Backend only)
If the user picks one of the saved cards, call the [Create Order (with Saved Card) API](/api/headless-cards/create-order-with-saved-card) from your backend using the `quoteId`, `walletAddress`, and the selected card's `paymentIdentifierId`.
| Parameter | Description |
| --------------------- | -------------------------------------------------------------------------------------------------- |
| `quoteId` | Quote ID returned by the [Get Quote API](https://docs.transak.com/api/whitelabel/lookup/get-quote) |
| `paymentInstrumentId` | Always `credit_debit_card` |
| `walletAddress` | The user's wallet address for the selected cryptocurrency and network |
| `paymentIdentifierId` | The saved card's identifier returned by the Get Saved Cards API |
| `additionalData` | `successUrl` and `failureUrl` to redirect the user after the payment |
A successful response returns the full order details with `redirectUrl`. Continue with the [Open the redirectUrl in a browser or WebView](#open-the-redirecturl-in-a-browser-or-webview) step below.
#### Create a transaction session (using Backend only)
Call the [Transaction Session API](/api/headless-cards/transaction-session-api) from your backend using the `quoteId`, `successUrl`, `failureUrl` and the user's wallet address. You can optionally pass a `config` and `billingAddress` object to customise the look and feel of the card component and billing details.
| Parameter | Description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `quoteId` | Quote ID returned by the [Get Quote API](https://docs.transak.com/api/whitelabel/lookup/get-quote) in the previous step |
| `walletAddress` | The user's wallet address for the selected cryptocurrency and network |
| `successUrl` | URL to redirect the user to when the transaction completes successfully |
| `failureUrl` | URL to redirect the user to when the transaction fails or is cancelled |
A successful response returns a `sessionId`.
#### Load the Card Component via Transak UI SDK
Use the Transak UI SDK to render the card payment component. Pass the `sessionId` received in the previous step.
#### JS
```bash
npm install @transak/ui-components
```
```tsx
import { createTransakCard } from '@transak/ui-components';
const card = createTransakCard({
sessionId, // sessionId from previous step
environment, // 'STAGING' | 'PRODUCTION'
onReady: () => {
// Component is ready
},
onChange: ({ isValid, errorCode }) => {
// Fires on form-state changes
},
onSuccess: ({ requestId }) => {
// Payment data captured — use requestId in the next step
},
onError: ({ code }) => {
// Handle error
},
});
await card.mount('checkout-slot');
card.submit(); // Partner-triggered tokenisation
// and then
card.unmount();
```
#### React
```bash
npm install @transak/ui-components-react
```
```tsx
import { useRef } from 'react';
import { TransakCard, type TransakCardRef } from '@transak/ui-components-react';
const cardRef = useRef(null);
{
// Component is ready
}}
onChange={({ isValid, errorCode }) => {
// Fires on form-state changes
}}
onSuccess={({ requestId }) => {
// Payment data captured — use requestId in the next step
}}
onError={({ code }) => {
// Handle error
}}
/>
// elsewhere
cardRef.current?.submit();
```
#### React Native
```bash
npm install @transak/ui-components-rn
```
```tsx
import { useRef } from 'react';
import { TransakCard, type TransakCardRef } from '@transak/ui-components-rn';
const cardRef = useRef(null);
{
// Component is ready
}}
onChange={({ isValid, errorCode }) => {
// Fires on form-state changes
}}
onSuccess={({ requestId }) => {
// Payment data captured — use requestId in the next step
}}
onError={({ code }) => {
// Handle error
}}
/>
// elsewhere
cardRef.current?.submit();
```
**Error codes**
The `onChange` callback fires repeatedly as the user types and receives `isValid` and an optional `errorCode`:
| Code | Description |
| -------------- | ------------------------------------------- |
| `CARD_INVALID` | The card details entered are invalid |
| `BIN_BLOCKED` | The card's BIN is blocked and can't be used |
The `onError` callback receives a `code` value. Use it to handle specific failure scenarios:
| Code | Description |
| ------------------------ | -------------------------------------------- |
| `CONFIG_LOAD_FAILED` | Card configuration could not be loaded |
| `PAYMENT_CAPTURE_FAILED` | Card payment capture failed |
| `INVALID_OPTIONS` | Invalid or missing options passed to the SDK |
| `IFRAME_LOAD_FAILED` | The embedded iframe failed to load |
| `INVALID_STATE` | SDK method called in an unexpected state |
#### Place order using the new card (using Backend only)
Once the SDK fires `onSuccess` with a `requestId`, call the [Create Order (with New Card) API](/api/headless-cards/create-order-with-new-card) from your backend using the `requestId` to complete the payment and create the order.
A successful response returns the full order details with `redirectUrl`. Continue with the [Open the redirectUrl in a browser or WebView](#open-the-redirecturl-in-a-browser-or-webview) step below.
#### Track the \`requestId\` (using Backend only)
Call the [Transaction Request Status API](/api/headless-cards/transaction-request-status-api) to check whether the request has been processed. Poll this endpoint until the status reaches a terminal state.
Once you receive an `orderId`, use the [Get Order by ID](https://docs.transak.com/api/public/get-order-by-order-id) API to fetch full order details, which will contain the `redirectUrl`.
#### Open the redirectUrl in a browser or WebView
Open the `redirectUrl` returned in the previous step in the browser or webview to complete any 3DS or bank authentication required by the payment provider.
Upon completing the transaction, the user will be redirected to either the `successUrl` or `failureUrl` you passed in the [Transaction Session API](/api/headless-cards/transaction-session-api) in case of a new card, or the [Create Order (with Saved Card) API](/api/headless-cards/create-order-with-saved-card) in case of a saved card.
| Outcome | Redirect destination |
| ------------------ | ------------------------------------------------------------------------------------ |
| Payment successful | `successUrl` passed in Transaction Session API or Create Order (with Saved Card) API |
| Payment failed | `failureUrl` passed in Transaction Session API or Create Order (with Saved Card) API |
## API Overview
#### [Transaction Session API](/api/headless-cards/transaction-session-api)
Creates a transaction session using a quote ID and wallet address, returns a `sessionId` to initialise the card payment component.
#### [Create Order (with New Card)](/api/headless-cards/create-order-with-new-card)
Places a crypto buy order using a newly added credit/debit card, based on the `requestId` returned by the SDK's onSuccess callback.
#### [Transaction Request Status API](/api/headless-cards/transaction-request-status-api)
Polls the status of the `requestId` until it reaches a terminal state.
#### [Get Saved Cards](/api/headless-cards/get-saved-cards)
Retrieves the user's saved credit/debit cards.
#### [Create Order (with Saved Card)](/api/headless-cards/create-order-with-saved-card)
Places a crypto buy order using a previously saved credit/debit card.
#### [Delete Saved Cards](/api/headless-cards/delete-saved-cards)
Deletes a user's saved credit/debit card.
## API Errors
#### Transaction Session API
| HTTP Status | Error Code | Message |
| ----------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| 400 | 6099 | successUrl and failureUrl are required for credit/debit card payments. |
| 401 | 1002 | Invalid or missing authentication token. |
| 422 | 6002 | KYC is not approved. Please complete KYC before creating a session. |
| 422 | 6003 | This feature is not enabled for your account. Please contact support. |
| 422 | 6005 | Quote not found or could not be loaded. |
| 422 | 6005 | This payment method is not currently supported. Please try a different payment method. |
| 422 | 6006 | The provided wallet address is invalid for the selected cryptocurrency and network. |
| 400 | 2030 | Your account has been disabled. Please get in touch with us at [fraud@transak.com](mailto:fraud@transak.com). |
| 500 | 6005 | Failed to create a session for the user. |
#### Create Order (with New and Saved Card) API
| HTTP Status | Error Code | Message |
| ----------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| 404 | 6007 | Request ID not found. |
| 409 | 4005 | Order exists. |
| 422 | 4001 | Invalid wallet address. Please provide a valid wallet address to proceed. |
| 422 | 4003 | Please upgrade your kyc to next level to proceed with this transaction. |
| 422 | 4013 | Minimum amount should be more than \{amount}. |
| 422 | 4015 | Invalid payment method for currency combination. |
| 422 | 4016 | FCA criteria not met, Please complete the assessments. |
| 422 | 6012 | KYC requirement is not approved for this transaction. |
| 422 | 6014 | Unable to process request. User location data is required for this transaction. |
| 400 | 2030 | Your account has been disabled. Please get in touch with us at [fraud@transak.com](mailto:fraud@transak.com). |
| 500 | 4021 | Something went wrong, try again later! |
| 500 | 6099 | Unable to process the order. Please try again. |
#### Transaction Request Status API
| HTTP Status | Error Code | Message |
| ----------- | ---------- | ------------------------------------------------------------------------------- |
| 404 | 6007 | Request ID not found. |
| 409 | 4005 | Order exists. |
| 422 | 4001 | Invalid wallet address. Please provide a valid wallet address to proceed. |
| 422 | 4003 | Please upgrade your kyc to next level to proceed with this transaction. |
| 422 | 4013 | Minimum amount should be more than \{amount}. |
| 422 | 4015 | Invalid payment method for currency combination. |
| 422 | 4016 | FCA criteria not met, Please complete the assessments. |
| 422 | 6011 | KYC requirement is not approved for this transaction. |
| 422 | 6014 | Unable to process request. User location data is required for this transaction. |
| 500 | 4006 | Unable to create order. |
| 500 | 4021 | Something went wrong, try again later! |
| 500 | 6099 | Unable to process the order. Please try again. |
## Interactive Demo
> Embed a card payment form in your own interface without routing users through the Transak widget.