Introduction
The Server-to-Server (S2S) Card Payment integration provides a secure way to process card transactions directly from your backend while maintaining PCI compliance. Support both new card payments and saved card tokens through dedicated APIs for optimal user experience and security.
3D Secure Ready Built-in 3D Secure authentication for enhanced security and compliance
Card Tokenization Save cards using dedicated API for faster repeat payments without storing sensitive data
Real-time Callbacks Receive instant payment status updates via server-to-server webhooks
3D Secure Authentication
3D Secure (3DS) is an authentication protocol that adds an extra layer of security for online card transactions. When a payment requires 3DS verification, EximPe returns an ACS (Access Control Server) template that must be rendered in the customer’s browser to complete authentication.
Prerequisites
Before you begin, ensure you have:
Credentials : Your Client ID and Client Secret
Domain Whitelist : Whitelisted your website domain for integration
Webhook URL : A secure endpoint to receive payment status updates
Callback URL : A publicly accessible URL configured in your EximPe dashboard for server-to-server callbacks.
HTTPS Endpoint : All card payment endpoints must use HTTPS for security compliance.
3DS Integration : Frontend capability to render HTML forms for 3D Secure authentication.
The following steps allow you to integrate server-to-server card payments:
Initiate payment (new card or saved token)
Handle 3D Secure authentication (if required)
Check payment transaction status
EximPe sends Server-to-Server callback response
Step 1: Initiate Payment
New Card Payment
For first-time card payments, provide complete card details:
{
"amount" : "1000.00" ,
"currency" : "INR" ,
"reference_id" : "CARD_13MYHALESH7" ,
"return_url" : "https://yoursite.com/payment/callback/" ,
"collection_mode" : "s2s" ,
"mop_type" : "debit_card" ,
"card_details" : {
"nickname" : "VISA Debit" ,
"number" : "4895380110000003" ,
"cardholder_name" : "John Doe" ,
"expiry_month" : "05" ,
"expiry_year" : "2030" ,
"cvv" : "123" ,
"network" : "visa" ,
"identifier" : "EX0001" ,
"save_card" : true
},
"buyer" : {
"name" : "John Doe" ,
"email" : "[email protected] " ,
"phone" : "+919876543210" ,
"address" : {
"line_1" : "123 Main Street" ,
"line_2" : "Apt 4B" ,
"city" : "City" ,
"state" : "State" ,
"postal_code" : "123456"
},
"ip_address" : "192.168.1.100" ,
"user_agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
},
"product" : {
"name" : "Sample Product" ,
"description" : "This is a sample product description" ,
"hs_code" : "98051000" ,
"hs_code_description" : "Portable automatic data processing machines" ,
"type_of_goods" : "physical_goods"
},
"invoice" : {
"number" : "INV_0HOZ0C" ,
"date" : "2025-09-04"
}
}
Saved Card Token Payment
For repeat payments using previously saved cards:
{
"amount" : "1000.00" ,
"currency" : "INR" ,
"reference_id" : "CARD_4FQ0AIHQEI9" ,
"return_url" : "https://yoursite.com/payment/callback/" ,
"collection_mode" : "s2s" ,
"mop_type" : "credit_card" ,
"card_details" : {
"token" : "1e6709282a21e83f43a020" ,
"identifier" : "EX0001" ,
"network" : "visa"
},
"buyer" : {
"name" : "John Doe" ,
"email" : "[email protected] " ,
"phone" : "+919876543210" ,
"address" : {
"line_1" : "123 Main Street" ,
"line_2" : "Apt 4B" ,
"city" : "City" ,
"state" : "State" ,
"postal_code" : "123456"
},
"ip_address" : "192.168.1.100" ,
"user_agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
},
"product" : {
"name" : "Sample Product" ,
"description" : "This is a sample product description" ,
"hs_code" : "98051000" ,
"hs_code_description" : "Portable automatic data processing machines" ,
"type_of_goods" : "physical_goods"
},
"invoice" : {
"number" : "INV_3MUK2I" ,
"date" : "2025-09-04"
}
}
For S2S Card Payment requests, you must include these required parameters:
collection_mode: must be set to "s2s"
mop_type: either "CREDIT_CARD" or "DEBIT_CARD"
buyer.ip_address: the customer’s device IP address (used for fraud prevention)
buyer.user_agent: the customer’s browser user-agent string (used for fraud prevention)
card_details: either complete card information (including optional save_card: true) or saved token details
S2S Card Payment Response
{
"success" : true ,
"message" : "S2S Card Payment Request created successfully" ,
"data" : {
"order_id" : "OD9888127185" ,
"acs_template": "PGh0bWw+PGJvZHk+PGZvcm0gbmFtZT0icGF5bWVudF9wb3N0IiBpZD0icGF5bWVudF9wb3N0IiBhY3Rpb249Imh0dHBzOi8vdGVzdC5wYXl1LmluL2UxMGMzNmExYWQ2YTQ1OTkzMWNhODYzNTBhZjIxZDU0ZDhiMTZhODRjYWQ1NDAxMDE2OGFlN2RjYmEwMmEwYWEvdGhyZWVEU2VjdXJlL21ldGhvZCIgbWV0aG9kPSJwb3N0Ij48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJQYVJlcSIgdmFsdWU9ImVkZTFmODA0MzBiMzgzYmY0OGZjNjRmZGMxNjE5YzM2YTlkYzVjM2NjMGI5YjQ4NDZkMDU5MTY2ZGUzMmM1MTQ1NDdhMGNiMmM5MTBhMmM4ZTFlY2E3ZTI1NzAxZWNiMzdhOGFjMGZiZjNjYTEwYjE2OTVhZGRjZGEwMGJlYmVjZjY4NGZmNzliYmM4ZjYxM2YyODUxMWIxNDljNmEwZTgxOTc0N2RiZTRlMDVhMjRhOTMyYWMyNzljMzA5ZTI4NzczNzU0YmUwY2I4ZTUzZDU5ZWUxOTY0OTAxNWM1NzZlMTQ2ODZlMmU5NjI5YzkyZDI3MmM1YjI0ZTIwNjE0OTgwOTk3ODk1NTAzMDM2YjkwZGUwZjNiNTkxZDEzMjczNTZkMTczMTI4OWMwNjY1NTEzYjVlMDYxYThmYmJjYTRhMjk0YmJjYzYyZWFiMzMwMmNmZGMwOGVhNTA2ZTA0NDg0YWE0NDNiNDBiNWQ2MWFiOTFhODViMDliNDRmMTE4N2M2OWRiNTE3ZTkwMDYwNjhhMjhjMzFiM2Y5MDEyYmNlMDg3MzcwZmE2ODBiNzdmNTlhNGQ4N2ZkMDViODRmNzk3ZjVlOTVhOTk4YTMxZjRjOTZkNTRhMzQyNDg3MTYxMDU5NWRmMGRkNGQ4YmE1YjExYTJmODMwYzFmOTM2NjRlN2Q3MTJlYjA4MTZhMTY2NzRhNTgxYTlkZDkwMGNjMDk0ZjZiYmE0OTRjZTk3MTNhNmU3MDI1NWEzNmJhNzg0MDlmMjEzN2Q1M2U0MTM5ZmU5ZjVlNDc4ZTEyMjAxNmUwMTAzNzQxYWIxNzBjZmUwMmUwMDQxNzkxZmM1NzhhMDQ0MDdhYmQ5NjUyNmFmMjMyMjg0MDhlOTJjNTcyNTg5ZTQ5ZThjMGYzZjhjYjNmNzk5MmFjNjg2NDExNmYyZTQ3NjQ4MGEzMjdlMzI0OWMyMzAzZmMxYjAzY2U3MWYyZTJmZGZjZmExYjg2OTYwOTRlMDk3ZTVhYWM1YTlhOTVjNTU5ZDRiNmY5NzNlOTI5NmY1Y2ZhNmY5NDJlMDNlMjUxN2QzNzlmNjkyMmU0NzQyYjliYmZjODgzYTVlMTc1YTE5YmMyNzQ1ZGI5Mzk5YTNjZGJhMTljMmM0Njc2NTE4NjgzNzYyZWM3MTUxOTQ2YjJhZTE1MzA2MDQ0YzhmMmVkNmVmOGU0YzNlZmU2M2Y0ZWFlNTY2N2IxNzRiMjcxOTA1YjQzOWRlYzMwMzQ4MGJmZDIwODE4MTZiMDgwMTk2ZjBmZmZiNThkMTA3Y2IxMDI1YjZlMmNjMDBmMzc5MjhkM2JkNjZhN2MxZmRkZDRjZDkwMDU0NDc5NTlmNDFkNThlMDFiZmY1YThhYjk0MjFlMzU5ZDY2ZTkwNzQyYTFlZTFjNzgyNzNhYmM5Y2RmZTljMDdhZDU4OTdkNTA3MjQ2MzFjNDZkODQ0MDhjMjNhOTc5NzBkMGFiYWZlZTBhMjllYjhiMThhNzU5ODMyM2EzMWU4MmQ2Y2IxZmRmNzhmMTQzMDBjOTA5YzhmYjA0YjNhMjNhOTYyYTBmMTA2ZjdhOTE5MTcwMWJlN2M1MDRjNmFhYmFjNjZhMmMyMTM2ZjNmMWE2N2U2MmIyY2Y4ZGNhYTc0MTFiYjczMTVkY2UzMiI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iTUQiIHZhbHVlPSJlMTBjMzZhMWFkNmE0NTk5MzFjYTg2MzUwYWYyMWQ1NDNiNDIxOGU0N2U1ZWU3MDI3M2I4NzdkMjFkYTE0MTNlIj48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJUZXJtVXJsIiB2YWx1ZT0iaHR0cHM6Ly90ZXN0LnBheXUuaW4vZTEwYzM2YTFhZDZhNDU5OTMxY2E4NjM1MGFmMjFkNTRkOGIxNmE4NGNhZDU0MDEwMTY4YWU3ZGNiYTAyYTBhYS9Db21tb25QZ1Jlc3BvbnNlSGFuZGxlciI+PC9mb3JtPjxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0Jz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5vbmxvYWQ9ZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5mb3Jtc1sncGF5bWVudF9wb3N0J10uc3VibWl0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIDwvc2NyaXB0PjwvYm9keT48L2h0bWw+"
}
}
For S2S Card Payment mode, the response includes:
order_id: Unique order identifier for tracking the transaction
acs_template: Base64-encoded HTML form for 3D Secure authentication (when required)
Step 2: Handle 3D Secure Authentication
When 3D Secure authentication is required, EximPe returns an acs_template that must be processed on the frontend:
3DS Authentication Flow
Decode the ACS Template : The acs_template is Base64-encoded HTML
Render in Browser : Display the decoded HTML in the customer’s browser
Auto-Submit Form : The form will automatically submit to the bank’s authentication server
Customer Authentication : Customer completes authentication (OTP, PIN, biometric, etc.)
Redirect to Return URL : After authentication, customer is redirected to your return_url
Frontend Implementation Example
// Decode the Base64 ACS template
function handleACSTemplate ( acsTemplate ) {
// Decode Base64
const decodedHTML = atob ( acsTemplate );
// Create a new window or iframe for 3DS
const authWindow = window . open ( '' , '3DS_Auth' , 'width=600,height=400' );
// Write the decoded HTML to the window
authWindow . document . write ( decodedHTML );
authWindow . document . close ();
// Monitor for window close (authentication complete)
const checkClosed = setInterval (() => {
if ( authWindow . closed ) {
clearInterval ( checkClosed );
// Check payment status after authentication
checkPaymentStatus ();
}
}, 1000 );
}
// Check payment status after 3DS completion
function checkPaymentStatus () {
// Call your backend to check order status
fetch ( '/api/check-payment-status' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ order_id: 'OD9888127185' })
})
. then ( response => response . json ())
. then ( data => {
if ( data . status === 'SUCCESS' ) {
// Payment successful - redirect to success page
window . location . href = '/payment-success' ;
} else if ( data . status === 'FAILED' ) {
// Payment failed - show error message
showErrorMessage ( 'Payment failed. Please try again.' );
} else {
// Still processing - continue checking
setTimeout ( checkPaymentStatus , 2000 );
}
});
}
Security Note : Always decode and render the ACS template in a secure context (HTTPS) and validate the response from the authentication server before proceeding with order fulfillment.
Saved Card Tokens
EximPe’s card tokenization system allows you to securely save card details for future payments using two different flows:
Tokenization Flows
Automatic Save (During Payment) : Add "save_card": true in the card_details object when initiating a payment. The card will be tokenized automatically upon successful payment.
Manual Save (Dedicated API) : Call the Save Card API to tokenize card details independently of a payment.
Flow 1: Automatic Save During Payment
To save a card while processing a payment, include the save_card parameter in your card_details object:
{
"amount" : "1000.00" ,
"collection_mode" : "s2s" ,
"mop_type" : "debit_card" ,
"card_details" : {
"number" : "4895380110000003" ,
"cardholder_name" : "John Doe" ,
"expiry_month" : "05" ,
"expiry_year" : "2030" ,
"cvv" : "123" ,
"network" : "visa" ,
"identifier" : "EX0001" ,
"save_card" : true
},
// ... other required fields
}
Flow 2: Manual Save via API
Use the dedicated Save Card API to tokenize cards manually:
POST /pg/tokens/
{
"number" : "4895380110000003" ,
"cardholder_name" : "John Doe" ,
"expiry_month" : "05" ,
"expiry_year" : "2030" ,
"cvv" : "123" ,
"network" : "visa" ,
"identifier" : "EX0001"
}
This returns a secure token that can be used for future payments without storing sensitive card data.
Complete Tokenization Example
// Step 1: Process payment with new card
const paymentResponse = await fetch ( '/pg/orders/' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-Client-ID' : 'YOUR_CLIENT_ID' ,
'X-Client-Secret' : 'YOUR_CLIENT_SECRET' ,
'X-Merchant-ID' : 'YOUR_MERCHANT_ID'
},
body: JSON . stringify ({
amount: "1000.00" ,
collection_mode: "s2s" ,
mop_type: "CREDIT_CARD" ,
card_details: {
number: "4895380110000003" ,
cardholder_name: "John Doe" ,
expiry_month: "05" ,
expiry_year: "2030" ,
cvv: "123" ,
network: "visa" ,
identifier: "EX0001"
},
// ... other required fields
})
});
// Step 2: After successful payment, save card for future use
if ( paymentResponse . data . status === 'SUCCESS' ) {
const tokenResponse = await fetch ( '/pg/tokens/' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-Client-ID' : 'YOUR_CLIENT_ID' ,
'X-Client-Secret' : 'YOUR_CLIENT_SECRET' ,
'X-Merchant-ID' : 'YOUR_MERCHANT_ID'
},
body: JSON . stringify ({
number: "4895380110000003" ,
cardholder_name: "John Doe" ,
expiry_month: "05" ,
expiry_year: "2030" ,
cvv: "123" ,
network: "visa" ,
identifier: "EX0001"
})
});
// Store the returned token for future payments
const cardToken = tokenResponse . data . card_token ;
}
Using Saved Tokens
For repeat payments, use the saved token instead of card details:
{
"card_details" : {
"token" : "1e6709282a21e83f43a020" ,
"identifier" : "EX0001" ,
"network" : "visa"
}
}
Token Management APIs
Step 3: Check Payment Transaction Status
Use the Order Status API to retrieve the current payment status:
curl -X GET https://api-pacb.eximpe.com/pg/orders/{order_id}/status/ \
-H "X-Client-ID: YOUR_CLIENT_ID" \
-H "X-Client-Secret: YOUR_CLIENT_SECRET" \
-H "X-Merchant-ID: YOUR_MERCHANT_ID" \
-H "X-API-Version: 1.0.0"
For detailed parameters and response formats, see the Get Order API
Payment Status Values
Status Description payment_pendingPayment initiated, awaiting completion payment_successfulPayment completed successfully failedPayment failed or was declined
Step 4: Server-to-Server Callback Response
EximPe sends real-time webhook notifications when payment status changes:
{
"event_type" : "PAYMENT_SUCCESSFUL" ,
"event_time" : "2024-02-15 16:53:15" ,
"version" : "1.0" ,
"sequence_number" : "e40552bf-ed12-4f35-9a97-162d97e6fa34" ,
"data" : {
"status" : "captured" ,
"message" : "Payment successful" ,
"mop_type" : "debit_card" ,
"order_id" : "OD3376378679" ,
"payment_id" : "PR6938527534" ,
"bank_ref_num" : "OD3376378679-PR6938527534" ,
"payment_completed_at" : "2025-06-24T12:30:44.000000Z"
}
}
For more webhook details, see:
Security Best Practices
PCI DSS Compliance
Never log card details : Ensure card numbers, CVV, and other sensitive data are never logged
Use HTTPS : All card payment endpoints must use HTTPS encryption
Tokenize when needed : Use the Save Card API to convert card details to tokens for repeat customers
Validate inputs : Implement proper validation for all card-related fields
Fraud Prevention
Required fields : Always include ip_address and user_agent for fraud detection
Velocity checks : Monitor for unusual payment patterns
Address verification : Validate billing address information
CVV verification : Always require CVV for new card transactions
3D Secure Best Practices
Fallback handling : Implement proper error handling for failed 3DS authentication
Timeout management : Set appropriate timeouts for 3DS flows
Mobile optimization : Ensure 3DS works seamlessly on mobile devices
User experience : Provide clear instructions during authentication
Error Handling
Common Error Scenarios
Error Code Description Resolution CARD_DECLINEDBank declined the transaction Ask customer to try different card or contact bank INSUFFICIENT_FUNDSNot enough balance Customer needs to check account balance EXPIRED_CARDCard has expired Customer needs to use valid card INVALID_CVVIncorrect CVV provided Ask customer to re-enter CVV 3DS_FAILED3D Secure authentication failed Customer needs to complete authentication NETWORK_ERRORNetwork connectivity issues Retry the transaction
Implementation Tips
Retry Logic : Implement exponential backoff for network-related errors
User Feedback : Provide clear, actionable error messages to customers
Logging : Log errors (without sensitive data) for debugging
Monitoring : Set up alerts for high error rates or specific error types
Next Steps
Test Integration : Use test cards and credentials to validate your integration
Go Live : Switch to production credentials after thorough testing
Monitor Performance : Track success rates, error patterns, and user experience metrics
Optimize Flow : Continuously improve based on user feedback and analytics
For additional support, consult our API Reference or contact our integration team.