Agent Payments With Stripe Link: The Token Approves the Money, Your Code Approves the Cart
LangChain's Restock sample shows where the real check in an AI agent purchase lives, and it is not in the wallet
A payment token can tell you how much it is allowed to spend. It cannot tell you what it is paying for.
That gap sits at the center of every agent that buys things, and LangChain's new Restock sample, published October 8, is the clearest look yet at how to close it. Restock is a Slack agent that orders office supplies, pays with Stripe's Link wallet, and checks out through Zinc, a retail API that speaks the Machine Payments Protocol. The blog post carries one sentence that should be pinned above every agent-payments design doc: "Nothing the model writes into a tool call can approve it."
The interesting part is how much code it takes to make that sentence true. The wallet does less than you might assume, and your tool does more.
The stakes: a yes that covers the wrong thing
Most people picture agent payment risk as a model with a credit card going on a spree. Spending limits fix that, and every agent wallet now ships one.
The failure that gets past spending limits is subtler. A human approves a purchase. Between that approval and the moment money moves, something changes: the cart, the quantity, the delivery address, the merchant. The approval still looks valid, because the thing doing the checking only looks at the amount. The person said yes to pens for the office. The agent spends that yes on something else that costs the same.
My position: in agent commerce, the payment token secures the money and nothing else. Binding the human's approval to the actual order is your job, in your tool code, and a sample that does it carefully is worth more than another wallet announcement.
How the Restock flow actually works
Restock runs on LangChain's Managed Deep Agents and puts two human gates in front of every purchase.
The first gate lives in Slack. The agent searches products, builds a cart, and calls request_restock_payment, which raises an interrupt with exactly two allowed decisions, approve and reject. Anything other than one clean approve counts as a rejection and cancels the order. The person sees the cart, the fees and an upfront amount before anything happens.
That upfront amount matters because, as the post explains, tax and shipping are not final until the order is placed. So Restock treats the shopping budget as a ceiling, asks for an upfront payment that covers the worst case, and lets Zinc refund the difference. In the post's demo, the user approved $23 for a pens order whose retailer total came to $21.18. Zinc's fee brought the charge to $22.18, and $0.82 came back.
The second gate lives at Stripe. Restock posts a Link approval link for the exact amount in Zinc's payment challenge, and the person approves it on Link's own site. Under the hood this is Stripe's documented machine-payments flow. The Link CLI decodes the merchant's HTTP 402 challenge with link-cli mpp decode, creates a spend request with link-cli spend-request create --credential-type shared_payment_token, and after approval completes the payment with link-cli mpp pay. Stripe's docs state that "shared payment tokens are one-time-use," so a failed payment means a fresh spend request rather than a retry with the same token.
So far, this sounds airtight. One-time token, exact amount, human approval on a page the model never touches.
Here is the line in the LangChain post that changes the picture: "The token doesn't enforce cart details on its own, so the tool also checks the order against what the user reviewed and confirms the approval is still fresh."
Where the real check lives
The token knows an amount and a merchant challenge. It does not know that the human reviewed a specific box of pens going to a specific office.
Restock's architecture doc spells out what its code checks before it hands the token over. Before submission, the code checks that the order "still matches the reviewed items, address, quantity, and chosen payment amount," and "a changed amount, currency, network, or private office prevents payment." The code also "checks fresh Link approval again before handing over the payment token," and expired unpaid instructions "refresh against the same cart" instead of silently attaching to a new one.
Then there is the token itself. Per the same doc, "the token is read from a private sandbox file inside the tool, then deleted." The model "does not receive payment tokens, wallet sessions, or the delivery address," and "only a public summary returns to the model." Credentials live in LangSmith Connections, the Link session sits in a user-owned Connection, and a sandbox proxy "verifies LangSmith's signature and the requesting tool's permission before returning a credential."
Read those together and the design becomes clear. Three separate things protect the purchase:
The wallet protects the money. One-time token, exact amount, human approval on Stripe's page.
The tool protects the order. It compares what is about to execute against what the human saw and refuses on any drift.
The sandbox protects the secret. The model never holds anything it could leak, replay or write into a later tool call.
Take away the middle layer and you still have a correctly scoped, one-time, human-approved token. You just no longer know what it bought.
Why the model cannot approve itself
The "nothing the model writes" sentence deserves a second look, because it describes a property you have to build, not one you get.
An agent with tool access can call tools with any arguments it likes. If your approval check reads a field the model can set (a flag in the tool call, a status the agent writes to state, a confirmation string in its own output), then the model can approve itself, whether through a bug, a confused plan, or a prompt injection from a product page it just read. Restock avoids that by making approval something that happens outside the model's reach: an interrupt answered by a human in Slack, and a Link page answered by a human in a browser. The tool reads the results of those events. It never trusts the model's description of them.
This is the same pattern Anthropic wrote into its usage policy on the same day for a very different domain. Its new rule for hardware that takes physical actions says an operator must be able to "observe the equipment and stop it if needed," and that the equipment "must also be able to hold a safe state if Claude is disconnected." Different stakes, same idea. The stop lives somewhere the model cannot talk to.
Put this into practice
You do not need Restock's whole stack to use its pattern. Start with the cheapest steps.
Run the sample without spending anything. Restock ships three modes. RESTOCK_MODE=rehearsal uses fictional products and simulated approval, with no Zinc or Link needed. RESTOCK_MODE=link-test runs real search and a real Link approval, and the README promises "approval completed in test mode, with nothing purchased." Walk through both as the approver. Notice what you are shown and what you are not.
Write down what your human actually approves. For any agent that spends money, sends email or changes production, list the fields the person sees at approval time. That list is your binding contract. If the executing action can differ from it on any field, you have a gap.
Re-check at execution, not at approval. The check that matters runs in the tool, immediately before the irreversible call. Compare the order, recipient and amount to the approved snapshot, and fail closed on any difference. Restock's architecture doc is a good template for which fields to compare.
Keep the token out of the model's context. Read secrets inside the tool, use them once, delete them, and return a summary. If your agent framework puts credentials in tool arguments or conversation state, fix that before you add payments.
Make approval an event, not a field. An interrupt answered by a person, a webhook from a wallet, a signed callback. Never a boolean the model can set.
The honest limitations
Restock is a sample, and LangChain says so plainly. It runs US delivery and USD only, one office per deployment, and pays from the requester's own wallet. The post's prices are illustrative, and the authors say they ran one live order to order_placed on a hosted deployment.
Coverage is the big constraint. In the post's own words, "the agent can only buy through MPP-enabled APIs." Zinc bridges to retailers today, but most of the web does not answer with an HTTP 402 payment challenge, so this pattern does not yet extend to arbitrary checkout pages.
Concurrency is unsolved in the sample. The README warns that "concurrent production use needs stronger coordination than the sample's process-local locks," and the architecture doc recommends database claims or leases instead. Two workers racing on the same order is exactly where a cart check can pass twice.
Setup is not free either. You need Python 3.11 to 3.14, a US LangSmith workspace with Managed Deep Agents access, an OpenAI key, a US Link account with a payment method, and a funded Zinc account that charges about $0.01 per search, even in test mode.
And the big caveat: the cart check is only as good as the fields it compares. Restock's checks cover items, address, quantity, amount, currency and network. If your domain has a field that matters and you forget to compare it, the token will happily pay for the version you did not review.
The question to ask your own agent
Wallets for agents are getting good. One-time tokens, exact amounts, approval pages the model cannot touch: that part of the problem is close to solved. What no wallet can do is know what your user meant to buy.
So find the line in your agent where a human's yes turns into an action, and ask one thing of it. If the action changed after the yes, would anything notice? If the answer lives in your tool code, you have built what Restock built. If it lives in the token, you have built a very secure way to pay for the wrong thing.
Sources: LangChain, "Agents that can pay" · langchain-samples/restock-agent · Restock architecture doc · Stripe, Pay machine-payment merchants · Anthropic 2026 Usage Policy update
Medium metadata
- Title: Agent Payments With Stripe Link: The Token Approves the Money, Your Code Approves the Cart
- Subtitle: LangChain's Restock sample shows where the real check in an AI agent purchase lives, and it is not in the wallet
- Tags: AI Agents, Payments, LangChain, Stripe, AI Security
- Canonical URL: import from the fervorai.dev post
- Reading time: about 8 minutes