Overview
Generates a time-limited secure token that allows you to display sensitive card information (full PAN, CVV, expiry date) as an image without ever handling this data directly in your application. The token provides access to a secure image URL that renders card details in a PCI-compliant manner.
PCI Compliance Made Easy This endpoint eliminates PCI compliance burden by returning card details as a secure image. Your application never touches or stores the actual card details.
Authentication
This endpoint requires authentication via Bearer token:
Authorization: Bearer YOUR_ACCESS_TOKEN
Request
Your public API client key
Set to true to route requests to the US backend environment
Bearer token for authentication
Body
The request body is optional . If omitted, default styling will be applied to the card image.
Customize the visual appearance of the card details image to match your brand Show customCss properties
customCss.cardBackgroundColor
Background color of the card image Example: #1A1A1A, #2563EB
Text color for card information Important: Avoid using the same color as cardBackgroundColor for readabilityExample: #FFFFFF, #F3F4F6
customCss.panBackgroundColor
Background color for the PAN number display area Example: #F9FAFB, #E5E7EB
Text color for PAN number Important: Avoid using the same color as panBackgroundColor for readabilityExample: #000000, #111827
Request Example
cURL
JavaScript
Python
TypeScript
curl -X POST https://dev.api.baanx.com/v1/card/details/token \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customCss": {
"cardBackgroundColor": "#000000",
"cardTextColor": "#FFFFFF",
"panBackgroundColor": "#EFEFEF",
"panTextColor": "#000000"
}
}'
Response
Success Response
Secure, time-limited token (UUID format) Lifetime: ~10 minutesUsage: Single-use token that becomes invalid after the image is accessed
URL that renders card details as a secure image Usage: Display card details by using this URL as the src attribute of an <img> tagFormat: <HOST>/details-image?token={token}Security: Treat this URL as highly sensitive. Do not log or store it.
{
"token" : "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb" ,
"imageUrl" : "https://cards.baanx.com/details-image?token=100a99cf-f4d3-4fa1-9be9-2e9828b20ebb"
}
Error Responses
401 - Unauthorized
403 - Forbidden
404 - Card Not Found
422 - Validation Error
498 - Invalid Client Key
499 - Missing Client Key
500 - Internal Server Error
{
"message" : "Not authenticated"
}
Integration Method
Display card details as a secure image without interactive elements.
Basic Implementation
const { imageUrl } = await generateCardDetailsToken ({
customCss: {
cardBackgroundColor: '#000000' ,
cardTextColor: '#FFFFFF' ,
panBackgroundColor: '#EFEFEF' ,
panTextColor: '#000000'
}
});
const img = document . createElement ( 'img' );
img . src = imageUrl ;
img . alt = 'Card Details' ;
img . style . maxWidth = '100%' ;
img . style . borderRadius = '12px' ;
document . getElementById ( 'card-image-container' ). appendChild ( img );
React Component Example
import { useState } from 'react' ;
export function CardDetailsImage () {
const [ imageUrl , setImageUrl ] = useState < string | null >( null );
const [ loading , setLoading ] = useState ( false );
const [ error , setError ] = useState < string | null >( null );
const handleViewCard = async () => {
setLoading ( true );
setError ( null );
try {
const response = await fetch ( 'https://dev.api.baanx.com/v1/card/details/token' , {
method: 'POST' ,
headers: {
'x-client-key' : 'YOUR_CLIENT_KEY' ,
'Authorization' : 'Bearer YOUR_ACCESS_TOKEN' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
customCss: {
cardBackgroundColor: '#000000' ,
cardTextColor: '#FFFFFF' ,
panBackgroundColor: '#EFEFEF' ,
panTextColor: '#000000'
}
})
});
if ( ! response . ok ) {
throw new Error ( 'Failed to generate card details token' );
}
const data = await response . json ();
setImageUrl ( data . imageUrl );
} catch ( err ) {
setError ( err instanceof Error ? err . message : 'An error occurred' );
} finally {
setLoading ( false );
}
};
return (
< div >
< button onClick = { handleViewCard } disabled = { loading } >
{ loading ? 'Loading...' : 'View Card Details' }
</ button >
{ error && < div className = "error" > { error } </ div > }
{ imageUrl && (
< div className = "card-image-container" >
< img
src = { imageUrl }
alt = "Card Details"
style = {{ maxWidth : '100%' , borderRadius : '12px' }}
/>
< button onClick = {() => setImageUrl ( null )} > Close </ button >
</ div >
)}
</ div >
);
}
Security Note Image URLs contain sensitive card information. Always:
Use HTTPS only
Never log or store the imageUrl
Display in secure contexts only
Clear the image from DOM when user is done viewing
Customization Examples
Dark Mode Theme
{
"customCss" : {
"cardBackgroundColor" : "#1F2937" ,
"cardTextColor" : "#F9FAFB" ,
"panBackgroundColor" : "#374151" ,
"panTextColor" : "#F3F4F6"
}
}
Light Mode Theme
{
"customCss" : {
"cardBackgroundColor" : "#FFFFFF" ,
"cardTextColor" : "#111827" ,
"panBackgroundColor" : "#F3F4F6" ,
"panTextColor" : "#1F2937"
}
}
Brand Colors
{
"customCss" : {
"cardBackgroundColor" : "#2563EB" ,
"cardTextColor" : "#FFFFFF" ,
"panBackgroundColor" : "#DBEAFE" ,
"panTextColor" : "#1E40AF"
}
}
Security Considerations
Token Lifetime and Single-Use
Tokens expire after ~10 minutes
Tokens are single-use and become invalid after first access
Generate a new token each time the user wants to view card details
Never store or cache tokens
PCI Compliance By using this endpoint, you avoid PCI compliance requirements as sensitive card data is delivered as an image. Your servers and frontend code never handle the actual card details.
URL Security
Treat imageUrl as highly sensitive data
Don’t log or store these URLs
Use HTTPS only
Display only in authenticated, secure contexts
Best Practices
Error Handling
async function showCardDetails () {
try {
const { imageUrl } = await generateCardDetailsToken ({
customCss: {
cardBackgroundColor: '#000000' ,
cardTextColor: '#FFFFFF' ,
panBackgroundColor: '#EFEFEF' ,
panTextColor: '#000000'
}
});
const img = document . createElement ( 'img' );
img . src = imageUrl ;
img . alt = 'Card Details' ;
img . style . maxWidth = '100%' ;
document . getElementById ( 'card-container' ). appendChild ( img );
} catch ( error ) {
if ( error . response ?. status === 404 ) {
alert ( 'No card found. Please order a card first.' );
} else if ( error . response ?. status === 401 ) {
alert ( 'Session expired. Please log in again.' );
} else if ( error . response ?. status === 422 ) {
alert ( 'Invalid styling parameters. Please check your customCss values.' );
} else {
alert ( 'Failed to load card details. Please try again.' );
}
}
}
Cleanup After Viewing
function createCardViewer () {
let currentImage : HTMLImageElement | null = null ;
async function showCard () {
const { imageUrl } = await generateCardDetailsToken ();
currentImage = document . createElement ( 'img' );
currentImage . src = imageUrl ;
currentImage . alt = 'Card Details' ;
document . getElementById ( 'card-container' ). appendChild ( currentImage );
}
function hideCard () {
if ( currentImage ) {
currentImage . remove ();
currentImage = null ;
}
}
return { showCard , hideCard };
}
const cardViewer = createCardViewer ();
Common Issues and Solutions
Symptom: Image fails to load with “Invalid or expired token” errorCause: Token has expired (>10 minutes old) or was already usedSolution: Generate a new token. Never reuse or cache tokens.
Symptom: Text is difficult to read on the card imageCause: Text color and background color are too similarSolution: Ensure sufficient contrast between text and background colors. Avoid using the same hex value for both.
Symptom: Image element shows broken image iconCause: Token may be invalid, expired, or network issueSolution: const img = document . createElement ( 'img' );
img . onerror = () => {
console . error ( 'Failed to load card image' );
alert ( 'Unable to display card details. Please try again.' );
};
img . src = imageUrl ;
Symptom: Request fails with 422 status codeCause: Invalid customCss parameters (e.g., malformed hex colors)Solution: Ensure all color values are valid 6-digit hex codes starting with #. Example: #1A1A1A, not 1A1A1A or #1A1A
GET /v1/card/status - Get basic card information before generating token
POST /v1/card/pin/token - Generate token to view card PIN
POST /v1/card/set-pin/token - Generate token to set/change card PIN
POST /v1/card/freeze - Temporarily disable card
POST /v1/card/order - Order a new card