> ## 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

> 在商户网页中使用钱包支付凭证，并上报实际支付结果。

Browser Pay 让 Agent 使用 Clink 签发的支付凭证，在商户网站的银行卡结账页面完成付款。商户无需预先注册到 Clink。Agent 操作商户网页；Clink 负责钱包、购买授权和凭证签发。

开始前，请连接 MCP 并读取当前业务规则。用户需要已授权购买及其预算范围，并满足以下条件：

* **支付卡。** 当前钱包返回的 `agent_pay_support` 表示卡片是否具备 Agent Pay 能力；商户或发卡行仍可能拒绝本次付款。
* **商户结账页。** Agent 能读取最终总额、填写卡表单及嵌入的支付字段、提交付款，并查看商户的支付或订单结果。
* **用户验证。** 用户能完成银行要求的验证，例如 3-D Secure 或一次性验证码。

收到加密凭证的平台还需要实现[凭证解密](/cn/guides/agent/browser_pay/decryption)。

## 支付流程

<Tabs>
  <Tab title="支付主流程">
    有效的购买授权覆盖本次付款时，`get_credential` 可以直接返回凭证。直接使用 `credential.card`；仅当返回 `key` 和 `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 商户网站
      participant A as Agent / 平台
      participant C as Clink MCP
      A->>M: 读取结账总额
      M-->>A: 金额与币种
      A->>C: get_credential
      C-->>A: 凭证与支付标识
      Note over A: 加密凭证按需解密
      A->>M: 核对总额并支付
      M-->>A: 支付结果
      A->>C: confirm_result
      C-->>A: 已记录报告
    ```
  </Tab>

  <Tab title="需要用户操作时">
    如果 `get_credential` 返回 `REDIRECT_USER` 链接，先完成以下流程，再回到支付主流程使用凭证。

    ```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 用户
      participant A as Agent / 平台
      participant C as Clink MCP
      C-->>A: REDIRECT_USER
      A-->>U: 展示用户操作链接
      U->>C: 完成绑卡或授权
      A->>C: get_operation
      C-->>A: 设置完成
      A->>C: get_credential
      C-->>A: 凭证与支付标识
    ```

    等待返回的设置 Operation 完成后，使用相同结账信息再次调用 `get_credential`，并保留已选择的 `paymentInstrumentId`（如有）。不要传入设置操作的 ID。其他 `SETUP_REQUIRED` 情况见第 2 步。
  </Tab>
</Tabs>

图中展示成功路径。未提交银行卡时，上报 `NOT_SUBMITTED`；已经提交但无法确认结果时，上报 `UNKNOWN`。

## 1. 读取结账最终金额

使用商户结账页展示的最终总额，包含运费和税费。不要使用商品标价，也不要将用户的最高预算当作付款金额。联系人和配送信息来自用户或其商户账户。

选择网站的银行卡付款选项，关闭保存支付信息的选项。如果用户指定使用某张钱包卡，先通过最新的 `get_account_state` 获取其 `paymentInstrumentId`，并检查 `agent_pay_support: true`；否则省略卡选择参数，使用默认卡。

## 2. 获取支付凭证

以下是一个 `tools/call` 请求。结账总额为 USD 12.50 时，传入 `amount: 1250`：

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

需要的 Scope 为 `wallet:read`、`payment:execute`、`instruction:read` 和 `instruction:write`。

Clink 检查支付卡并匹配有效的购买授权。已有授权覆盖本次付款时，可以在本次调用中直接返回凭证；否则，可以为当前结账发起一次性授权。无需在每次 Browser Pay 调用前先查询或创建购买授权。

按实际返回内容处理：

| 返回内容 | 下一步 |
| :- | :- |
| 包含 `credential` | 继续第 3 步。 |
| `REDIRECT_USER` / `PASSKEY` | 将 `next_action.params.redirect_url` 提供给用户，授权本次付款。 |
| `REDIRECT_USER` / `PAYMENT_METHOD_SETUP` | 将返回的链接提供给用户，添加或选择支付卡并授权本次付款。 |
| `SETUP_REQUIRED` / `DEFAULT_CARD` | 根据 `wallet_cards` 展示卡品牌和尾号，让用户选择仅用于本次结账，或修改默认卡。 |
| `SETUP_REQUIRED` / `PURCHASE_INSTRUCTION` | 针对返回的支付卡和金额完成[购买授权设置](/cn/guides/agent/wallet_service)，再获取凭证。 |

当跳转返回 `actor: "USER_DEVICE_ONLY"` 时，由用户在自己的设备上打开链接。Agent 不应在自己的浏览器中打开或预览。提供 Passkey 或绑卡链接后，等待同一个设置 Operation：

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

设置完成后，使用结账信息再次调用 `get_credential`，不要传入设置操作的 `operationId`。如果用户为本次结账指定了卡，每次调用都保留相同的 `paymentInstrumentId`；如果用户选择修改默认卡，先调用 `set_default_card`，再省略卡选择参数重试。

打开链接不代表授权已完成。返回内容仍要求操作时，继续遵循当前 `next_action`。

## 3. 读取或解密凭证

根据实际返回形态处理，不要假设所有客户端都收到同一种结果：

| 形态 | 使用方式 |
| :- | :- |
| `credential.card` | 已直接提供卡信息，使用该对象，无需解密。 |
| `credential.key` 和 `credential.payload` | 完整保留两个字符串，按[凭证解密范例](/cn/guides/agent/browser_pay/decryption)解密。 |

云端平台通过线下联系 Clink 配置公钥，详见[平台接入](/cn/guides/agent/platform_integration)。

### 支付凭证如何受到保护

<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>

当前 Visa 路径使用 Token 化卡号和动态安全码填写商户卡表单。Token 化卡号替代用户原始卡号，动态安全码有有效期；使用实际返回的凭证及到期信息完成本次结账。

平台收到 `key` 与 `payload` 时，凭证另经平台公钥加密，使用对应私钥解密后读取卡字段。这层保护用于凭证交付；购买范围由 [Passkey 确认的购买授权](/cn/guides/agent/wallet_service#passkey-与购买授权)决定。直接返回 `credential.card` 时，同样需要遵守授权范围和凭证有效期。

### 保留支付标识

保留以下标识用于结果上报：

| `confirm_result` 参数 | 来源 |
| :- | :- |
| `operationId` | 签发本次卡凭证的 `get_credential` 返回中的 `operation_id`；也对应凭证负载中的 `clientReferenceId` |
| `orderId` | 负载中的 `orderId`，或 `resources.payment_order_id` |
| `paymentExecutionDetailId` | 负载中的 `paymentExecutionDetailId`，或 `resources.payment_execution_detail_id` |

`orderId` 标识 Clink 的支付订单，不是商户订单号。商户返回订单号时，单独保留该商户订单号。

<Note>
  `get_credential` Operation 的 `status: "SUCCEEDED"` 表示凭证已签发，不代表商户已收款。`get_operation` 不会返回凭证，也不能独立核实商户的支付结果。
</Note>

`get_credential.amount` 和 `confirm_result.paidAmount` 使用最小货币单位；凭证负载的 `amount` 使用主货币单位。例如 USD 12.50 分别表示为 `1250` 和 `12.50`。请按币种精度转换，不要对所有币种统一乘以 100。

## 4. 填写并提交商户支付

将返回的卡号、有效期和安全码填写到当前结账页的银行卡字段，包括嵌入页面的支付服务商字段。有效期格式以表单要求为准。返回 `cardholderName` 和 `billingAddress` 时使用它们；缺少账单信息时向用户获取，不要自行编造。

在凭证有效期内使用。解密后的有效期信息及 `ttlMinutes`（如有）优先于外层 `credential.expires_at` 的估算值。

提交前再次核对总额：

* 总额未变：提交并查看商户结果。需要 3-D Secure 或一次性验证码时，由用户完成。
* 总额变化：不要提交旧凭证。上报 `NOT_SUBMITTED` 和 `failureReason: "AMOUNT_CHANGED"`，再在用户授权范围内按新总额获取凭证。

卡信息仅用于本次结账的支付字段，不要写入聊天、日志或保存的笔记。向用户描述支付卡时，使用 `credential.display`。

## 5. 上报实际观察到的结果

使用第 3 步保留的标识，通过 `confirm_result` 上报本次 Browser Pay 支付。以下示例表示已观察到支付成功：

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

| Outcome | 使用场景 |
| :- | :- |
| `SUCCEEDED` | 商户页面明确确认支付成功。 |
| `FAILED` | 提交后，商户明确显示支付失败。 |
| `NOT_SUBMITTED` | 没有提交银行卡，例如总额变化、解密失败或用户取消。该结果不要求先点击支付。 |
| `UNKNOWN` | 已提交银行卡，但无法确定结果。 |

成功页展示实际付款金额时，同时传入 `paidAmount` 和 `currency`。`failureReason` 仅适用于 `FAILED` 和 `NOT_SUBMITTED`，详见[完整参数参考](/cn/api-reference/mcp/browser_pay#confirm_result)。

对于 `UNKNOWN`，保留支付标识，查看商户已有订单或支付结果，不要再次付款。在返回的 `report_deadline` 前补报最终结果。相同结果可以安全重报；冲突的最终结果会被拒绝。

Clink 记录 Agent 的报告，并返回 `agent_reported_result` 消息。该记录不是商户的独立确认。本流程的退款由商户处理。

根据商户页面实际展示的信息，向用户简要说明结果。例如，页面已确认以下信息时：

> Example Store 已确认支付 USD 12.50。商户订单号：EX-1042。

如果页面没有展示商户订单号，就省略该项，不要编造或用 Clink 的 `orderId` 替代。

## 恢复流程，避免重复购买

| 情况 | 恢复方式 |
| :- | :- |
| 凭证请求超时、返回 `issuance_incomplete`，或提交前丢失响应 | 使用相同结账信息和所选卡重试 `get_credential`。最终结果上报前，Clink 复用尚未处理的凭证，不会创建另一笔购买。 |
| 凭证在提交前过期 | 使用相同请求获取同一订单的新凭证。若返回 `credential_unavailable`，使用已有标识上报 `NOT_SUBMITTED` 和 `CREDENTIAL_EXPIRED`。 |
| 解密失败 | 不要提交。上报 `NOT_SUBMITTED`，可使用 `resources` 中的标识。如果标识不可用，读取签发 Operation 并解决接入问题；不要编造 ID 或发起新支付。 |
| 结果上报失败，或返回 `result_reporting_unavailable` | 使用相同参数重试 `confirm_result`，不要再次付款。 |
| 已上报最终结果 | 本次购买已结束。随后使用相同信息调用 `get_credential` 会开始新购买，只能在用户授权新购买时调用。 |

`confirm_result` 仅用于 Browser Pay。UCP Checkout 和直接支付通过各自工具取得结果，不应通过该接口上报。

字段约束和错误码见 [Browser Pay 工具](/cn/api-reference/mcp/browser_pay)及 [Operation 与恢复](/cn/api-reference/mcp/operations)。


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