> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Test Agent Cards

> Use staging test cards to exercise card registration, verification, and credential minting

In staging, every card-network rail routes to a deterministic mock of Visa Intelligent Commerce and Mastercard Agent Pay. No request reaches a real card network, but the endpoints, response shapes, statuses, and error codes match production. The card number you save selects the scenario, so you can test success and failure paths without a real card.

## Prerequisites

* **Staging API key** — a client-side key from the <a href="https://staging.crossmint.com/console/projects/apiKeys" target="_blank">Crossmint Staging Console</a>. In staging, all scopes are included by default.
* **Card flow** — the integration from [Save a Card](/agents/payment-methods/cards/save-card), [Register a Card](/agents/payment-methods/cards/register-card), [Create an Agent Card](/agents/payment-methods/cards/create-agent-card), and [Retrieve Secure Card Numbers](/agents/payment-methods/cards/retrieve-agent-card), pointed at `https://staging.crossmint.com`.

## Test Cards

Save one of these numbers with any future expiration date and any three-digit CVC. Any Visa or Mastercard number not listed follows its brand's happy path.

| Card | Brand | Outcome |
| - | - | - |
| `4242 4242 4242 4242` | Visa | Succeeds end to end |
| `5555 5555 5555 4444` | Mastercard | Succeeds end to end |
| `5186 1600 0000 0001` | Mastercard | Fails at registration with `CARD_REJECTED` |
| `4929 9803 9556 7582` | Visa | Fails at verification: the one-time code is rejected with `INVALID_OTP` |
| `5186 1600 0000 0003` | Mastercard | Fails at verification: the hosted page appears to succeed, but the rail never becomes `active` |

## What a Successful Card Returns

[Register a Card](/agents/payment-methods/cards/register-card) reports one card-network rail for the card. The `rail` is always `agentic-token`; the `provider` names the network program behind it, `vic` for Visa Intelligent Commerce or `agentpay` for Mastercard Agent Pay:

```json theme={null}
{
    "paymentMethodId": "pm_123",
    "rails": [
        {
            "rail": "agentic-token",
            "provider": "agentpay",
            "status": "enabled"
        }
    ]
}
```

An order intent created for that card ([Create an Agent Card](/agents/payment-methods/cards/create-agent-card)) carries the same rail with `status: "pending_verification"`. After the cardholder approves the allowance in `OrderIntentVerification`, fetch the order intent again: the rail reports `status: "active"` and you can mint.

```json theme={null}
{
    "rail": "agentic-token",
    "provider": "agentpay",
    "status": "active",
    "credentialFormats": ["card", "network-token"]
}
```

## Failure Scenarios

<Note>
  The three cards below are designed to fail. The error each one produces is the expected result of the scenario, not
  a problem with your integration.
</Note>

### Card Rejected at Registration

Save `5186 1600 0000 0001`. The registration request succeeds, but the Mastercard rail is reported in `error`:

```json theme={null}
{
    "paymentMethodId": "pm_123",
    "rails": [
        {
            "rail": "agentic-token",
            "provider": "agentpay",
            "status": "error",
            "error": { "code": "CARD_REJECTED" }
        }
    ]
}
```

The card is saved and the rejection is permanent. Confirm that your UI treats this as a saved card with one failed rail, not as a failed save. Order intents for this card include an `encrypted-card` rail, which is enabled for every staging project, so mint through it instead. See [Mint an Encrypted Card](/agents/payment-methods/cards/retrieve-agent-card#mint-an-encrypted-card).

### One-Time Code Rejected

Save `4929 9803 9556 7582`. Registration succeeds with a `vic` rail `enabled`, and the order intent's rail is `pending_verification`. In `OrderIntentVerification`, the Visa flow asks for a one-time code and rejects every code with `INVALID_OTP`. The user can enter another code, but this card never accepts one, so verification does not complete and the rail stays `pending_verification`:

```json theme={null}
{
    "rail": "agentic-token",
    "provider": "vic",
    "status": "pending_verification",
    "credentialFormats": ["card", "network-token"]
}
```

Confirm that your UI lets the user retry or abandon the verification, and that nothing mints while the rail is `pending_verification`.

### Hosted Page Returns but Verification Fails

Save `5186 1600 0000 0003`. Registration succeeds with an `agentpay` rail `enabled`. During verification, the mock Mastercard-hosted page shows a success message and returns to your application, but when Crossmint confirms the result with the network, the confirmation fails. `OrderIntentVerification` calls `onVerificationError`, and the rail stays `pending_verification`.

Confirm that your integration waits for `onVerificationComplete` and then fetches the order intent until the rail reports `active`, rather than minting as soon as the hosted page closes.

## Test Verification

Verification is the step where the cardholder approves an order intent's allowance through the `OrderIntentVerification` component. The mocks run the same browser flow as production, so popups, message listeners, and origin checks are all exercised.

* **Visa** — the verification asks the user to choose a one-time code method (a masked phone number or email address) and accepts any code, unless the card scenario says otherwise. On a device without a passkey, a mock Visa screen enrolls one. Later order intents on the same device go straight to passkey authentication, as in production.
* **Mastercard** — the component opens a mock Mastercard-hosted page that shows its progress and returns to your application. The rail becomes `active` only after Crossmint confirms the result, so fetch the order intent again before minting.

Use an HTTPS tunnel when you test verification from a local browser. It exercises the same iframe, origin, and popup behavior as your deployed site.

## Check the Minted Credentials

Mock credentials are deterministic, so repeated runs return stable values. Use them in integration tests only; they are not accepted by real merchants.

| Format | Value |
| - | - |
| `card` | A virtual card number: `4000 0010 0000 4242` for the `4242` Visa card and `5100 0010 0000 4446` for the `4444` Mastercard. Other cards return `4000 0010 0000 0000` (Visa) or `5100 0010 0000 0006` (Mastercard). The expiration date matches the saved card, and the CVC is derived deterministically |
| `network-token` | The same virtual number with a deterministic cryptogram. Visa returns ECI `07` and Mastercard returns ECI `06` |

Credential expiry follows each network's rule rather than a uniform test value. The Visa mock returns a short synthetic cryptogram window, so do not calibrate how long a credential stays usable against it. Use every credential immediately.

## Test Common Scenarios

The allowance accounting in staging is real, so these scenarios behave exactly as in production.

* **Spend limits** — create an order intent for `10.00`, mint a credential for `7.00`, then read the order intent: `amount.available` is `3.00`. Minting `4.00` next fails with `ORDER_INTENT_AMOUNT_EXCEEDED`.
* **Encrypted card fallback** — save `5186 1600 0000 0001` and mint through the `encrypted-card` rail, as described in [Card Rejected at Registration](#card-rejected-at-registration).
* **CVC recollection** — expire a saved card's CVC on demand to test the `pending_cvc_recollection` state. See [Test in Staging](/agents/payment-methods/cards/recollect-cvc#test-in-staging).

## Next Steps

<CardGroup cols={2}>
  <Card title="Create an Agent Card" icon="credit-card" href="/agents/payment-methods/cards/create-agent-card">
    Create an order intent and verify its rail
  </Card>

  <Card title="Cards Quickstart" icon="rocket" href="/agents/cards-quickstart">
    Run the complete flow in the reference app
  </Card>
</CardGroup>
