开发者文档

SOOBEY · 合作伙伴接入

推荐阅读顺序

01 · 确认场景先确认要对接云端支付 API,还是 POS 终端协议。
02 · 准备接入请联系 Soobey 团队获得对应接入方式的测试参数。
03 · 实现协议按所选方式实现请求、回调和交易状态处理。
04 · 联调上线通过对应模式的验收测试后,再切换到生产环境。
交易结果未明时: 超时、断网或返回 UNKNOWN / PROCESSING,都不能说明付款失败。先查询原订单或完成对账;确认结果前不要再次发起扣款。

对接准备

对接准备

确定接入方式后,请联系Soobey团队获得测试参数。

对接角色建议阅读接口范围
经营服务商 / 系统商 / 商户通用规范 → 云端 API云端支付 API
POS 终端使用方POS 协议云推 / 局域网 / Android AIDL

按接入方式准备

方式所需参数/组件配置资料
Cloud APIapp_id · isv_code · merchant_no · 商户私钥/平台公钥/HTTPS 回调地址Base URL / 签名验签样本
POS Cloud Push初始化并绑定的 POS、终端标识、后台接口凭证后台地址与完整云推报文
POS LANPOS IP · 16789 · 收银机密钥/POS 公钥;查询需后台权限其他币种单位、后台查询凭证
AIDL / SoftPOSAAR · 同机 Android App/POS、包名和 APK SHA-256 白名单currency/metadata/冷启动规则

通用规范

协议、金额与签名

公共报文规则只适用于对应协议。云端 API、POS LAN 与 AIDL 的字段和状态不可混用。

接入方式连接/报文金额与标识
Cloud APIHTTPS POST · UTF-8 · RSA2 · JSONtotal_fee: String · 币种最小单位;merchant_order_no 商户单号,out_trade_no 平台单号
POS LANHTTP POST · RSA2 · JSONtotal_fee: String · 原文为“分”。terminal_trace + terminal_time 为业务键
AIDL / SoftPOSAndroid Binder · ParcelableamountMinor: Long · 区域币种最小单位;sessionId 为会话标识

云端公共请求参数

参数名称类型长度必填是否参与签名说明
req_verString3YY版本号:1.0
app_idString14YY应用appid
terminal_noString10NN终端号
isv_codeString8YN代理商id
sign_typeString32YY支持 RSA2,具体⻅本文签名规约一栏
encrypt_typeString10NO(非空时参与)加密算法,默认false。开发者可对请求参数req_params先做 AES 加密,然后对整个请求报文进行 RSA 签名。
key_signString32YNRSA2签名值
req_timeString32YY发送请求的时间戳(毫秒),示例值:1615187698031,时间戳要求在15分钟内
req_idString32YY请求ID,判断是否重复请求。网关不做强校验,只做日志记录,后续可用于人工运维排查,202101010002011
req_paramsString---YY请求参数的集合,最大长度不限,除公共请求参数外所有请求参数都必须放在这个参数中传递,格式:JSON字符串

云端公共响应参数

参数名称类型长度必填说明
resp_codeString20Y返回码(参照公共错误码)
resp_msgString100Y返回码描述(参照公共错误码)
key_signString32NRSA2签名值 code=10000 或20000 才返回
resp_paramsString---Y返回参数的集合,最大长度不限,除公共请求参数外所有请求参数都必须放在这个参数中传递,格式:JSON字符串

云端请求签名

按原文签名章节:req_ver、app_id、sign_type、req_time、req_id、req_params 参与签名;encrypt_type 非空时加入。按字段名 ASCII 升序排列,以 & 连接 k=v,使用 UTF-8 和商户私钥进行 RSA2 签名。isv_code、terminal_no、key_sign 不参与。

req_params = JSON.stringify(business)
fields = pick(request, ["req_ver", "app_id", "sign_type", "req_time", "req_id", "req_params"])
if (request.encrypt_type is nonempty): fields.encrypt_type = request.encrypt_type
canonical = join(sortKeysAscii(fields).map(key => key + "=" + fields[key]), "&")
key_sign = rsa2SignUtf8(canonical, merchantPrivateKey)
// Preserve req_params exactly. Do not parse/reformat it after signing.

不要把请求编号当作防重复扣款保证

云端原文说明 req_id 不做强校验,主要用于日志;CPM 的 merchant_order_no 也明确不验重。超时或结果未知时保留原交易标识,先查询/对账,不直接重发扣款或退款。

云端支付 API

云端 API:由商户服务端调用

先完成公共签名,再按支付场景选择一个创建接口。订单查询、退款与撤销使用原交易标识,不是再次创建支付。

测试/生产地址及接入参数请联系 Soobey 团队获得。示例不包含真实凭证。

付款码支付(CPM)POST /open/payment/barcodepay

扫描顾客出示的付款码,提交支付请求。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过,dana钱包必传
pay_typeString3Y支付方式:0:未知 自动识别(相关:7.1,7.2)1:dana(印尼)4:微信支付5:支付宝支付6:银联二维码8:mpay钱包(澳门)13:Payme(香港)14:payNow (新加坡)17:GrabPay (新加坡)
merchant_order_noString32Y终端流水号,可填写商户系统的业务订单号(扫呗不做该值的验重,若多次请求使用同一个值,会导致一个单号有多条订单记录)
terminal_timeString14Y终端交易时间,yyyyMMddHHmmss,全局统一时间格式。
total_feeString11Y订单金额,单位分,单位和币种有关,请查询附录
auth_noString128Y授权码,消费者app上的付款码
sub_appidString32N子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888
goods_tagString32N商品标记 示例值:WXG
order_bodyString128N订单描述,显示在订单详情页面
attachString128N附加数据,原样返回
terminal_locationString128N受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间
terminal_ipString16N收银设备端IP(IPV4格式 ,人行侧风控主要依据,请真实填写)
time_expireString11N订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s
currencyString3N交易币种,支持币种⻅附录:7.1交易币种,符合ISO 4217标准的三位字母代码 示例值:HKD
goods_detailString6000N订单包含的商品列表信息,Json数组转String格式。
└goods_idString32Y商品编号
└goods_nameString128Y商品名称
└quantityString11Y商品数量,需为整数,不要带小数点
└priceString11Y商品单价,单位为分,单位和币种有关,请查询附录
notify_urlString256N外部系统通知地址
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_stateString10N业务结果:“PAYSUCCESS” 支付成功,“PAYERROR”支付失败,“USERPAYING”支付中
state_msgString128N业务结果描述
pay_typeString3N支付方式:1:dana(印尼)2:QRIS (印尼国家码)4:微信支付5:支付宝支付6:银联二维码13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)16:Dash (新加坡)17:GrabPay (新加坡)19:liquidpay (泰国)
total_feeString12N金额,单位分
merchant_receipt_feeString12N商家应结算金额,单位分,单位和币种有关,请查询附录
buyer_pay_feeString12N买家实付金额(分),单位和币种有关,请查询附录
platform_discount_feeString12N平台优惠金额(分),单位和币种有关,请查询附录
merchant_discount_feeString12N商家优惠金额(分),单位和币种有关,请查询附录
end_timeString14N支付完成时间,yyyyMMddHHmmss,全局统一时间格式
merchant_order_noString32Y外部流水号,填写商户系统的支付订单号,需要保持唯一性
out_trade_noString32N平台唯一订单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
该接口不按 merchant_order_no 验重。超时或结果未知时,先查询订单,不要直接重复扣款。
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_order_no\":\"ORDER-001\",\"pay_type\":\"5\",\"total_fee\":\"1280\",\"terminal_time\":\"20261009120000\",\"auth_no\":\"TEST_PAYMENT_CODE\",\"currency\":\"HKD\",\"notify_url\":\"https://merchant.example/notify\",\"time_expire\":\"600\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"order_state\":\"PAYSUCCESS\",\"total_fee\":\"1280\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/barcodepay", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.order_state == "PAYSUCCESS"): markPaidOnce()
else: applyEndpointStatePolicy(result.order_state)

订单码支付(MPM)POST /open/payment/prepay

创建订单后展示 qr_code;顾客扫码完成支付。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pay_typeString3Y支付方式:0:未知2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码8:mpay钱包(澳门)13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)16:Dash(新加坡)17:GrabPay (新加坡)18:FPS(香港)20:VA(越南)21:DuitNow(马来西亚)
wallet_typeString3N钱包类型,1、支付宝app香港版,2 支付宝app内地版,3、微信app香港版,4 微信app内地版
total_feeString11Y订单金额,单位分,单位和币种有关,请查询附录
sub_appidString32N子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888
goods_tagString32N商品标记 示例值:WXG
sub_openidString128O用户在子商户sub_appid下用户唯一标识
order_bodyString128N订单描述,显示在订单详情页面
attachString128N附加数据,原样返回
terminal_locationString128N受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间
terminal_ipString16Y收银机、POS机等设备的公网IP
time_expireString11N订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s
currencyString3N交易币种,支持币种⻅附录:7.1交易币种
goods_detailString6000N订单包含的商品列表信息,Json数组转String格式。
└goods_idString32Y商品编号
└goods_nameString128Y商品名称
└quantityString11Y商品数量,需为整数,不要带小数点
└priceString11Y商品单价,单位为分,单位和币种有关,请查询附录
notify_urlString256N外部系统通知地址
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pre_order_stateString10N业务结果:“SUCCESS” 下单成功,“ERROR”下单失败
pre_state_msgString128N业务结果描述
pay_typeString3N支付方式:2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)21:DuitNow (马来西亚码)
total_feeString12N金额,单位分
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
out_trade_noString32N平台唯一订单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
qr_codeString128N二维码码串,用于生成二维码,展示给用户进行扫码支付 示例值:weixin://wxpay/s/An4baqw
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_order_no\":\"ORDER-001\",\"pay_type\":\"5\",\"total_fee\":\"1280\",\"terminal_ip\":\"192.0.2.10\",\"currency\":\"HKD\",\"notify_url\":\"https://merchant.example/notify\",\"time_expire\":\"600\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"pre_order_state\":\"SUCCESS\",\"qr_code\":\"EXAMPLE_QR_PAYLOAD\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/prepay", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.pre_order_state == "SUCCESS"):
    displayQr(result.qr_code)
    confirmWithQueryOrVerifiedWebhook() // creation/client return is not payment success

公众号支付POST /open/payment/jspay

服务端创建公众号支付订单,前端使用返回参数调用微信 JSAPI。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pay_typeString3Y支付方式:4:微信支付
wallet_typeString3N钱包类型:3:微信app香港版,4:微信app内地版
total_feeString11Y订单金额,单位分,单位和币种有关,请查询附录
sub_appidString32N子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888
goods_tagString32N商品标记 示例值:WXG
sub_openidString128O用户在子商户sub_appid下用户唯一标识
order_bodyString128N订单描述,显示在订单详情页面
attachString128N附加数据,原样返回
terminal_locationString128N受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间
terminal_ipString16Y用户手机端IP(IPV4格式 ,人行侧风控主要依据,请真实填写)
time_expireString11N订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s
currencyString3N交易币种,支持币种⻅附录:7.1交易币种
goods_detailString6000N订单包含的商品列表信息,Json数组转String格式。
└goods_idString32Y商品编号
└goods_nameString128Y商品名称
└quantityString11Y商品数量,需为整数,不要带小数点
└priceString11Y商品单价,单位为分,单位和币种有关,请查询附录
notify_urlString256N外部系统通知地址
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pre_order_stateString10N业务结果:“SUCCESS” 下单成功,“ERROR”下单失败
pre_state_msgString128N业务结果描述
pay_typeString3N支付方式:4:微信支付
total_feeString12N金额,单位分
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
out_trade_noString32N平台唯一订单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
prepay_idString128N支付宝预支付交易会话标识生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时 示例值:wx201410272009395522657a690389285100
appIdString16N微信公众号支付返回字段,公众号id
timeStampString32N微信公众号支付返回字段,时间戳,示例:1414561699,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。
nonceStrString32N微信公众号支付返回字段,随机字符串
package_strString128N微信公众号支付返回字段,订单详情扩展字符串,示例:prepay_id=123456789,统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=
signTypeString32N微信公众号支付返回字段,签名方式,示例:MD5,RSA
paySignString512N微信公众号支付返回字段,签名
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_order_no\":\"ORDER-001\",\"pay_type\":\"4\",\"total_fee\":\"1280\",\"terminal_ip\":\"192.0.2.10\",\"currency\":\"HKD\",\"notify_url\":\"https://merchant.example/notify\",\"time_expire\":\"600\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"pre_order_state\":\"SUCCESS\",\"appId\":\"EXAMPLE_APP\",\"timeStamp\":\"1791518400\",\"nonceStr\":\"EXAMPLE_NONCE\",\"package_str\":\"prepay_id=EXAMPLE\",\"signType\":\"RSA\",\"paySign\": \"EXAMPLE_SIGNATURE\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/jspay", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.pre_order_state == "SUCCESS"):
    invokeWalletClientPayment(result)
    confirmWithQueryOrVerifiedWebhook() // creation/client return is not payment success

小程序支付POST /open/payment/minipay

服务端创建订单,由对应钱包小程序调用客户端支付接口。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pay_typeString3Y支付方式:4:微信支付(香港、澳门)5:支付宝支付8:mpay钱包(澳门)
wallet_typeString3N钱包类型1:支付宝app香港版,2:支付宝app内地版,3:微信app香港版,4:微信app内地版
total_feeString11Y订单金额,单位分,单位和币种有关,请查询附录
sub_appidString32N子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888
goods_tagString32N商品标记 示例值:WXG
sub_openid(不支持)String128O用户在子商户sub_appid下用户唯一标识
openidString128Yopenid
order_bodyString128N订单描述,显示在订单详情页面
attachString128N附加数据,原样返回
terminal_locationString128N受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间
terminal_ipString16Y用户手机端IP(IPV4格式 ,人行侧风控主要依据,请真实填写)
time_expireString11N订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s
currencyString3N交易币种,支持币种⻅附录:7.1交易币种
goods_detailString6000N订单包含的商品列表信息,Json数组转String格式。
└goods_idString32Y商品编号
└goods_nameString128Y商品名称
└quantityString11Y商品数量,需为整数,不要带小数点
└priceString11Y商品单价,单位为分,单位和币种有关,请查询附录
notify_urlString256N外部系统通知地址
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pre_order_stateString10N业务结果:“SUCCESS” 下单成功,“ERROR”下单失败
pre_state_msgString128N业务结果描述
pay_typeString3N支付方式:4:微信支付(香港、澳门)5:支付宝支付
total_feeString12N金额,单位分
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
out_trade_noString32N平台唯一订单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
prepay_idString128N支付宝预支付交易会话标识生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时 示例值:wx201410272009395522657a690389285100(与参数prepay_url同时只会有一个有值)
prepay_urlString128N支付宝预支付响应跳转链接,例如:https://render.alipay.com/p/w/ac-fe-adaptor/?ACCodeValue=https%3A%2F%2Fglobal.alipay.com%2F2810020400931K6t7Q46a2tDdr2r7qU3zyKq(与参数prepay_id同时只会有一个有值)
appIdString16N微信小程序支付返回字段,公众号id
timeStampString32N微信小程序支付返回字段,时间戳,示例:1414561699,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。
nonceStrString32N微信小程序支付返回字段,随机字符串
package_strString128N微信小程序支付返回字段,订单详情扩展字符串,示例:prepay_id=123456789,统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=
signTypeString32N微信小程序支付返回字段,签名方式,示例:MD5,RSA
paySignString512N微信小程序支付返回字段,签名
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_order_no\":\"ORDER-001\",\"pay_type\":\"4\",\"total_fee\":\"1280\",\"terminal_ip\":\"192.0.2.10\",\"openid\": \"YOUR_OPENID\",\"currency\":\"HKD\",\"notify_url\":\"https://merchant.example/notify\",\"time_expire\":\"600\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"pre_order_state\":\"SUCCESS\",\"appId\":\"EXAMPLE_APP\",\"timeStamp\":\"1791518400\",\"nonceStr\":\"EXAMPLE_NONCE\",\"package_str\":\"prepay_id=EXAMPLE\",\"signType\":\"RSA\",\"paySign\": \"EXAMPLE_SIGNATURE\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/minipay", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.pre_order_state == "SUCCESS"):
    invokeWalletClientPayment(result)
    confirmWithQueryOrVerifiedWebhook() // creation/client return is not payment success

移动网页支付(WAP)POST /open/payment/wappay

创建订单并跳转 pay_url;回跳后仍需查询或处理通知。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pay_typeString3Y支付方式:WAP支付方式logo.zip3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)13:Payme(香港)18:FPS(香港)
wallet_typeString3N钱包类型:当pay_type:5 支付宝支付1:支付宝香港2:支付宝内地当pay_type:4 微信支付3:微信app香港版4:微信app内地版当pay_type:3 银行卡5: VISA6: Master
total_feeString11Y订单金额,单位分,单位和币种有关,请查询附录
sub_appidString32N子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888
goods_tagString32N商品标记 示例值:WXG
sub_openidString128O用户在子商户sub_appid下用户唯一标识
order_bodyString128N订单描述,显示在订单详情页面
attachString128N附加数据,原样返回
terminal_ipString16Y用户手机端IP(IPV4格式)
time_expireString11N订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s
currencyString3N交易币种,支持币种⻅附录:7.1交易币种
goods_detailString6000N订单包含的商品列表信息,Json数组转String格式。
└goods_idString32Y商品编号
└goods_nameString128Y商品名称
└quantityString11Y商品数量,需为整数,不要带小数点
└priceString11Y商品单价,单位为分,单位和币种有关,请查询附录
notify_urlString256N外部系统通知地址
return_urlString256N支付完成后的返回地址
refer_urlString256N商户经营网址
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
pre_order_stateString10N业务结果:“SUCCESS” 下单成功,“ERROR”下单失败
pre_state_msgString128N业务结果描述
pay_typeString3N支付方式:4:微信支付
total_feeString12N金额,单位分
merchant_order_noString32Y商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252
out_trade_noString32N平台唯一订单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
pay_urlString256Y支付跳转链接
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_order_no\":\"ORDER-001\",\"pay_type\":\"5\",\"total_fee\":\"1280\",\"terminal_ip\":\"192.0.2.10\",\"currency\":\"HKD\",\"notify_url\":\"https://merchant.example/notify\",\"time_expire\":\"600\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"pre_order_state\":\"SUCCESS\",\"pay_url\":\"https://example.invalid/payment\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/wappay", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.pre_order_state == "SUCCESS"):
    redirectCustomer(result.pay_url)
    confirmWithQueryOrVerifiedWebhook() // creation/client return is not payment success

订单查询POST /open/payment/query

通过平台订单号或商户订单号查询支付或退款结果。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
out_trade_noString32O平台交易(退款)单号,和merchant_order_no二选一
merchant_order_noString32O商户系统内部的单号,和out_trade_no二选一
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_stateString10N业务结果:“PAYSUCCESS” 支付成功,“PAYERROR”支付失败,“USERPAYING”支付中, “NOTPAY”未支付 “REFUNDSUCCESS”退款成功,“REFUNDING”退款中,“CANCELSUCCESS”撤销成功,“CANCELERROR”撤销失败
state_msgString128N业务结果描述
pay_typeString3N支付方式:1:dana钱包 2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)9:shopee钱包(泰國)10:Boost钱包(马来西亚)11:Grbpay钱包(马来西亚)12:Touch'n Go eWallet钱包(马来西亚)13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)16:Dash (新加坡)17:GrabPay (新加坡)18:FPS(香港)19:liquidpay (泰国)
wallet_typeString3N钱包类型,1、支付宝app香港版,2 支付宝app内地版,3、微信app香港版,4 微信app内地版
total_feeString12N金额,单位分
refund_feeString12N退款金额,单位分
merchant_receipt_feeString12N商家应结算金额,单位分,单位和币种有关,请查询附录,order_state="PAYSUCCESS"时返回
buyer_pay_feeString12N买家实付金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
platform_discount_feeString12N平台优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
merchant_discount_feeString12N商家优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
refund_receipt_feeString12N商家应结算退款金额,单位分,order_state="REFUNDSUCCESS"时返回
refund_buyer_pay_feeString12N买家实付退款金额(分),order_state="REFUNDSUCCESS"时返回
refund_platform_discount_feeString12N平台优惠退款金额(分),order_state="REFUNDSUCCESS"时返回
refund_merchant_discount_feeString12N商家优惠退款金额(分),order_state="REFUNDSUCCESS"时返回
end_timeString14N支付(退款)完成时间,yyyyMMddHHmmss,全局统一时间格式
merchant_order_noString32Y支付(退款)商户系统内部单号
out_refund_noString32N平台唯一退款单号
out_trade_noString32N平台唯一交易订单号
channel_trade_noString32N支付(退款)通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N支付(退款)银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N支付(退款)附加数据,原样返回
order_bodyString128N支付(退款)订单标题描述
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"out_trade_no\":\"ORIGINAL_PLATFORM_ORDER\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"order_state\":\"PAYSUCCESS\",\"total_fee\":\"1280\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/query", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.order_state == "PAYSUCCESS"): markPaidOnce()
else: applyEndpointStatePolicy(result.order_state)

支付退款请求POST /open/payment/refund

按原支付订单发起退款,保存返回的 out_refund_no。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
out_trade_noString32O平台交易单号,和merchant_order_no二选一
merchant_order_noString32O商户系统内部的单号,和out_trade_no二选一
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
refund_feeString12Y退款金额,单位分
order_bodyString128N退款原因备注
attachString128N附加数据,原样返回
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_stateString10N业务结果:“REFUNDSUCCESS”退款成功,“REFUNDERROR”退款失败,“REFUNDING”退款中
state_msgString128N业务结果描述
pay_typeString3N支付方式:1:dana钱包 2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)9:shopee钱包(泰國)10:Boost钱包(马来西亚)11:Grbpay钱包(马来西亚)12:Touch'n Go eWallet钱包(马来西亚)13:Payme(香港)14:payNow (新加坡)16:Dash (新加坡)17:GrabPay (新加坡)18:FPS(香港)19:liquidpay (泰国)
total_feeString12N金额,单位分
refund_feeString12N金额,单位分
end_timeString14N支付完成时间,yyyyMMddHHmmss,全局统一时间格式
merchant_order_noString32Y商户系统内部单号
out_trade_noString32N平台唯一订单号
out_refund_noString32N平台唯一退款单号
channel_trade_noString32N通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N附加数据,原样返回
order_bodyString128N退款原因备注
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"out_trade_no\":\"ORIGINAL_PLATFORM_ORDER\",\"refund_fee\":\"1280\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"order_state\":\"REFUNDSUCCESS\",\"refund_fee\":\"1280\",\"out_refund_no\":\"EXAMPLE-REFUND\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/refund", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.order_state == "REFUNDSUCCESS"): recordRefundOnce(result.out_refund_no)
else: keepRefundPendingUntilConfirmed() // do not blindly resubmit refund

支付撤销请求POST /open/payment/cancel

仅针对未支付订单;已支付订单使用退款。

来源:境外支付API 文档 · 对应接口请求/响应字段表。Y 必填;N 可选;O 条件必填。

业务请求字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
out_trade_noString32O平台交易单号,和merchant_order_no二选一
merchant_order_noString32O商户系统内部的单号,和out_trade_no二选一
merchant_noString15Y平台商户号
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_bodyString128N撤销原因备注
attachString128N附加数据,原样返回
业务响应字段 · resp_params
参数名称类型长度必填说明
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_stateString10N业务结果:“CANCELSUCCESS”撤销成功,“CANCELERROR”撤销失败
state_msgString128N业务结果描述
pay_typeString3N支付方式:1:dana钱包 2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)9:shopee钱包(泰國)10:Boost钱包(马来西亚)11:Grbpay钱包(马来西亚)12:Touch'n Go eWallet钱包(马来西亚)13:Payme(香港)14:payNow (新加坡)16:Dash (新加坡)17:GrabPay (新加坡)18:FPS(香港)19:liquidpay (泰国)
merchant_order_noString32Y商户系统内部单号
out_trade_noString32N平台唯一订单号
attachString128N附加数据,原样返回
order_bodyString128N订单标题描述
完整报文结构与伪代码

结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 HKD 12.80;响应为按字段表构造的示例,不是实测返回。

请求示例

{
  "req_ver": "1.0",
  "app_id": "YOUR_APP_ID",
  "isv_code": "YOUR_ISV",
  "sign_type": "RSA2",
  "req_time": "CURRENT_EPOCH_MS",
  "req_id": "UNIQUE_REQUEST_ID",
  "req_params": "{\"pay_ver\":\"100\",\"merchant_no\": \"YOUR_MERCHANT\",\"out_trade_no\":\"ORIGINAL_PLATFORM_ORDER\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

响应示例

{
  "resp_code": "10000",
  "resp_msg": "Example only",
  "resp_params": "{\"merchant_no\": \"YOUR_MERCHANT\",\"merchant_name\":\"Example merchant\",\"merchant_order_no\":\"ORDER-001\",\"out_trade_no\":\"EXAMPLE-PLATFORM-ORDER\",\"order_state\":\"CANCELSUCCESS\"}",
  "key_sign": "EXAMPLE_SIGNATURE"
}

处理伪代码

business = buildBusinessParams() // use this endpoint's field table
payload = JSON.stringify(business) // serialize once; preserve the exact string
request = buildEnvelope(payload, currentEpochMs(), newRequestId())
request.key_sign = signRsa2(canonicalRequestFields(request), merchantPrivateKey)
response = POST(baseUrl + "/open/payment/cancel", request)
if (networkError || signatureError): keepPendingAndQueryOriginalOrder()
else:
    verifySignedCloudResponse(response)
    if (response.resp_code != "10000"): handleEnvelopeErrorWithoutAssumingPaymentFailed()
    else: result = JSON.parse(response.resp_params)
if (result.order_state == "CANCELSUCCESS"): recordCancellation()
else: queryOriginalOrderBeforeAnyNewPayment()

按支付场景接入

创建订单成功、浏览器回跳和客户端支付回调均不能单独作为服务端入账依据。字段及状态以对应接口为准。

POS 终端协议 · 3.0

POS 终端协议:三种模式,分别对接

先看你的业务系统在哪里运行、由谁展示支付界面,再选择接入模式。云推、局域网和 AIDL 的连接方式不同,各自对应一套接口和处理流程。

模式适用场景通信方式内容入口
Cloud Push业务系统后台远程推送收款 / 退款任务到 POSHTTPS API云推模式
局域网收银收银机与 POS 同一局域网;POS 展示支付 UI 并同步返回结果HTTP + RSA2 · 16789局域网收银
SDK / AIDL(计划中)调用应用与 Soobey POS 安装在同一台 Android 设备Android Binder · AIDLSDK / SoftPOS

云端推送

云推模式:服务端远程触发 POS

商户后台创建订单后,通过平台接口把收款任务发送到指定 POS 或已绑定的终端。支付结果再用查询接口确认;退款也以任务形式发送到 POS。

接口清单

open/order/sendPrePay推送预支付 / 打开 POS 收款页
open/order/query按 out_trade_no 或 terminal_trace + terminal_time 查单
open/order/sendPush推送退款任务

联调时请测试

测试指定终端和绑定终端(send_mode=1 / 2)、预支付有效期(大于 120 且不超过 300 秒)、缺少 terminal_trace / total_fee 的报文、两种查单方式,以及处理中状态 pay_status_code=3。退款则覆盖全额、部分和银行卡退款。

查看 POS 验收流程 →
// Pseudocode — sign the request using the Cloud API common spec
order = {
  send_mode: 1,                 // 1: target terminal; 2: bound terminal
  to_terminal_no: "POS-001",
  terminal_trace: "T202610060001",
  total_fee: "1280",
  expiration_time: "180"
}
pushResult = await POST("open/order/sendPrePay", sign(order))
if pushResult.accepted:
    status = await queryByOutTradeNo(pushResult.out_trade_no)
    if status.pay_status_code == "3":
        reconcileOriginalOrder() // do not create another charge
Cloud Push 和 POS LAN 的部分字段名称相似,但接口地址、报文封装和响应规则不同。请按所选模式调用对应接口,不要交叉使用。

局域网收银

局域网收银:收银机直连 POS

收银机和 POS 接入同一局域网后,收银机可直接调用 POS。支付或退款界面由 POS 展示,收银机等待同步响应;如果网络中断或 POS 没有响应,先查原订单,不要马上重试扣款。

支付地址http://{POS_IP}:16789/open/order/sendPrePay

报文与时间约束

  • POST · JSON · Content-Length 必填 · 请求体最大 16 KB
  • req_ver 可选,值 110;有值时参与签名
  • app_id · sign_type=RSA2 · req_params · key_sign
  • req_time 必填;毫秒时间戳,有效窗口 15 分钟
  • req_id 每次请求唯一;重试要生成新值并重新签名
  • encrypt_type 不支持,不要携带
  • total_fee 正整数;原文单位为“分”
  • expiration_time 60–180 秒;POS 接收后开始计时

密钥、幂等键与状态

收银机用收银机私钥签请求,POS 用收银机公钥验请求;POS 用 POS 私钥签成功响应的 resp_params 原文,收银机用 POS 公钥验响应。公钥 X.509/SPKI Base64;私钥 PKCS#8 Base64;不带 PEM 头尾或换行。

terminal_trace + terminal_time 标识业务订单;同单保持不变。req_id 仅防重放,每次 HTTP 请求都重新生成。

1 PAID2 FAILED3 PROCESSING / UNKNOWN4 CANCELED

PROCESSING / UNKNOWN 必须先查原订单;只有确认终态失败后才能按新业务意图重试。

核心业务字段

字段规则含义
pay_typeEDC / SCAN / OCTOPUS可选支付方式提示
terminal_trace≤32 alphanumeric收银机流水号;与 terminal_time 共同识别订单
terminal_timeyyyy-MM-dd HH:mm:ss / yyyyMMddHHmmss收银机交易时间
total_feestring · positive integer原文金额单位为“分”;不得传小数
order_body≤128订单描述,可选
attach≤128附加信息;同步响应回显,查询不返回

响应字段与验签

字段用途 / 规则
resp_code / resp_msg外层处理结果;成功受理为 10000
key_sign成功响应对原始 resp_params 的 RSA2 签名
pay_status_code1 成功 / 2 明确失败 / 3 处理中或未知 / 4 已撤销
terminal_trace / terminal_time / total_fee验签后必须与原请求核对
out_trade_no / channel_order_no / channel_trade_no成功时可能返回;订单详情以 4.1.2 查询为准
duplicate同幂等键、同业务参数重放时标识是否命中原订单
收银机必须先判 HTTP,再判 resp_code;仅成功且有 resp_params 的响应需验 key_sign。验签原文是 resp_params 原始字符串,不含外层;无 resp_params 的错误响应不签名。POS 同步等待最长 180 秒,客户端 HTTP 读超时须大于 180 秒(建议至少 210 秒)。
结果恢复: 断网、读超时、验签失败或状态码 3 时,按原 terminal_trace + terminal_time 调用状态查询接口。文档建议最多 15 次、每 5 秒一次;耗尽仍未知时转人工 / 对账。相同业务键+相同字段重放不重复下单,duplicate=true;同键不同字段返回 20002。明确失败状态 2 / 4 后如需新支付,更新 terminal_time 或 terminal_trace。结果未确认前不要新建支付单。
// Pseudocode — keep the business idempotency key; refresh req_id per HTTP attempt
businessKey = terminalTrace + "|" + terminalTime
result = await sendSignedPosRequest({
  req_id: newUniqueRequestId(),
  req_params: { terminal_trace: terminalTrace, terminal_time: terminalTime, total_fee: amountMinor }
})
if (result.pay_status_code == "3" || responseWasLost):
    result = await queryOriginalOrder(terminalTrace, terminalTime)
if (result.pay_status_code == "1"): markPaid()
else if (result.pay_status_code == "2" || result.pay_status_code == "4"): markFinal(result)
else: keepPendingAndReconcile(businessKey) // never charge again while unknown

SDK / Android AIDL · SoftPOS

SDK / AIDL:同机应用调用 POS 服务(计划中)

如果你的业务应用和 Soobey POS 安装在同一台 Android 终端,就可以通过 AIDL 调用 POS 服务。支付界面和扫码由 POS 负责;这条接入方式不调用云端 HTTPS API。

集成组件

AAR: soobey-pos-external-contract-1.0.0.aar

POS 和外部 App 必须使用同一版本的 AAR。请勿自行重新定义同名 AIDL 接口。

Service: IPosPaymentService · Callback: IPosPaymentCallback

绑定时使用 Service action com.soobey.pos.external.action.PAYMENT_SERVICE 和 package com.soobey.pos。Android 11 及以上版本请显式指定 package。

POS 会检查 Binder 调用方 UID、包名和 APK SHA-256 是否在初始化时下发的白名单中。未授权调用不会创建会话,也不会返回内部订单号。

协议与金额

AIDL 传递 Parcelable 对象,不是 JSON。createPayment 只同步返回是否受理或具体受理错误,不会等待支付完成;后续状态通过 oneway callback 通知,回调丢失时可调用 queryPayment 查询。

金额使用 Long 型最小单位整数,不要传 Double、Float 或字符串。

Service 方法

方法作用关键语义
getReadiness()查询 POS 就绪状态不创建会话;仅 READY 可发起支付
createPayment(request, callback)创建支付会话返回 accepted / sessionId 或受理错误,不代表扣款结果
queryPayment(sessionId)查询会话快照回调丢失、进程重启或 UNKNOWN 时补偿查询
cancelPayment(sessionId)请求取消会话已进入扣款时不保证取消;最终状态为准
onStateChanged(snapshot)异步状态通知oneway · 可能重复投递 · 幂等处理

请求与返回对象

ExternalPaymentRequest

apiVersionint · 必填 · 当前为 1
clientRequestIdUUID · 同一调用方 24 小时会话幂等
merchantOrderNoString · 必填 · 后台检查订单归属与未支付状态
amountMinorlong · 最小单位正整数
methodCARD / SCAN_QR / PRESENT_QR / OCTOPUS
metadataBundle · 可选 · 仅允许白名单展示字段

禁止传银行卡数据、密钥、付款码、内部流水号或后端签名;扫码付款码只能在 POS 自有扫码 UI 采集。

受理 / 快照返回

ExternalPaymentAcceptedsessionId · accepted · errorCode · errorMessage
ExternalPaymentSnapshotsessionId · clientRequestId · merchantOrderNo · status · message · updatedAt
internalOutTradeNo仅支付成功终态返回
uiPendingIntent状态 WAITING_FOR_UI 时返回,由外部 App 前台发送以拉起 POS 支付页
ExternalReadinessstate · supportedMethods · reason
接入前请确认字段差异: POS 3.0 主文档包含 currency,AIDL 初版则增加了 metadata、未列出 currency,并说明 amountMinor 使用 Long 最小单位。请在开发前与 Soobey 确认 currency 是否需要单独传入,以及 metadata 可用字段。

状态机与 PendingIntent

ACCEPTED → BOOTSTRAPPING → READY → WAITING_FOR_UI → PROCESSING
                              │          │                 ├→ SUCCESS
                              │          └→ CANCELED       ├→ FAILED
               └→ BOOTSTRAP_FAILED          └→ UNKNOWN

SUCCESS / FAILED / CANCELED / BOOTSTRAP_FAILED = terminal states
UNKNOWN = outcome not confirmed; queryPayment(sessionId), never assume failure

收到 WAITING_FOR_UI 后,请让处于前台的 App 发送一次性 uiPendingIntent,以打开 POS 支付页。Android 10 及以上版本不要从后台 Service 直接调用 startActivity。

// Pseudocode based on the AIDL contract
intent = Intent("com.soobey.pos.external.action.PAYMENT_SERVICE")
intent.setPackage("com.soobey.pos")
bindService(intent)
if (service.getReadiness().state != "READY"): stopAndShowReadinessReason()
accepted = service.createPayment(request, callback)
if (!accepted.accepted): handleAcceptanceError(accepted.errorCode)
else:
    persist(accepted.sessionId)
    onStateChanged(snapshot):
        if (snapshot.status == "WAITING_FOR_UI"): sendFromForeground(snapshot.uiPendingIntent)
        if (snapshot.status == "UNKNOWN"): queryPayment(snapshot.sessionId)
        if (snapshot.status in ["SUCCESS", "FAILED", "CANCELED", "BOOTSTRAP_FAILED"]): updateOrderIdempotently(snapshot)
// On Binder death / process restart, reconnect and query the stored sessionId.

受理错误码

1001 API 版本不兼容 · 1003 商户订单无效 · 1004 金额错误 · 1006 支付方式不支持 · 1007 clientRequestId 重复 · 1008 有并发支付 · 1009 拒绝敏感字段 · 1010 Service 不可用 · 1011 初始化失败。

收到 1007 时,请用原 sessionId 查询;如果状态还是 UNKNOWN,不要重新创建支付。

查询与取消

如果状态是 UNKNOWN 或没有收到回调,先调用 queryPayment,之后每 5 秒查询一次,最多 15 次。仍无法确认时,等待后续回调或转人工处理,不要重新下单。cancelPayment 只是取消请求,最终结果仍以状态查询为准。

如果客户端进程退出,已受理的交易不会因此取消。POS 会保留会话和最终状态;App 重连后用 sessionId 查询。建议监听 Binder death,并按 sessionId / clientRequestId 做幂等处理。

回调通知

回调通知:服务端确认支付结果

云端支付 API 会把支付和退款结果异步发送到 notify_url。接收后先验签,再按业务标识幂等处理,最后返回应答。

回调外层字段

参数名称类型长度必填说明
req_verString3Y版本号:1.0
app_idString64Y应用appid
sign_typeString32Y支持 RSA2,具体⻅本文签名规约一栏
encrypt_typeString10N加密算法。 默认AES,如果为空,业务参数req_params 不加密。
key_signString32Y签名串
req_timeString32Y发送请求的时间戳(毫秒),示例值:1615187698031,时间戳要求在15分钟内
req_idString32Y请求ID,判断是否重复请求。网关不做强校验,只做日志记录,后续可用于人工运维排查,202101010002011
req_paramsString---Y请求参数的集合,最大长度不限,除公共请求参数外所有请求参数都必须放在这个参数中传递,格式:JSON字符串
回调业务字段 · req_params
参数名称类型长度必填说明
pay_verString3Y接口内业务逻辑兼容版本号,可用值“100”
merchant_noString15Y平台商户号
merchant_nameString40Y商户名称
store_codeString10N店铺编号
device_noString32N商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
order_stateString10N业务结果:“PAYSUCCESS” 支付成功,“REFUNDSUCCESS”退款成功
state_msgString128N业务结果描述
pay_typeString3N支付方式:1:dana钱包 2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)9:shopee钱包(泰国)10:Boost钱包(马来西亚)11:Grbpay钱包(马来西亚)12:Touch'n Go eWallet钱包(马来西亚)13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)16:Dash (新加坡)17:GrabPay (新加坡)18:FPS(香港)19:liquidpay (泰国)
wallet_typeString3N钱包类型1:支付宝app香港版,2:支付宝app内地版,3:微信app香港版,4:微信app内地版
total_feeString12N金额,单位分
refund_feeString12N退款金额,单位分
merchant_receipt_feeString12N商家应结算金额,单位分,单位和币种有关,请查询附录,order_state="PAYSUCCESS"时返回
buyer_pay_feeString12N买家实付金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
platform_discount_feeString12N平台优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
merchant_discount_feeString12N商家优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回
refund_receipt_feeString12N商家应结算退款金额,单位分,order_state="REFUNDSUCCESS"时返回
refund_buyer_pay_feeString12N买家实付退款金额(分),order_state="REFUNDSUCCESS"时返回
refund_platform_discount_feeString12N平台优惠退款金额(分),order_state="REFUNDSUCCESS"时返回
refund_merchant_discount_feeString12N商家优惠退款金额(分),order_state="REFUNDSUCCESS"时返回
end_timeString14N支付(退款)完成时间,yyyyMMddHHmmss,全局统一时间格式
merchant_order_noString32Y支付(退款)商户系统内部单号
out_refund_noString32N平台唯一退款单号
out_trade_noString32N平台唯一交易订单号
channel_trade_noString32N支付(退款)通道订单号,微信订单号、支付宝订单号等
channel_order_noString64N支付(退款)银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配
user_idString32N付款方用户id,“微信openid”、“支付宝账户”
attachString128N支付(退款)附加数据,原样返回
order_bodyString128N支付(退款)订单标题描述
退款不能仅按支付订单号+REFUNDSUCCESS 去重,否则可能遗漏第二笔部分退款。未拿到稳定退款标识时先保存通知,查询/人工确认,不新增退款入账。
事件状态标识后端动作
支付成功order_state=PAYSUCCESS验签、幂等更新订单
退款成功order_state=REFUNDSUCCESS验签、幂等更新退款结果
1 · 接收HTTPS POST · application/json · UTF-8
2 · 验签用平台公钥按公共规则校验 key_sign
3 · 处理如配置 AES,先验签再解密;按支付/退款业务标识幂等更新
4 · 应答5 秒内返回 return_code=01;失败返回 02 触发重试
// Pseudocode: keep envelope fields separate from business fields
envelope = parseJson(rawRequest)
if (!verifyCallback(envelope, platformPublicKey)): return { return_code: "02" }
payload = envelope.req_params // original signed string
if (envelope.encrypt_type == "AES"): payload = decryptWithConfirmedAesConfig(payload)
event = parseJson(payload)
if (!matchesMerchantAndOriginalOrder(event)): persistForReview(); return { return_code: "02" }
if (event.order_state == "REFUNDSUCCESS" && !stableRefundReferenceConfirmed(event)):
    persistForReconciliation(event); return { return_code: "02" }
transaction:
    key = stableBusinessEventKey(event) // payment reference, or confirmed refund reference
    if (!alreadyProcessed(key)):
        applyPaymentOrRefundState(event)
        recordProcessed(key)
return { return_code: "01", return_msg: "success" }
// Complete persistence/processing before ACK; respond within 5 seconds.
查看平台回调重试节奏(首次 + 最多 9 次)

下列时间均相对于首次推送,不是相邻两次的等待间隔。

0s30s1m5m10m30m1h6h12h24h

平台最多发送 10 次(含首次),重试周期最长 24 小时。资料提到 AES/CBC/PKCS5Padding,但没有说明 IV 如何生成和传递;启用加密回调前,请先向 Soobey 确认 IV 规则。

错误码与排查

错误码与排查:按接口族解释

同一个错误码在不同接口里可能代表不同问题。先确认请求走的是哪种接入方式,再按对应表格排查。

云端 API · 系统级错误码

10000 · success20000 · business failure30000 · system error40000 · invalid parameter

POS LAN · resp_code

Code典型含义建议动作
20001上一笔支付尚未结束等待当前交易结束;不要频繁重试
20002同一业务幂等键对应不同参数核对请求;新订单更换业务流水键
20003 / 20004 / 20005订单已存在 / 已过期 / 支付页未就绪按原单查询;修正有效期或稍后重试
30000–30002系统异常或密钥未就绪先查交易状态;联系 POS / 平台运维
40002–40009公共参数、签名、时间、防重放或 JSON 格式错误按具体字段修正;每次请求生成新 req_id 并重签
40010–40016业务字段校验失败检查 attach、金额、流水号、时间、有效期、描述和 notify_url
40090–40097HTTP / 报文层错误:路径、方法、Content-Length、大小、Content-Type、限流核对请求封装;限流时等待约 1 分钟后再试
遇到不确定结果时: 超时、断网或返回 UNKNOWN、PROCESSING、InProgress、NotFound 时,请保留原订单和业务标识,先查询或对账;仍无法确认时再转人工处理。不要立即重试扣款。

通道与市场支持

通道与市场支持

具体商户能使用哪些渠道、币种和钱包,请以商户开通配置为准。

ISO 4217 提供币种代码和标准小数位,但不代表该币种已在 Soobey 开通。接入前请确认商户支持范围,并按对应接口的金额字段说明传值。
查看 ISO 4217 币种代码与小数位(156 种)

表格按代码去重,依据 SIX 当前 List One,仅列币种(不含基金、贵金属、测试及无币种代码)。Minor Unit 是标准小数位:2 表示 1 个主单位可分为 100 个最小单位;0 表示无小数位。金额字段的实际传值方式仍以具体接口说明为准。

代码币种名称(官方英文)小数位(Minor Unit)
AEDUAE Dirham2
AFNAfghani2
ALLLek2
AMDArmenian Dram2
AOAKwanza2
ARSArgentine Peso2
AUDAustralian Dollar2
AWGAruban Florin2
AZNAzerbaijan Manat2
BAMConvertible Mark2
BBDBarbados Dollar2
BDTTaka2
BHDBahraini Dinar3
BIFBurundi Franc0
BMDBermudian Dollar2
BNDBrunei Dollar2
BOBBoliviano2
BRLBrazilian Real2
BSDBahamian Dollar2
BTNNgultrum2
BWPPula2
BYNBelarusian Ruble2
BZDBelize Dollar2
CADCanadian Dollar2
CDFCongolese Franc2
CHFSwiss Franc2
CLFUnidad de Fomento4
CLPChilean Peso0
CNYYuan Renminbi2
COPColombian Peso2
CRCCosta Rican Colon2
CUPCuban Peso2
CVECabo Verde Escudo2
CZKCzech Koruna2
DJFDjibouti Franc0
DKKDanish Krone2
DOPDominican Peso2
DZDAlgerian Dinar2
EGPEgyptian Pound2
ERNNakfa2
ETBEthiopian Birr2
EUREuro2
FJDFiji Dollar2
FKPFalkland Islands Pound2
GBPPound Sterling2
GELLari2
GHSGhana Cedi2
GIPGibraltar Pound2
GMDDalasi2
GNFGuinean Franc0
GTQQuetzal2
GYDGuyana Dollar2
HKDHong Kong Dollar2
HNLLempira2
HTGGourde2
HUFForint2
IDRRupiah2
ILSNew Israeli Sheqel2
INRIndian Rupee2
IQDIraqi Dinar3
IRRIranian Rial2
ISKIceland Krona0
JMDJamaican Dollar2
JODJordanian Dinar3
JPYYen0
KESKenyan Shilling2
KGSSom2
KHRRiel2
KMFComorian Franc0
KPWNorth Korean Won2
KRWWon0
KWDKuwaiti Dinar3
KYDCayman Islands Dollar2
KZTTenge2
LAKLao Kip2
LBPLebanese Pound2
LKRSri Lanka Rupee2
LRDLiberian Dollar2
LSLLoti2
LYDLibyan Dinar3
MADMoroccan Dirham2
MDLMoldovan Leu2
MGAMalagasy Ariary2
MKDDenar2
MMKKyat2
MNTTugrik2
MOPPataca2
MRUOuguiya2
MURMauritius Rupee2
MVRRufiyaa2
MWKMalawi Kwacha2
MXNMexican Peso2
MYRMalaysian Ringgit2
MZNMozambique Metical2
NADNamibia Dollar2
NGNNaira2
NIOCordoba Oro2
NOKNorwegian Krone2
NPRNepalese Rupee2
NZDNew Zealand Dollar2
OMRRial Omani3
PABBalboa2
PENSol2
PGKKina2
PHPPhilippine Peso2
PKRPakistan Rupee2
PLNZloty2
PYGGuarani0
QARQatari Rial2
RONRomanian Leu2
RSDSerbian Dinar2
RUBRussian Ruble2
RWFRwanda Franc0
SARSaudi Riyal2
SBDSolomon Islands Dollar2
SCRSeychelles Rupee2
SDGSudanese Pound2
SEKSwedish Krona2
SGDSingapore Dollar2
SHPSaint Helena Pound2
SLELeone2
SOSSomali Shilling2
SRDSurinam Dollar2
SSPSouth Sudanese Pound2
STNDobra2
SVCEl Salvador Colon2
SYPSyrian Pound2
SZLLilangeni2
THBBaht2
TJSSomoni2
TMTTurkmenistan New Manat2
TNDTunisian Dinar3
TOPPa’anga2
TRYTurkish Lira2
TTDTrinidad and Tobago Dollar2
TWDNew Taiwan Dollar2
TZSTanzanian Shilling2
UAHHryvnia2
UGXUganda Shilling0
USDUS Dollar2
UYUPeso Uruguayo2
UZSUzbekistan Sum2
VEDBolívar Soberano2
VESBolívar Soberano2
VNDDong0
VUVVatu0
WSTTala2
XAFCFA Franc BEAC0
XCDEast Caribbean Dollar2
XCGCaribbean Guilder2
XOFCFA Franc BCEAO0
XPFCFP Franc0
YERYemeni Rial2
ZARRand2
ZMWZambian Kwacha2
ZWGZimbabwe Gold2

联调、验收与上线

联调、验收与上线

按你实际采用的接入方式完成联调和验收。必测项和端到端流程都通过,并经双方确认后,再切换到生产环境。

Cloud API

检查公共参数、RSA2 签名和 Content-Type;跑通五种支付方式、查单、全额 / 部分退款和撤销;验证支付及退款通知的验签与重复通知处理。至少完成 6 个端到端场景;当前清单共 43 项必测项。

POS 3.0 · Cloud Push

测试指定终端和绑定终端推送、180 秒有效期、两种查单方式、退款、更新 req_id 后的幂等重试、断网后查单,以及并发 / Busy 场景。POS 联调清单共 58 项必测项,包含局域网模式。

POS 3.0 · LAN

确认通过端口 16789 发起局域网 HTTP 请求,并测试 Content-Length、16 KB 限制、签名和防重放、支付 / 退款 / 状态查询、响应验签及 UNKNOWN 状态恢复。

切生产前清单

1沙盒验收通过,双方确认结果
2切换生产地址、商户号和密钥 / 证书
3按 Soobey 确认的币种、通道最低金额与方案完成小额真实交易
4观察 1 小时,确认无异常后正式开放
查看验收后监控与日常巡检
告警触发条件级别
成功率下降5 分钟内低于 95%P1
响应超时5 分钟内超时率大于 5%P2
POS 不可达连续 3 次连接失败P1
证书即将过期少于 30 天P3
持续 UNKNOWN同一笔连续 3 次查询 UNKNOWNP2
频率巡检
每日前一日成功率、失败原因与异常交易复核
每周证书有效期、POS 磁盘与内存
每月对账收银机交易与平台后台数据
生产异常与回滚

生产异常时不要把生产订单路由到测试环境。合作方应与 Soobey 确认停止新增交易、保留生产查询/对账能力及处理在途或 UNKNOWN 交易的方案,再执行回滚。

SoftPOS 验收需补充: 现有 POS 验收清单覆盖 Cloud Push 和局域网,没有 AIDL / SoftPOS 专项测试。如果采用 SDK 模式,请在上线前和 Soobey 一起确认连接、授权拒绝、回调丢失、进程重启恢复和幂等处理等测试场景。

关键验收用例

以下按当前接入方式展示关键验收用例。请按对应接口的字段表准备测试报文。

Cloud API · 关键用例
原文用例号测试步骤预期结果
CA-01正确私钥签名并发送请求验签通过;业务响应按接口判断
CA-02 / CA-03错误签名/缺签名拒绝受理
CB-01使用有效测试付款码调用 barcodepayPAYSUCCESS,保存平台订单号
CP-01调用 prepay 创建二维码订单返回二维码;不直接标记已支付
CQ-01 / CQ-04查询成功支付/退款订单返回对应业务状态;核对原交易
CR-01 / CR-02全额/部分退款保存退款标识
CC-01 / CC-02撤销未支付/已支付订单未支付可撤销;已支付走退款
CN-03 / CN-04验签与重复通知验签后幂等处理
POS Cloud Push · 关键用例
原文用例号测试步骤预期结果
CP-01 / CP-02send_mode=1 指定终端;send_mode=2 绑定终端对应 POS 收到收款任务
CQ-01 / CQ-02后台按 out_trade_no 或流水号+时间查询返回原订单状态
CQ-04支付中查询pay_status_code=3
CR-01 / CR-02 / CR-03发送全额、部分及银行卡退款任务POS 确认退款
POS LAN · 关键用例
原文用例号测试步骤预期结果
LK-01 / LK-02使用正确/错误收银机私钥签名10000/40005
LK-04 / LK-05超出 15 分钟时间窗口/窗口内重复 req_id40006/40007
LP-02 / LP-03在途新单/同业务键不同参数20001/20002
LB-01 / LB-02读取超时 210 秒/30 秒210 秒不提前断开;短超时后先查原单
LB-03 / LB-04不携带 encrypt_type;req_ver=110 参与签名按 LAN 签名规范受理
CS-04断网后原业务参数+新 req_id 重试duplicate=true;不重复创建订单
CS-05断网后调用后台兜底查询保留原业务键;未确认前不新建支付

开发者工具 · 静态报文示例

报文与响应示例预览

选择接口和场景,查看对应的请求与响应示例。这里只展示静态报文,不校验参数、不验签,也不会发送请求。

示例报文仅供对照接口结构,不能直接用于真实交易。

响应为所选场景的静态示例,不代表真实交易结果。暂不提供 AIDL/Cloud Push 报文预览。