Rightshold™ Sign up

Answers · agent payments

When an AI agent pays a seller with a Stripe shared payment token (SPT), what stops the seller charging more than the purchase, charging again later, or keeping the card? How do I set the limits, revoke a token and tell when it's been used?

Last updated

TL;DR: The token carries its own limits, and Stripe enforces them. A shared payment token (SPT) is Stripe's scoped payment credential for purchases an agent makes. The seller gets the token, not the card number. When the agent creates one, usage_limits is required: a currency, a max_amount in the currency's smallest unit (1000 is $10.00), and an expires_at timestamp. Stripe's seller docs say the agent sets max_amount to match the transaction total. The token is also tied to one seller, through that seller's Stripe profile (network_business_profile). Once the seller reaches the amount, the token is deactivated with reason consumed. It can also end as expired, revoked or resolved. Deactivated is terminal, so no new payments can be made with it. For a later charge from the same token, the token must have usage_limits.recurring_interval set, and Stripe rejects setup_future_usage on PaymentIntents made with an SPT, so a seller can't quietly save the card from a one-time token. The agent can revoke a token at any time, which stops the seller creating a payment with it, and webhooks tell you when it's used or deactivated. Three things to watch. SPTs are a preview product (API version 2026-09-30.preview, Agentic Commerce preview terms), available in the US, Canada and listed European countries. Revoking stops new payments but doesn't refund one already made. And a seller can resolve the token into network credentials for a third-party processor, after which charging happens outside Stripe's own payment flow.

What should I check, step by step?

1. Issue one token per purchase. Set usage_limits[max_amount] to the confirmed total in the smallest currency unit, including tax and shipping, and usage_limits[currency] to the checkout currency.

  1. Set usage_limits[expires_at] as close as the checkout allows: minutes or hours for a one-off purchase, not the far-future example timestamp in the docs.
  2. Grant the token to the right seller. Pass the seller's Stripe profile in seller_details[network_business_profile], collected during seller onboarding.
  3. Only set usage_limits.recurring_interval when the customer has agreed to a subscription. Without it, a seller can't reuse the token for later charges, and Stripe blocks setup_future_usage on SPT payments either way.
  4. Subscribe to shared_payment.issued_token.used and shared_payment.issued_token.deactivated, and verify webhook signatures. Show the customer when a payment is made and when the token is finished.
  5. Handle shared_payment.issued_token.requires_action. 3D Secure can be triggered by the issuer, the seller or Stripe, and the customer has to complete it on your surface before the token becomes active again.
  6. Revoke tokens you no longer need, for example when the user cancels or a checkout times out: POST /v1/shared_payment/issued_tokens/{id}/revoke. Check deactivated_reason afterwards.
  7. If you're the seller, retrieve the granted token and read its usage_limits before you create the PaymentIntent, and listen for shared_payment.granted_token.deactivated so you don't try to charge a dead token.
  8. Keep your own record of what the agent was allowed to buy alongside the SPT ID. The token caps the amount, but it doesn't know whether the item was the one the customer wanted.

How does a Stripe shared payment token get from an agent to a seller?

Stripe's agent guide sets out the flow. The customer gives the agent a payment method, usually collected with Stripe's Payment Element. The agent issues an SPT to the seller's Stripe profile for that transaction and sends the token ID to the seller. The seller creates a PaymentIntent with it, and Stripe processes the payment. When the PaymentIntent is confirmed, Stripe clones the customer's payment method into a new PaymentMethod for the seller, and refunds and reporting then work as if the seller had been given that payment method directly.

What do Stripe shared payment token usage limits enforce?

usage_limits is required when a token is created, and it holds the currency, max_amount and expires_at, plus recurring_interval for recurring tokens. Stripe's API reference lists four deactivation reasons: consumed (the allowed amount limit has been reached), expired, revoked and resolved (resolved by a seller). Deactivated is a terminal state.

Does revoking a Stripe shared payment token refund a payment?

Revoking prevents new payments. It doesn't reverse a payment the seller has already created, so refunds and disputes go through the seller and your card issuer as usual. For the Agentic Commerce Protocol, OpenAI's Delegated Payment Spec says OpenAI isn't the merchant of record, and refunds and chargebacks stay with the merchant and its payment provider.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before my agent issues a shared payment token, check this $42.50 checkout at shop.example against its own spending policy and record the decision with the token ID as the reference.”

One-click setup

{
  "tool": "authorize_spend",
  "arguments": {
    "credential_id": "YOUR_AGENT_CREDENTIAL_ID",
    "amount_minor": 4250,
    "currency": "USD",
    "merchant_domain": "shop.example",
    "category": "retail",
    "reference": "spt_..."
  }
}

Rightshold records spending decisions your agent asks for. It never holds or moves money, isn't affiliated with Stripe or OpenAI, and doesn't process cards or tokens. Stripe details are from its shared payment token docs and API reference (preview API version 2026-09-30.preview), checked on November 10, 2026. Not financial advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'