Virtual cards for AI agents. Pay USDC or XLM on Stellar, get a Visa card number in ~33 seconds.
API: https://api.cards402.com
Web: https://cards402.com
cards402/
├── backend/ Node.js/Express API, Soroban watcher, SQLite, policy engine
├── contract/ Soroban smart contract (Rust)
├── sdk/ TypeScript client + CLI + MCP server (npm: cards402)
├── web/ Next.js marketing site, docs, operator dashboard
├── docs/ Published API guide (skill.md, llms.txt)
├── examples/ Integration examples
└── scripts/ Deploy and ops tooling
Everything is open source. The backend, SDK, contract, web app, and operator
dashboard all live in this repo. The fulfillment engine that scrapes upstream
gift-card providers (vcc/) is a separate private service — it talks to the
backend over HTTP + HMAC webhooks.
Node.js/Express backend. Soroban event watcher, order state machine, policy engine (spend limits, approval flows, time windows), agent auth (API keys with bcrypt + prefix index), operator dashboard API, webhook delivery with per-origin circuit breakers, and background jobs (reconciliation, expiry, pruning).
cd backend
npm install
cp .env.example .env # fill in Stellar keys, VCC config, SMTP
npm run dev # http://localhost:4000
npm test # 1,038 testsSQLite (WAL mode, better-sqlite3). Migrations run automatically on startup.
Agent-facing client library. Exports Cards402Client (HTTP wrapper),
payViaContract / payViaContractOWS (Soroban contract invocation),
purchaseCard / purchaseCardOWS (create → pay → wait all-in-one), and an
MCP server for Claude Desktop or any MCP host.
cd sdk
npm install
npm run buildCLI commands: cards402 onboard, cards402 purchase, cards402 wallet,
cards402 mcp. Published to npm as cards402.
Next.js app serving the landing page, docs, blog, changelog, and the full operator dashboard (agents, orders, approvals, alerts, treasury, margins, webhooks, audit log).
cd web
npm install
npm run dev # http://localhost:3000
npm run buildRust contract deployed on Stellar mainnet. Receives USDC or XLM from agents and emits a payment event that the backend watcher indexes.
cd contract
cargo build --target wasm32-unknown-unknown --releaseContract ID is set via RECEIVER_CONTRACT_ID in the backend env.
See the quickstart, the full API reference, or the skill.md drop-in agent instructions.
- Ask your operator to create an agent in the dashboard — they'll give you a claim code
npx -y cards402@latest onboard --claim <code>— exchanges the claim code for credentials- Fund the wallet with XLM (or USDC after opening a trustline)
npx -y cards402@latest purchase --amount 10— buys a $10 Visa card
Or use the SDK programmatically:
import { purchaseCardOWS } from 'cards402';
const card = await purchaseCardOWS({
apiKey: process.env.CARDS402_API_KEY!,
walletName: 'my-agent',
amountUsdc: '10.00',
paymentAsset: 'usdc',
});
// card = { number, cvv, expiry, brand, order_id }For raw-keypair wallets (no OWS), use payViaContract + Cards402Client:
import { Cards402Client, payViaContract } from 'cards402';
const client = new Cards402Client({ apiKey: 'cards402_...' });
const order = await client.createOrder({ amount_usdc: '10.00' });
await payViaContract({ walletSecret: process.env.STELLAR_SECRET!, payment: order.payment });
const card = await client.waitForCard(order.order_id);See ARCHITECTURE.md for the full system design: fulfillment pipeline, Soroban event watcher, CTX integration, security model, and API reference.
This repo uses npm workspaces, Husky
pre-commit hooks, and lint-staged
for formatting. Commitlint enforces
conventional commits. Allowed scopes: backend, web, sdk, infra,
deps, ci.
npm install # root dev tooling (husky, lint-staged, commitlint)
cd backend && npm install
cd web && npm install
cd sdk && npm installCI runs typecheck, lint, tests (backend 1,038 + web 57 + SDK 114), Semgrep SAST, gitleaks secret scan, and Playwright E2E on every push and PR.