> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sapiom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Sapiom Pay is for platforms whose agent shops for many end users. Each end user is a buyer with their own Sapiom key and saved cards.
> Use the buyer's key for every call made on that buyer's behalf. Never use one buyer's key for another user, and never give the agent the platform key.
> Agents call the hosted MCP tools at https://api.sapiom.ai/v1/mcp. Backends call the REST API at https://api.sapiom.ai/v1. Both take the key in an x-api-key header.
> Never ask a buyer for a card number, expiry date or CVV in chat. Buyers enter card details only on Sapiom's hosted pages.
> Follow the nextAction in each transaction result. Action links are secrets for the intended buyer only.
> Use one idempotencyKey per transaction. After a timeout, retry with the same key. Never start a new transaction to escape an uncertain outcome.
> Report an order as placed only when order.outcome is confirmed. If it is unknown, stop and hand off to a person.

# Pay in the browser

> Attach the Browser Pay SDK to the browser that runs checkout, so the merchant receives the real card while your code only handles a placeholder.

Your browser worker is the code that runs the merchant's checkout in a browser session you control. When a transaction is ready, it fills checkout with a placeholder card. Our Browser Pay SDK relays it via Sapiom, which sends it on with the buyer's real card.

**You need:**

* A transaction whose `nextAction.type` is `payment_ready`. See [Authorize a transaction](https://docs.sapiom.ai/transactions/authorize.md).
* A Chromium browser your code controls, with a Chrome DevTools Protocol (CDP) WebSocket endpoint.
* The buyer's key.

## Install

```bash theme={null}
npm install @sapiom/browser-pay
```

## Get the placeholder card

List the buyer's placeholders and pick the one whose `transactionId` matches your transaction:

```bash theme={null}
curl https://api.sapiom.ai/v1/card-placeholders \
  -H "x-api-key: $SAPIOM_BUYER_KEY"
```

Each placeholder has a `number`, `expMonth`, `expYear`, `cvc` and `injectionRef`. Your code, not your AI model, should fill the card fields. Keep placeholders out of logs and out of the model's context.

## Attach Browser Pay, then fill the form

Attach before typing any card field, and wait for `attachInterceptor` to resolve:

```typescript theme={null}
import { attachInterceptor, httpPaymentRelay } from "@sapiom/browser-pay";

const handle = await attachInterceptor(cdpUrl, {
  relay: httpPaymentRelay({
    baseUrl: "https://api.sapiom.ai",
    apiKey: buyerKey,
    transactionId,
  }),
  profileId: "shopify-card-vault",
  placeholder: { number: placeholder.number, injectionRef: placeholder.injectionRef },
});

handle.on((event) => {
  if (event.type === "refused" || event.type === "failed" || event.type === "relayed_unfulfilled") {
    // Flag this transaction for follow-up. Do not start a new transaction.
  }
});
```

Then open `continueUrl`, fill the card fields with the placeholder's `number`, expiry and `cvc`, and submit. When checkout finishes, call `await handle.detach()`.

`cdpUrl` is a CDP WebSocket URL, or a Puppeteer or Playwright object that provides one through `wsEndpoint()`.

## Check the result

| Event | Meaning |
| - | - |
| `relayed` | The payment processor answered. The order is not confirmed yet. |
| `relayed_unfulfilled` | The relay finished, but the page could not receive the answer. |
| `refused` | Sapiom refused the relay. `reason` says why. |
| `failed` | The request could not be relayed. `reason` says why. |

Whatever the event, the next step is the same: [confirm the order](https://docs.sapiom.ai/transactions/confirm-and-recover.md). No event proves that money did or did not move.

Browser Pay currently works with Shopify card checkout. It does not support Shop Pay yet. Options, events and reason codes are in the [Browser Pay SDK reference](https://docs.sapiom.ai/api-reference/browser-pay-sdk.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.