💳 Card on File Transactions
What is a Card on File Transaction?
A Card on File (COF) transaction uses payment credentials previously stored by Coinflow to process future payments. This enables customers to make purchases without re-entering their card details, creating a frictionless checkout experience.
📘 Customer Initiated Transactions (CIT)
Card on File transactions are also known as Customer Initiated Transactions (CIT) because the customer actively participates in making the payment at the point of authorization.
Key Characteristics
- Customer Participation Required: The customer actively initiates each payment using stored credentials
- No Fixed Schedule: Transactions occur on-demand rather than following a recurring schedule
- Explicit Permission: Requires customer consent to store card details for future use
- One-Click Experience: Reduces friction by eliminating the need to re-enter payment information
✅ Using Coinflow’s Prebuilt UI?
If you’re using Coinflow’s prebuilt UI components, customer consent and credential storage are automatically handled for you in compliance with card network requirements.
Card on File Mandate & Compliance
The growth of digital commerce has led to increased use of stored payment credentials. Card networks (Visa, Mastercard, etc.) have responded by introducing strict requirements and processes to protect both merchants and consumers.
Compliance Requirements
To ensure compliance with the stored credential mandate, you must:
Critical Compliance Steps
- Inform customers how their stored payment credentials will be used
- Obtain explicit permission from customers to store payment credentials
- Notify customers about any changes to terms of use
- Get consent for each transaction when initiating Card on File payments
Note: If using Coinflow’s Prebuilt UI, items 1-2 are automatically handled. You are always responsible for item 4.
Benefits of Card on File
Reduced Friction
Customers can complete purchases in seconds without re-entering payment details
Higher Conversion
Streamlined checkout experiences lead to improved conversion rates
Improved Retention
Makes repeat purchases easier, encouraging customer loyalty
Secure Storage
Coinflow handles PCI-compliant storage of sensitive payment data
How It Works
Customer Makes Initial Purchase
Customer completes their first transaction and opts in to save their payment credentials for future purchases.
Coinflow Securely Stores Credentials
Payment details are tokenized and stored securely in Coinflow’s PCI-compliant vault.
Customer Initiates Future Purchase
For subsequent purchases, customer selects their saved payment method and authorizes the transaction.
Payment is Processed
Coinflow processes the payment using the stored credentials without requiring the customer to re-enter card details.
Card on File vs. Subscriptions vs. Merchant Initiated Transactions
Understanding the differences between payment types helps ensure compliance and proper implementation:
| Feature | Card on File | Subscriptions | Merchant Initiated (MIT) |
|---|---|---|---|
| Initiator | Customer | Automatic | Merchant |
| Schedule | On-demand | Fixed recurring | Variable |
| Customer Present | Yes | Initially | No |
| Use Case | Repeat purchases | Recurring billing | Account top-ups, usage charges |
| Consent Required | Per transaction | Once, at signup | Once, with conditions |
💡 Need Recurring Billing?
If you need automated recurring payments on a schedule, check out our Subscriptions Overview documentation.
Implementation Guide
Implementing Card on File checkout is a two-step process:
- Initial Purchase - Store the customer’s payment credentials
- Subsequent Purchases - Use the stored credentials for future transactions
Step 1: Create Initial Card Payment
For the customer’s first purchase, use either the Card Checkout or Token Checkout endpoint to process the payment and store their credentials.
Option A: Card Checkout
Use this endpoint when you have raw card details from the customer:
POST /api/checkout/card/{merchantId}
View Card Checkout API Reference
Option B: Token Checkout
Use this endpoint when you have a tokenized card (e.g., from a previous tokenization):
POST /api/checkout/token/{merchantId}
View Token Checkout API Reference
Save the Payment ID or Card Token
After a successful initial purchase, you can reference the card for future Card on File transactions using either:
- The
paymentIdfrom the response (to use a specific transaction as the velocity limit reference) - The
tokenfrom the response (system will automatically use the most recent CVV-verified transaction)
Save whichever identifier fits your implementation best.
Step 2: Make Card on File Purchases
For subsequent purchases, use the Card on File Checkout endpoint with either the original payment ID or the card token.
POST /api/checkout/card-on-file
View Card on File Checkout API Reference
Request Parameters:
You must provide one of the following to identify the saved card:
originalPaymentId- The payment ID from a specific CVV-verified transactiontoken- The card token (system automatically finds the most recent CVV-verified transaction for velocity validation)
Using Card Token vs. Payment ID
When you pass a token instead of an originalPaymentId, Coinflow automatically locates the most recent CVV-verified transaction for that card token and uses it to validate velocity limits (transaction count, amount multiplier, and expiration window).
This is useful when you want to use a saved card without tracking individual payment IDs—just pass the card token and the system handles the rest.
Example Request with Original Payment ID:
{
"subtotal": {
"cents": 2500,
"currency": "USD"
},
"originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
"settlementType": "Bank"
}
Example Request with Card Token:
{
"subtotal": {
"cents": 2500,
"currency": "USD"
},
"token": "4111114324324111_bt",
"settlementType": "Bank"
}
Step 3: Handle Chargeback Protection (If Enabled)
Required for Chargeback Protection
If you have chargeback protection enabled, you must collect and send the Coinflow device ID with your Card on File checkout requests.
Add Coinflow Purchase Protection to Your Application:
Web Applications
-
Follow the Implement Chargeback Protection guide to add the Coinflow Purchase Protection script to every page on your site. Coinflow will provide you with the credentials needed to initialize it on sandbox and production.
-
Get the device ID and include it in the API request:
const deviceId = getCoinflowDeviceId();
// Include in request headers
headers: {
'x-device-id': deviceId
}
React Applications
- Add the
<CoinflowPurchaseProtection>component to every page:
import {CoinflowPurchaseProtection} from '@coinflow/react';
function App() {
return (
<>
<CoinflowPurchaseProtection merchantId="your-merchant-id" />
{/* Your app content */}
</>
);
}
- Get the device ID from the component’s context and include it in your API calls.
Include chargebackProtectionData:
{
"subtotal": {
"cents": 2500,
"currency": "USD"
},
"originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
"settlementType": "Bank",
"chargebackProtectionData": [
{
"productName": "Premium Subscription",
"productType": "subscription",
"quantity": 1,
"rawProductData": {
"productID": "premium-monthly",
"productDescription": "Monthly premium subscription",
"billingCycle": "monthly"
}
}
]
}
Learn More About Chargeback Protection
Step 4: Handle 3DS Challenges (If Enabled)
Required for 3DS-Enabled Transactions
If 3D Secure (3DS) authentication is required, you must handle the 3DS challenge flow before the payment can be completed.
When a Card on File transaction requires 3DS authentication, the API will return a response indicating that 3DS verification is needed.
3DS Challenge Flow:
- Detect 3DS Required: Check the response for HTTP Code 412
- Present Challenge: Display the 3DS challenge iframe to the customer
- Complete Authentication: Wait for customer to complete verification
- Retry Payment: Submit the payment again with 3DS authentication data
Example React Implementation:
import {useEffect, useState} from 'react';
function CardOnFileCheckout() {
const [threeDsRequired, setThreeDsRequired] = useState(false);
const [threeDsUrl, setThreeDsUrl] = useState('');
const handleCardOnFilePayment = async () => {
const response = await fetch('/api/checkout/card-on-file', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'your-merchant-api-key',
'x-device-id': getCoinflowDeviceId(),
},
body: JSON.stringify({
subtotal: {cents: 2500, currency: 'USD'},
originalPaymentId: 'payment-id-here',
settlementType: 'Bank',
}),
});
const data = await response.json();
if (data.threeDsRequired) {
setThreeDsRequired(true);
setThreeDsUrl(data.threeDsChallengeUrl);
} else {
// Payment successful
handleSuccess(data);
}
};
const handle3DsComplete = async authenticationData => {
// Retry payment with 3DS data
const response = await fetch('/api/checkout/card-on-file', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'your-merchant-api-key',
},
body: JSON.stringify({
subtotal: {cents: 2500, currency: 'USD'},
originalPaymentId: 'payment-id-here',
settlementType: 'Bank',
threeDsAuthenticationData: authenticationData,
}),
});
const data = await response.json();
handleSuccess(data);
};
return (
<div>
{threeDsRequired ? (
<ThreeDsChallenge url={threeDsUrl} onComplete={handle3DsComplete} />
) : (
<button onClick={handleCardOnFilePayment}>Pay with Saved Card</button>
)}
</div>
);
}
Complete 3DS Challenge Implementation Guide
Complete Example
Here’s a complete example showing all components together:
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/card-on-file \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'Authorization: your-merchnat-api-key' \
--header 'x-device-id: device-id-from-coinflow-purchase-protection' \
--data '{
"subtotal": {
"cents": 5000,
"currency": "USD"
},
"originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
"chargebackProtectionData": [
{
"productName": "Game Credits",
"productType": "inGameProduct",
"quantity": 500,
"rawProductData": {
"productID": "credits-500",
"productDescription": "500 in-game currency credits"
}
}
]
}'
{
"paymentId": "650e8400-e29b-41d4-a716-446655440001"
}
Merchant Configuration Settings
Card on File functionality includes several configurable settings that control how and when stored credentials can be used. These settings help you manage security, fraud prevention, and compliance.
Configuration Required
Card on File must be enabled on your merchant account before you can accept Card on File payments. Contact your Coinflow integration representative to configure these settings.
Available Configuration Options
Your Coinflow integration team will configure the following Card on File settings for your merchant account:
Velocity Controls:
maxCount- Maximum number of Card on File payments allowed within a time periodperiod- Time window in seconds for the maxCount limit (e.g., 86400 for 24 hours)
Payment Limits:
maxMultiple- Maximum multiplier for Card on File transaction amounts compared to the original payment (e.g., 3x means a Card on File payment can be up to 3× the original payment amount)
Time-Based Restrictions:
expiration- Time window in seconds during which an original payment can be used as a Card on File reference (e.g., 86400 for 24 hours)
Example Configuration
"enabled": true,
"maxCount": 5,
"period": 86400,
"maxMultiple": 3,
"expiration": 86400
This configuration means:
- ✅ Card on File is enabled
- ✅ Maximum 5 Card on File payments per 24 hours per original payment
- ✅ Card on File payments can be up to 3× the original payment amount
- ✅ Original payments can be referenced for 24 hours after initial transaction
Error Handling
Understanding and properly handling Card on File errors is critical for a smooth customer experience.
Common Error Codes
403 Forbidden - Card on File Not Enabled
Error Message:
Card on file not enabled. Please contact your integrations representative.
Cause: Card on File functionality is not enabled on your merchant account.
Resolution:
- Contact your Coinflow integration representative to enable Card on File
- Once enabled, configure the appropriate settings for your use case
400 Bad Request - Different Payment Source
Error Message:
Cannot perform card on file operations with different payment source
Cause: You’re attempting to use an original payment made with a different payment source — for example, referencing a mobile wallet payment (Apple Pay, Google Pay) when charging a regular card, or vice versa.
Resolution:
- Use a regular card payment as the original payment for regular Card on File transactions
- For Apple Pay, see Apple Pay Subsequent Transactions
- Google Pay payments cannot be used as Card on File references — those customers must authenticate each time
400 Bad Request - Using Card on File as Original Payment
Error Message:
Cannot perform card on file operations for a originalPaymentId which is a card on file transaction,
please pass the originalPaymentId which processed with the CVV Verification
Cause: You’re attempting to use a Card on File payment as the original payment reference for another Card on File transaction.
Resolution:
- Only use the initial payment (with CVV verification) as the
originalPaymentId - Do not chain Card on File transactions
- Always reference back to the first payment in the chain
410 Gone - Maximum Payments Reached
Error Message:
Max number of Card-on-File payments reached. (X payments in Y seconds)
Cause: The customer has exceeded the maximum number of Card on File payments allowed within the configured time period.
What This Means:
- The original payment reference can no longer be used
- This is a security measure to prevent abuse
- Based on your merchant’s
maxCountandperiodsettings
Resolution Options:
-
Option A: Show Coinflow Prebuilt UI
- Present Coinflow’s checkout UI to the customer
- Customer will re-enter their card details with CVV verification
- Creates a new original payment reference
-
Option B: Reassociate Card via API
- Direct the customer to verify their card again
- Process a new card payment with CVV (
/api/checkout/token/{merchantId}) - Use this new payment as the original payment reference going forward
Recommended Approach
Show a friendly message: “For security, please verify your card details” and present the Coinflow checkout UI for re-verification.
410 Gone - Original Payment Expired
Error Message:
This original payment can no longer be used as a card-on-file reference because it has exceeded
the allowed X-minute reference window.
Cause: Too much time has passed since the original payment was created. The payment reference has expired based on your merchant’s expiration setting.
What This Means:
- Original payment references are only valid for a configured time period
- This prevents using very old payments as references
- Based on your merchant’s
expirationsetting (in seconds)
Resolution Options:
-
Option A: Show Coinflow Prebuilt UI
- Present Coinflow’s checkout UI to the customer
- Customer will re-enter their card details with CVV verification
- Creates a fresh original payment reference
-
Option B: Reassociate Card via API
- Process a new card payment with CVV (
/api/checkout/card/{merchantId}) - Save this new payment ID as the original payment reference
- Use for future Card on File transactions
- Process a new card payment with CVV (
Proactive Approach
Track when original payments are approaching expiration and prompt customers to re-verify their cards before expiration occurs.
410 Gone - Payment Over Maximum Total
Error Message:
Amount exceeds limit: the total for a card-on-file transaction cannot exceed $X.XX (the allowed
multiplier of Y) of the original payment amount ($Z.ZZ).
Cause: The Card on File payment amount exceeds the configured multiplier of the original payment amount.
Example:
- Original payment: $10.00
- Multiplier setting: 3
- Maximum allowed: $30.00
- Your request: $35.00 ❌
What This Means:
- Prevents significantly larger charges than the customer originally authorized
- Based on your merchant’s
maxMultiplesetting - Security measure to protect customers from unexpected large charges
Resolution Options:
-
Option A: Show Coinflow Prebuilt UI for Full Amount
- Present Coinflow’s checkout UI with the full purchase amount
- Customer re-enters card details and authorizes the larger amount
- Creates a new original payment reference at the higher amount
-
Option B: Split the Payment
- Use Card on File for the maximum allowed amount
- Request separate authorization for the remaining balance
- Clearly communicate to customer why verification is needed
-
Option C: Reassociate Card at Higher Amount
- Process a new card payment at or above the desired amount (
/api/checkout/card/{merchantId}) - Use this payment as the new original payment reference
- Future Card on File payments can be up to the multiplier of this new amount
- Process a new card payment at or above the desired amount (
Customer Communication
When a payment exceeds limits, explain clearly: “This purchase amount requires additional verification. Please confirm your payment details.”
Handling 410 Errors - Quick Reference
All 410 Gone errors indicate that the original payment reference can no longer be used. Here’s what to do:
async function handleCardOnFilePayment(originalPaymentId, amount) {
try {
const response = await fetch(`/api/checkout/card-on-file`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'your-merchant-api-key',
'x-device-id': getCoinflowDeviceId(),
},
body: JSON.stringify({
subtotal: amount,
originalPaymentId: originalPaymentId,
}),
});
if (!response.ok) {
const error = await response.json();
if (response.status === 410) {
// Original payment reference is no longer valid
return handleExpiredReference(error);
}
throw new Error(error.message);
}
return await response.json();
} catch (error) {
console.error('Card on File payment failed:', error);
throw error;
}
}
function handleExpiredReference(error) {
// Show friendly message to customer
const message = 'For your security, please verify your card details again.';
// Option 1: Show Coinflow Prebuilt UI
showCoinflowCheckoutUI();
// Option 2: Redirect to re-associate card flow
// redirectToCardVerification();
}
Best Practice
Always catch 410 errors and provide a seamless re-verification flow. Customers should never see raw error messages - instead, guide them to verify their payment method with clear, friendly messaging.
Best Practices
Clearly Communicate Storage Intent
Make it obvious to customers that their payment method will be saved and how it will be used. Use clear checkbox labels like “Save this card for faster checkout” rather than pre-checked boxes.
Provide Easy Management
Give customers a way to view, update, and delete their stored payment methods through their account settings.
Confirm Each Purchase
Always show customers a clear confirmation screen before processing a Card on File payment, including the amount and saved payment method being used.
Frequently Asked Questions
Can customers have multiple cards on file?
Yes, customers can store multiple payment methods. Your implementation should allow them to select which saved card to use for each purchase.
How is Card on File different from tokenization?
Tokenization is the security mechanism used to safely store card details. Card on File refers to the business flow of using those stored credentials for future purchases with customer consent.
Are there additional fees for Card on File?
No, Card on File transactions are processed with the same fee structure as regular card transactions. There are no additional charges for storing payment credentials.
Next Steps
Zero Authorization
Validate and store cards without charging the customer
Merchant Initiated Transactions
Process charges without customer involvement using stored credentials
Testing Guide
Test your Card on File implementation
Webhooks
Set up webhooks for payment notifications