Skip to main content
you’re building a browser agent. you can add payments without bringing your application, agent, or browser into pci dss scope. create a KERNEL vault and add a wallet backed by stripe link or agentcard. the provider-hosted flow collects and stores the user’s payment method, so neither you nor your agent handles the card number or cvc. attach the vault when you create a browser session, give the agent the returned aliases, and let it complete a web checkout. KERNEL handles authorization and payment handoff at egress. stripe link and agentcard are credential providers, not merchant payment processors. at the browser form layer, both work with any web checkout that accepts standard card details, and the merchant’s processor does not need to be stripe. end-to-end handoff also requires the outgoing request to match one of the native processor adapters. you can use either stripe link or agentcard. choose based on how the payment credential is created and when the user approves it: agentcard is backed by a card the user enrolls, but the agent and browser still enter aliases rather than the underlying card details. those details remain outside the browser and are handled during provider handoff at egress. to run either path with a coding agent that has access to the KERNEL cli, use one of these prompts. connect the provider wallet first through your trusted application or a terminal outside the coding agent. the agent must stop whenever a provider action is required because cli output can contain the action url.
this guide starts after you have an existing browser agent. it changes how you prepare and pass payment input, not how your agent navigates or reasons about the checkout page.

Before you start

  • install a KERNEL sdk version that includes the vaults resource.
  • set KERNEL_API_KEY and KERNEL_PROJECT_ID in the trusted controller that creates your browser.
  • use a low-value web checkout you control whose outgoing payment request matches a native processor adapter. the merchant processor doesn’t need to be stripe.
  • stripe link card creation is live-only. agentcard mode comes from the integration’s configured credential.
  • for agentcard, keep an application-owned AGENTCARD_MODE deployment setting and fail closed unless it explicitly matches the sandbox or live environment you intend to use. the vault api does not return this mode.
keep wallet collection and payment approval outside the agent. show hosted action urls only in a trusted user-facing surface. the only payment values you give the agent are the aliases returned in card state.

1. Create a vault

scope the client and vault to the same project that will own the browser session.
vaults.upsert creates the vault or retrieves an existing vault with the same name. vault names are immutable within the project.

2. Connect the end user’s payment method and prepare a card item

wallet and card are KERNEL api resources, not the underlying wallet or card. your end user initiates setup and purchases through your product. your application then makes the authenticated api calls on their behalf. a card item represents the payment authorization and aliases for a purchase; creating one does not add or expose the end user’s real card. the end user creates the purchase intent. your application translates that confirmed intent into a KERNEL card item without exposing its api key to the user or agent.

Once per end user and provider

your payment settings ui must allow at most one wallet item for each provider in a vault. list the vault’s items before rendering provider controls, group wallet items by spec.provider, and apply this flow: if both stripe link and agentcard wallets exist, hide both provider add options. recheck this condition in your trusted controller immediately before wallet creation so a stale ui cannot submit a second wallet. the api currently makes item keys unique, not wallet providers. using a different key can create another wallet for the same provider, so your product must enforce the one-per-provider rule. deleting a wallet invalidates its dependent card items; require an explicit replacement flow rather than creating a second wallet beside it.
  1. your end user chooses a provider that does not already have a wallet in the vault.
  2. your application creates or retrieves a vault for that end user, checks its items again, then creates a wallet item only when that provider is absent.
  3. your application presents the returned action in a trusted user-facing surface outside the agent-controlled browser.
  4. your end user completes the provider-hosted connection or enrollment flow.
  5. your application waits until the wallet item’s status is connected.
this is the point where your end user adds or connects their real payment method. the end user does not create the KERNEL wallet item directly.

Present hosted actions in your application

provider action urls are bearer-like handoffs to enrollment or approval. route them through your trusted application:
  1. your backend retrieves the item and keeps the raw action url out of logs, analytics, and model context.
  2. store the action server-side under an opaque id bound to the authenticated end user, vault id, item key, and action name.
  3. render a link to your own authenticated action endpoint. before redirecting, verify the session owns that binding and the item still returns the same action.
  4. send the redirect with Cache-Control: no-store and Referrer-Policy: no-referrer.
  5. apply a short application ttl capped by item.expires_at or state.authorization.expires_at when present. invalidate the record immediately when the action changes, disappears, or reaches a terminal state.
the presentProviderAction functions later in this guide represent this application-owned flow. the checkout agent and its browser must never receive the raw provider url.

For each purchase

purchase verification is a required, fail-closed gate before creating or updating a card item:
  1. let the browser agent propose the merchant, amount, currency, and item or cart contents. treat every proposed value as untrusted.
  2. independently obtain the expected values from a trusted source. prefer your order or cart backend. when no backend exists, use deterministic page extraction with fixed selectors or structured page data, not another model response.
  3. normalize the values in trusted code and compare the proposal with the trusted result. compare the amount in minor currency units and require the merchant, currency, and item or cart contents to match.
  4. stop when any value is missing, cannot be verified, or disagrees. do not create or update a card item and do not invoke authorization.
  5. show the independently verified values to the end user and wait for explicit confirmation.
  6. freeze that verified, confirmed purchase object. derive the card specification and any authorization request from that same object. do not accept replacement values from the agent after confirmation.
  7. for stripe link, list the connected wallet’s payment methods and let the end user select one. for agentcard, pin an enrolled card or let the end user choose during approval.
  8. ask KERNEL to prepare a card item on the end user’s behalf. stripe link requires a new one-use item. agentcard can reuse a ready item and update its specification when the api permits. the item refers to the connected wallet; it is not the end user’s real card.
  9. for stripe link, invoke the advertised authorize operation using the same verified purchase object, then present any returned approval action to the end user. agentcard begins authorization after the browser submits checkout.
  10. wait for the card item to become ready, then pass only its aliases to the browser agent.
never create or authorize a card from values supplied only by the browser agent. end-user confirmation does not make an unverified proposal trustworthy. the independently verified purchase object must be the single source for the card specification, approval display, and authorization.
purchase verification doesn’t depend on the merchant processor. prefer the merchant’s trusted order or cart backend. if one isn’t available, use documented structured checkout data or deterministic extraction for that checkout, and fail closed when the values can’t be independently verified. for a stripe payment link without an order or cart backend, use the payment-link response as the deterministic source. the current response exposes account_settings.display_name, line_item_group.total, line_item_group.currency, and line_item_group.line_items. use dom text and data-testid attributes only as supplemental checks. stripe can render multiple responsive copies of a summary or omit product-level test ids in another layout, so don’t require a specific test id or number of matching elements. these are stripe page details rather than a KERNEL contract. if the structured response is missing or its values disagree with the rendered checkout, fail verification instead of falling back to model inference. stripe adaptive pricing can change the checkout’s displayed amount and currency for the browser’s location. create the card item from the active presentment amount and currency shown to the user and submitted by that checkout, not the payment link’s base integration amount and currency. include those active values in the verified purchase object and the confirmation screen. when the checkout response is your deterministic source, create the attached browser in step 3 before you create or update the card item, then inspect and submit with that same browser session. the vault attachment covers items created later in that vault.
don’t start checkout until the wallet is connected and the card item is ready. without a wallet item, card creation fails because spec.wallet must reference a wallet from the same vault and provider. with an unconnected link wallet, card creation returns a conflict. with an unconnected agentcard wallet, a card without card_id can remain requested, while a pinned card_id cannot be validated. neither path is ready for checkout.
we’re adding credential-provider integrations and merchant-processor adapters and will update this guide as coverage expands. we plan to build additional card-collection and vault-management surfaces so developers can connect the credential providers and third-party vaults they already use. over time, we want KERNEL to support more of the browser-side steps required to complete a payment without exposing the underlying credential to the agent or browser.
both credential-provider flows leave you with a card item whose state.status is ready and whose state.aliases contains number, cvc, exp_month, and exp_year.

Collect non-card checkout fields

payment aliases cover only the card number, cvc, and expiry. merchant checkouts can also require email, billing name, postal code, shipping address, phone number, or other customer data. collect the required values from the end user in your trusted application, or load values the end user has already approved from your backend. pass them to the browser agent separately from the card aliases. do not ask the agent to invent missing customer data. merchant-specific agent disclosures are normal checkout fields. if the page asks whether automation is acting for another person, instruct the agent to answer truthfully in the merchant’s form before submission. for a checkout that offers I am an AI agent acting on behalf of someone else, select that option. stripe can render hidden or duplicate copies of its disclosure control for responsive layouts. target the visible label. if the label doesn’t toggle the control, locate the associated real input[type="checkbox"] and invoke its native dom click(). read that same input’s checked property and require it to be true before submission. if you can’t verify the checked state, stop without submitting. don’t bypass the disclosure or replace the page’s normal submission with a raw processor request. after triggering submission once, never retry it, including after a timeout, unchanged page, or indeterminate result. retrieve the item immediately before creating the browser. don’t cache aliases after an item expires, changes state, or is deleted.

3. Attach the vault to the browser

vault attachments are fixed at browser creation. use the same project-scoped client that created the vault.
browser_live_view_url lets the end user watch the checkout during confirmation and agentcard approval pauses. presentLiveView represents your authenticated application page: keep the url server-side with the end user and browser session binding, render or embed it only after checking that session, and remove it when you delete or time out the browser. don’t log the url or put it in model context. see live view for iframe and csp requirements. connect your existing agent to browser.cdp_ws_url. see Controlling a Browser for supported connection options.

4. Give the aliases to your agent

pass the aliases as structured task input. instruct the agent to use them in the page’s normal card fields and submit checkout once.
replace the angle-bracketed fields in your controller before sending the task. don’t put oauth codes, action urls, provider responses, the vault api key, or the browser connection url in the prompt. the agent can fill both top-level fields and payment fields embedded in iframes. let the merchant page’s own submission code create the outgoing request. don’t replace the checkout with a raw processor api call.

5. Keep approval and observation outside the agent

start observing the card item before the agent submits checkout and keep the observer running until the merchant reaches a terminal order state. this is required for agentcard, where the outgoing checkout request is held while the user approves it. the same observer works for stripe link and provides item events after credential substitution. the example uses presentProviderAction, an application-owned function. it must publish the action only to an authenticated session for the end user who owns the vault. bind the action to that user, vault, and item; expire it no later than the item or authorization expiry; and stop serving it as soon as the action changes or disappears. don’t put the url in application logs, analytics, model context, or the agent-controlled browser.
start the observer before checkout and cancel it only after the checkout controller reaches a terminal merchant state or its reconciliation deadline. the following application-owned functions stand in for your existing agent and order backend:
if the merchant has not reached a terminal state by your controller’s deadline, classify the attempt as indeterminate, stop the observer, retain the attempt identifiers, and do not submit checkout again. the observer presents user actions and reads events; it does not submit checkout or repeat authorization. each cli --wait performs one bounded observation, so rerun the commands to continue observing the existing attempt. CLI commands prepare and observe the payment state; they don’t submit merchant payments or retry them. run --open only from the trusted controller or a human-operated terminal, and never send its output to the browser agent. events returns an ordered array. an empty array means no new observation arrived during the wait. it does not mean payment failed. correlate event.browser_id with the browser you created when a vault is attached to more than one session.

6. Verify the outcome

use item state, item events, the checkout page, and the merchant’s order record together. use the merchant order record as the authority for whether the expected order was created and paid. require its merchant, amount, currency, and items to match the frozen purchase object. use authorization state and item events to explain the provider and handoff path, and use the checkout page as supporting evidence. only report success when the trusted merchant record confirms the matching order. a ready agentcard item, an approved authorization, a delivered replay, or a success page cannot establish that by itself. merchant success text is page-specific: a completed stripe checkout might say Thanks for your payment, but don’t use that string or any other generic text matcher as the success condition. when the sources disagree or the merchant record is unavailable, keep the result indeterminate and do not retry.
a timeout, browser deletion, missing event, or closed checkout does not undo provider execution or cancel a merchant order. don’t retry automatically. retain the vault id, card key, browser id, and last event id until you have reconciled the attempt.
delete the browser when the task and outcome inspection are complete. keep or delete the vault and provider items according to whether the user needs them for a future task.