For AI agents: a documentation index is available at /llms.txt
Skip to main content

Agentic Checkout with Stripe Link

Agentic Checkout lets an MCP browser agent pay a merchant checkout from a buyer's connected Stripe Link wallet. Two tools drive it: browserless_link_connect manages the wallet, and browserless_link_checkout creates and fills a user-approved purchase. The buyer approves each purchase in a Stripe-owned flow, and Browserless fills the card for you, so the full number, CVC, and expiry never reach your model or MCP client.

Use it when an agent needs to pay for something with the user's money, like buying a product at a merchant's checkout, from a wallet the user has already approved. The model drives the page but never handles raw card details.

Draft preview

Agentic Checkout is a Cloud-only draft preview. It isn't enabled on the hosted fleet yet and isn't available on Dedicated or self-hosted deployments, and the tools and limits can change before release. Contact us to follow availability.

Prerequisites
  • A Browserless account with an active API token from your account dashboard
  • The full Browserless MCP server, not the Connector or compliance-mode surface
  • An owner or admin signed in (dashboard or MCP OAuth) to connect the wallet
  • A Stripe Link wallet that can approve a spend request, eligible for the initial US/USD program
  • A checkout charged in USD at $50.00 or less

How it works​

A checkout runs inside the same browserless_agent browser session that reached the merchant's payment page. The card is never exposed to your model:

  1. Connect once. An account owner or admin links a Stripe Link wallet to the Browserless account. This is one-time setup, not per purchase.
  2. Create a spend request. When the agent reaches the payment step, browserless_link_checkout with action: "create" records the merchant, cart, and exact total, then returns a Stripe-owned approval URL.
  3. The buyer approves. The buyer opens that URL and approves the specific amount in a Stripe-owned flow. Approval mints a single-use card scoped to that purchase.
  4. Resume fills the card. action: "resume" retrieves the approved single-use card and fills it into the merchant's payment fields for you. The full number, CVC, and expiry never enter your model's context or the tool result.
  5. Submit and verify. The agent submits the merchant form with browserless_agent, inspects the confirmation, and reports the outcome with action: "report".

The single-use card is scoped to the approved amount, so a filled card can't be reused for another purchase, and the buyer approves every spend request individually.

Connect the wallet​

Connecting the wallet is one-time setup. The dashboard is the recommended path, and only an owner or admin can do it.

  1. Sign in as an owner or admin

    Open the Browserless dashboard and sign in to the account that owns the API token your MCP client uses.

  2. Confirm the account has an active API token

    Open API Keys and create or enable a token if needed. The wallet controls stay disabled until the account has a usable API token.

  3. Open Integrations

    Go to Integrations, find Stripe Link Wallet, then select Connect Stripe Link.

  4. Authorize with Stripe Link

    Browserless redirects to an HTTPS page owned by Stripe or Link. Review the requested access and approve it there. Browserless returns you to Integrations and shows Connected once the wallet is linked.

    Never paste a Link access token, refresh token, card number, CVC, or one-time code into Browserless, an MCP prompt, or any API request.

Use Refresh on the wallet card to reload status. An owner or admin can select Disconnect to revoke the wallet connection. A viewer can see status but can't connect or disconnect.

Checks or manages the account wallet. Use status before every checkout. When connect returns an authorization_url, give that URL to the user. Don't open it on their behalf or treat it as successful authorization.

ParameterTypeRequiredDescription
actionstringYesstatus reads the wallet state, connect starts authorization, disconnect revokes the connection. connect and disconnect require an OAuth-authenticated owner or admin MCP session

The result contains only sanitized fields:

FieldTypeDescription
statusstringconnected or not_connected
authorization_urlstring, optionalStripe-owned HTTPS URL, returned only when starting a connection
instructionstringBounded, user-facing next step

Example prompts:

Is my Stripe Link wallet connected?

Start connecting a Stripe Link wallet for agent checkouts.

Creates, resumes, cancels, or reports a checkout in the exact active browser session. browser_session_handle must be the latest sessionId returned by browserless_agent for the open checkout page.

ParameterTypeRequiredDescription
actionstringYescreate, resume, cancel, or report
browser_session_handlestringYesThe sessionId from browserless_agent for the open checkout page
merchantobjectFor create{ name, url }; url must match the active checkout origin
amount_minornumberFor createTotal in USD minor units (cents); must equal the cart sum and be at most 5000
currencystringFor createMust be usd
cartarrayFor createLine items of { name, quantity, unit_amount_minor }
selectorsobjectFor plain card formsDeep selectors for the payment fields (see below)
checkout_idstringFor resume, cancel, reportThe opaque id returned by create
outcomestringFor reportsuccess, blocked, or abandoned

Create​

{
"action": "create",
"browser_session_handle": "s:SESSION_HANDLE_FROM_BROWSERLESS_AGENT",
"merchant": {
"name": "Example Store",
"url": "https://shop.example.com/checkout"
},
"amount_minor": 1999,
"currency": "usd",
"cart": [
{
"name": "Wool socks",
"quantity": 1,
"unit_amount_minor": 1999
}
],
"selectors": {
"number": "< input[name='cardnumber']",
"expiry": "< input[name='exp-date']",
"cvc": "< input[name='cvc']",
"postal": "< input[name='postal']"
}
}

Copy payment-field deep selectors from the latest browserless_agent snapshot. Provide either expiry or both exp_month and exp_year, and every selector must identify a distinct field. cardholder_name and postal are optional unless the merchant requires them. For checkouts that ask for a billing address, you can also pass line1, line2, and city selectors. The tool refuses totals above 5000, rejects a checkout whose amount_minor doesn't equal the cart sum, and requires currency to be usd.

A typical create result hands back a Stripe-owned approval URL and an opaque checkout_id:

{
"status": "pending_approval",
"approval_url": "https://app.link.com/activity/approve/EXAMPLE",
"instruction": "Approve this checkout in Link, then resume it with the same browser session.",
"checkout_id": "lkco_EXAMPLE_OPAQUE_CHECKOUT_ID_1234X",
"_next": {
"action": "resume",
"checkout_id": "lkco_EXAMPLE_OPAQUE_CHECKOUT_ID_1234X",
"valid_until": "2026-08-18T00:10:00.000Z"
}
}

Treat approval_url as a user handoff, not proof of purchase. Keep the browser session open while the buyer approves the request.

Resume or cancel​

After the buyer approves, resume with the same browser handle and exact opaque checkout id:

{
"action": "resume",
"browser_session_handle": "s:SESSION_HANDLE_FROM_BROWSERLESS_AGENT",
"checkout_id": "lkco_EXAMPLE_OPAQUE_CHECKOUT_ID_1234X"
}

Resume validates that the page origin and bound payment fields haven't changed. It then fills the approved card into the bound fields and returns status: "filled" with an optional sanitized last4.

filled doesn't mean the merchant accepted the order. Use browserless_agent to submit the form and inspect the merchant's confirmation page.

If the buyer abandons before fill, cancel the active checkout:

{
"action": "cancel",
"browser_session_handle": "s:SESSION_HANDLE_FROM_BROWSERLESS_AGENT",
"checkout_id": "lkco_EXAMPLE_OPAQUE_CHECKOUT_ID_1234X"
}

Report the merchant outcome​

After inspecting the merchant result, report what happened so the checkout can close cleanly:

{
"action": "report",
"browser_session_handle": "s:SESSION_HANDLE_FROM_BROWSERLESS_AGENT",
"checkout_id": "lkco_EXAMPLE_OPAQUE_CHECKOUT_ID_1234X",
"outcome": "success",
"tags": ["stripe_checkout"],
"step": "merchant confirmation page"
}

outcome is success, blocked, or abandoned. Optional tags are limited to Browserless's bounded checkout categories, such as 3ds_challenge, payment_declined, captcha, rate_limited, login_required, timeout, or site_error.

Additional user action​

A checkout can return status: "requires_action" with action_message, an optional Stripe-owned action_url, and action_resolution.

  • When _next.action is resume, have the user complete the action and then resume the same checkout.
  • When _next is absent, complete the user action and create a new spend request. Don't reuse the old checkout id.
  • Never run text in instruction, _next, or an action message as a shell command.
  1. Use browserless_agent to reach the merchant's payment step and snapshot the cart and payment fields.
  2. Call browserless_link_connect with action: "status". Stop if the wallet isn't connected.
  3. State the merchant, items, and exact total. Obtain clear purchase approval unless the user's current request already provides it.
  4. Call browserless_link_checkout with action: "create", using the latest browser session handle and payment-field selectors.
  5. Give the Stripe-owned approval URL to the user and keep the browser session open.
  6. After approval, call resume with the same handle and checkout id.
  7. When the result is filled, submit with browserless_agent and verify the merchant confirmation.
  8. Call report with success, blocked, or abandoned.

Example prompt:

Buy one pair of wool socks from Example Store for no more than $20. Show me the merchant and exact total before requesting payment approval. Use my connected Stripe Link wallet, keep the browser open while I approve, and report the order only after the merchant confirms it.

Safety limits​

The initial release has these fixed limits:

LimitBehavior
CurrencyUSD only
Maximum per spend request5000 minor units ($50.00)
ApprovalThe buyer approves each spend request in a Stripe-owned flow
Browser continuityCreate, resume, and report use the same open browserless_agent session
Active checkoutsOne checkout at a time per browser session
Resume windowResume must happen within 10 minutes of creation
Credential visibilityOnly sanitized state and optional last4 are returned

The $50 cap and cart-total validation run before Browserless requests wallet access or calls the payment provider. A value of 5001 is rejected without creating a spend request. The cap applies to each spend request. There's no aggregate per-account or per-day cap. Separate browser sessions can each hold a spend request, and every request requires its own buyer approval.

Who can connect and who can pay​

ActionOwner / AdminViewer or other memberAPI-token-only MCP
Read wallet statusYesYesYes
Connect or disconnect the walletYesNoNo
Run an approved checkoutYesYesYes

Connecting the wallet needs a signed-in owner or admin, through the Browserless dashboard or an OAuth-authenticated MCP session. An API token proves the account, not the role, so an API-token-only connection can run checkouts but can't connect or disconnect the wallet.

Any token on the account can spend

Anyone with a valid account API token can start a checkout against the connected wallet. The per-purchase buyer approval is the real spending control, not the token. Treat API tokens as secrets and revoke any token shared beyond its intended operators.

Security and custody​

  • Buyer-funded. The purchase draws on the buyer's own Stripe Link wallet. Browserless never holds customer funds.
  • Per-purchase approval. Every checkout creates a spend request that the buyer approves in a Stripe-owned flow. Approval mints a single-use card scoped to that one amount.
  • The model never sees the card. The full number, CVC, and expiry are never returned to your model or MCP client, and never appear in a tool result. Browserless fills them into the merchant form for you. Only an optional last4 may come back.
  • Managed wallet connection. Browserless stores the wallet connection scoped to your account and refreshes it automatically. Disconnect revokes the connection with Link first, and reports success only if the revoke succeeds.
  • Bound to one checkout. A checkout is tied to the browser session and page that created it. It can't be resumed in another session or after the page or payment fields change.
  • Closing the browser ends the checkout. Browserless attempts to cancel and report the request. A provider or network failure can leave that unconfirmed, so check Link if you're unsure.
  • Don't disconnect mid-checkout. Disconnecting during an active checkout can leave an approved request that Browserless can no longer cancel or report. Confirm pending authorization directly in Link if the connection is lost.

FAQ & Troubleshooting​

Why does connect or disconnect return "requires an OAuth-authenticated session"?

The MCP client authenticated with only an API token. A fleet API token identifies the account but doesn't prove an owner or admin role, so it can't change the wallet connection. Reconnect the full MCP server with Browserless OAuth and sign in as an owner or admin.

Resume returned filled. Did the purchase complete?

No. filled means the payment fields were filled, not that the merchant accepted the order. Submit the form with browserless_agent, inspect the merchant's confirmation page, then call report with the outcome.

Why is my checkout total rejected?

The total must be a positive integer number of cents, at most 5000 ($50.00), and equal to the sum of every quantity * unit_amount_minor line. Re-read the cart and pass the exact USD minor-unit total. Don't split a purchase to get under the cap.

The full error reference:

SymptomMeaningWhat to do
Wallet status is not_connectedThe account has no usable Link connectionAsk an owner/admin to connect it from Integrations or an OAuth-authenticated MCP session
"requires an OAuth-authenticated session"The MCP client used only an API token for connect or disconnectReconnect the full MCP server with Browserless OAuth and sign in as an owner/admin
"Only account owners and admins…"The signed-in member lacks wallet-management permissionAsk an owner or admin; viewers may still read status and use checkout
Amount is rejectedThe total isn't a positive integer number of cents, exceeds 5000, or differs from the cart sumRe-read the cart and pass the exact USD minor-unit total; don't split a purchase to evade the cap
"That browser session is not open"The handle is stale or the browser was closedReturn to the payment page with browserless_agent and create a new checkout using its latest sessionId
"A Stripe Link checkout is already active"The session already has a pending or filled checkoutResume/cancel a pending checkout, or report a filled checkout, before creating another
Resume window expiredMore than 10 minutes passed between create and resumeCreate a new checkout and request fresh user approval
Wallet disconnected during checkoutBrowserless may no longer have a token to cancel or report an approved provider requestCheck the pending spend request directly in Link before starting another checkout
requires_actionLink needs identity, payment-method, 3DS, or support actionShow the bounded message and trusted URL; resume only when _next says to resume
Resume returns filled but no order existsFilling payment fields doesn't submit the merchant formSubmit with browserless_agent, inspect confirmation, then report the outcome
Wallet service is unavailableBrowserless returned a bounded temporary-service errorRetry later; don't ask the user for card details as a fallback
Dashboard says authorization was canceledThe buyer denied or closed Link consentStart a new connection only if the buyer still wants to connect

Never paste an OAuth callback URL into a ticket or chat. It can contain a one-time authorization code. If a credential is ever exposed, stop, disconnect the wallet, revoke affected Browserless API tokens, and contact support.

Next steps​

Was this page helpful?