Auto-provision a virtual Visa card to complete an online purchase. Use when user asks to buy something and needs payment, or explicitly mentions cypher-pay/agent-pay. Handles onboarding (email OTP + KYC — once ever), token generation (once per device), funding, card creation, 3DS, and card lifecycle.
90
88%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Risky
Do not use without reviewing
Cypher Pay gives AI agents programmable virtual Visa cards. Create cards on demand, set spend limits, handle 3DS, and manage card lifecycle (single-use or reusable). All operations available via the agent-pay CLI — every command outputs JSON to stdout.
Trigger when end-user needs to buy something online and lacks a payment method, OR explicitly asks for "cypher pay" / "agent card" / "virtual card for this purchase".
This is a CONSUMER automation flow. Do NOT:
package.json or install dependencies into user projectsYou run CLI commands yourself. The user sees only: onboarding prompts (email, OTP, personal details), funding links, and purchase confirmations. All agent-pay commands output JSON — parse it silently, surface only what matters to the user.
Ensure the CLI is available. Install globally once (silent, no user prompt needed):
npm install -g @cypherhq/agent-payOr use npx @cypherhq/agent-pay <command> if you prefer not to install globally.
Start here. Every time. No exceptions.
Step 1 — Check for existing token:
Check env AGENT_PAY_TOKEN. Starts with agt_ → skip to Step 2.
Check ~/.config/cypher-pay/token. Exists and starts with agt_ → export it:
export AGENT_PAY_TOKEN="$(cat ~/.config/cypher-pay/token)"Skip to Step 2.
No token found → ask user for their email, then run:
agent-pay auth-status <email>This returns { "enrolled": bool, "kycComplete": bool }. No OTP sent, no auth required. Branch:
| enrolled | kycComplete | Action |
|---|---|---|
| true | true | User has account — just needs token. Run Returning user flow below. |
| true | false | Account exists, KYC incomplete. Get token first (Returning user flow), then resume KYC. |
| false | false | Brand new user. Present Onboarding paths and let them pick. |
Step 2 — Verify token works:
agent-pay agentExit code 0 → token valid, proceed to purchase flow. Exit code 2 (auth error) → token stale. Delete stored token, restart from Step 1:
rm -f ~/.config/cypher-pay/tokenUser is enrolled but has no local token. Get one via OTP:
agent-pay request-token <email>Tell user: "Check your email for a verification code."
agent-pay verify-otp <email> <otp>Returns { "agentId": "...", "token": "agt_..." }. Persist immediately:
mkdir -p ~/.config/cypher-pay
printf '%s' 'agt_...' > ~/.config/cypher-pay/token
chmod 0600 ~/.config/cypher-pay/token
export AGENT_PAY_TOKEN='agt_...'If kycComplete was false, continue to KYC steps in Path B below.
First-run only (enrolled=false). Present BOTH options — do not pick for the user:
First-time setup — pick one: A) Web signup — sign up at https://agentpay.cypherhq.io in your browser. Easiest option. B) Right here — I'll walk you through it step by step. You'll only need your browser once for identity verification.
agt_) from the dashboard when done.agt_. Reject and re-prompt if not.agent-pay agent.All commands run by you. User provides info conversationally — never show them raw commands or JSON.
B1. Send OTP:
agent-pay request-token <email>Tell user: "I've sent a verification code to your email."
B2. Verify OTP: Ask user for the code they received.
agent-pay verify-otp <email> <code>Persist the returned token immediately (see Returning user flow).
B3. Submit KYC application: Collect from user conversationally: first name, last name, phone, date of birth, address (line1, city, state, country, postal code). Then:
agent-pay submit-application \
--firstName "Alice" --lastName "Smith" \
--email "alice@example.com" --phone "+14155551234" \
--dob "1990-01-15" \
--line1 "123 Main St" --city "San Francisco" \
--state "CA" --country "US" --postalCode "94105"If response contains kycUrl → tell user: "Open this link to complete identity verification: <kycUrl>"
If kycAlreadyComplete is true → skip to B4.
B4. Wait for KYC approval:
agent-pay kyc-statusPoll this every 15–30 seconds. When status indicates approval, confirm to user: "You're all set."
B5. Verify:
agent-pay agentBoth paths produce same result. Subsequent invocations skip onboarding entirely (Step 1 finds stored token).
After onboarding completes (first run only), ask the user which card mode they prefer:
How would you like cards handled for purchases? A) Single-use cards (recommended) — a new card is created for each purchase and destroyed afterward. More secure: each purchase is isolated, card details can't be reused. B) Reusable card — one card is created and reused across purchases. Frozen between uses, unfrozen when needed. Simpler to manage if you make frequent purchases.
Persist the choice to ~/.config/cypher-pay/card-mode (value: single-use or reusable). Default to single-use if user doesn't pick. On subsequent runs, read from file — don't re-ask.
This is the core loop. User wants to buy something → you handle payment.
1. Check balance:
agent-pay balanceReturns $X.XX (e.g. $12.50). If balance < purchase amount:
agent-pay fund <amountUsd>Returns { "redirectUrl": "...", ... }. Tell user: "Open this link to add funds: <redirectUrl>". Poll agent-pay balance until funds arrive.
2. Create card sized to purchase:
agent-pay create-card --tag "purchase-$(date +%s)" --purpose "Buy headphones" --limit 50--tag must be unique per agent. Use timestamp or order ID.--limit = max per-transaction in USD. Set to expected charge amount.Output shows tag, masked card number, and expiry.
3. Get card details for checkout:
agent-pay get-card --tag "purchase-$(date +%s)" --revealReturns full PAN/CVV/expiry. Use to fill checkout form silently.
To display the card to the user:
agent-pay get-card --tag "purchase-tag" --prettyShows an ASCII art card with masked PAN (last 4 only) and expiry. Show this to the user after card creation.
If user explicitly asks for full PAN or CVV:
agent-pay get-card --tag "purchase-tag" --reveal --prettyShows full PAN and CVV in the ASCII art card. Warn once: "Card details will be visible in your conversation history."
SECURITY: Default output is masked — last 4 + expiry only. Full PAN/CVV only with --reveal when user explicitly asks. Use --reveal without --pretty to fill checkout forms, then discard.
4. Handle 3DS if triggered:
agent-pay 3ds-poll <cardId> --timeout 30000Two possible outcomes:
{ "approved": true, "requestId": "..." } — 3DS auto-approved. No user action needed.{ "approved": false, "requiresUserOtp": true, "message": "..." } — 3DS OTP was sent to the user's email by the card provider. Tell the user: "A verification code was sent to your email for this purchase. Please enter it on the merchant's checkout page." The agent cannot approve this automatically — the user must complete it themselves in the browser.5. Wait for charge to land:
agent-pay wait-for-txn <cardId> --timeout 30000Polls until a transaction appears on the card. Do NOT cancel before this confirms — cancelling during an in-flight auth will decline the charge.
6. Cancel card:
agent-pay cancel-card <cardId>Destroys the card. Frees the slot (max 5 active cards). If wait-for-txn times out with settled: false, freeze instead of cancel and tell user the charge may still be processing.
2. Get or create the reusable card: Check for an existing reusable card first:
agent-pay list-cardsLook for a card with tag reusable-default (or whatever tag was used). If found and status is frozen/inactive → unfreeze it:
agent-pay get-card --tag "reusable-default"
# If status is inactive:
agent-pay unfreeze --tag "reusable-default"If no reusable card exists, create one:
agent-pay create-card --tag "reusable-default" --purpose "Reusable purchase card" --limit 5003–4. Get card and 3DS: Same as Mode A steps 3–4 (use --tag "reusable-default").
5. Wait for charge to land:
agent-pay wait-for-txn <cardId> --timeout 300006. Freeze card (do NOT cancel):
agent-pay freeze <cardId>Card stays in your active slots but is blocked from new charges until next purchase.
Confirm purchase succeeded. Show last-4 digits of card if useful (from get-card). Never reveal PAN/CVV/expiry/token.
All commands require AGENT_PAY_TOKEN in env unless noted. Output is human-readable by default; add --json to any command for machine-parseable JSON.
agent-pay auth-status <email> # Check enrollment + KYC status
agent-pay request-token <email> # Send OTP to email
agent-pay verify-otp <email> <otp> # Verify OTP → get bot tokenagent-pay agent # Get agent account info
agent-pay kyc-status # Check KYC status
agent-pay balance # Balance in USD cents
agent-pay fund <amountUsd> # Get funding redirect URLagent-pay create-card --tag "x" [--purpose "..."] [--limit N] [--daily-limit N] [--monthly-limit N] [--reveal] [--pretty]
agent-pay get-card --tag "x" # Card info (masked)
agent-pay get-card --tag "x" --reveal # Full PAN/CVV/expiry — SENSITIVE
agent-pay get-card --tag "x" --pretty # ASCII art card (masked)
agent-pay get-card --tag "x" --reveal --pretty # ASCII art card (full PAN+CVV)
agent-pay freeze --tag "x" # Deactivate card
agent-pay unfreeze --tag "x" # Reactivate frozen card
agent-pay cancel-card --tag "x" [--reason "..."] # Permanent, irreversible
agent-pay list-cards # Active cards (--all includes cancelled)agent-pay wait-for-txn <cardId> [--timeout 30000] [--interval 3000] # Poll until charge lands
agent-pay transactions # Cross-card transaction history
agent-pay spend-stats [--start "2025-01-01"] [--end "2025-01-31"]agent-pay 3ds-poll <cardId> [--timeout 60000] [--interval 2000]agent-pay --schema # Full JSON schema of all commands, flags, and outputs| Exit code | Meaning |
|---|---|
| 0 | Success — JSON on stdout |
| 1 | Usage error (bad command, missing flag) — message on stderr |
| 2 | API error (auth failure, server error) — message on stderr |
On exit code 2 with auth message → token may be stale. Delete ~/.config/cypher-pay/token and re-auth.
agt_~/.config/cypher-pay/token with mode 0600. No other location. Never echo token value in conversation.The CLI wraps the @cypherhq/agent-pay TypeScript SDK. Developers building custom integrations can use the SDK directly:
npm install @cypherhq/agent-payimport { createClient } from '@cypherhq/agent-pay';
const ap = createClient(); // reads AGENT_PAY_TOKEN from envKey exports: createClient, parseExpiry, AgentPayAuthError, AgentPayApiError.
Full SDK documentation: see the package README or agent-pay --schema for the complete API surface.
Environment variables:
AGENT_PAY_TOKEN — bot token (required, must start with agt_)AGENT_PAY_BASE_URL — API base URL (optional, defaults to production)04bf5f2
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.