Mint a one-time-use payment credential (virtual card PAN or Shared Payment Token) from a user's Link wallet so an agent can complete a purchase on their behalf. User approves each spend request from the Link mobile app; real card details never reach the agent.
Automate repetitive workflows and reduce manual effort
Example: Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example: Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example: Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
Time estimate: 15-45 minutes depending on use case complexity
Prerequisites
Submit your Claude Code skill and start earning
browse install link.com/create-payment-credential-0nc34aCompatible with
Supported agents
| name | create-payment-credential |
| title | Link Create One-Time-Use Payment Credential |
| description | >- Mint a one-time-use payment credential (virtual card PAN or Shared Payment Token) from a user's Link wallet so an agent can complete a purchase on their behalf. User approves each spend request from the Link mobile app; real card details never reach the agent. |
| website | link.com |
| category | payments |
| tags | - payments - stripe - link - agentic-commerce - virtual-card - mcp - cli |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | cli |
| alternative_methods | - method: mcp rationale: >- Same code paths exposed as a stdio MCP server via `npx @stripe/link-cli --mcp`. Preferred when the agent runtime already speaks MCP — no shell-quoting trap on repeatable --line-item / --total flags; auth is shared with `link-cli auth login`. - method: browser rationale: >- There is no public web-UI path on link.com or app.link.com to mint a one-time-use card for agent use. The wallet UI manages funding sources only. Confirmed: do not waste turns scripting it. - method: api rationale: >- Stripe does not publish a standalone REST API for the Link agent-wallet surface. The internal `@stripe/link-sdk` is not on npm. Use the CLI (or MCP) — they are the canonical API. |
| verified | false |
| proxies | false |
Given a purchase the user wants an agent to complete on their behalf, mint a one-time-use payment credential from the user's Link wallet — either a virtual card (PAN + CVC + expiry) usable in any merchant checkout form, or a Shared Payment Token (SPT) for merchants that support the Machine Payment Protocol. Real card details are never exposed to the agent; the credential is scoped to amount + currency + (for cards) merchant and is single-use. The user explicitly approves each request from the Link mobile app before credentials are released. Read-mostly with one approved write per call (mint + retrieve the credential); the agent never charges the underlying funding source directly.
Do not use for recurring subscriptions, agent-driven account top-ups without per-charge approval, or any flow where the user can't tap-approve in real time — the spend request expires (~30 min) and needs human approval each time.
This is a CLI / MCP skill. There is no web-UI path on link.com to mint a one-time-use card for agent use — the entire surface is @stripe/link-cli (also exposed as a stdio MCP server) plus the Link mobile app for approval. Do not try to script the Link web wallet at app.link.com for this; the wallet UI is for human card management only. Lead with the CLI; the MCP integration is the same code paths wrapped in stdio JSON-RPC.
npm install -g @stripe/link-cli
link-cli auth login --client-name "Claude Code"
auth login prints a verification_url and a short human-readable phrase. The user opens the URL on a phone (or the same browser), signs into Link, and enters the phrase to bind the CLI session to their account. Credentials are written to ~/.config/link-cli-nodejs/config.json by default; override with --auth <path> or LINK_AUTH_FILE env var if you need multiple identities side-by-side.
Verify with link-cli auth status — it returns authenticated: true plus consumer_id. If authenticated: false, the user has not yet confirmed the device.
link-cli payment-methods list --format json
Returns an array of { id, type, brand|bank_name, last4, exp_month, exp_year, nickname }. Pick the id (csmrpd_…) the user wants to fund the one-time card from. If the list is empty, the user has no payment methods in Link and must add one at https://app.link.com/wallet first.
(Optional: link-cli shipping-address list if the merchant needs a delivery address; link-cli user-info retrieve for billing email/name. Both can be passed verbatim into the merchant's form.)
link-cli spend-request create \
--payment-method-id csmrpd_001 \
--merchant-name "Stripe Press" \
--merchant-url "https://press.stripe.com" \
--amount 3500 \
--currency usd \
--line-item "name:Working in Public,unit_amount:3500,quantity:1" \
--total "type:total,display_text:Total,amount:3500" \
--context "Purchasing 'Working in Public' (paperback) from press.stripe.com on behalf of the user. The user explicitly requested this title in chat; one-time purchase, ship to address on file." \
--request-approval \
--output-file /tmp/link-card.json \
--format json
Required arguments:
| Flag | Constraint |
|---|---|
--payment-method-id | A csmrpd_… from step 2. |
--merchant-name, --merchant-url | Required for credential_type=card. Forbidden for shared_payment_token. |
--amount | Integer cents. Hard cap 50000 (= $500.00). Larger amounts are server-rejected. |
--currency | 3-letter ISO. Defaults to usd. |
--context | Minimum 100 characters. This is the text the user reads on their phone before approving — write a real, specific human-readable rationale, not boilerplate. Approvals are denied for vague context. |
--line-item | Repeatable key:value,key:value string. Keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. |
--total | Repeatable key:value string. Keys: type (required; one of subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). |
--request-approval (default true) creates the request and triggers a push notification to the user's Link app, then polls until the request reaches a terminal state. Alternatively, omit it and call link-cli spend-request request-approval <id> later — useful when you want to surface the request to the user out-of-band first.
--output-file <path> is strongly recommended. Without it, on success the response includes the full PAN, CVC, and billing address in the JSON envelope — those will land in your agent transcript and any log it writes. With --output-file, stdout shows only brand/last4/exp + a card_output_file field, while the unmasked card is written to the path with 0600 permissions. Pass --force to overwrite an existing file.
For development against no real funding source, append --test — the CLI provisions a test-mode card (4242 4242 4242 4242) without touching real funds. The user still has to approve in the Link app (test approvals are tagged [TEST]).
If you used --request-approval, the create command already polled and returned when the request was approved, denied, expired, or canceled. Otherwise:
link-cli spend-request retrieve lsrq_001 --interval 2 --max-attempts 300 --include card
--interval > 0 polls; --max-attempts 0 is unlimited (but --timeout still applies — default 600s, longer than the server-side spend-request TTL). On POLLING_TIMEOUT (non-zero exit, code: POLLING_TIMEOUT), the request is still alive on the server; you can re-retrieve later.
Terminal states:
approved → response includes a card object (or for SPT, a token usable with mpp pay).denied → user tapped Decline. No credential.expired → user didn't act in time (~30 min from create).canceled → caller invoked spend-request cancel lsrq_….Card path (credential_type=card, the default). The approved retrieve returns:
{
"id": "lsrq_001",
"status": "approved",
"credential_type": "card",
"card": {
"number": "4111111111111111",
"cvc": "123",
"exp_month": 12,
"exp_year": 2027,
"brand": "visa",
"last4": "1111",
"billing_address": {
"name": "Jane Doe",
"line1": "...",
"city": "...",
"postal_code": "...",
"country": "US"
},
"valid_until": "2026-05-19T00:13:00Z"
},
"amount": 3500,
"currency": "usd"
}
Drop those fields into the merchant's checkout form (any merchant — not Stripe-only and not Link-aware). Submit. The card is good for one successful authorization up to amount at merchant_url until valid_until. After charge or after valid_until passes, the card is dead.
SPT path (credential_type=shared_payment_token):
# Decode the merchant's 402 challenge
link-cli mpp decode --challenge 'Payment id="ch_001", realm="...", method="stripe", intent="charge", request="..."'
# → returns network_id
link-cli spend-request create \
--credential-type shared_payment_token \
--network-id <network_id from decode> \
--payment-method-id csmrpd_001 \
--amount 100 \
--context "..." \
--request-approval
# (no --merchant-name / --merchant-url for SPT — they are forbidden)
link-cli mpp pay https://climate.stripe.dev/api/contribute \
--spend-request-id lsrq_001 \
--method POST \
--data '{"amount":100}'
The SPT is single-use — if the HTTP 402 retry fails, mint a new spend request.
link-cli spend-request cancel lsrq_001
Works from created, pending_approval, or approved state (the latter invalidates the card before it's used).
The same surface area is exposed as a stdio MCP server:
{
"mcpServers": {
"link": { "command": "npx", "args": ["@stripe/link-cli", "--mcp"] }
}
}
Auth is shared with link-cli auth login. Tools mirror commands (spend-request.create, payment-methods.list, mpp.pay, etc.). Approval still happens out-of-band in the Link mobile app. Prefer this in agents that already speak MCP — same constraints, no shell-quoting trap on the repeatable --line-item/--total flags.
consumer_id at auth.amount is capped at 50000 cents (= $500.00). This is a hard server-side cap, not a CLI-side check. Larger amounts return a validation error. For higher totals you must currently split into multiple spend requests, each approved separately.context must be ≥ 100 characters. Server-validated. Boilerplate ("user wants to buy something") will pass the length check but is the #1 reason users decline a request — they read this text on their phone. Include merchant, exact item(s), why now, and any non-obvious detail (shipping, recurring nature, etc.).merchant_name + merchant_url are required for card credential type and forbidden for SPT. The reverse for SPT — only network_id is required there. Mixing the two (e.g. passing merchant_url with credential_type=shared_payment_token) returns a validation error.--request-approval polls — it doesn't return immediately. The create call blocks until the request is approved, denied, expired, or canceled. If you need a fire-and-forget create, drop the flag and call spend-request request-approval <id> separately.retrieve --interval N --max-attempts M --timeout T polls client-side. Reaching the timeout/max-attempts before a terminal status exits non-zero with code: "POLLING_TIMEOUT" — do NOT treat that as a denial. The request is still alive on the server; re-poll with another retrieve.merchant_url. An SPT is dead after one MPP pay attempt regardless of success — if the merchant 5xx's, you have to mint a new spend request, not retry with the same SPT.merchant_url. Stripe Issuing enforces merchant match on authorization. A card minted for press.stripe.com will be declined if used at a different merchant. Set merchant_url to the exact storefront the agent will check out at; getting the subdomain wrong is a common cause of unexpected declines.--output-file <path> (and --format json) so the unmasked PAN/CVC never appear on stdout. The file is written 0600; the stdout response only contains brand/last4/expiry + a card_output_file pointer. Don't cat the file into the chat afterward — pipe it into the checkout-form fill directly.--test flag for development. Creates a test-mode spend request whose approved card is the Stripe test number 4242 4242 4242 4242. No real funds move. Approvals in the Link app are tagged [TEST]. Use this for any integration testing — there is no other sandbox mode.link.com / app.link.com is not a substitute. The wallet UI lets users manage funding sources but does not surface a "create one-time-use card" button for human users in a useful way. Don't waste turns scripting the web UI — the CLI is the only API.auth login is interactive and out-of-band. The CLI cannot complete login on its own — it must surface the URL + phrase to the user, who confirms on a separate device. For headless setups, pre-authenticate on a trusted machine and copy ~/.config/link-cli-nodejs/config.json to the agent host (or use LINK_AUTH_FILE to point at the copied file).@stripe/link-cli is the only npm package; internal @stripe/link-sdk is not publicly published. Don't try npm install @stripe/link-sdk. To talk to the API outside the CLI, run the CLI as an MCP server (--mcp) and consume the JSON-RPC tools from your agent runtime.NO_UPDATE_NOTIFIER=1 to suppress the CLI's per-invocation update-check chatter in CI / agent transcripts. Otherwise expect an update block in auth status output when a newer version is on npm.--line-item '{"name":"Shoes"}' does not work. Use --line-item "name:Shoes,unit_amount:5000,quantity:1" — commas separate key:value pairs, no spaces around :. Prefer the MCP path if your agent runtime can't reliably shell-quote these (the MCP tool accepts a proper JSON array).The CLI emits structured output in one of toon (default for agents), json, yaml, md, or jsonl. Below are the JSON shapes for the four states a caller will see end-to-end.
// 1. create + approved (card path, --output-file used)
{
"id": "lsrq_001",
"status": "approved",
"credential_type": "card",
"amount": 3500,
"currency": "usd",
"merchant_name": "Stripe Press",
"merchant_url": "https://press.stripe.com",
"expires_at": "2026-05-19T00:13:00Z",
"card": {
"brand": "visa",
"last4": "1111",
"exp_month": 12,
"exp_year": 2027,
"valid_until": "2026-05-19T00:13:00Z",
"card_output_file": "/tmp/link-card.json"
}
}
// 2. create + approved (SPT path)
{
"id": "lsrq_002",
"status": "approved",
"credential_type": "shared_payment_token",
"network_id": "ntwk_stripe",
"amount": 100,
"currency": "usd",
"expires_at": "2026-05-19T00:13:00Z",
"shared_payment_token": "spt_..."
}
// 3. denied / expired / canceled
{
"id": "lsrq_003",
"status": "denied", // or "expired" | "canceled"
"credential_type": "card",
"amount": 3500,
"currency": "usd"
}
// 4. polling timed out before terminal status (NOT a denial — request still alive)
{
"code": "POLLING_TIMEOUT",
"message": "Polling reached --timeout / --max-attempts while the request was still pending_approval.",
"spend_request_id": "lsrq_004"
}
// 5. validation error from create
{
"code": "INVALID_REQUEST",
"message": "context must be at least 100 characters"
// or: "amount must not exceed 50000"
// or: "merchant_url is forbidden when credential_type is shared_payment_token"
}
After approved with --output-file, the on-disk JSON contains the unmasked card:
// /tmp/link-card.json (mode 0600)
{
"number": "4111111111111111",
"cvc": "123",
"exp_month": 12,
"exp_year": 2027,
"brand": "visa",
"last4": "1111",
"billing_address": {
"name": "Jane Doe",
"line1": "510 Townsend St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94103",
"country": "US"
},
"valid_until": "2026-05-19T00:13:00Z"
}
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versioncreate-payment-credentialExecute the skills CLI command in your project's root directory to begin installation:
browse install link.com/create-payment-credential-0nc34aFetches create-payment-credential from link.com/create-payment-credential-0nc34a and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
.cursor/skills/create-payment-credential
Restart Cursor to activate create-payment-credential. Access via /create-payment-credentialin your agent's command palette.
Learn more:View source on GitHubSkills CLI docsAbout CursorWhat are agent skills?
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
mcp-cli-scripts
jezweb/claude-skills · Productivity · 2 shared tags
feishu-cli-board
riba2534/feishu-cli · Productivity · tag: cli
upgrade-stripe
stripe/ai · Productivity · tag: stripe
create-mcp-app
modelcontextprotocol/ext-apps · Productivity · tag: mcp
atlassian-mcp
jeffallan/claude-skills · Productivity · tag: mcp
mcp:setup-context7-mcp
neolabhq/context-engineering-kit · Productivity · tag: mcp
Registry listing for create-payment-credential matched our evaluation — installs cleanly and behaves as described in the markdown.
Keeps context tight: create-payment-credential is the kind of skill you can hand to a new teammate without a long onboarding doc.
We added create-payment-credential from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
create-payment-credential reduced setup friction for our internal harness; good balance of opinion and flexibility.
Registry listing for create-payment-credential matched our evaluation — installs cleanly and behaves as described in the markdown.
Useful defaults in create-payment-credential — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
create-payment-credential is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
create-payment-credential has been reliable in day-to-day use. Documentation quality is above average for community skills.
Solid pick for teams standardizing on skills: create-payment-credential is focused, and the summary matches what you get after install.
I recommend create-payment-credential for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
showing 1-10 of 36