Before you start
- have an existing browser agent. this guide adds payment handling, not navigation or reasoning.
- choose a wallet integration from the wallet overview, then follow its tab below. for shop pay, follow the shop pay guide, which uses the same controller pattern.
- install a KERNEL sdk with the
vaultsresource. setKERNEL_API_KEYandKERNEL_PROJECT_IDin your controller. - use a low-value checkout you control. paying with the user’s own card is live-only, and
fillwrites only on the origin of the purchase’smerchant_url, so you need the top-level checkout page’s url and verified field selectors for the card inputs. link is live-only and requires an https merchant origin. on stripe checkouts that support link pay tokens, KERNEL fills the payment without field selectors; elsewhere you need verified field selectors for the virtual card. agentcard requires a native processor adapter; the processor doesn’t need to be stripe. - for agentcard, set
AGENTCARD_MODEin your controller and verify it against the credential’s mode. customer-owned configs exposetest_mode(truemeans sandbox); for KERNEL-managed credentials, confirm the deployment’s mode. stop if the mode is unknown or mismatched. - identify how you’ll read the merchant’s trusted order record. you need it to confirm a matching paid order. deterministic checkout data can verify purchase details before submission, but without the order record afterward, the result remains indeterminate.
Roles and resources
- controller: your trusted application code. it calls KERNEL, verifies purchases, authorizes field bindings, presents user actions, and observes payment state.
- agent: your browser automation. it proposes purchase details and selectors, then completes the approved checkout.
- user: the person who connects a payment method, confirms the purchase, and completes provider approval.
Shared safety rules
One-time setup
1. Create a vault
scope the client and vault to the project that will own the browser session. these clients disable automatic sdk retries.vaults.upsert creates the vault or retrieves one with the same name. vault names
are immutable within the project.
2. Connect a wallet
allow at most one wallet item per provider in a vault. list the vault’s items and group wallets byspec.provider before rendering your payment settings:
recheck in your controller immediately before creating a wallet. the api makes
item keys unique, not providers, so a different key can create a duplicate wallet.
deleting a wallet invalidates its dependent card items; use an explicit
remove-and-replace flow instead of adding a second wallet.
- let the user select a provider that doesn’t already have a wallet in the vault.
- create the wallet item through your controller, following the pay with card setup, link setup, or agentcard setup.
- present the returned action using the authenticated flow below. the user connects or enrolls their real payment method with the provider.
- wait for the wallet’s status to become
connectedbefore preparing a purchase.
Present hosted actions in your application
provider action urls are bearer-like handoffs to enrollment or approval. route them through your controller:- your controller retrieves the item and keeps the raw action url out of logs, analytics, and model context.
- store the action server-side under an opaque id bound to the authenticated user, vault id, item key, and action name.
- 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.
- send the redirect with
Cache-Control: no-storeandReferrer-Policy: no-referrer. - apply a short application ttl capped by
item.expires_atorstate.authorization.expires_atwhen present. invalidate the record immediately when the action changes, disappears, or reaches a terminal state.
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
1. Attach the vault to a browser
vault attachments are fixed at browser creation. use the same project-scoped client that created the vault.browser_live_view_url lets the user watch the checkout during confirmation
and agentcard approval pauses. presentLiveView represents your authenticated
user-facing page: keep the url server-side with the 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.
navigate to checkout in this session before verifying the purchase. use the same
session to inspect and submit it; the vault attachment includes items created later.
2. Verify and confirm the purchase
- let the agent propose the merchant, amount, currency, and item or cart contents. treat every proposed value as untrusted.
- 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.
- normalize the values in your controller 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.
- stop when any value is missing, cannot be verified, or disagrees. do not create or update a card item and do not invoke authorization.
- show the independently verified values to the user and wait for explicit confirmation.
- 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.
3. Collect other checkout fields
collect required email, billing, shipping, phone, and other customer fields from the user or their previously approved backend data. pass them separately from payment input; don’t ask the agent to invent missing values. answer any agent disclosure truthfully in the merchant’s form and verify the control is selected before submission. if a required field or disclosure can’t be completed and verified, stop. see checkout-specific notes for stripe’s disclosure controls.4. Prepare payment input and submit once
follow the tab for your provider. each path uses the frozen purchase object from step 2, a connected wallet in the same vault, and this browser session.- User's own card
- Link by Stripe
- Agentcard
Create and authorize the purchase
a purchase using the user’s own card is approved before checkout, soauthorize takes no
browser or page parameters. authorize once the agent reaches the final checkout
page: the one-time security code expires shortly after it’s issued.- create a
carditem namednotebook-orderfrom the verified purchase. setmerchant_urlto the top-level checkout page’s url.fillwrites only on that url’s exact origin, so a checkout hosted on another domain needs that domain’s url. visa cards also requiremerchant_country.carditems withprovider: "kernel"can’t be updated; to change the purchase, delete the item and create a new one. - require
authorizeinavailable_operationsand invoke it, then present any returnedspend_approvalaction through your controller. visa cards use it for the cardholder’s approval, and cards without network tokens use it to collect a fresh security code. supported mastercard cards return no action. - wait for the card to become
ready. awaitread holds for at most 60 seconds, so keep retrieving while it’spending_authorization; the cardholder has up to 30 minutes to use the approval link.
--open only in your controller or a human-operated terminal, and
keep its output outside the agent. repeat the get while state.status is
pending_authorization.declined means the card network refused to issue a code. stop; KERNEL never
approves the purchase again on its own, so the cardholder must approve a new
purchase. for recovery_required, stop and follow
verify the outcome.Fill the card
for eligible cards,fill writes a network token number, its expiry, and a
one-time security code. checkoutURL / checkout_url is the browser’s exact
current top-level https url, including query and fragment, on the origin of
merchant_url. a page on another origin returns 403 with destination_denied
before any writes. payment inputs inside processor iframes are supported.cards collected through KERNEL have no stored billing details. requesting a billing_* field
returns field_unavailable before any writes, so enter billing details from
the user’s approved data instead.exp_month (MM) and exp_year
(YYYY) instead of expiration. request only fields that are currently
visible. if a completed fill reveals another field, make a separate fill with
only the new field.handle the per-field outcomes as in the fill outcome contract:
fill never submits, so a retry is safe. retry only after checking the page,
and never in an automatic loop.only continue on completed. complete the remaining customer fields and
disclosures, then submit once, promptly: the one-time security code expires.
verify the outcome against the merchant’s order record.Report the merchant outcome
after the merchant’s order record shows a definitive outcome, report it once withconfirm_transaction when the card advertises it. report the amount the
merchant charged, in minor units, its currency as an uppercase code such as
USD, and the time you observed the outcome. don’t report an outcome you
couldn’t verify, and don’t repeat a report whose response was lost. waitForMerchantResolution represents your order backend.Verify the outcome
use the merchant’s trusted order record to confirm a paid order whose merchant, amount, currency, and items match the frozen purchase. item state, events, and the checkout page provide supporting evidence, not proof by themselves. if the record is unavailable or the sources disagree, keep the result indeterminate and don’t retry.
retain the vault id, card key, browser id, and last event id until reconciliation
is complete. delete the browser after outcome inspection or your reconciliation
deadline; this doesn’t undo provider execution or cancel an order. keep or delete
the vault and provider items based on future use, except when
recovery_required
prohibits deletion.
Checkout-specific notes
Stripe payment links and adaptive pricing
Stripe payment links and adaptive pricing
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.Stripe agent disclosure controls
Stripe agent disclosure controls
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.Stripe's save with link option
Stripe's save with link option
stripe checkouts can pre-check “save my information with link for faster
checkout”. while it’s checked, stripe also requires a phone number and won’t
submit the payment without one. unless the user asked to save their details to link, uncheck it before submitting and read
the input’s
checked property to confirm. these are stripe page details rather
than a KERNEL contract.Missing or unconnected wallets
Missing or unconnected wallets
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.Try with a coding agent
connect the provider wallet first through your controller or a human-operated terminal. these prompts require exactly one connected wallet for the chosen provider inuser-12345 and a coding agent with access to the KERNEL cli.
complete the prerequisites, including verifying the payment
mode and identifying your merchant order record. replace the checkout url with
a low-value checkout you control.
the coding agent must stop whenever a provider action is required: cli output
can contain the action url. keep enrollment, authorization actions, and approval
observation outside that agent. the prompts repeat the safety requirements so
they remain self-contained when copied.