Repository navigation
Conversation
Two tools let Bell buy through Crossmint Agent Checkouts: crossmint_checkout starts a run from a product URL, a plain-language task and a spending cap, answers form questions and declines or cancels; crossmint_pay settles the payment request with the operator's order intent. Payment goes through Eve's tool approval rather than a confirmation in chat. crossmint_pay is declared with approval: always(), the prompt shows the amount, currency and merchant the model put in the call, and after approval the server compares those with the live Crossmint request and with the cap the run was created under before paying. Payments need an authenticated sender, and only the requesting principal can approve. Operator policy is checked before a run is created, so a refused request is never billed: an optional per-checkout ceiling (CROSSMINT_MAX_COST) and an optional merchant allowlist (CROSSMINT_ALLOWED_MERCHANTS). A saved buyer profile (CROSSMINT_BUYER_PROFILE_ID) lets checkouts skip shipping and contact questions. The API key, buyer id, buyer profile and order intent id stay on the server. Each snapshot is projected to a metadata allowlist before Eve can persist it, and a conversation can only act on runs it started in this process. Link, the browser runtime and the hooks are unchanged; with the Crossmint variables unset both tools return not_configured.
One tool starts a checkout at any store with a product URL, a sentence and a spending cap, then answers the forms. A second tool pays after the person approves the exact total in Eve, and the server checks that total, the currency, the merchant and the cap against Crossmint's live request before paying. The card number never reaches Bell or the model. Nothing changes unless the Crossmint variables are set.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Agent Checkouts could not pay on its own: the order intent it needs takes a client key with the user's JWT, and only the card branch could sign one. Move the operator token, the JWKS route, the operator-only proxy, and the Crossmint React SDK here, and add /crossmint/setup, an operator page in Crossmint's styling. It checks the connection live and shows the JWKS endpoint and issuer to paste when Crossmint rejects Bell's token, saves delivery details as a buyer profile, lists budgets with what is left and their card rails, cancels them, and approves new ones in Crossmint's card form after an explicit confirmation, with one idempotency key per draft. It registers the card with the operator's email before creating the order intent, because Crossmint refuses an empty registration and its card component sends one. A card without a Visa or Mastercard agent rail still pays through Crossmint's encrypted card, and the page says so. The proxy forbids framing, and every action checks the operator's credentials and origin again. While a run works, crossmint_checkout returns at each new stage, a fixed phrase chosen from Crossmint's activity kinds, so Bell tells the person what is happening instead of showing "Working" for minutes. Crossmint's own progress text is never passed on, since it can name the buyer and is written while reading merchant pages. Progress reads stay within the wait and stop on cancel. The approval names the payee in plain words, "Pay 16.90 EUR at Zara (payments.zara.com) with your saved card?", and the server cross-check now also refuses a store name that is not Crossmint's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add crossmint_card_checkout on top of the Agent Checkouts setup. At the merchant's payment step the model maps the card inputs with exact CSS selectors and Eve asks the person to approve the amount at the merchant's host. The server reads the operator's order intent and refuses unless it is active, scoped to this merchant, in this currency, with enough left, unexpired, and backed by an active Visa Intelligent Commerce or Mastercard Agent Pay rail. It mints a one-time card only while the browser privacy lock is held, with an idempotency key per tool call, and fills it through the hosted-page path link__checkout uses. The card never leaves the fill, the browser is quarantined after payment entry, and any failure after a mint answers a fixed "do not retry" so no second card is issued. Paying in Bell's own browser is opt-in with CROSSMINT_CARD_CHECKOUT=1. Until then the tool answers not_configured, and the setup keys alone only approve budgets for Agent Checkouts, so they never add a second way to pay or the database requirement for every browser tool. The card module builds on the shared operator config and request helper. With the card path on, the setup page offers Verify card for a budget whose Visa or Mastercard rail is pending, through Crossmint's verification component, and points to it after approving a budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aadopii
force-pushed
the
feat/crossmint-agent-cards
branch
from
November 2, 2026 14:08
1b43c0b to
a9305bc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #34, which now carries the setup page, the operator token and the Crossmint client. Review the last commit.
#34 hands the whole checkout to Crossmint. This PR keeps the checkout in Bell's own browser and pays with a Crossmint agent card. The model drives the merchant page with Bell's existing tools, maps the payment fields with exact CSS selectors, and calls
crossmint_card_checkout. The tool mints a one-time card from the budget the user approved on the setup page and fills it server-side through the same hosted-page pathlink__checkoutuses. Nothing underserver/linkchanges.server/browser/privacy-lock.tsgains one condition so the browser quarantine also engages for this path.The card is the user's own, enrolled in Visa Intelligent Commerce or Mastercard Agent Pay: Mastercard cards from any country, and U.S.-issued Visa cards. Rewards, statement lines and disputes work as for any purchase.
Opt-in
It is off until
CROSSMINT_CARD_CHECKOUT=1, and needsLINK_SANDBOX=0andDATABASE_URLfor the privacy guard. The setup keys alone only approve budgets for Agent Checkouts, so setting them up never adds a second way to pay or the database requirement. With the card path on, the setup page offers Verify card for a budget whose network rail is pending.Guards
Payment runs through Eve's approval gate. The person reads "Pay 12.49 EUR at shop.example with your Crossmint agent card?", and only the authenticated sender who asked can approve. Before minting, the server reads the order intent and refuses unless it is active, the rail is active, the balance covers the amount, it names this merchant, and it has not expired. It mints only while the browser lock is held, with an idempotency key, so a retry never issues a second card. Any failure after a mint answers a fixed "do not retry".
The credential is read inside the fill and never returned. After payment entry the browser is quarantined from further model access, as with Link.
Tests
419 pass on Node 24 with typecheck, lint and the build. The card tests are mock-only: one case per refusal reason, the mint request and its idempotency key, the two 409 codes an operator must act on, the opt-in, the refusal without the browser lock, and that no credential value reaches output. The staging smoke steps are in
docs/crossmint.mdand have not been run.🤖 Generated with Claude Code