Skip to main content
Kernel runs Chromium browsers in the cloud for agents. This guide shows how a Kernel browser pays at a merchant’s checkout with a Natural browser token: the agent types a stand-in card, and Natural’s proxy swaps in the real card on the way to the payment processor. The real card number never reaches your agent, your servers or Kernel. You need:
  • A Natural agent key with wallets.read, payments.read, payments.create and saved_cards.use
  • A Kernel API key in KERNEL_API_KEY. Custom proxies come with Kernel’s Start-Up and Enterprise plans.
  • @onkernel/sdk and playwright (npm install @onkernel/sdk playwright)

How it fits together

  1. Shop. The agent browses in a Kernel browser and gets to the merchant’s payment step.
  2. Open a session. Your backend calls POST /card-sessions with the purchase and the processor host that receives the card, then sends the user the approvalUrl.
  3. Claim. Once the user approves, POST /card-sessions/{sessionId}/claim returns a stand-in card and a proxy login.
  4. Swap the proxy. Create a Kernel custom proxy from the claim, with Natural’s proxy certificate, and switch the running browser onto it.
  5. Pay. The agent fills in the stand-in card and submits.
The agent stays in the same browser the whole time, so the cart and checkout state are kept.

1. Shop

Find the processor host

allowedHosts must name the host the checkout sends the card to, not the merchant’s website. Wildcards aren’t accepted. To find it, watch the checkout’s requests:
Common hosts include api.stripe.com, payments.braintree-api.com and pci-connect.squareup.com. If the payment form encrypts the card in the browser, the proxy can’t swap it in: see when the proxy can’t reach the checkout.

2. Open a session and wait for approval

The user has to approve, and you have to claim, before the session’s claimExpiresAt: 10 minutes after you open it. Open the session when the agent is at the payment step, not earlier.

3. Claim and create a Kernel proxy

Create a Kernel custom proxy from the claim. Pass the certificate at caBundleUrl as ca_bundle so the browser’s traffic trusts Natural’s proxy.
Create a new Kernel proxy for every claim. The host and login differ between claims, and a Kernel proxy’s settings can’t be edited after it’s created. Kernel checks the connection when you create a proxy, so a wrong or expired login shows up here, before anything touches the browser. If you lose the claim response, retry the claim with the same Idempotency-Key for a fresh login: see retrying a claim.

4. Swap the proxy

The swap takes under a second. Your CDP connection, open pages and their state stay as they are, but requests in flight during the swap may fail, so swap while the payment page is idle, before the agent fills in the card. While the proxy is attached, all of the browser’s traffic goes through it. Kernel applies ca_bundle in its own network layer, so there’s nothing to install in Chrome. Make sure you pass it: without it, HTTPS requests fail once the browser is on the proxy.

5. Check the route, then pay

Load every allowed host first. If the connection through the proxy doesn’t work, for example because the login expired, Kernel returns a 5xx status with an X-Forwarder-Error or X-Kernel-Proxy-Error header. A 4xx from the host itself is fine: api.stripe.com/ answers 404. Wrap the check and the payment in try/finally so the browser leaves the proxy, and the proxy is deleted, even when either one fails:
If routing fails, stop. Never send the stand-in card around the proxy, and before retrying, check that the earlier attempt didn’t go through. Treat the claim as a secret: don’t log or store any of it, including the cardholder name and billing address.

6. Clean up

The finally block switches the browser back to Kernel’s default egress and deletes the proxy. The proxy login stops working at the claim’s expiresAt either way, 10 minutes after the claim by default. Set ttlSeconds on the session, up to 900, if checkout needs longer.

When the proxy can’t reach the checkout

Some checkouts encrypt the card in the browser or inside the processor’s own iframe, so the stand-in number never appears in a request the proxy can see. For those, open the session with requestAgentToken: true. When the user approves, they can also set up agent payments on the card, and the session returns a mandateId. Then pay with an agent token: it’s a tokenized card the agent types in directly, with no proxy and no swap.

Customers’ cards

To pay with a Connect customer’s saved card, pass customerPartyId in data.attributes when you open the session, and as a query parameter when you get or claim it. See pay with a customer’s saved card.

What each party sees

Your Natural agent key stays in your backend. Kernel only ever holds a proxy login for one purchase.