---
updatedAt: 2026-08-06T18:26:32.000Z
agentTools:
  projectIndex: https://docs.nmi.com/llms.txt
---

# Credential on File Best Practices

# Overview

Credential on File (CoF) enables merchants to securely store customer payment credentials for future transactions, supporting recurring payments and improving checkout experiences. This guide covers implementation with the Payment API using Collect.js and Gateway.js, with special considerations for 3-D Secure (3DS) and PSD2 compliance.

<Cards columns="2">
  <Card title="PSD2 Compliance Required" icon="shield-alt">
    For countries under PSD2 mandate requiring 3-D Secure authentication, you **must** use Gateway.js for proper SCA compliance.
  </Card>

  <Card title="Risk Mitigation" icon="chart-line">
    Following these best practices helps mitigate risk of recurring transaction declines, even in non-PSD2 regions.
  </Card>
</Cards>

***

# Choose Your Implementation Approach

Before implementing Credential on File, select the approach that best fits your needs:

<Cards columns="2">
  <Card title="Custom Recurring Implementation" href="#implementation-flow" icon="code">
    **Build your own recurring flows** using CIT/MIT flagging for maximum control and customization. This guide covers the technical implementation details for this approach.
  </Card>

  <Card title="Recurring Module" href="../docs/recurring-module" icon="sync-alt">
    **Use our built-in recurring module** for automated subscription management with simplified integration. Less technical complexity, pre-built recurring logic. **Available in non-PSD2 regions only.**
  </Card>
</Cards>

## When to Choose Custom Implementation

* You need full control over recurring payment timing and logic
* You have complex billing scenarios (usage-based, tiered pricing, etc.)
* You want to handle subscription management in your own system
* You need custom retry logic or payment failure handling

## When to Choose Recurring Module

* You want faster implementation with less technical overhead
* You have standard subscription billing needs
* You prefer our automated retry and failure handling
* You want built-in subscription management features

> **Note:** The rest of this guide focuses on **custom recurring implementation** using CIT/MIT flagging. For Recurring Module documentation, see our [Recurring Payments Module Guide](../docs/recurring-module) .

***

# Implementation Flow

<Tabs>
  <Tab title="Initial Transaction">
    ### Setting Up Your First Transaction

    The initial transaction establishes the credential storage relationship and must be properly flagged as a "first store" transaction.

    #### Using Collect.js Configuration

    For **PSD2/3DS regions**, mandate a step-up challenge by setting `challengeIndicator` to `04`:

    ```javascript
    CollectJS.configure({
        callback: (e) => {
            const options = {
                paymentToken: e.token,
                currency: 'USD',
                amount: '1000',
                email: 'customer@example.com',
                phone: '8008675309',
                city: 'New York',
                state: 'NY',
                address1: '123 First St.',
                country: 'US',
                firstName: 'John',
                lastName: 'Doe',
                postalCode: '60001',
                challengeIndicator: '04' // Mandatory for 3DS transactions
            }
        }
    });
    ```

    #### Payment API Request for Initial Storage

    ```bash
    curl -X POST https://sandbox.nmi.com/api/v5/payments/sale \
      -H "Content-Type: application/json" \
      -H "Authorization: 2jPu***************jkp1" \
      -d '{
        "amount": 123.00,
        "payment_details": {
          "payment_token": "{INSERT_PAYMENT_TOKEN}"
        },
        "customer_vault": {
          "add_customer": true,
          "billing_method": "recurring"
        },
        "cit_mit": {
          "stored_credential_indicator": "stored",
          "initiated_by": "customer"
        },
        "cardholder_auth": {
          "cavv": "{INSERT_CAVV}",
          "xid": "{INSERT_XID}",
          "eci": "{INSERT_ECI}",
          "cardholder_auth": "{INSERT_CARDHOLDER_AUTH}",
          "three_ds_version": "{INSERT_THREE_DS_VERSION}",
          "directory_server_id": "{INSERT_DIRECTORY_SERVER_ID}"
        }
      }'
    ```

    > **Important:** Store the returned `id` (transaction ID) from this initial transaction - it's required for all subsequent transactions.
  </Tab>

  <Tab title="Customer Initiated (CIT)">
    ### Customer Initiated Transactions

    Customer Initiated Transactions occur when the cardholder is present and actively participating in the payment process.

    #### Key Characteristics

    * Customer is available for authentication
    * 3DS authentication may be required (defaults to `challengeIndicator: '01'`)
    * CVV verification should be obtained when possible
    * 3DS variables must be included in payment request for PSD2 regions

    #### Payment API Request

    ```bash
    curl -X POST https://sandbox.nmi.com/api/v5/payments/sale \
      -H "Content-Type: application/json" \
      -H "Authorization: 2jPu*****************jkp1" \
      -d '{
        "amount": 123.00,
        "payment_details": {
          "customer_vault_id": "{INSERT_CUSTOMER_ID}"
        },
        "customer_vault": {
          "billing_method": "recurring"
        },
        "cit_mit": {
          "stored_credential_indicator": "used",
          "initiated_by": "customer",
          "initial_transaction_id": "{INSERT_INITIAL_TRANSACTION_ID}"
        },
        "cardholder_auth": {
          "cavv": "{INSERT_CAVV}",
          "xid": "{INSERT_XID}",
          "eci": "{INSERT_ECI}",
          "cardholder_auth": "{INSERT_CARDHOLDER_AUTH}",
          "three_ds_version": "{INSERT_THREE_DS_VERSION}",
          "directory_server_id": "{INSERT_DIRECTORY_SERVER_ID}"
        }
      }'
    ```

    <Accordion title="CIT Use Cases" icon="user">
      Customer making a one-time purchase with saved card, updating subscription or billing information, customer-triggered recurring payment modifications, or any transaction where customer authentication is available.
    </Accordion>
  </Tab>

  <Tab title="Merchant Initiated (MIT)">
    ### Merchant Initiated Transactions

    Merchant Initiated Transactions are processed without customer participation, typically for automated recurring billing.

    #### Key Characteristics

    * Customer is **not** present during transaction
    * **No 3DS authentication** should be used (customer unavailable for challenge)
    * Relies on initial transaction's authentication
    * Lower risk of decline when properly implemented

    #### Payment API Request

    ```bash
    curl -X POST https://sandbox.nmi.com/api/v5/payments/sale \
      -H "Content-Type: application/json" \
      -H "Authorization: 2jPu*****************jkp1" \
      -d '{
        "amount": 123.00,
        "payment_details": {
          "customer_vault_id": "{INSERT_CUSTOMER_ID}"
        },
        "customer_vault": {
          "billing_method": "recurring"
        },
        "cit_mit": {
          "stored_credential_indicator": "used",
          "initiated_by": "merchant",
          "initial_transaction_id": "{INSERT_INITIAL_TRANSACTION_ID}"
        }
      }'
    ```

    <Accordion title="MIT Use Cases" icon="cog">
      Scheduled subscription payments, account top-ups and auto-reloads, installment payments, usage-based billing, and failed payment retries.
    </Accordion>
  </Tab>
</Tabs>

***

# Compliance & Security Requirements

## PSD2 & Strong Customer Authentication (SCA)

**PSD2 Regions Requirements:**

* European Economic Area (EEA) transactions where both issuing and acquiring banks are in EEA
* Requires Strong Customer Authentication (SCA)
* Gateway.js mandatory for 3DS implementation

**SCA Exemptions:**

* MIT transactions mostly exempted from 3DS
* Initial transaction must pass 3DS authentication
* UK/EEA customers require challenged 3DS for first transaction

### Transaction ID Management

| Transaction Type   | Gateway Transaction ID Required         | Notes                                   |
| ------------------ | --------------------------------------- | --------------------------------------- |
| **Initial (CIT)**  | Generated automatically                 | Store this ID for future reference      |
| **Subsequent CIT** | Reference original or previous approved | Links back to authenticated transaction |
| **MIT**            | Reference original CIT transaction      | Proves initial customer authentication  |

***

# Best Practices & Troubleshooting

<Accordion title="Parameter Guidelines" icon="list-check">
  **Always Required:**

  * `stored_credential_indicator`: 'stored' (initial) or 'used' (subsequent)
  * `initiated_by`: 'customer' or 'merchant'
  * `initial_transaction_id`: For all subsequent transactions

  **Conditional Requirements:**

  * `billing_method`: Not required for unscheduled subsequent transactions
  * `challengeIndicator`: Only for initial 3DS transactions ('04')
  * 3DS variables: Required when using Gateway.js
</Accordion>

<Accordion title="Common Implementation Errors" icon="exclamation-triangle">
  **Avoiding Transaction Declines:**

  * Using wrong `initiated_by` value for transaction type
  * Missing `initial_transaction_id` in subsequent transactions
  * Improper 3DS implementation for PSD2 regions

  **Security Issues:**

  * Exposing credentials in code or logs
  * Not using environment variables for sensitive data
  * Insufficient access control implementation
</Accordion>

<Accordion title="Testing & Validation" icon="flask">
  **Pre-Production Checklist:**

  1. **Initial Transaction Testing** - Verify credential storage with proper CoF indicators, confirm 3DS challenge flow for PSD2 regions, validate transaction\_id storage and retrieval

  2. **CIT Transaction Testing** - Test with customer present scenarios, verify 3DS authentication when required, confirm proper credential usage indicators

  3. **MIT Transaction Testing** - Verify no 3DS authentication attempted, test automated recurring payment scenarios, validate proper reference to initial transaction
</Accordion>

***

# Quick Reference

## Transaction Comparison

| Aspect                            | Initial Transaction  | Customer Initiated (CIT) | Merchant Initiated (MIT) |
| --------------------------------- | -------------------- | ------------------------ | ------------------------ |
| **Customer Present**              | ✅ Yes                | ✅ Yes                    | ❌ No                     |
| **3DS Required**                  | ✅ Yes (PSD2 regions) | ⚠️ May be required       | ❌ No                     |
| **Challenge Indicator**           | '04' (if 3DS)        | '01' (default)           | N/A                      |
| **stored\_credential\_indicator** | 'stored'             | 'used'                   | 'used'                   |
| **initiated\_by**                 | 'customer'           | 'customer'               | 'merchant'               |
| **CVV Collection**                | ✅ Recommended        | ✅ Recommended            | ❌ Not applicable         |

Need additional support? Contact our integration team for specific implementation guidance.