Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Retrieve payment credentials with spend requests


Retrieve payment credentials with spend requests

A Link spend request lets your agent retrieve a one-time-use payment credential to buy anywhere online. Your agent creates a spend request, the customer approves it, and Link returns the credential. Your agent then completes the purchase with that credential.

Spend requests support several payment options, including one-time-use virtual cards and shared payment tokens. A one-time-use virtual card works at any seller that accepts cards online. A shared payment token works only at sellers that accept shared payment tokens.

Link CLI gives you one integration across payment rails. Your agent requests a credential without integrating each rail directly.

Before you begin

Before you begin, make sure that:

  • You’ve set up OAuth , including the payment _ methods. agentic scope.
  • You’ve installed Link CLI and keep it up to date: npm install -g @stripe/link-cli . Update it regularly to get the latest commands and skills.

How spend requests work

  1. Your agent creates a spend request with the purchase amount, merchant, context, and payment credential type.
  2. Link returns an approval _ url to present to the customer.
  3. The customer approves the request on the Link website or in the Link mobile app. Customers don’t need to install the mobile app to approve.
  4. Your agent polls the spend request until it sees that the request is approved.
  5. Link returns a one-time-use payment credential your agent uses to complete the purchase.

Create a spend request

To create a spend request, use the spend-request create command:

Create spend request

link-cli spend-request create \
 --amount 3500 \
 --context "Purchasing 'Working in Public' from press.stripe.com. The customer initiated this purchase through the shopping assistant." \
 --merchant-name "Stripe Press" \
 --merchant-url "https://press.stripe.com" \
 --line-item "name:Working in Public,unit_amount:3500,quantity:1" \
 --total "type:total,display_text:Total,amount:3500"

Response

Present the approval_url to the customer and ask them to approve the purchase.

By default, spend-request create returns a card credential—a one-time-use virtual card. Set --credential-type to choose the type that matches how your agent pays:

Credential typeWhen to use it
Virtual card ( card, default)Buying on the open web, at any merchant that accepts cards.
Shared payment token ( shared_payment_token)Paying sellers that accept shared payment tokens, including machine-payment merchants.

Parameters

The spend-request create command accepts the following parameters:

ParameterRequiredDescription
--amountYesPurchase amount in the smallest currency unit (for example, 3500 for 35.00 USD).
--contextYesDescription of what’s being purchased and why. Must be at least 100 characters. This appears to the customer in the approval prompt.
--merchant-nameConditionalThe merchant where the purchase occurs. Required for card requests. Omit for shared_payment_token requests.
--merchant-urlConditionalThe URL of the product or merchant page. Required for card requests. Omit for shared_payment_token requests.
--network-idConditionalRequired for shared_payment_token requests. Retrieve it from the seller’s profile_id when you use UCP, or with mpp decode when you pay machine-payment merchants.
--payment-method-idNoThe payment method to charge. Defaults to the customer’s default payment method, or the first eligible one when no default is set.
--credential-typeNoType of payment credential to return: card (default) or shared_payment_token.
--currencyNoThree-letter ISO currency code. Defaults to usd.
--line-itemNoA line item to display on the approval screen. Repeatable.
--totalNoA total to display on the approval screen. Repeatable.
--metadataNoArbitrary string data in key:value format. Repeatable. Maximum 50 keys, keys up to 40 characters, values up to 500 characters.
--testNoCreates a test mode spend request that returns test credentials without a real charge. Defaults to false.

Line items and totals

The --line-item and --total parameters take repeatable key:value pairs. They control what the customer sees on the approval screen, so include them when the purchase has more than one component.

The keys for the --line-item parameter, where name is required:

  • name
  • quantity
  • unit _ amount
  • description
  • sku
  • url
  • image _ url
  • product _ url

The keys for the --total parameter, where all three are required:

  • type , one of subtotal , tax , total , items _ base _ amount , items _ discount , discount , fulfillment , shipping , fee , gift _ wrap , tip , or store _ credit
  • display _ text
  • amount

For example, to create a spend request for a purchase with multiple items, run:

Itemized request

link-cli spend-request create \
 --amount 12000 \
 --context "Purchasing trail running shoes from example.com. The customer selected these after comparing three options with the shopping assistant." \
 --merchant-name "Example Store" \
 --merchant-url "https://example.com/running-shoes" \
 --line-item "name:Running Shoes,unit_amount:12000,quantity:1,description:Trail runners" \
 --total "type:subtotal,display_text:Subtotal,amount:12000" \
 --total "type:total,display_text:Total,amount:12000"

Poll for approval

After presenting the approval URL, poll the spend request until it reaches a terminal status:

Poll spend request

link-cli spend-request retrieve lsrq_abc123 --interval 2 --max-attempts 300

The --interval flag sets the polling interval in seconds, and --max-attempts sets how many polls to make before giving up. Polling exits successfully only after the request reaches a terminal status: approved, denied, expired, or canceled.

The customer has 10 minutes from the approval request to respond, after which the status becomes expired. Size --interval and --max-attempts to cover that window. See Limits.

Handle interruptions while polling

Two outcomes stop polling before a terminal status:

  • A status of requires_action : The customer needs to do something before the request can proceed. Present next _ action. display _ message and next _ action. action _ url to the customer, then resume polling. See Next actions for how to branch on each action type.
  • An exhausted timeout : If --timeout elapses or --max-attempts runs out while the request is still non-terminal, the command exits non-zero with code: "the related setting _ the related setting" .

Don't treat a polling timeout as a completed purchase

A the related setting exit means the request is still pending, not that it failed or succeeded. Retrieve the spend request again to determine its actual status before you retry or tell the customer anything.

Retrieve card payment credentials

Retrieving a spend request excludes card details by default, to keep the cardholder’s PII out of any response shown to the customer. Pass --include card to return them:

Retrieve with card details

link-cli spend-request retrieve lsrq_abc123 --include card --format json

To keep the full card out of your agent’s transcript and logs, write it to a file with --output-file. Standard output then carries only redacted fields:

Write credentials to a file

Card numbers printed to standard output can persist in agent transcripts, model context, and log aggregation. Use --output-file in any hosted agent. Link CLI creates the file with 0600 permissions, and fails rather than overwriting an existing file unless you pass --force.

When you set --output-file, the JSON output replaces the card object with redacted fields and adds a card_output_file path pointing at the file. The approved spend request contains the credential:

Approved response

{
 "id": "lsrq_abc123",
 "status": "approved",
 "card": {
 "brand": "visa",
 "number": "4242424242424242",
 "cvc": "100",
 "exp_month": 6,
 "exp_year": 2029,
 "billing_address": {
 "name": "Jenny Rosen",
 "postal_code": "94015",
 "country": "US"
 },
 "valid_until": "2026-06-13T03:40:10Z"
 }
}

The card is one-time-use. By default, it expires 12 hours after you create the spend request, at the time shown in valid_until.

Complete the purchase

Use the card details from the approved spend request to complete checkout on the merchant’s site. Your agent can fill in the card number, CVC, expiration date, and billing address at checkout.

Limits

These limits apply per agent integration. To raise them for your integration, contact your Stripe sales representative.

LimitValue
Per request500 USD
Daily500 USD
Monthly, over 30 days20,000 USD
Concurrent active requests30, counting created and approved
Concurrent approved requests10
Creation rate50 per hour, and 200 over 60 days
Approval window10 minutes from the approval request
Credential validity12 hours from spend request creation

Spend request statuses

A spend request moves through one of nine statuses. Handle each one explicitly, because polling returns whatever the current status is.

StatusMeaningAction
createdThe request exists and approval will be requested.Continue polling until the status changes to pending_approval.
pending_approvalWaiting for the customer to approve or deny.Continue polling.
requires_actionThe customer needs to complete an action before the request can proceed.Present next_action.display_message and action_url to the customer, then follow Next actions.
approvedThe customer approved the request. Payment credentials are available.Complete the purchase.
deniedThe customer denied the request.Tell the customer, and don’t retry without creating a new request.
expiredThe customer didn’t respond within the approval window.Create a new spend request if the customer still wants to proceed.
canceledThe request was canceled before completion.Create a new spend request if the customer still wants to proceed.
succeededThe payment completed.No further action.
failedThe payment failed and the request is terminal.Read status_details.failed.code for the failure reason before retrying.

Next actions

When a spend request has a status of requires_action, read status_details.requires_action.next_action. It contains:

FieldDescription
typeThe kind of action the customer needs to complete.
resolutionHow your agent proceeds after the customer acts.
display_messageA customer-facing string you can present directly to the customer.
action_urlA Stripe-hosted URL to send the customer to, when one applies.
expires_atWhen action_url expires, as an ISO 8601 string. null when there’s no expiry.

Branch on type and resolution rather than on failure_code alone, because the same failure_code maps to different action types depending on context.

Action typeResolutionWhat to do
ssn_verificationcreate_new_spend_request_after_completionSend the customer to action_url to verify their identity, then create a new spend request.
identity_verificationcreate_new_spend_request_after_completionSend the customer to action_url for additional identity verification, then create a new spend request.
contact_supportcreate_new_spend_request_after_completionIdentity verification attempts are exhausted. Send the customer to Link support.
select_payment_methodcreate_new_spend_requestThe payment method was declined. Ask the customer to choose another, then create a new spend request.
add_payment_methodcreate_new_spend_request_after_completionNo eligible payment method is on file. Send the customer to action_url to add one, then create a new spend request.
update_payment_methodcreate_new_spend_requestThe card needs attention, such as an expiry, address, or security code problem. Send the customer to action_url, then create a new spend request.
re_authorizecreate_new_spend_requestThe charge exceeded the approved amount. Create a new spend request for the correct amount.
three_d_secureauto_resumeSend the customer to action_url to complete the challenge, then keep polling. The request resumes on its own.
three_d_secure_retrycreate_new_spend_requestThe challenge wasn’t completed. Create a new spend request.

Only auto_resume keeps the existing spend request alive. Every other resolution means the request is terminal, so create a new one after the customer acts.

Raise the amount on an approved request

Agents don’t always know the final price when they request approval. A checkout might require card details before it shows the final total, including tax or shipping. Rather than requesting a buffer amount upfront, you can raise the amount on a spend request the customer already approved.

Raising the amount requires the customer to approve again. On approval, Link triggers an incremental authorization so the card can be charged for the higher amount.

Before you call update, check that:

  • The request supports incremental authorization. Read incremental _ auth _ enabled on the spend-request retrieve response.
  • The customer already approved the request.
  • You haven’t successfully used the card yet. A virtual card can’t be used more than once.

Pass the new total, not the difference:

Raise the amount

link-cli spend-request update lsrq_abc123 --amount 7500

Then ask the customer to approve again and poll for their decision:

Request approval and poll

link-cli spend-request request-approval lsrq_abc123

link-cli spend-request retrieve lsrq_abc123 --interval 2 --max-attempts 300

Incremental authorizations aren’t guaranteed. A safe default is to try the increase and fall back to canceling and recreating the request on any error. In every failure case, the spend request stays usable at its original amount—a failed increase never invalidates credentials you already hold.

What happenedHow it surfacesWhat to do
The increase succeededstatus: approved with the higher amountUse the card you already retrieved.
The issuer declined the increaseA payment-declined errorProceed at the original amount, or cancel and recreate.
The increase exceeds the customer’s limitsA limits error with a specific codeBranch on the code. The request is unchanged and still usable.
The card was already usedA conflict errorPoll retrieve. Create a new request if you still need to spend more.
The card doesn’t support incremental authorizationA not_supported errorCancel and recreate.

Amount is the only field you can change this way. The card details stay the same throughout.

Manage a spend request

Retrieve a spend request to see the details of the transaction, including refunds and payment success events:

Retrieve a request

link-cli spend-request retrieve lsrq_abc123

List all spend requests for the authorized customer:

List requests

link-cli spend-request list

Cancel a request from the created, pending_approval, or approved state:

Cancel a request

link-cli spend-request cancel lsrq_abc123

Test your integration

Pass --test to create a test mode spend request. Link CLI returns test credentials, such as card number 4000009990001984, and doesn’t charge the underlying payment method:

Test mode spend request

link-cli spend-request create \
 --test \
 --amount 3500 \
 --context "Purchasing 'Working in Public' from press.stripe.com. The customer initiated this purchase through the shopping assistant." \
 --merchant-name "Stripe Press" \
 --merchant-url "https://press.stripe.com"

To walk through both credential types interactively, run link-cli demo, which always uses test mode.

See also

Last verified 2026-09-24

Is this helpful?