Skip to main content
Virtual cards work anywhere cards are accepted. When your agent needs to buy from a website that doesn’t have an API, it can drive a real browser session and fill in the checkout form with virtual card credentials. This guide explains the end-to-end flow: saving a card, issuing a scoped virtual card, and using a browser automation tool like Stagehand or Browser Use to complete the purchase.
For supported merchants (Amazon, Shopify stores, US only), use Fast Checkout instead — it’s a single API call with no browser needed.

How it works

The key idea: the agent never sees the user’s real card. It receives a scoped virtual card — limited by amount, merchant, and duration — that it uses to pay. If the card is compromised or the agent misbehaves, the blast radius is contained.

Prerequisites

Steps

1

Save a card and create a virtual card

The user saves their card via Crossmint’s PCI-compliant UI. The card is enrolled for agentic use, and a virtual card is issued with spending mandates (amount, merchant, duration). The user approves via passkey.For the full setup, see:
  1. Save a Card
  2. Enroll a Card
  3. Create a Virtual Card
2

Retrieve virtual card credentials

When the agent is ready to make a purchase, it fetches the virtual card credentials scoped to the specific merchant:
const BASE_URL = "https://staging.crossmint.com/api/unstable";

const response = await fetch(
    `${BASE_URL}/order-intents/${orderIntentId}/credentials`,
    {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "X-API-KEY": CROSSMINT_API_KEY,
            Authorization: `Bearer ${jwt}`,
        },
        body: JSON.stringify({
            merchant: {
                name: "Example Store",
                url: "https://www.example-store.com",
                countryCode: "US",
            },
        }),
    }
);

const { card } = await response.json();
// card.number, card.expirationMonth, card.expirationYear, card.cvc
Each credential fetch returns a fresh, merchant-scoped card number. If leaked, it can’t be reused at a different merchant.See Retrieve Virtual Card Credentials for the full API reference.
3

Navigate the checkout with a browser automation tool

There are several ways to drive a checkout session, and the right one depends on your use case — direct DOM control, LLM-driven autonomous browsing, or your own framework. In every case the integration with Crossmint is the same: you fetch a fresh, merchant-scoped virtual card with the snippet above and feed those credentials into whichever tool runs the browser.
import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();

const page = stagehand.page;
await page.goto("https://www.example-store.com/checkout");

await page.act(`Fill in the checkout form with:
- Card number: ${card.number}
- Expiration: ${card.expirationMonth}/${card.expirationYear}
- CVC: ${card.cvc}`);

await page.act("Submit the order");
await page.observe("Wait for the order confirmation page");

await stagehand.close();

When to use Browser Checkout vs Fast Checkout

Browser CheckoutFast Checkout
CoverageAny website that accepts cardsAmazon, Shopify stores (US only)
How it worksAgent drives a real browser sessionSingle API call, no browser needed
LatencyHigher — page loads, form filling, CAPTCHA handlingLower — direct API
ReliabilityCan break when sites change their DOMStable API contract
Stablecoin supportNo — cards onlyYes — can pay with stablecoins on card-only merchants
Use Browser Checkout when the merchant isn’t supported by Fast Checkout — it works anywhere a card is accepted. Use Fast Checkout when the merchant is supported — it’s faster, more reliable, and supports stablecoin payments.

Learn more

Cards setup

Full card delegation flow: save, enroll, issue, and retrieve.

Cards quickstart

End-to-end quickstart for virtual cards.

Fast Checkout

Skip the browser entirely for supported merchants.

How Agents Pay

The full mental model for agent payments.