跳到正文
PayHub开发者文档

创建支付

契约 v1.0.0

createPayment
POST/v1/payments
所需权限payments:write需要幂等键

创建与商户订单一一对应的 Payment;confirm=true 时立即提交首次尝试。 (商户, 环境, merchant_order_no) 唯一,商户与环境由 API Key 推导,请求中不传商户号;平台在发送上游前先保存 Payment 与尝试。 原始卡数据只在平台隔离的卡处理环境中瞬时使用,不落库、不写日志;未开通直接传卡时返回 403 capability_disabled。 同一订单在结果未知期间再次提交,只返回原对象或 409,不触发新交易。 200 为幂等复用,201 为新建,202 为已受理但结果待确认;2xx 都不代表扣款成功,以 status 或经验签的通知为准。

请求头

请求头必填格式说明
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 对象 CreatePaymentRequest

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

商户订单号,1-64 个字母、数字、点、下划线、冒号或横线;同一商户同一环境内唯一,按原值区分大小写,不自动去空格。

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

示例:ORDER-DEMO-001

amount
integer(int64)必填

订单金额,最小货币单位,须符合币种与限额配置。

约束:≥ 1

示例:10000

currency
string必填

已启用的大写三字母币种代码。

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

示例:USD

confirm
boolean否

为 true 时立即尝试支付。

约束:默认 false

示例:true

payment_method_data
PaymentMethodData
条件:confirm=true 时与 payment_method_id 二选一;confirm=false 时不得提交

直接传卡的支付方式数据,只在 confirm=true 且商户已开通直接传卡能力时接受。 原始卡字段只在平台隔离的卡处理环境中瞬时使用,绝不写入数据库、缓存、队列、日志或错误报告。与 payment_method_id 二选一。

type
string必填

支付方式类型,首期只支持 card。

  • card
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:card

card
CardDetails必填

原始卡信息,只在受控卡处理链路中瞬时使用。

payment_method_id
string
条件:confirm=true 时与 payment_method_data 二选一

适配器支持的限域支付凭据,须属于当前环境、上游账户与本商户;不代表平台提供永久卡库。

约束:长度 1–255

示例:pm_demo_001

return_url
string(uri)
条件:confirm=true 时必填

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

约束:最长 2048

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

description
string否

订单摘要,不得包含卡号等敏感信息。

约束:最长 256

示例:示例订单

customer_reference
string否

商户侧客户标识,不要求姓名或完整联系方式。

约束:最长 128

示例:CUSTOMER-DEMO-001

billing_details
BillingDetails
条件:按当前上游能力要求;缺失时在提交上游前返回 400,error.field 指明字段

持卡人最小必要信息,是否必填由当前上游适配器能力决定。

name
string否

持卡人姓名。

约束:最长 256

示例:Test Customer

email
string(email)否

持卡人邮箱。

约束:最长 254

示例:customer@example.com

address
Address否

账单地址。

browser_info
BrowserInfo
条件:按当前上游能力要求;缺失时在提交上游前返回 400,error.field 指明字段

付款人真实浏览器上下文,用于 3DS。必须来自付款人浏览器,不能用商户服务器信息替代;是否必填由当前上游适配器能力决定,缺失必要信息时在提交上游前返回明确错误。

user_agent
string否

付款人浏览器的 User-Agent。

约束:最长 2048

示例:Mozilla/5.0

accept_header
string否

付款人浏览器的 Accept 请求头。

约束:最长 2048

示例:text/html,application/xhtml+xml

language
string否

浏览器语言(BCP 47)。

约束:最长 35

示例:zh-CN

screen_width
integer(int32)否

约束:≥ 0

示例:1366

screen_height
integer(int32)否

约束:≥ 0

示例:768

color_depth
integer(int32)否

约束:1–48

示例:24

timezone_offset_minutes
integer(int32)否

时区偏移分钟数,采用 JavaScript getTimezoneOffset() 的符号语义,例如 UTC+8 为 -480。

约束:-840–720

示例:-480

javascript_enabled
boolean否

示例:true

ip_address
string否

付款人 IPv4 或 IPv6 地址,须按受信代理链获取,不能用商户服务器 IP 替代。

约束:最长 45

示例:203.0.113.10

metadata
object否

商户自定义键值,最多 20 个键;键最长 40 字符,值为最长 200 字符的字符串。禁止放入卡号等敏感数据,平台会做检查并拒绝。

约束:最多 20 个键值最长 200

示例:{"business_order_type":"one_time_purchase"}

请求示例

使用限域支付凭据创建并确认

curl
curl -X POST 'https://api.payhub.bbpays.site/v1/payments' \
  -H 'Authorization: Bearer <TEST_SERVER_API_KEY>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <UNIQUE_OPERATION_KEY>' \
  -d '{
  "merchant_order_no": "ORDER-DEMO-001",
  "amount": 10000,
  "currency": "USD",
  "confirm": true,
  "payment_method_id": "pm_demo_001",
  "return_url": "https://merchant.example/payment/return",
  "description": "示例订单",
  "customer_reference": "CUSTOMER-DEMO-001",
  "billing_details": {
    "name": "Test Customer",
    "email": "customer@example.com"
  },
  "browser_info": {
    "user_agent": "Mozilla/5.0",
    "accept_header": "text/html,application/xhtml+xml",
    "language": "zh-CN",
    "screen_width": 1366,
    "screen_height": 768,
    "color_depth": 24,
    "timezone_offset_minutes": -480,
    "javascript_enabled": true,
    "ip_address": "203.0.113.10"
  },
  "metadata": {
    "business_order_type": "one_time_purchase"
  }
}'

需要替换的占位符

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

直接传卡创建并确认(卡字段为占位符)

curl
curl -X POST 'https://api.payhub.bbpays.site/v1/payments' \
  -H 'Authorization: Bearer <TEST_SERVER_API_KEY>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <UNIQUE_OPERATION_KEY>' \
  -d '{
  "merchant_order_no": "ORDER-DEMO-002",
  "amount": 10000,
  "currency": "USD",
  "confirm": true,
  "payment_method_data": {
    "type": "card",
    "card": {
      "number": "<UPSTREAM_TEST_CARD_NUMBER>",
      "exp_month": 12,
      "exp_year": 2030,
      "cvc": "<UPSTREAM_TEST_CVC>"
    }
  },
  "return_url": "https://merchant.example/payment/return",
  "description": "示例订单",
  "customer_reference": "CUSTOMER-DEMO-002",
  "billing_details": {
    "name": "Test Customer",
    "email": "customer@example.com"
  },
  "browser_info": {
    "user_agent": "Mozilla/5.0",
    "accept_header": "text/html,application/xhtml+xml",
    "language": "zh-CN",
    "screen_width": 1366,
    "screen_height": 768,
    "color_depth": 24,
    "timezone_offset_minutes": -480,
    "javascript_enabled": true,
    "ip_address": "203.0.113.10"
  }
}'

需要替换的占位符

  • <TEST_SERVER_API_KEY>:测试环境服务端 API Key:在商户后台「API Key」页面创建
  • <UNIQUE_OPERATION_KEY>:你为这次提交生成的幂等键(如 UUID),网络重试沿用同一个
  • <UPSTREAM_TEST_CARD_NUMBER>:测试卡号:登录商户后台「接口文档与测试指南」查看
  • <UPSTREAM_TEST_CVC>:测试卡 CVC:与测试卡号一起在商户后台查看

说明

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

响应

幂等复用:同一幂等键且安全业务参数一致,返回原 Payment 的最新状态,不产生第二次执行。

同键重放:返回原 Payment 的最新状态,不产生第二次执行
{
  "id": "pay_demo_001",
  "merchant_order_no": "ORDER-DEMO-001",
  "environment": "test",
  "amount": 10000,
  "currency": "USD",
  "status": "succeeded",
  "resolution_status": "known",
  "captured_amount": 10000,
  "refunded_amount": 0,
  "refund_returned_amount": 0,
  "refund_reserved_amount": 0,
  "refund_status": "none",
  "authentication_status": "authenticated",
  "reconciliation_status": "pending",
  "upstream_receipt_status": "not_received",
  "latest_attempt_id": "pat_demo_001",
  "attempt_count": 1,
  "version": 4,
  "next_action": null,
  "failure": null,
  "description": "示例订单",
  "customer_reference": "CUSTOMER-DEMO-001",
  "metadata": {
    "business_order_type": "one_time_purchase"
  },
  "card": {
    "brand": "visa",
    "last4": "1234"
  },
  "created_at": "2026-09-23T09:00:00Z",
  "succeeded_at": "2026-09-23T09:04:30Z",
  "expires_at": "2026-09-23T09:30:00Z",
  "request_id": "req_demo_002"
}

响应字段

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

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

平台支付号。

示例:pay_demo_001

merchant_order_no
string必填

商户订单号,按原值区分大小写。

示例:ORDER-DEMO-001

environment
string必填

环境:test 为测试,live 为生产。测试与生产对象相互隔离。

  • test
  • live
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:test

amount
integer(int64)必填

订单金额,最小货币单位。首次提交上游后不可修改。

约束:≥ 1

示例:10000

currency
string必填

大写三字母币种代码。

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

示例:USD

status
string必填

Payment 状态。客户端不得把未知状态当作成功。

  • created:订单已建立,尚未提交有效扣款尝试;有效期内允许新尝试
  • processing:已提交,正在处理或结果尚未确认;不允许新尝试
  • requires_action:当前尝试需要付款人完成认证等动作;不允许新尝试
  • failed:最近一次尝试已明确失败;不是终态,满足期限、次数与风控条件时可显式重试
  • succeeded:已确认支付成功
  • canceled:已确认安全取消
  • expired:没有未解决的尝试且订单已到期关闭
  • created:订单已建立,尚未提交有效扣款尝试;有效期内允许新尝试
  • processing:已提交,正在处理或结果尚未确认;不允许新尝试
  • requires_action:当前尝试需要付款人完成认证等动作;不允许新尝试
  • failed:最近一次尝试已明确失败;不是终态,满足期限、次数与风控条件时可显式重试
  • succeeded:已确认支付成功
  • canceled:已确认安全取消
  • expired:没有未解决的尝试且订单已到期关闭
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:requires_action

resolution_status
string必填

结果确认程度。

  • known:结果已确认
  • needs_query:结果未知,平台正在用原标识向上游查证
  • manual_review:超过自动查询窗口,转人工跟进;不会自动判失败
  • known:结果已确认
  • needs_query:结果未知,平台正在用原标识向上游查证
  • manual_review:超过自动查询窗口,转人工跟进;不会自动判失败
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:known

captured_amount
integer(int64)必填

已确认扣款金额;成功时等于 amount。

约束:≥ 0

示例:0

refunded_amount
integer(int64)必填

已确认的有效退款本金,即成功退款累计减去已确认的退款退回;不含处理中的退款,也不含平台异常退款。

约束:≥ 0

示例:0

refund_returned_amount
integer(int64)必填

已确认退回的退款本金累计。

约束:≥ 0

示例:0

refund_reserved_amount
integer(int64)必填

审核中及处理中退款的本金占用。

约束:≥ 0

示例:0

refund_status
string必填

按有效退款本金 refunded_amount 派生的退款汇总状态:none、partial、full。

  • none
  • partial
  • full
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:none

authentication_status
string可为空必填

当前尝试的 3DS 认证状态,取认证会话状态:not_required、pending、challenge、authenticated、failed、abandoned、expired,须容忍新增取值。 认证成功(authenticated)不等于扣款成功,不要据此判断支付结果。尚无尝试或未进入认证时为 null。

示例:challenge

reconciliation_status
ReconciliationStatus必填

平台资金处理进度,仅供对账参考,不代表支付是否成功,也不代表何时打款。

  • pending
  • matched
  • difference
  • resolved
  • 将来可能新增取值;不认识的状态不要当作成功。
upstream_receipt_status
UpstreamReceiptStatus必填

平台资金处理进度,仅供对账参考,不代表支付是否成功,也不代表何时打款。

  • not_received
  • partially_received
  • received
  • reversed
  • 将来可能新增取值;不认识的状态不要当作成功。
latest_attempt_id
string可为空必填

最近一次支付尝试号;尚未提交尝试时为 null。

示例:pat_demo_001

attempt_count
integer(int32)必填

已发起的尝试次数;默认最多 3 次。

约束:≥ 0

示例:1

version
integer(int64)必填

对象版本,每次有效业务变更递增。比较版本来丢弃旧事件,不要按状态名排序。

约束:≥ 1

示例:2

next_action
NextAction可为空必填

status=requires_action 时需要付款人完成的动作,其他情况为 null。

type
string必填

首期公共 API 只开放 redirect_to_url。客户端须容忍未来新增的类型。

  • redirect_to_url
  • 将来可能新增取值;不认识的状态不要当作成功。

示例:redirect_to_url

authentication_session_id
string必填

认证会话号,关联具体的支付尝试。

示例:auth_demo_001

url
string(uri)必填

平台认证承载页地址。

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

expires_at
string(date-time)必填

认证访问的失效时间(最长 10 分钟)。

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

failure
PaymentFailure可为空必填

latest_attempt_id 所指尝试明确失败时的原因,否则为 null。

code
string必填

失败原因码。

示例:card_declined

message
string必填

脱敏说明。

示例:发卡行拒绝了该交易。

attempt_id
string必填

失败的支付尝试号。

示例:pat_demo_001

description
string否

订单摘要。

约束:最长 256

示例:示例订单

customer_reference
string否

商户侧客户标识。

约束:最长 128

示例:CUSTOMER-DEMO-001

metadata
object否

商户自定义键值,最多 20 个键;键最长 40 字符,值为最长 200 字符的字符串。禁止放入卡号等敏感数据,平台会做检查并拒绝。

约束:最多 20 个键值最长 200

示例:{"business_order_type":"one_time_purchase"}

card
CardSummary可为空必填

最近一次尝试所用卡的脱敏信息;尚无卡信息时为 null。

brand
string必填

卡品牌。

示例:visa

last4
string必填

卡号后四位。

约束:格式 ^[0-9]{4}$

示例:1234

created_at
string(date-time)必填

创建时间。

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

succeeded_at
string(date-time)可为空必填

确认支付成功的时间;未成功时为 null。

示例:null

expires_at
string(date-time)必填

可发起新尝试的截止时间,创建时确定(默认创建后 30 分钟,平台可在 5–120 分钟之间调整,以本字段为准)。到期只关闭新的付款入口,不否定已提交的支付。

示例:2026-09-23T09:30: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商户被暂停或关闭;已受理业务的回调、查询、通知不受影响联系平台运营
409idempotency_conflict复用了键但金额、币种、订单号等不同属于集成缺陷:检查幂等键生成逻辑;不要改参数后重放原键;新操作使用新键
409operation_in_progress并发发送了同键请求稍后用同一个键重试,或查询 related_resource_id;不要换键
409payment_in_progress在途(processing / requires_action)时再次 confirm,或用新键对同一订单重复提交查询 related_resource_id 指向的 Payment,按其状态继续(引导付款人完成认证或等待结果);不要新建订单
409order_no_conflict换幂等键但商户订单号相同查询 related_resource_id;确需再次收款且原支付已关闭时使用新订单号
422currency_not_supported商户配置与上游能力的交集不含该币种改用已启用币种或联系平台运营
422amount_out_of_range低于最低 / 高于最高单笔金额,或超过日累计限额;错误中不回传具体阈值调整金额或联系平台
422card_brand_not_supported商户配置与上游能力的交集不含该品牌提示付款人换卡
422fee_exceeds_amount金额过小,按费率计算的手续费超过金额提高金额或联系平台调整配置
422payment_method_unusablepayment_method_id 不属于当前环境、上游账户或本商户重新获取支付凭据
422url_not_allowedreturn_url / cancel_url 不匹配已登记的地址规则在 商户后台回跳地址页面 登记后重新提交
422risk_rejected命中风险名单等基础规则;不说明具体规则与阈值不要尝试绕过;有疑问联系平台
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通用上游或平台依赖故障,平台无法确认本次请求是否已生效同上

注意事项

  • (商户, 环境, merchant_order_no) 唯一:换了幂等键但订单号相同,不会创建第二个 Payment(返回已有对象或 409 order_no_conflict)。
  • 订单号按原值区分大小写、不去空格;只允许字母、数字、点、下划线、冒号与横线,非法字符直接拒绝。
  • confirm=false 时不接受卡信息;直接传卡需要平台为你开通“直接传卡”能力,否则返回 403 capability_disabled。
  • 请求中没有、也不接受手续费、可结算金额之类的字段。
  • 金额首次提交上游后不能修改;要改金额,先关闭原支付,再用新订单号重建。
  • description、metadata 不得包含卡号等敏感信息,命中会返回 400 sensitive_data_rejected。

警告

200、201、202 都不代表扣款成功:以 status=succeeded 或经验签的 payment.succeeded 通知为准;202 表示结果未知,不要换键重提。

这页有帮助吗?