Create Payment Credential
Other24.8K installs
What it does
Gets secure payment credentials (cards, tokens) from a Link wallet for one-time purchases and recurring payments. Use when the user says "get me a card", "buy something", "pay for X", "make a purchase", "I need to pay", "complete checkout", or asks to set up a subscription or…
Install
npx skills add https://github.com/stripe/link-cli --skill create-payment-credentialWebsite
www.skills.sh/stripe/link-cli/create-payment-credentialDetails
From the skill’s SKILL.md or README, by its authors. View the original
Create Payment Credential
Use Link to get secure payment credentials from a Link wallet for one-time purchases and recurring payments.
The CLI can produce three credential types:
- A virtual card (PAN) for use with a standard web checkout form. The issued card works anywhere.
- A Shared Payment Token (SPT) when the seller is in the Stripe Network and accepts payments programmatically (for example with Machine Payment Protocols).
- A Link Pay Token (LPT) for a supported Stripe payment surface.
Installing
Install with npm install -g @stripe/link-cli. Always run the installed link-cli binary; never substitute a package runner such as npx, pnpx, or bunx.
Running commands
Link CLI can run as an MCP server or as a standalone CLI.
MCP: Add the following to your MCP client config (.mcp.json, etc.)
{
"mcpServers": {
"link": {
"command": "link-cli",
"args": ["--mcp"]
}
}
}
Run the MCP server directly with link-cli --mcp.
Call tools/list to see all available MCP tools.
Common commands/options
- List all commands:
link-cli --llms - List all commands with parameters:
link-cli --llms-full - Get a command's exact schema with
--schema. For example,link-cli spend-request create --schema - Multi-step commands return a
_nextaction. Spend-request approval and automatic-resume polling return_next.argv;mpp payreturns_next.poll_argvand_next.pay_argv. Invoke these directly without a shell. Thecommandvalue is a Link CLI subcommand: pass[command, ...args]to the trusted CLI entrypoint. Dynamic compatibility strings are omitted on Windows — see the security notes. Authentication also returns a static_next.commandfor polling. - By default all output is in
toonformat. Pass--format [json|md|yaml]to change output format. - Some commands return a verification or approval URL. These must be presented to the user clearly for their action.
--authflag to store auth credentials in a specific file instead of the default location.auth loginwrites to this file; all other commands read from it. Example:link-cli auth login --auth credentials.json
_Recommended_: Run link-cli --llms to understand all the available commands. The --llms-full output is the canonical reference for parameter names, types, and valid values. Pass --schema before invoking a command to understand its parameters and constraints.
Core flow
Copy this checklist and track progress:
- Step 1: Authenticate with Link for the whole task
- Step 2: Evaluate merchant site (determine credential type)
- Step 3: Get payment methods
- Step 4: Create spend request with correct credential type
- Step 5: Complete payment
Step 1: Authenticate with Link for the whole task
Check auth status:
link-cli auth status
When authenticated, the response also reports the session's granted scope and authorization_details (when the token endpoint returned them). If the response includes an update field, a newer version of link-cli is available — run the update_command from that field to upgrade before proceeding.
If not authenticated:
link-cli auth login --client-name ""
Replace ` with the name of your agent or application (for example, Personal Assistant, Shopping Bot`). This name appears in the user's Link app when they approve the connection. Use a clear, unique, identifiable name.
New logins request the userinfo:read and payment_methods.agentic scopes and all four financial-insights source actions by default: read_link_transactions, read_external_transactions, read_balances, and read_source_details. If the user wants payment-only access, use link-cli auth login --client-name "" --no-financial-insights. If they want only certain actions, pass those --source-actions flags; an explicit list replaces the default. Do not combine explicit --financial-insights or --no-financial-insights with --source-actions or --authorization-detail. If the user does not want the default payment scope, pass --no-agentic-payments.
If login initiation fails specifically because the extra source actions are unsupported or unavailable, explain that financial insights will be unavailable and retry once with --no-financial-insights when the payment still needs a Link connection. Do not automatically retry after the user declines or abandons approval.
The response includes a _next command — run it to poll until authenticated. If your environment cannot relay the verification code while a separate polling command blocks I/O, use inline polling instead: auth login --client-name "" --interval 5 --timeout 300. This yields the code immediately then polls in the same command.
If the user's email is already known and no creation-time callback context was supplied, save them time by adding it as the URL-encoded fromEmail query parameter to any app.link.com verification or action URL; preserve existing query parameters.
DO NOT PROCEED until the user is authenticated with Link.
Always check the current authentication status before starting a new login flow — the user might already be logged in.
If the user is already authenticated but you need broader access (an additional scope, --source-actions, or --authorization-detail), use auth upgrade instead of auth login. It accepts the same explicit access flags but does not add the login-only financial-insights default. It merges what you request with the current scope/authorization_details and starts a new approval for the superset — so existing access is never dropped. Check auth status first so you know what's already granted. The current session stays valid during the approval and is only replaced once the user approves the new one, so an abandoned upgrade leaves the existing session working. Do not start an upgrade solely to fetch an optional brand insight for a purchase.
Optionally, before a purchase, run link-cli user-info retrieve to inspect the address, applicable spend limits, and verification requirements. Finite limit values are cents, while null limit or remaining values mean unlimited. When agent_wallet_verification_requirement.action_url is present, direct the user there to complete the required action.
Step 2: Evaluate the merchant site BEFORE creating a spend request
If the user has not named a merchant, especially for a request such as buy from my usual store, use an available Link top-brand insight as a clue before choosing a site. When the current connection has access and the commands are available, run link-cli insights list-available-types --format json, find a top-brand insight whose description matches the purchase category, then run link-cli insights list --insight --format json. Use only a ready result, and treat it as observed purchase history rather than a preference the user stated. An explicitly named merchant takes precedence.
If the command is unavailable, access is missing, or the insight is pending, empty, or fails, continue with the user's other instructions or ask them which merchant to use. Do not upgrade access, repeatedly retry, or block the purchase solely for this optional clue.
CRITICAL: Before calling spend-request create you must complete this checklist:
- Understand how the merchant accepts payments (cards or machine payments or other). Do NOT default to
cardcredential type. The merchant determines the credential type — you cannot know it without checking first. Skipping this step will produce a spend request with the wrong credential type. - Have the final total amount needed. Inclusive of any shipping costs, taxes or other costs. Skipping this step will produce a spend request that does not cover the full amount needed, and will be rejected.
- Clear context and understanding of what the user is purchasing. Be sure to know sizes, colors, shipping options, etc. Skipping this step will produce a spend request that the user does not recognize or understand.
Determine how the merchant accepts payment:
- Navigate to the merchant page — browse it, read the page content, and understand how the site accepts payment.
- If the checkout page includes the AI-agent steering block (find the
.AiAgentPaymentSteeringcontainer — visually hidden but present in the DOM, typically inside a Stripe iframe) — it may support the Link Pay Token flow (Step 5, Link Pay Token section). Requires browser automation. Before creating an LPT request, verify that bothinput[name="link_pay_token"]anddata-stripe-merchant-accountappear in the same frame. Read the account ID from that attribute. If either marker does not appear, usecardinstead. Without browser automation, usecard. - If the page has a credit-card form and no AI-agent steering block (no
.AiAgentPaymentSteering) — usecard. - If the page describes an API or programmatic payment flow — make a request to the relevant endpoint. If it returns HTTP 402 with a
www-authenticateheader, useshared_payment_token.
What you find determines which credential type to use:
| What you see | Credential type | What to request |
|---|---|---|
.AiAgentPaymentSteering block containing both input[name="link_pay_token"] and data-stripe-merchant-account | link_pay_token | Link Pay Token (else card) |
| Credit-card form, no AI-agent steering block | card (default) | Card |
HTTP 402 with method="stripe" in www-authenticate | shared_payment_token | Shared payment token (SPT) |
HTTP 402 without method="stripe" in www-authenticate | not supported | Do not continue |
For 402 responses: Use mpp pay — it handles the entire flow automatically (probes URL, parses challenge, picks payment method, creates spend request, gets approval, and pays). See Step 5.
Step 3: Confirm payment method and potentially shipping addresses
Link will automatically use the default payment method on the account. If the user explicitly asks to pay with a specific card or bank, use the list command to show available options. Note that not all of the user's payment methods might appear; this will filter on agentic-ready payment types.
link-cli payment-methods list
Only rename or clear a payment-method nickname when the user explicitly asks. Never infer that a nickname should change. If the target ID is not known, run payment-methods list first and identify the intended method using only its redacted details and existing nickname. Then use:
link-cli payment-methods update --nickname "Work card"
Pass --nickname "" to clear a nickname.
Only set or clear the wallet-wide default when the user explicitly asks. Use payment-methods list to identify the intended method from redacted details if its ID is unknown. Setting a new default replaces the previous wallet default. Pass an explicit value; false clears the selected method's default status:
link-cli payment-methods update --is-default true
link-cli payment-methods update --is-default false
--nickname and --is-default can be combined. Omitted fields stay unchanged.
If the merchant checkout requires a shipping or delivery address, fetch the user's saved shipping addresses. Use the default address unless the user specifies otherwise.
link-cli shipping-address list
Step 4: Create the spend request with the right credential type
For card and Shared Payment Token flows, use the command below. For Link Pay Token, do not create this generic request: follow the LPT instructions in Step 5 after you have read the merchant account ID from the checkout DOM.
link-cli spend-request create \
--amount \
--currency \
--context "" \
--merchant-name "" \
--merchant-url "" \
--line-item "name:,unit_amount:,quantity:" \
--total "type:total,display_text:Total,amount:"
Card requests may also include --network-id to identify the merchant's network profile. Keep the card's merchant name and URL parameters.
Completion callbacks (optional): If your application has a callback destination, generate an opaque, unpredictable nonce (for example, NONCE="$(openssl rand -hex 32)") and add both flags to the create command above:
--completion-callback-url "https://agent.example.com/link/callback" \
--nonce "$NONCE"
Save the nonce unchanged and verify an exact match when the callback is received. Both flags must be supplied together. The URL must be valid and at most 2,048 characters; the nonce must be nonblank and at most 512 UTF-16 code units. The API validates live-mode HTTPS and URL security. Use the returned approval_url and action_url as-is; do not manually append callback parameters when creation-time context was supplied. Retrieve the request to check its status after a callback.
Currency: Pass the merchant's checkout currency with --currency as a 3-letter ISO 4217 code (e.g. usd, eur, gbp). If omitted, Link uses the consumer's default spend-request currency. Do not convert prices yourself. If the currency is not supported, the API rejects the request.
Amounts (--amount, unit_amount, and --total amounts) are integers in the currency's smallest unit (e.g. cents): 1999 is $19.99 USD or €19.99 EUR. Some currencies have no minor unit, so 1999 in jpy is ¥1,999.
Delayed merchant charges: spend-request create --expires-at accepts Unix seconds or an ISO 8601 timestamp ending in Z (UTC), such as 2027-02-01T12:00:00Z. The CLI converts ISO input to Unix seconds for the API. Returned request expires_at is an ISO 8601 timestamp ending in Z (UTC). This sets the request expiry at creation. Use it for a preorder, booking, or charge after delivery. Cover the expected charge date and explain the timing in context; omit it for an ordinary purchase. One-time requests default to 7 days and allow up to 365 days. Recurring requests default to their maximum, up to 1,827 days; an earlier expiry ends the spending permission sooner without changing the reset cadence. An explicit timestamp must be at least 3 hours in the future. Country caps apply: Japan and unknown account countries use a 180-day cap. The API validates the applicable limit.
The 30-minute approval window still applies. Always check current status and credential valid_until. A later expiry does not guarantee funds or make a one-time SPT reusable.
Recurring payments: Use recurring terms only when the user's request covers the subscription or recurring purchase. Confirm the spending limit, currency, and cadence from the user or existing task context. Describe these terms in context so the user can review them during approval.
Add --recurring-interval day|week|month|year to spend-request create. --recurring-interval-count is an optional positive integer; the server defaults it to 1. For a $20 monthly limit, use --amount 2000 --currency usd --recurring-interval month. For every two weeks, use --recurring-interval week --recurring-interval-count 2. The amount is the spending limit for each period, not a lifetime total. The merchant schedules charges. Keep the credential type and merchant targeting required by checkout; recurring terms do not replace those inputs. Omit recurring flags for one-time purchases.
Follow normal approval and credential retrieval. Recurring card requests stay active after individual charges. Do not poll for succeeded after each payment or create a replacement each period. Confirm payment from the merchant's result or transaction records. Respect credential expiry, including card.valid_until.
spend-request update cannot change the interval or count. To stop future use of a credential, call spend-request cancel and check the result. Canceling a spend request revokes its credential but does not cancel the merchant subscription. Complete the merchant's cancellation flow when that is what the user requested.
--line-item keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. Repeatable for multiple items.
--total 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). Repeatable (e.g. subtotal + tax + shipping + total).
Do not proceed to payment while the request is still created or pending_approval. If polling exits with POLLING_TIMEOUT, keep waiting or ask the user whether to continue polling. If they deny, ask for clarification what to do next. If the user wants to abort, cancel the spend request:
link-cli spend-request cancel
spend-request retrieve --interval 2 waits for the initial status to change when it is created, pending_approval, or requires_action with auto_resume. All other statuses, including submitted and unfamiliar API values, return immediately. A status change does not necessarily mean approval: inspect the returned status and retrieve again if it is still waiting.
Recommend the user approves with the Link app. Show the download URL.
Test mode: Add --test to create testmode credentials instead of real ones. Useful for development and integration testing. Link Pay Token does not support test mode.
Approval details: For delegated/pre-approved flows, pass --approval-detail as a JSON object (MCP/agent) or JSON string (CLI). Required fields: approved_at (unix timestamp), approval_method (click|programmatic|voice), app_name, external_user_id. Optional: ip_address, user_agent, device_type (mobile|web), agent_log_id, external_user_name, external_session_id, device_id, authentication_method (biometric_face|biometric_fingerprint|passkey).
Metadata: Attach arbitrary string data with the repeatable --metadata "key:value" flag (CLI) or a { key: value } object (MCP/agent). Max 50 keys, key ≤ 40 chars, value ≤ 500 chars. Example: --metadata "order_id:ord_123" --metadata "team:growth".
Actions can appear at creation or later, on both requires_action and terminal failed requests. Inspect the current action with:
link-cli spend-request retrieve --next-action --format json
The stable JSON contract is one array item: [{"next_action": }]. Read type, display_message, action_url, resolution, and optional expires_at (string or null). A null action means none is exposed in this snapshot; it does not establish approval or exclude later verification. Missing/inaccessible requests remain errors. This command does not poll, force verification, return credentials, complete an action, approve, or recreate a request, and adds no _next continuation. Do not combine it with --include, --output-file, --force, or nonzero --interval/--max-attempts; --timeout is ignored. Human TTY use requires an explicit format.
Show display_message and the exact non-null server action_url to the user. The user opens the URL and completes OTP/identity verification themselves; the agent must not complete these checks or reconstruct the URL.
- For
auto_resume, keep the same request. After each user completion, inspect a new snapshot or ordinary retrieve without polling for subsequent actions. Visapartner_auth_challengecan becomepartner_create_card_enrollmentwhile status remainsrequires_actionand the URL stays unchanged; present the updated action for the user to complete. Ordinary retrieve with--interval 2 --max-attempts 300can wait for a status change, but OTP submission or one status change does not establish approval. Inspect the actual result until final success or terminal failure. - For
create_new_spend_requestorcreate_new_spend_request_after_completion, foll
More Other skills
See allOther
Implement a piece of work based on a spec or set of tickets.
843.9K installsnpx skills add https://github.com/mattpocock/skills --skill implementOther
Turn the current conversation into a spec and publish it to the project issue tracker: no interview, just synthesis of what you've already discussed.
785.9K installsnpx skills add https://github.com/mattpocock/skills --skill to-specOther
Turn a decision you can't fully answer into a questionnaire for someone else to fill in.
559.8K installsnpx skills add https://github.com/mattpocock/skills --skill to-questionnaireOther
Stop. That last message did not land: re-pitch it.
511.1K installsnpx skills add https://github.com/mattpocock/skills --skill wait-what
Skills are shared by members and not reviewed by us. Read a skill’s code before you install it.