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

# 二维码支付

> 为指定客户创建专属托管收款页面，支持扫码、链上转账和钱包支付。

为指定客户创建专属收款页面，扫码即可用稳定币完成支付。

二维码支付（QR Pay）是 StablePay 面向指定客户的托管收款页面。商户调用 Open API 或在 Merchant Portal 中为某个客户创建一条二维码支付，拿到托管页面链接后，把它生成二维码摆在收银台、贴在海报上，或通过聊天、邮件发给客户。客户扫码打开页面，填写邮箱与金额，选择稳定币和网络，用链上转账或钱包支付完成付款。地址分配、收款二维码、链上监听、支付确认和结果通知都由 StablePay 托管。

与收款链接不同，每条二维码支付都绑定一个具体客户，因此同一个客户可以反复使用同一条收款入口，商户也能按客户汇总累计支付金额与成功笔数。其内部资源仍沿用 `customer_deposit` 与 `deposit_session_id` 的命名，与本文档中的「二维码支付」是同一个对象。

## 适用场景

当收款对象明确、并且同一个客户会多次付款时，适合使用二维码支付：

* 线下收银台、柜台或门店海报上的固定收款二维码。
* 客服、社群、邮件中发给指定客户的一条专属收款链接或二维码。
* 交易平台、钱包、账户型产品的客户余额充值。
* 需要给长期客户保留一条不过期的收款入口。
* 客户分散在不同网络，希望由托管页面统一引导选链、选币的场景。

如果要向不特定人群公开分享一条可复用收款页，请使用 收款链接；如果需要正式账单与到期日，请使用 Invoicing；如果由后端创建一次性 checkout 会话，请使用 收银台。二维码支付本身不提供退款接口，退回客户资金请使用 Payouts Open API。

## 工作流程

1. 商户在 Merchant Portal 创建，或调用创建接口传入 10 位 `external_customer_id` 与 `allow_multiple_deposits`，可选传入客户资料、过期时间、描述和回跳地址。
2. StablePay 按当前商户与 `external_customer_id` 查找 Customer：不存在则创建，已存在则直接复用。
3. 接口只返回 `deposit_session_id` 和托管页面 url，不返回任何链上地址。
4. 商户把 url 生成二维码，或直接分享给客户。
5. 客户打开页面，填写邮箱和金额，选择支付方式。
6. 选择链上转账时，页面按所选币种与网络展示该条二维码支付对应的地址、Memo/Tag 和二维码，客户完成转账；选择钱包支付时，输入的金额作为固定应付金额，进入标准钱包支付流程。
7. StablePay 确认收款后生成支付记录、页面展示成功，并投递 `payment.completed` Webhook。
8. 成功支付沿用普通支付结算链路，按 T+1 自然日以同币种结算。

## 核心能力

| 能力 | 说明 |
| :- | :- |
| 客户绑定 | 每条二维码支付绑定一个 Customer，按 `external_customer_id` 自动创建或复用。 |
| 托管收款页面 | StablePay 提供币种、网络、地址、二维码与成功页，商户无需自建页面。 |
| 多次支付 | 由 `allow_multiple_deposits` 决定是单次使用还是可重复支付。 |
| 可选有效期 | `expires_at` 留空即永久有效，不设默认值，也不限制最长有效期。 |
| 地址隔离 | 每条二维码支付分配独立地址，同一客户的不同二维码支付互不干扰。 |
| 二维码收款 | 页面二维码达到常见手机钱包可识别的纠错等级。 |
| 双支付方式 | 同时支持链上转账支付与钱包支付。 |
| 支付结果通知 | 复用现有 payment.\* Webhook 与 Payments API 查询，无需新增事件类型。 |
| Portal 管理 | 列表与详情、累计支付金额、成功笔数、关联支付记录及导出。 |

## 客户模型

Customer 是商户维度的统一客户对象，与订阅共用一个模型，没有单独的「充值客户」子类型。同一个 `external_customer_id` 在同一商户下唯一、创建后不可修改；相同的 ID 在不同商户下则是两个完全独立的客户，客户资料与链上地址互不可见。

创建二维码支付时传入的姓名、邮箱、手机号只用于新建 Customer，已存在的 Customer 不会被覆盖。一个 Customer 可以拥有多条二维码支付，每条各自分配地址，累计支付金额与成功笔数也分别统计。商户也不需要单独调用客户接口：Portal 的客户页面可以直接创建客户，Open API 则在创建二维码支付时按需自动创建。托管页面上的邮箱使用 Customer 的邮箱预填并允许修改，提交值只作为本次支付的快照，不回写 Customer。

## 链上地址与二维码

地址按 `merchant_id + deposit_session_id + address_family` 固定分配，因此不同二维码支付即使属于同一个客户，地址也彼此独立。同一条二维码支付内，Ethereum、Base、Arbitrum 等 EVM 网络复用同一个 EVM 地址；TRON、Solana 等非 EVM 地址族分别生成对应地址。地址在该地址族第一次被请求时懒分配，之后始终返回同一个地址。

支持 Memo/Tag 的网络必须同时展示地址与 Memo/Tag，两者共同构成完整收款凭证；页面也会提示客户只能通过所选网络发送所选币种。链上地址只在终端客户打开托管页面并选择币种与网络后展示，创建和查询接口都不返回地址，Merchant Portal 的列表、详情和客户详情页同样不展示地址、地址族、支持网络或 Memo/Tag。

## 有效期与多次支付

`allow_multiple_deposits` 在创建时必填，没有默认值。设为 false 时该条二维码支付为单次使用：首笔支付成功后状态变为 `closed`，页面不再展示地址，也不再提供继续支付的入口；设为 true 时，客户可以在有效期内重复付款。

`expires_at` 使用 Unix 秒且必须晚于当前时间。不传表示永久有效，接口在响应中返回 `null`，既没有默认有效期，也不限制最长有效期。对外状态有三个取值：`active`（可支付）、`closed`（已关闭，单次支付已完成）、`expired`（已过期）。

需要特别注意的是，状态失效不会让链上地址失效。客户把地址保存到钱包后，在二维码支付已关闭或已过期时继续转账，StablePay 仍会识别、入账并生成支付记录，标记为 `outside_session`。这类支付与正常支付适用同样的费率、结算和成功 Webhook 规则。

## 金额、币种与费用

二维码支付只支持 StablePay 已配置的 U 类稳定币，不涉及法币充值、法币计费或币种兑换。金额全部使用十进制定点字符串传输，不使用浮点数。

链上转账支付不比较客户输入金额与链上实际到账金额，因此不存在少付、多付或部分收款状态：地址收到任意符合入账条件的正数金额并完成确认后即支付成功。钱包支付则以客户输入的金额作为固定应付金额，复用普通支付的金额校验与状态流转。两种方式最终都以实际支付成功金额为准。

收到 USDT 以 USDT 计费，收到 USDC 以 USDC 计费，不做币种互换。手续费按实际支付成功金额计算，`fee_amount = actual_amount × fee_rate`，默认费率 1%，可按商户单独配置；订单成功时固化费率与手续费快照，后续费率调整不追溯历史订单。结算金额为 `net_amount = actual_amount − fee_amount`。费率、手续费与净额属于内部结算数据，不会通过 Payments API、Webhook 或 Merchant Portal 返回。

## 支付结果与通知

链上转账在达到目标确认数并通过风控后才创建 Trade Order，因此对外状态直接是 `paid`，中间不会出现处理中状态。钱包支付在客户选择该方式时预创建 `pending` 订单，之后复用普通支付的 `pending`、`processing`、`paid`、`failed`、`expired`、`canceled` 状态流转。

支付成功统一通过现有的 `payment.completed` 事件通知，`data.object.payment_type` 为 `customer_deposit`，并携带 `customer_id` 与 `deposit_session_id`。链上检测中与确认中不发送 Webhook，二维码支付关闭或过期也不发送，结算完成不新增事件。Webhook 的签名、Event ID、重试与幂等规则沿用现有定义，商户需要支持重复通知。

## 结算

成功支付沿用普通支付的结算链路，按 T+1 自然日结算，周末与节假日正常处理：T 日成功的订单在 T+1 日进入结算批次，结算金额为同币种的 net\_amount，不发生法币兑换。

## Merchant Portal

Portal 以二维码支付为主记录展示，而不是把单笔支付铺在列表里。列表支持按客户 ID、二维码支付 ID、状态和创建时间范围筛选，展示客户、累计支付金额、成功支付笔数、状态与创建时间，操作列可以查看详情和复制收款链接。累计金额是该条二维码支付下所有 `payment_status=paid` 支付记录的金额之和，USDT 与 USDC 统一以 U 展示但不做兑换。

创建入口要求先从搜索结果中选中一个现有客户，不支持只输入自由文本。创建时可设置过期时间、是否允许多次支付、描述与 `metadata`；Portal 不提供币种与网络配置，托管页面始终使用商户已开通的全部受支持 U 币种与网络。创建成功后只展示可复制的收款链接，不返回也不展示链上地址。

详情页先展示配置、累计支付金额和成功笔数，再展示该条二维码支付关联的支付记录，支付记录不展示费率、手续费或净额。客户详情页新增二维码支付区域，列出该客户的全部二维码支付，同样不展示链上地址。

## API 概览

| 用途 | 接口 |
| :- | :- |
| [创建二维码支付](https://docs.stablepayfi.ai/api-reference/二维码支付/创建二维码支付.md) | `POST /api/v1/customer-deposits` |
| [查询二维码支付](https://docs.stablepayfi.ai/api-reference/二维码支付/查询二维码支付.md) | `GET /api/v1/customer-deposits/{deposit_session_id}` |

请求需要 Bearer API Key，并携带 `X-StablePay-Timestamp`、`X-StablePay-Nonce`、`X-StablePay-Signature` 三个签名头，创建请求还必须携带 `Idempotency-Key`。签名串为 `{timestamp}.{nonce}.{requestBody}`，用 HMAC-SHA256 计算后取小写 hex，GET 请求的 requestBody 为空字符串。完整鉴权与签名说明见 集成前准备。

### 创建二维码支付

```bash theme={"system"}
curl --request POST 'https://api.stablepay.co/api/v1/customer-deposits' \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: 8f4d0c1e-3b7a-4d2f-9c55-2f0a6d9b1e73' \
  --header 'X-StablePay-Timestamp: 1791878400' \
  --header 'X-StablePay-Nonce: 550e8400-e29b-41d4-a716-446655440000' \
  --header 'X-StablePay-Signature: <SIGNATURE>' \
  --data '{
    "external_customer_id": "1234567890",
    "customer_email": "customer@example.com",
    "allow_multiple_deposits": true,
    "description": "收银台固定收款码",
    "success_url": "https://merchant.example/qr-pay/success",
    "cancel_url": "https://merchant.example/qr-pay/cancel",
    "metadata": {"store": "SH-001"}
  }'
```

响应示例（201 首次创建，200 为幂等重放；字段值为占位）

```json theme={"system"}
{
  "deposit_session_id": "20261013110310801082920000001001",
  "customer_id": "10000001",
  "status": "active",
  "allow_multiple_deposits": true,
  "expires_at": null,
  "url": "<hosted checkout URL>",
  "metadata": {"store": "SH-001"},
  "created": 1791878400
}
```

创建成功返回 201；携带同一 `Idempotency-Key` 的重复请求返回 200 与同一条二维码支付。`external_customer_id` 不是 10 位数字、`allow_multiple_deposits` 缺失、或回跳地址不是绝对 HTTPS URL 时返回 400；幂等键冲突返回 409；查询不存在或不属于当前商户时统一返回 404 `resource_not_found`。

## 与其它收款方式的区别

| 对比项 | 二维码支付 | 收款链接 | Invoicing |
| :- | :- | :- | :- |
| 收款对象 | 绑定的指定客户 | 公开，任何人 | 指定的账单客户 |
| 复用方式 | 同一客户可重复支付 | 可分享给多个付款人 | 一次性账单，有到期日 |
| 金额来源 | 客户自填，或钱包支付固定金额 | 商品定价 | 账单金额 |
| 创建方式 | Open API 或 Portal | Portal | Portal 或 API |

## 重要说明

* 二维码支付不提供退款接口。需要退回客户资金时，使用 Payouts Open API，并可在 `metadata` 中记录原支付 ID 便于审计，但这不构成自动退款关系。
* 不支持客户提现、法币充值、法币计费或币种兑换。
* 关闭或过期不影响已分配地址的入账归属，超出有效期范围的到账会标记为 `outside_session`，费率与结算规则不变。
* 链上地址只对终端客户在托管页面展示，任何接口与 Portal 页面都不返回地址。
* 可用的币种、网络与最小金额取决于商户已开通的币—链配置，详见 支持的钱包 与 支持的网络。
* 客户页面支持商家 logo 与品牌色，配置方式见 [品牌设置](https://docs.stablepayfi.ai/zh/product/Branding-Settings.md)。

## 相关页面

* [创建二维码支付](https://docs.stablepayfi.ai/api-reference/二维码支付/创建二维码支付.md)
* [查询二维码支付](https://docs.stablepayfi.ai/api-reference/二维码支付/查询二维码支付.md)
* [集成前准备](https://docs.stablepayfi.ai/zh/api/getting-started.md)
* [Webhook 通知](https://docs.stablepayfi.ai/zh/api/webhook-notifications.md)
* [收款链接](https://docs.stablepayfi.ai/zh/product/Payment-Links.md)
* [收银台](https://docs.stablepayfi.ai/zh/product/Stablecoin-Checkout.md)
* [账单收款](https://docs.stablepayfi.ai/zh/product/Invoicing.md)
* [支持的钱包](https://docs.stablepayfi.ai/zh/product/Supported-Wallets.md)
* [支持的网络](https://docs.stablepayfi.ai/zh/product/Supported-Networks.md)


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