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

# Browser Pay

> Use a wallet payment credential on a merchant website, then report the result.

Browser Pay lets an Agent complete a merchant website's card checkout using a payment credential issued by Clink. The merchant does not need to be registered with Clink. The Agent operates the merchant website; Clink handles the wallet, purchase authorization, and credential issuance.

Before starting, connect to MCP and read its current business rules. The user must have authorized the purchase, including any budget limit. Check these conditions:

* **Payment card.** The current wallet response's `agent_pay_support` indicates card eligibility. The merchant or issuer may still decline the payment.
* **Merchant checkout.** Your Agent can read the final total, fill the card form including embedded payment fields, submit payment, and inspect the merchant's payment or order result.
* **User verification.** The user can complete any required bank verification, such as 3-D Secure or a one-time code.

A platform that receives encrypted credentials also needs the [decryption implementation](/guides/agent/browser_pay/decryption).

## The payment flow

<Tabs>
  <Tab title="Payment flow">
    When a valid purchase authorization covers the payment, `get_credential` can return the credential directly. Use `credential.card` as provided; decrypt only when the response contains `key` and `payload`.

    ```mermaid theme={null}
    %%{init: {"theme":"base","themeVariables":{"fontFamily":"inherit","actorBkg":"#F7F7F7","actorBorder":"#E7E7E7","actorTextColor":"#161616","actorLineColor":"#E7E7E7","signalColor":"#71717A","signalTextColor":"#3F3F46","noteBkgColor":"#F8E1CC","noteBorderColor":"#F8E1CC","noteTextColor":"#161616"},"sequence":{"width":116,"height":44,"actorMargin":64,"diagramMarginX":12,"diagramMarginY":12,"messageMargin":28,"noteMargin":14,"boxMargin":12,"wrap":false,"mirrorActors":false,"actorFontSize":14,"messageFontSize":14,"noteFontSize":14}}}%%
    sequenceDiagram
      participant M as Merchant
      participant A as Agent / platform
      participant C as Clink MCP
      A->>M: Read final total
      M-->>A: Amount and currency
      A->>C: get_credential
      C-->>A: Credential + payment IDs
      Note over A: Decrypt if encrypted
      A->>M: Recheck total and pay
      M-->>A: Payment result
      A->>C: confirm_result
      C-->>A: Report recorded
    ```
  </Tab>

  <Tab title="When user action is required">
    If `get_credential` returns a `REDIRECT_USER` link, complete this flow, then return to the payment flow to use the credential.

    ```mermaid theme={null}
    %%{init: {"theme":"base","themeVariables":{"fontFamily":"inherit","actorBkg":"#F7F7F7","actorBorder":"#E7E7E7","actorTextColor":"#161616","actorLineColor":"#E7E7E7","signalColor":"#71717A","signalTextColor":"#3F3F46","noteBkgColor":"#F8E1CC","noteBorderColor":"#F8E1CC","noteTextColor":"#161616"},"sequence":{"width":116,"height":44,"actorMargin":64,"diagramMarginX":12,"diagramMarginY":12,"messageMargin":28,"noteMargin":14,"boxMargin":12,"wrap":false,"mirrorActors":false,"actorFontSize":14,"messageFontSize":14,"noteFontSize":14}}}%%
    sequenceDiagram
      participant U as User
      participant A as Agent / platform
      participant C as Clink MCP
      C-->>A: REDIRECT_USER
      A-->>U: Show user action link
      U->>C: Complete card setup or approval
      A->>C: get_operation
      C-->>A: Setup complete
      A->>C: get_credential
      C-->>A: Credential + payment IDs
    ```

    Wait for the returned setup Operation to complete, then repeat `get_credential` with the same checkout facts and selected `paymentInstrumentId`, if any. Do not pass the setup operation ID. Other `SETUP_REQUIRED` cases are described in step 2.
  </Tab>
</Tabs>

The diagram shows the successful path. If the card is never submitted, report `NOT_SUBMITTED`; if submission occurred but its result is unknown, report `UNKNOWN`.

## 1. Read the final checkout amount

Use the merchant checkout page's final total, including shipping and tax. Do not use the product list price or treat the user's maximum budget as the amount to charge. Obtain contact and delivery details from the user or their merchant account.

Select the website's card payment option and leave any option to save payment details disabled. If the user named a specific wallet card, obtain its `paymentInstrumentId` from a fresh `get_account_state` response and check `agent_pay_support: true`. Otherwise, omit the selector to use the default card.

## 2. Request a credential

The following is a `tools/call` request. For a checkout total of USD 12.50, send `amount: 1250`:

```json theme={null}
{
  "name": "get_credential",
  "arguments": {
    "merchantUrl": "https://shop.example.com/checkout",
    "merchantName": "Example Store",
    "amount": 1250,
    "currency": "USD"
  }
}
```

Required scopes are `wallet:read`, `payment:execute`, `instruction:read`, and `instruction:write`.

Clink checks the chosen card and matches an active purchase authorization. If one covers the payment, the call can return the credential immediately. Otherwise, it can start a one-time authorization for this checkout. You do not need to list or create purchase authorizations before every Browser Pay call.

Handle the actual response:

| Response | Next step |
| :- | :- |
| `credential` is present | Continue to step 3. |
| `REDIRECT_USER` / `PASSKEY` | Give the user `next_action.params.redirect_url` to authorize this payment. |
| `REDIRECT_USER` / `PAYMENT_METHOD_SETUP` | Give the user the returned link to add or choose a card and authorize this payment. |
| `SETUP_REQUIRED` / `DEFAULT_CARD` | Show the returned `wallet_cards` by brand and last four digits. Let the user select a card for this checkout or choose to change their default. |
| `SETUP_REQUIRED` / `PURCHASE_INSTRUCTION` | Complete the [purchase authorization setup](/guides/agent/wallet_service) for the returned card and amount, then request the credential again. |

When a redirect has `actor: "USER_DEVICE_ONLY"`, the user opens it on their own device. Do not open or preview it in the Agent's browser. After presenting a Passkey or card setup link, wait for the same setup Operation:

```json theme={null}
{
  "name": "get_operation",
  "arguments": {
    "operationId": "<setup operation_id>",
    "maxWaitSeconds": 60
  }
}
```

Once setup is complete, repeat `get_credential` with the checkout facts. Do not pass the setup `operationId`. Preserve `paymentInstrumentId` on each call if the user selected a card for this checkout. If the user chose a new default instead, call `set_default_card` before repeating the request without that selector.

Opening a link is not proof that authorization is complete. If the response still requires action, follow the current `next_action`.

## 3. Read or decrypt the credential

Inspect the returned shape rather than assuming every client receives the same form:

| Shape | How to use it |
| :- | :- |
| `credential.card` | Card details are already available. Use this object; no decryption is required. |
| `credential.key` and `credential.payload` | Preserve both strings exactly and decrypt them using the [credential decryption example](/guides/agent/browser_pay/decryption). |

Cloud platforms arrange their public key with Clink through an offline contact. See [platform integration](/guides/agent/platform_integration).

### How payment credentials are protected

<div className="not-prose my-4 w-fit p-7">
  <img src="https://mintcdn.com/clink/WOHh_9VfSF-k-jkf/images/partners/visa-blue.png?fit=max&auto=format&n=WOHh_9VfSF-k-jkf&q=85&s=dd416e18fa3d7f11748b4b2d9282ee53" alt="Visa" width={208} height={68} className="m-0 block h-auto w-20" noZoom data-path="images/partners/visa-blue.png" />
</div>

The current Visa flow uses a tokenized card number and a dynamic security code in the merchant's card form. The tokenized number replaces the user's original card number, and the dynamic security code has an expiry. Use the returned credential and its expiry information for this checkout.

When a platform receives `key` and `payload`, the credential is additionally encrypted for its public key. Decrypt with the matching private key to read the card fields. This protects credential delivery; the [purchase authorization confirmed with a passkey](/guides/agent/wallet_service#passkeys-and-purchase-authorization) defines the permitted spending. A response containing `credential.card` is also subject to the authorization limits and credential expiry.

### Keep payment identifiers

Keep these identifiers for reporting:

| `confirm_result` argument | Source |
| :- | :- |
| `operationId` | `operation_id` from the `get_credential` response that issued the card; also `clientReferenceId` in the credential payload |
| `orderId` | Payload `orderId`, or `resources.payment_order_id` |
| `paymentExecutionDetailId` | Payload `paymentExecutionDetailId`, or `resources.payment_execution_detail_id` |

`orderId` identifies Clink's payment order; it is not the merchant's order number. Keep the merchant's order number separately if the merchant returns one.

<Note>
  A `get_credential` Operation with `status: "SUCCEEDED"` means the credential was issued. It does not mean the merchant was paid. `get_operation` never returns the credential and cannot independently verify the merchant's payment result.
</Note>

`get_credential.amount` and `confirm_result.paidAmount` use minor currency units. The credential payload's `amount` uses major units: for USD 12.50, these are `1250` and `12.50` respectively. Convert according to the currency's precision; do not multiply every currency by 100.

## 4. Fill and submit the merchant payment

Fill the returned card number, expiry, and security code into the card fields on this checkout, including payment provider fields embedded in the page. Match the expiry format expected by the form. Use the returned `cardholderName` and `billingAddress` when available; ask for missing billing information instead of inventing it.

Use the credential within its validity period. The decrypted expiry information and `ttlMinutes`, when present, take precedence over the outer `credential.expires_at` estimate.

Recheck the total immediately before submission:

* If unchanged, submit and inspect the merchant's result. The user completes any required 3-D Secure or one-time code step.
* If changed, do not submit the old credential. Report `NOT_SUBMITTED` with `failureReason: "AMOUNT_CHANGED"`, then request a credential for the new total within the user's authorization.

Card details are for this checkout's payment fields. Do not include them in chat, logs, or saved notes. Use `credential.display` to describe the card to the user.

## 5. Report the observed result

Call `confirm_result` for the Browser Pay payment using the identifiers from step 3. For an observed successful payment:

```json theme={null}
{
  "name": "confirm_result",
  "arguments": {
    "orderId": "<issued orderId>",
    "paymentExecutionDetailId": "<issued paymentExecutionDetailId>",
    "operationId": "<issuing operation_id>",
    "outcome": "SUCCEEDED",
    "paidAmount": 1250,
    "currency": "USD"
  }
}
```

| Outcome | Use when |
| :- | :- |
| `SUCCEEDED` | The merchant page explicitly confirmed that payment succeeded. |
| `FAILED` | The merchant showed a payment failure after submission. |
| `NOT_SUBMITTED` | You did not submit the card, for example because the total changed, decryption failed, or the user cancelled. This outcome does not require clicking Pay first. |
| `UNKNOWN` | The card was submitted, but you could not establish the result. |

Supply `paidAmount` and `currency` together when the success page shows the paid amount. Add `failureReason` only with `FAILED` or `NOT_SUBMITTED`. See the [full parameter reference](/api-reference/mcp/browser_pay#confirm_result).

For `UNKNOWN`, keep the payment identifiers and inspect the merchant's existing order or payment result. Do not submit another payment. Report the final result before the returned `report_deadline`. A repeated report with the same outcome is safe; a conflicting final outcome is refused.

Clink records the Agent's report and returns an `agent_reported_result` message. The report is not independent confirmation from the merchant. Refunds for this flow are handled with the merchant.

Give the user a brief result using only details observed on the merchant page. For example, when the page confirms these details:

> Example Store confirmed payment of USD 12.50. Merchant order: EX-1042.

If no merchant order number was shown, omit it. Do not invent one or substitute Clink's `orderId`.

## Recovery without a duplicate purchase

| Situation | Recovery |
| :- | :- |
| Credential request timed out, returned `issuance_incomplete`, or its response was lost before submission | Repeat `get_credential` with the same checkout facts and selected card. Before final reporting, Clink reuses the outstanding credential rather than creating another purchase. |
| Credential expired before submission | Repeat the same request to obtain a replacement for the same order. If `credential_unavailable` is returned, use the known identifiers to report `NOT_SUBMITTED` with `CREDENTIAL_EXPIRED`. |
| Decryption failed | Do not submit. Report `NOT_SUBMITTED`, using identifiers from `resources` if available. If identifiers are unavailable, read the issuing Operation and resolve the integration failure; do not invent IDs or start a new payment. |
| Result reporting failed or returned `result_reporting_unavailable` | Retry the same `confirm_result` arguments. Do not pay again. |
| A final result was already reported | The purchase is finished. A later `get_credential` call with the same facts starts a new purchase, so call it only for a newly authorized purchase. |

`confirm_result` belongs only to Browser Pay. UCP Checkout and direct payments obtain their results through their own tools; do not report those payments through this endpoint.

For field constraints and error codes, see [Browser Pay tools](/api-reference/mcp/browser_pay) and [Operations and recovery](/api-reference/mcp/operations).


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