> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.coinflow.cash/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server.

# 💳 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:

> **Warning**
>
> **Critical Compliance Steps**
>
> 1. **Inform customers** how their stored payment credentials will be used
> 2. **Obtain explicit permission** from customers to store payment credentials
> 3. **Notify customers** about any changes to terms of use
> 4. **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](/guides/subscriptions/subscriptions-overview) documentation.

---

## Implementation Guide

Implementing Card on File checkout is a two-step process:

1. **Initial Purchase** - Store the customer's payment credentials
2. **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:

```bash
POST /api/checkout/card/{merchantId}
```

[View Card Checkout API Reference](/api-reference/api-reference/checkout/card-checkout)

**Option B: Token Checkout**

Use this endpoint when you have a tokenized card (e.g., from a previous tokenization):

```bash
POST /api/checkout/token/{merchantId}
```

[View Token Checkout API Reference](/api-reference/api-reference/checkout/token-checkout)

> **Info**
>
> **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 `paymentId` from the response (to use a specific transaction as the velocity limit reference)
> * The `token` from 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.

```bash
POST /api/checkout/card-on-file
```

[View Card on File Checkout API Reference](/api-reference/api-reference/checkout/card-on-file-checkout)

**Request Parameters:**

You must provide **one** of the following to identify the saved card:

* `originalPaymentId` - The payment ID from a specific CVV-verified transaction
* `token` - The card token (system automatically finds the most recent CVV-verified transaction for velocity validation)

> **Info**
>
> **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:**

```json
{
  "subtotal": {
    "cents": 2500,
    "currency": "USD"
  },
  "originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
  "settlementType": "Bank"
}
```

**Example Request with Card Token:**

```json
{
  "subtotal": {
    "cents": 2500,
    "currency": "USD"
  },
  "token": "4111114324324111_bt",
  "settlementType": "Bank"
}
```

### Step 3: Handle Chargeback Protection (If Enabled)

> **Warning**
>
> **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

1. Follow the [Implement Chargeback Protection](/guides/checkout/payment-security-risk-management/fraud-protection/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.

2. Get the device ID and include it in the API request:

```javascript
const deviceId = getCoinflowDeviceId();

// Include in request headers
headers: {
  'x-device-id': deviceId
}
```

#### React Applications

1. Add the `<CoinflowPurchaseProtection>` component to every page:

```jsx
import {CoinflowPurchaseProtection} from '@coinflow/react';

function App() {
  return (
    <>
      <CoinflowPurchaseProtection merchantId="your-merchant-id" />
      {/* Your app content */}
    </>
  );
}
```

2. Get the device ID from the component's context and include it in your API calls.

**Include chargebackProtectionData:**

```json
{
  "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](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection)

### Step 4: Handle 3DS Challenges (If Enabled)

> **Warning**
>
> **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:**

1. **Detect 3DS Required**: Check the response for HTTP Code 412
2. **Present Challenge**: Display the 3DS challenge iframe to the customer
3. **Complete Authentication**: Wait for customer to complete verification
4. **Retry Payment**: Submit the payment again with 3DS authentication data

**Example React Implementation:**

```jsx
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](/recipes/recipes/complete-checkout-with-3-ds-challenge-react)

---

## Complete Example

Here's a complete example showing all components together:

**`Request`**

```bash Request
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"
        }
      }
    ]
  }'
```

**`Response`**

```json Response
{
  "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.

> **Info**
>
> **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 period
* `period` - 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

```json
"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](/guides/checkout/payment-scenarios/subsequent-transactions/apple-pay)
* 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 `maxCount` and `period` settings

**Resolution Options:**

1. **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

2. **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

> **Tip**
>
> **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 `expiration` setting (in seconds)

**Resolution Options:**

1. **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

2. **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

> **Tip**
>
> **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 `maxMultiple` setting
* Security measure to protect customers from unexpected large charges

**Resolution Options:**

1. **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

2. **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

3. **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

> **Warning**
>
> **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:

```javascript
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();
}
```

> **Success**
>
> **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](/guides/checkout/payment-scenarios/subsequent-transactions/zero-authorization)

Validate and store cards without charging the customer

#### [Merchant Initiated Transactions](/guides/checkout/payment-scenarios/subsequent-transactions/merchant-initiated-transactions)

Process charges without customer involvement using stored credentials

#### [Testing Guide](/guides/checkout/testing/testing-credit-cards)

Test your Card on File implementation

#### [Webhooks](/guides/developer-resources/webhooks/checkout-webhooks)

Set up webhooks for payment notifications