跳到正文
PayHub开发者文档

创建托管收银会话

契约 v1.0.0

createCheckoutSession
POST/v1/checkout/sessions
所需权限payments:write需要幂等键

创建关联统一 Payment 的托管收银会话。二选一:传 payment_id;或传 merchant_order_no + amount + currency,由平台创建或复用 Payment。 两组身份参数同时提交或都缺失时返回 400。复用已有订单时金额或币种不一致返回 422; 关联 Payment 已成功时返回 200 与 status=completed 的只读会话,不生成新的可扣款入口;其他不可支付状态返回 409。 请求不含卡数据;return_url、cancel_url 须匹配已登记的地址规则;金额、币种与收款商户不能通过 URL 参数改变。 换用新的幂等键但订单号、金额、币种一致时,为同一 Payment 生成新的收银会话,不产生第二个 Payment。

请求头

请求头必填格式说明
Authorization是Bearer <API_KEY>

服务端密钥,只能在商户服务端使用;商户与环境由密钥推导。缺失、无效、撤销或过期返回 401。

Content-Type是application/json

请求体为 UTF-8 编码的 JSON。

Idempotency-Key是1–255 个可见 ASCII 字符

幂等键,1–255 个可见 ASCII 字符。作用域为商户、环境、方法与路径:同键且安全业务参数一致时复用原业务对象,参数冲突返回 409 idempotency_conflict。 一次提交使用一个键,网络重试沿用原键;换卡等新的提交使用新键。 同键并发时只有一个请求取得执行权,其余请求等待其事务提交后返回同一对象(200);等待超时返回 409 operation_in_progress(retryable=true),稍后用原键重试。 被 400、401、403、422 拒绝的请求不占用幂等键,修正后用新键提交。

请求体

JSON 对象 CreateCheckoutSessionRequest

名称类型必填说明
payment_id
string
条件:与(merchant_order_no + amount + currency)二选一,不得同时提交

已存在的 Payment。传入时不得同时传 merchant_order_no、amount、currency。

约束:长度 1–64

示例:pay_demo_002

merchant_order_no
string
条件:不传 payment_id 时与 amount、currency 一起必填

商户订单号;与 amount、currency 一起提交时,平台创建或复用该订单对应的 Payment。

约束:格式 ^[A-Za-z0-9._:-]{1,64}$

示例:ORDER-DEMO-002

amount
integer(int64)
条件:不传 payment_id 时与 merchant_order_no、currency 一起必填

订单金额,最小货币单位;复用已有订单时须与原订单一致。

约束:≥ 1

示例:10000

currency
string
条件:不传 payment_id 时与 merchant_order_no、amount 一起必填

币种;复用已有订单时须与原订单一致。

约束:格式 ^[A-Z]{3}$

示例:USD

description
string否

收银页展示的订单摘要。

约束:最长 256

示例:示例托管收银订单

return_url
string(uri)必填

支付结束后的商户返回地址,须匹配当前环境已登记的回跳地址规则:按协议、主机(精确或一级通配)、端口与路径前缀(按路径段)匹配,查询串与片段不参与匹配。平台回跳时原样使用该地址,不追加任何参数。

约束:最长 2048

示例:https://merchant.example/payment/return

cancel_url
string(uri)否

“返回商户”地址,须匹配当前环境已登记的回跳地址规则:按协议、主机(精确或一级通配)、端口与路径前缀(按路径段)匹配,查询串与片段不参与匹配。点击“返回商户”不等于撤销扣款。

约束:最长 2048

示例:https://merchant.example/payment/cancel

locale
string否

收银页语言(BCP 47):zh 开头为中文,en 开头为英文;其他取值或未传时使用商户默认语言。

约束:格式 ^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$

示例:zh-CN

请求示例

为已创建的 Payment 创建收银会话

curl
curl -X POST 'https://api.payhub.bbpays.site/v1/checkout/sessions' \
  -H 'Authorization: Bearer <TEST_SERVER_API_KEY>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <UNIQUE_OPERATION_KEY>' \
  -d '{
  "payment_id": "pay_demo_008",
  "return_url": "https://merchant.example/payment/return",
  "cancel_url": "https://merchant.example/payment/cancel",
  "locale": "zh-CN"
}'

需要替换的占位符

  • <TEST_SERVER_API_KEY>:测试环境服务端 API Key:在商户后台「API Key」页面创建
  • <UNIQUE_OPERATION_KEY>:你为这次提交生成的幂等键(如 UUID),网络重试沿用同一个

按订单信息创建(平台创建或复用 Payment)

curl
curl -X POST 'https://api.payhub.bbpays.site/v1/checkout/sessions' \
  -H 'Authorization: Bearer <TEST_SERVER_API_KEY>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <UNIQUE_OPERATION_KEY>' \
  -d '{
  "merchant_order_no": "ORDER-DEMO-008",
  "amount": 10000,
  "currency": "USD",
  "description": "示例托管收银订单",
  "return_url": "https://merchant.example/payment/return",
  "cancel_url": "https://merchant.example/payment/cancel",
  "locale": "zh-CN"
}'

需要替换的占位符

  • <TEST_SERVER_API_KEY>:测试环境服务端 API Key:在商户后台「API Key」页面创建
  • <UNIQUE_OPERATION_KEY>:你为这次提交生成的幂等键(如 UUID),网络重试沿用同一个

说明

服务端 API Key 只能在你的服务端使用,文档站不提供在线调试。获取测试 Key:商户后台 API Key(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)

响应

同键幂等复用,或关联 Payment 已成功时返回的只读会话。

关联支付已成功:返回只读会话,不生成新的扣款入口
{
  "id": "cs_demo_002",
  "payment_id": "pay_demo_008",
  "status": "completed",
  "checkout_url": "https://pay.payhub.example/checkout/<SHORT_LIVED_TOKEN>",
  "expires_at": "2026-09-23T09:30:00Z",
  "return_url": "https://merchant.example/payment/return",
  "cancel_url": "https://merchant.example/payment/cancel",
  "locale": "zh-CN",
  "created_at": "2026-09-23T09:20:00Z",
  "request_id": "req_demo_019"
}

需要替换的占位符

  • <SHORT_LIVED_TOKEN>:平台返回的短时凭据,原样使用,不要记录

响应字段

返回对象 字段说明见 对象小节。

名称类型必填说明
id
string必填

收银会话号。

示例:cs_demo_002

payment_id
string必填

关联的 Payment。

示例:pay_demo_002

status
string必填

收银会话状态。

  • open:可提交支付
  • completed:仅在关联 Payment 成功后出现
  • expired:不再允许新提交;不代表关联支付失败
  • open:可提交支付
  • completed:仅在关联 Payment 成功后出现
  • expired:不再允许新提交;不代表关联支付失败
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:open

checkout_url
string(uri)必填

收银页地址,携带只绑定本会话的短时凭据,不含商户服务端密钥。只用于让付款人浏览器整页跳转:不要写入日志、分析工具或错误上报,也不要分享给他人。

示例:https://pay.payhub.example/checkout/<SHORT_LIVED_TOKEN>

expires_at
string(date-time)必填

会话失效时间,创建时确定:最长 30 分钟(平台可调短)且不超过订单剩余可支付期。过期后的只读期内(创建时确定,默认且最长 24 小时)付款人仍可用原链接查看会话与支付结果(只读,不能提交),之后链接失效。

示例:2026-09-23T09:30:00Z

return_url
string(uri)必填

支付结束后的商户返回地址。

示例:https://merchant.example/payment/return

cancel_url
string(uri)可为空必填

付款人点击“返回商户”时的地址;点击它不等于撤销已提交的扣款。未提供时为 null。

示例:https://merchant.example/payment/cancel

locale
string必填

收银页语言。

示例:zh-CN

created_at
string(date-time)必填

创建时间。

示例:2026-09-23T09:00:00Z

request_id
string必填

本次请求的唯一标识,用于排查与支持。

示例:req_demo_001

可能的错误码

HTTP错误码何时出现如何处理
400invalid_request缺 Idempotency-Key;订单号含非法字符;payment_method_data 与 payment_method_id 同时提交;confirm=false 携带卡信息;confirm=true 缺 return_url;收银会话两组身份参数同时提交或都缺;缺少上游要求的 browser_info / billing_details 字段;游标、时间格式、limit 不合法按 error.field 修正后重新提交,不要自动重扣
400sensitive_data_rejecteddescription、metadata 中出现卡号样式的数字等删除敏感内容后重新提交;检查你的系统为何把卡数据写进这些字段
403capability_disabled未开通直接传卡;支付或退款申请能力被关闭;该币种未开放改用托管收银台或联系平台运营
403merchant_not_active商户被暂停或关闭;已受理业务的回调、查询、通知不受影响联系平台运营
404not_foundID 错误;用测试 Key 查询生产对象;查询平台异常退款(不通过开放 API 返回)核对 ID 与 Key 的环境;平台不会透露对象是否属于其他商户
409idempotency_conflict复用了键但金额、币种、订单号等不同属于集成缺陷:检查幂等键生成逻辑;不要改参数后重放原键;新操作使用新键
409operation_in_progress并发发送了同键请求稍后用同一个键重试,或查询 related_resource_id;不要换键
409invalid_state取消 processing / succeeded 的支付;对已过期、已取消、已成功的订单 confirm;为不可支付的订单创建收银会话查询对象最新状态后决定
409attempt_limit_reached默认最多 3 次,可被平台收紧不能再对该订单扣款;确认原支付关闭后用新订单号
422order_amount_mismatch创建收银会话时同一订单号的金额或币种变了金额不可修改:关闭原支付后用新订单号创建
422currency_not_supported商户配置与上游能力的交集不含该币种改用已启用币种或联系平台运营
422amount_out_of_range低于最低 / 高于最高单笔金额,或超过日累计限额;错误中不回传具体阈值调整金额或联系平台
422url_not_allowedreturn_url / cancel_url 不匹配已登记的地址规则在 商户后台回跳地址页面 登记后重新提交
503temporarily_unavailable平台暂停了该通道的新交易;响应不说明内部原因稍后用原幂等键重试;本次没有产生 Payment 或扣款;持续出现时联系平台运营
401unauthenticated通用未带 Authorization;Key 复制不完整;轮换后旧 Key 已过期;Key 被撤销检查凭据,在 商户后台 API Key 页面 核对 Key 状态与环境
403forbidden通用只读 Key 创建退款;getEvent 缺少事件所属业务的读权限;请求来源 IP 不在 Key 的白名单时返回更具体的 ip_not_allowed使用具备所需 scope 的 Key;不要绕过限制
429rate_limited通用商户、Key 维度的频率限制;换 Key 不能绕过商户总限额等待 Retry-After 秒后用原幂等键重试
500internal_error通用—用原幂等键重试或按商户订单号 / 退款号查询;不能换键重扣
502 / 503upstream_unavailable通用上游或平台依赖故障,平台无法确认本次请求是否已生效同上

注意事项

  • 两组身份参数二选一:payment_id,或 merchant_order_no + amount + currency;同时提交或都缺失返回 400。
  • 复用已有订单时金额或币种不一致返回 422 order_amount_mismatch;关联支付已成功时返回 200 与 status=completed 的只读会话,不生成新的扣款入口;其他不可支付状态返回 409。
  • 换用新的幂等键但订单信息一致时,为同一 Payment 生成新的收银会话,不产生第二个 Payment。
  • return_url、cancel_url 必须匹配已登记的回跳地址规则:登记回跳地址(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)。
  • 改 URL 参数不能改变金额、币种或收款商户。

警告

checkout_url 含收银令牌:只用于把付款人浏览器整页跳转过去,不要写入日志、分析工具或错误上报,也不要分享给他人。

这页有帮助吗?