SOOBEY · 合作伙伴接入
推荐阅读顺序
01 · 确认场景 先确认要对接云端支付 API,还是 POS 终端协议。
02 · 准备接入 请联系 Soobey 团队获得对应接入方式的测试参数。
03 · 实现协议 按所选方式实现请求、回调和交易状态处理。
04 · 联调上线 通过对应模式的验收测试后,再切换到生产环境。
交易结果未明时: 超时、断网或返回 UNKNOWN / PROCESSING,都不能说明付款失败。先查询原订单或完成对账;确认结果前不要再次发起扣款。
对接准备
对接准备
确定接入方式后,请联系Soobey团队获得测试参数。
对接角色 建议阅读 接口范围
经营服务商 / 系统商 / 商户 通用规范 → 云端 API 云端支付 API
POS 终端使用方 POS 协议 云推 / 局域网 / Android AIDL
按接入方式准备 方式 所需参数/组件 配置资料
Cloud API app_id · isv_code · merchant_no · 商户私钥/平台公钥/HTTPS 回调地址 Base URL / 签名验签样本
POS Cloud Push 初始化并绑定的 POS、终端标识、后台接口凭证 后台地址与完整云推报文
POS LAN POS IP · 16789 · 收银机密钥/POS 公钥;查询需后台权限 其他币种单位、后台查询凭证
AIDL / SoftPOS AAR · 同机 Android App/POS、包名和 APK SHA-256 白名单 currency/metadata/冷启动规则
通用规范
协议、金额与签名
公共报文规则只适用于对应协议。云端 API、POS LAN 与 AIDL 的字段和状态不可混用。
接入方式 连接/报文 金额与标识
Cloud API HTTPS POST · UTF-8 · RSA2 · JSON total_fee: String · 币种最小单位;merchant_order_no 商户单号,out_trade_no 平台单号
POS LAN HTTP POST · RSA2 · JSON total_fee: String · 原文为“分”。terminal_trace + terminal_time 为业务键
AIDL / SoftPOS Android Binder · Parcelable amountMinor: Long · 区域币种最小单位;sessionId 为会话标识
云端公共请求参数 参数名称 类型 长度 必填 是否参与签名 说明 req_verString 3 Y Y 版本号:1.0 app_idString 14 Y Y 应用appid terminal_noString 10 N N 终端号 isv_codeString 8 Y N 代理商id sign_typeString 32 Y Y 支持 RSA2,具体⻅本文签名规约一栏 encrypt_typeString 10 N O(非空时参与) 加密算法,默认false。开发者可对请求参数req_params先做 AES 加密,然后对整个请求报文进行 RSA 签名。 key_signString 32 Y N RSA2签名值 req_timeString 32 Y Y 发送请求的时间戳(毫秒),示例值:1615187698031,时间戳要求在15分钟内 req_idString 32 Y Y 请求ID,判断是否重复请求。网关不做强校验,只做日志记录,后续可用于人工运维排查,202101010002011 req_paramsString --- Y Y 请求参数的集合,最大长度不限,除公共请求参数外所有请求参数都必须放在这个参数中传递,格式:JSON字符串
云端公共响应参数 参数名称 类型 长度 必填 说明 resp_codeString 20 Y 返回码(参照公共错误码) resp_msgString 100 Y 返回码描述(参照公共错误码) key_signString 32 N RSA2签名值 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过,dana钱包必传 pay_typeString 3 Y 支付方式:0:未知 自动识别(相关:7.1,7.2)1:dana(印尼)4:微信支付5:支付宝支付6:银联二维码8:mpay钱包(澳门)13:Payme(香港)14:payNow (新加坡)17:GrabPay (新加坡) merchant_order_noString 32 Y 终端流水号,可填写商户系统的业务订单号(扫呗不做该值的验重,若多次请求使用同一个值,会导致一个单号有多条订单记录) terminal_timeString 14 Y 终端交易时间,yyyyMMddHHmmss,全局统一时间格式。 total_feeString 11 Y 订单金额,单位分,单位和币种有关,请查询附录 auth_noString 128 Y 授权码,消费者app上的付款码 sub_appidString 32 N 子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888 goods_tagString 32 N 商品标记 示例值:WXG order_bodyString 128 N 订单描述,显示在订单详情页面 attachString 128 N 附加数据,原样返回 terminal_locationString 128 N 受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间 terminal_ipString 16 N 收银设备端IP(IPV4格式 ,人行侧风控主要依据,请真实填写) time_expireString 11 N 订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s currencyString 3 N 交易币种,支持币种⻅附录:7.1交易币种,符合ISO 4217标准的三位字母代码 示例值:HKD goods_detailString 6000 N 订单包含的商品列表信息,Json数组转String格式。 └goods_idString 32 Y 商品编号 └goods_nameString 128 Y 商品名称 └quantityString 11 Y 商品数量,需为整数,不要带小数点 └priceString 11 Y 商品单价,单位为分,单位和币种有关,请查询附录 notify_urlString 256 N 外部系统通知地址
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_stateString 10 N 业务结果:“PAYSUCCESS” 支付成功,“PAYERROR”支付失败,“USERPAYING”支付中 state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式:1:dana(印尼)2:QRIS (印尼国家码)4:微信支付5:支付宝支付6:银联二维码13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)16:Dash (新加坡)17:GrabPay (新加坡)19:liquidpay (泰国) total_feeString 12 N 金额,单位分 merchant_receipt_feeString 12 N 商家应结算金额,单位分,单位和币种有关,请查询附录 buyer_pay_feeString 12 N 买家实付金额(分),单位和币种有关,请查询附录 platform_discount_feeString 12 N 平台优惠金额(分),单位和币种有关,请查询附录 merchant_discount_feeString 12 N 商家优惠金额(分),单位和币种有关,请查询附录 end_timeString 14 N 支付完成时间,yyyyMMddHHmmss,全局统一时间格式 merchant_order_noString 32 Y 外部流水号,填写商户系统的支付订单号,需要保持唯一性 out_trade_noString 32 N 平台唯一订单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述
该接口不按 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pay_typeString 3 Y 支付方式: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_typeString 3 N 钱包类型,1、支付宝app香港版,2 支付宝app内地版,3、微信app香港版,4 微信app内地版 total_feeString 11 Y 订单金额,单位分,单位和币种有关,请查询附录 sub_appidString 32 N 子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888 goods_tagString 32 N 商品标记 示例值:WXG sub_openidString 128 O 用户在子商户sub_appid下用户唯一标识 order_bodyString 128 N 订单描述,显示在订单详情页面 attachString 128 N 附加数据,原样返回 terminal_locationString 128 N 受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间 terminal_ipString 16 Y 收银机、POS机等设备的公网IP time_expireString 11 N 订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s currencyString 3 N 交易币种,支持币种⻅附录:7.1交易币种 goods_detailString 6000 N 订单包含的商品列表信息,Json数组转String格式。 └goods_idString 32 Y 商品编号 └goods_nameString 128 Y 商品名称 └quantityString 11 Y 商品数量,需为整数,不要带小数点 └priceString 11 Y 商品单价,单位为分,单位和币种有关,请查询附录 notify_urlString 256 N 外部系统通知地址
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pre_order_stateString 10 N 业务结果:“SUCCESS” 下单成功,“ERROR”下单失败 pre_state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式:2:QRIS (印尼国家码)3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通13:Payme(香港)14:payNow (新加坡)15:Thai QR (泰国)21:DuitNow (马来西亚码) total_feeString 12 N 金额,单位分 merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 out_trade_noString 32 N 平台唯一订单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述 qr_codeString 128 N 二维码码串,用于生成二维码,展示给用户进行扫码支付 示例值: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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pay_typeString 3 Y 支付方式:4:微信支付 wallet_typeString 3 N 钱包类型:3:微信app香港版,4:微信app内地版 total_feeString 11 Y 订单金额,单位分,单位和币种有关,请查询附录 sub_appidString 32 N 子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888 goods_tagString 32 N 商品标记 示例值:WXG sub_openidString 128 O 用户在子商户sub_appid下用户唯一标识 order_bodyString 128 N 订单描述,显示在订单详情页面 attachString 128 N 附加数据,原样返回 terminal_locationString 128 N 受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间 terminal_ipString 16 Y 用户手机端IP(IPV4格式 ,人行侧风控主要依据,请真实填写) time_expireString 11 N 订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s currencyString 3 N 交易币种,支持币种⻅附录:7.1交易币种 goods_detailString 6000 N 订单包含的商品列表信息,Json数组转String格式。 └goods_idString 32 Y 商品编号 └goods_nameString 128 Y 商品名称 └quantityString 11 Y 商品数量,需为整数,不要带小数点 └priceString 11 Y 商品单价,单位为分,单位和币种有关,请查询附录 notify_urlString 256 N 外部系统通知地址
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pre_order_stateString 10 N 业务结果:“SUCCESS” 下单成功,“ERROR”下单失败 pre_state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式:4:微信支付 total_feeString 12 N 金额,单位分 merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 out_trade_noString 32 N 平台唯一订单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述 prepay_idString 128 N 支付宝预支付交易会话标识生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时 示例值:wx201410272009395522657a690389285100 appIdString 16 N 微信公众号支付返回字段,公众号id timeStampString 32 N 微信公众号支付返回字段,时间戳,示例:1414561699,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。 nonceStrString 32 N 微信公众号支付返回字段,随机字符串 package_strString 128 N 微信公众号支付返回字段,订单详情扩展字符串,示例:prepay_id=123456789,统一下单接口返回的prepay_id参数值,提交格式如:prepay_id= signTypeString 32 N 微信公众号支付返回字段,签名方式,示例:MD5,RSA paySignString 512 N 微信公众号支付返回字段,签名
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pay_typeString 3 Y 支付方式:4:微信支付(香港、澳门)5:支付宝支付8:mpay钱包(澳门) wallet_typeString 3 N 钱包类型1:支付宝app香港版,2:支付宝app内地版,3:微信app香港版,4:微信app内地版 total_feeString 11 Y 订单金额,单位分,单位和币种有关,请查询附录 sub_appidString 32 N 子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888 goods_tagString 32 N 商品标记 示例值:WXG sub_openid(不支持) String 128 O 用户在子商户sub_appid下用户唯一标识 openidString 128 Y openid order_bodyString 128 N 订单描述,显示在订单详情页面 attachString 128 N 附加数据,原样返回 terminal_locationString 128 N 受理终端设备实时经纬度信息,格式为(纬度/经度):+31.2579921/-120.729388 +表示北纬、东经, -表示南纬、西经。 经度是向东到180°或向西到180° 纬度是0至90度之间 terminal_ipString 16 Y 用户手机端IP(IPV4格式 ,人行侧风控主要依据,请真实填写) time_expireString 11 N 订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s currencyString 3 N 交易币种,支持币种⻅附录:7.1交易币种 goods_detailString 6000 N 订单包含的商品列表信息,Json数组转String格式。 └goods_idString 32 Y 商品编号 └goods_nameString 128 Y 商品名称 └quantityString 11 Y 商品数量,需为整数,不要带小数点 └priceString 11 Y 商品单价,单位为分,单位和币种有关,请查询附录 notify_urlString 256 N 外部系统通知地址
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pre_order_stateString 10 N 业务结果:“SUCCESS” 下单成功,“ERROR”下单失败 pre_state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式:4:微信支付(香港、澳门)5:支付宝支付 total_feeString 12 N 金额,单位分 merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 out_trade_noString 32 N 平台唯一订单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述 prepay_idString 128 N 支付宝预支付交易会话标识生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时 示例值:wx201410272009395522657a690389285100(与参数prepay_url同时只会有一个有值) prepay_urlString 128 N 支付宝预支付响应跳转链接,例如:https://render.alipay.com/p/w/ac-fe-adaptor/?ACCodeValue=https%3A%2F%2Fglobal.alipay.com%2F2810020400931K6t7Q46a2tDdr2r7qU3zyKq(与参数prepay_id同时只会有一个有值) appIdString 16 N 微信小程序支付返回字段,公众号id timeStampString 32 N 微信小程序支付返回字段,时间戳,示例:1414561699,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。 nonceStrString 32 N 微信小程序支付返回字段,随机字符串 package_strString 128 N 微信小程序支付返回字段,订单详情扩展字符串,示例:prepay_id=123456789,统一下单接口返回的prepay_id参数值,提交格式如:prepay_id= signTypeString 32 N 微信小程序支付返回字段,签名方式,示例:MD5,RSA paySignString 512 N 微信小程序支付返回字段,签名
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pay_typeString 3 Y 支付方式:WAP支付方式logo.zip3:银行卡4:微信支付5:支付宝支付6:银联二维码7:八达通8:mpay钱包(澳门)13:Payme(香港)18:FPS(香港) wallet_typeString 3 N 钱包类型:当pay_type:5 支付宝支付1:支付宝香港2:支付宝内地当pay_type:4 微信支付3:微信app香港版4:微信app内地版当pay_type:3 银行卡5: VISA6: Master total_feeString 11 Y 订单金额,单位分,单位和币种有关,请查询附录 sub_appidString 32 N 子商户在微信开放平台申请移动应用对应的APPID 示例值:wx8888888888888888 goods_tagString 32 N 商品标记 示例值:WXG sub_openidString 128 O 用户在子商户sub_appid下用户唯一标识 order_bodyString 128 N 订单描述,显示在订单详情页面 attachString 128 N 附加数据,原样返回 terminal_ipString 16 Y 用户手机端IP(IPV4格式) time_expireString 11 N 订单相对超时时间。单位s,从交易创建时间开始计算。该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1~7200的整数,不传默认7200s currencyString 3 N 交易币种,支持币种⻅附录:7.1交易币种 goods_detailString 6000 N 订单包含的商品列表信息,Json数组转String格式。 └goods_idString 32 Y 商品编号 └goods_nameString 128 Y 商品名称 └quantityString 11 Y 商品数量,需为整数,不要带小数点 └priceString 11 Y 商品单价,单位为分,单位和币种有关,请查询附录 notify_urlString 256 N 外部系统通知地址 return_urlString 256 N 支付完成后的返回地址 refer_urlString 256 N 商户经营网址
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 pre_order_stateString 10 N 业务结果:“SUCCESS” 下单成功,“ERROR”下单失败 pre_state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式:4:微信支付 total_feeString 12 N 金额,单位分 merchant_order_noString 32 Y 商户系统内部的单号,只能是数字、大小写字母_- 且在同一个子商户号下唯一 示例值:1234323JKHDFE1243252 out_trade_noString 32 N 平台唯一订单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述 pay_urlString 256 Y 支付跳转链接
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” out_trade_noString 32 O 平台交易(退款)单号,和merchant_order_no二选一 merchant_order_noString 32 O 商户系统内部的单号,和out_trade_no二选一 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_stateString 10 N 业务结果:“PAYSUCCESS” 支付成功,“PAYERROR”支付失败,“USERPAYING”支付中, “NOTPAY”未支付 “REFUNDSUCCESS”退款成功,“REFUNDING”退款中,“CANCELSUCCESS”撤销成功,“CANCELERROR”撤销失败 state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式: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_typeString 3 N 钱包类型,1、支付宝app香港版,2 支付宝app内地版,3、微信app香港版,4 微信app内地版 total_feeString 12 N 金额,单位分 refund_feeString 12 N 退款金额,单位分 merchant_receipt_feeString 12 N 商家应结算金额,单位分,单位和币种有关,请查询附录,order_state="PAYSUCCESS"时返回 buyer_pay_feeString 12 N 买家实付金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 platform_discount_feeString 12 N 平台优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 merchant_discount_feeString 12 N 商家优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 refund_receipt_feeString 12 N 商家应结算退款金额,单位分,order_state="REFUNDSUCCESS"时返回 refund_buyer_pay_feeString 12 N 买家实付退款金额(分),order_state="REFUNDSUCCESS"时返回 refund_platform_discount_feeString 12 N 平台优惠退款金额(分),order_state="REFUNDSUCCESS"时返回 refund_merchant_discount_feeString 12 N 商家优惠退款金额(分),order_state="REFUNDSUCCESS"时返回 end_timeString 14 N 支付(退款)完成时间,yyyyMMddHHmmss,全局统一时间格式 merchant_order_noString 32 Y 支付(退款)商户系统内部单号 out_refund_noString 32 N 平台唯一退款单号 out_trade_noString 32 N 平台唯一交易订单号 channel_trade_noString 32 N 支付(退款)通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 支付(退款)银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 支付(退款)附加数据,原样返回 order_bodyString 128 N 支付(退款)订单标题描述
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” out_trade_noString 32 O 平台交易单号,和merchant_order_no二选一 merchant_order_noString 32 O 商户系统内部的单号,和out_trade_no二选一 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 refund_feeString 12 Y 退款金额,单位分 order_bodyString 128 N 退款原因备注 attachString 128 N 附加数据,原样返回
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_stateString 10 N 业务结果:“REFUNDSUCCESS”退款成功,“REFUNDERROR”退款失败,“REFUNDING”退款中 state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式: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_feeString 12 N 金额,单位分 refund_feeString 12 N 金额,单位分 end_timeString 14 N 支付完成时间,yyyyMMddHHmmss,全局统一时间格式 merchant_order_noString 32 Y 商户系统内部单号 out_trade_noString 32 N 平台唯一订单号 out_refund_noString 32 N 平台唯一退款单号 channel_trade_noString 32 N 通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 附加数据,原样返回 order_bodyString 128 N 退款原因备注
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” out_trade_noString 32 O 平台交易单号,和merchant_order_no二选一 merchant_order_noString 32 O 商户系统内部的单号,和out_trade_no二选一 merchant_noString 15 Y 平台商户号 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_bodyString 128 N 撤销原因备注 attachString 128 N 附加数据,原样返回
业务响应字段 · resp_params 参数名称 类型 长度 必填 说明 merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_stateString 10 N 业务结果:“CANCELSUCCESS”撤销成功,“CANCELERROR”撤销失败 state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式: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_noString 32 Y 商户系统内部单号 out_trade_noString 32 N 平台唯一订单号 attachString 128 N 附加数据,原样返回 order_bodyString 128 N 订单标题描述
完整报文结构与伪代码 结构示例,不是真实验签样本。示例占位参数需替换为实际配置,金额示例为 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()
支付/退款通知 notify_url · HTTPS POST
查看完整回调字段、验签与应答 → 按支付场景接入
付款码支付 采集付款码 → barcodepay → 判断 order_state → 未知时 query
查看对应接口 → 二维码支付 prepay → 展示 qr_code → 顾客扫码 → query/回调
查看对应接口 → 公众号支付 jspay → 前端调用微信 JSAPI → query/回调(不要再调用 prepay)
查看对应接口 → 小程序支付 minipay → 对应钱包客户端接口 → query/回调
查看对应接口 → 网页支付 wappay → 跳转 pay_url → query/回调
查看对应接口 → 创建订单成功、浏览器回跳和客户端支付回调均不能单独作为服务端入账依据。字段及状态以对应接口为准。
POS 终端协议 · 3.0
POS 终端协议:三种模式,分别对接
先看你的业务系统在哪里运行、由谁展示支付界面,再选择接入模式。云推、局域网和 AIDL 的连接方式不同,各自对应一套接口和处理流程。
模式 适用场景 通信方式 内容入口
Cloud Push 业务系统后台远程推送收款 / 退款任务到 POS HTTPS API 云推模式
局域网收银 收银机与 POS 同一局域网;POS 展示支付 UI 并同步返回结果 HTTP + RSA2 · 16789 局域网收银
SDK / AIDL(计划中) 调用应用与 Soobey POS 安装在同一台 Android 设备 Android Binder · AIDL SDK / 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_signreq_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 PAID 2 FAILED 3 PROCESSING / UNKNOWN 4 CANCELED
PROCESSING / UNKNOWN 必须先查原订单;只有确认终态失败后才能按新业务意图重试。
核心业务字段
字段 规则 含义
pay_type EDC / SCAN / OCTOPUS 可选支付方式提示 terminal_trace ≤32 alphanumeric 收银机流水号;与 terminal_time 共同识别订单 terminal_time yyyy-MM-dd HH:mm:ss / yyyyMMddHHmmss 收银机交易时间 total_fee string · positive integer 原文金额单位为“分”;不得传小数 order_body ≤128 订单描述,可选 attach ≤128 附加信息;同步响应回显,查询不返回
响应字段与验签
字段 用途 / 规则 resp_code / resp_msg 外层处理结果;成功受理为 10000 key_sign 成功响应对原始 resp_params 的 RSA2 签名 pay_status_code 1 成功 / 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 · 可能重复投递 · 幂等处理
请求与返回对象
ExternalPaymentRequestapiVersionint · 必填 · 当前为 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_verString 3 Y 版本号:1.0 app_idString 64 Y 应用appid sign_typeString 32 Y 支持 RSA2,具体⻅本文签名规约一栏 encrypt_typeString 10 N 加密算法。 默认AES,如果为空,业务参数req_params 不加密。 key_signString 32 Y 签名串 req_timeString 32 Y 发送请求的时间戳(毫秒),示例值:1615187698031,时间戳要求在15分钟内 req_idString 32 Y 请求ID,判断是否重复请求。网关不做强校验,只做日志记录,后续可用于人工运维排查,202101010002011 req_paramsString --- Y 请求参数的集合,最大长度不限,除公共请求参数外所有请求参数都必须放在这个参数中传递,格式:JSON字符串
回调业务字段 · req_params 参数名称 类型 长度 必填 说明 pay_verString 3 Y 接口内业务逻辑兼容版本号,可用值“100” merchant_noString 15 Y 平台商户号 merchant_nameString 40 Y 商户名称 store_codeString 10 N 店铺编号 device_noString 32 N 商户终端设备号(商户自定义,如门店编号),必须在平台已配置过 order_stateString 10 N 业务结果:“PAYSUCCESS” 支付成功,“REFUNDSUCCESS”退款成功 state_msgString 128 N 业务结果描述 pay_typeString 3 N 支付方式: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_typeString 3 N 钱包类型1:支付宝app香港版,2:支付宝app内地版,3:微信app香港版,4:微信app内地版 total_feeString 12 N 金额,单位分 refund_feeString 12 N 退款金额,单位分 merchant_receipt_feeString 12 N 商家应结算金额,单位分,单位和币种有关,请查询附录,order_state="PAYSUCCESS"时返回 buyer_pay_feeString 12 N 买家实付金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 platform_discount_feeString 12 N 平台优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 merchant_discount_feeString 12 N 商家优惠金额(分),单位和币种有关,请查询附录order_state="PAYSUCCESS"时返回 refund_receipt_feeString 12 N 商家应结算退款金额,单位分,order_state="REFUNDSUCCESS"时返回 refund_buyer_pay_feeString 12 N 买家实付退款金额(分),order_state="REFUNDSUCCESS"时返回 refund_platform_discount_feeString 12 N 平台优惠退款金额(分),order_state="REFUNDSUCCESS"时返回 refund_merchant_discount_feeString 12 N 商家优惠退款金额(分),order_state="REFUNDSUCCESS"时返回 end_timeString 14 N 支付(退款)完成时间,yyyyMMddHHmmss,全局统一时间格式 merchant_order_noString 32 Y 支付(退款)商户系统内部单号 out_refund_noString 32 N 平台唯一退款单号 out_trade_noString 32 N 平台唯一交易订单号 channel_trade_noString 32 N 支付(退款)通道订单号,微信订单号、支付宝订单号等 channel_order_noString 64 N 支付(退款)银行渠道订单号,微信支付时显示在支付成功页面的条码,可用作扫码查询和扫码退款时匹配 user_idString 32 N 付款方用户id,“微信openid”、“支付宝账户” attachString 128 N 支付(退款)附加数据,原样返回 order_bodyString 128 N 支付(退款)订单标题描述
退款不能仅按支付订单号+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 次) 下列时间均相对于首次推送,不是相邻两次的等待间隔。
0s 30s 1m 5m 10m 30m 1h 6h 12h 24h
平台最多发送 10 次(含首次),重试周期最长 24 小时。资料提到 AES/CBC/PKCS5Padding,但没有说明 IV 如何生成和传递;启用加密回调前,请先向 Soobey 确认 IV 规则。
错误码与排查
错误码与排查:按接口族解释
同一个错误码在不同接口里可能代表不同问题。先确认请求走的是哪种接入方式,再按对应表格排查。
云端 API · 系统级错误码
10000 · success 20000 · business failure 30000 · system error 40000 · 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–40097 HTTP / 报文层错误:路径、方法、Content-Length、大小、Content-Type、限流 核对请求封装;限流时等待约 1 分钟后再试
遇到不确定结果时: 超时、断网或返回 UNKNOWN、PROCESSING、InProgress、NotFound 时,请保留原订单和业务标识,先查询或对账;仍无法确认时再转人工处理。不要立即重试扣款。
通道与市场支持
通道与市场支持
具体商户能使用哪些渠道、币种和钱包,请以商户开通配置为准。
ISO 4217 提供币种代码和标准小数位,但不代表该币种已在 Soobey 开通。接入前请确认商户支持范围,并按对应接口的金额字段说明传值。
查看 ISO 4217 币种代码与小数位(156 种)
表格按代码去重,依据 SIX 当前 List One,仅列币种(不含基金、贵金属、测试及无币种代码)。Minor Unit 是标准小数位:2 表示 1 个主单位可分为 100 个最小单位;0 表示无小数位。金额字段的实际传值方式仍以具体接口说明为准。
筛选代码或币种名称
联调、验收与上线
联调、验收与上线
按你实际采用的接入方式完成联调和验收。必测项和端到端流程都通过,并经双方确认后,再切换到生产环境。
检查公共参数、RSA2 签名和 Content-Type;跑通五种支付方式、查单、全额 / 部分退款和撤销;验证支付及退款通知的验签与重复通知处理。至少完成 6 个端到端场景;当前清单共 43 项必测项。
测试指定终端和绑定终端推送、180 秒有效期、两种查单方式、退款、更新 req_id 后的幂等重试、断网后查单,以及并发 / Busy 场景。POS 联调清单共 58 项必测项,包含局域网模式。
确认通过端口 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 次查询 UNKNOWN P2
频率 巡检 每日 前一日成功率、失败原因与异常交易复核 每周 证书有效期、POS 磁盘与内存 每月 对账收银机交易与平台后台数据
生产异常与回滚 生产异常时不要把生产订单路由到测试环境。合作方应与 Soobey 确认停止新增交易、保留生产查询/对账能力及处理在途或 UNKNOWN 交易的方案,再执行回滚。
SoftPOS 验收需补充: 现有 POS 验收清单覆盖 Cloud Push 和局域网,没有 AIDL / SoftPOS 专项测试。如果采用 SDK 模式,请在上线前和 Soobey 一起确认连接、授权拒绝、回调丢失、进程重启恢复和幂等处理等测试场景。
关键验收用例 以下按当前接入方式展示关键验收用例。请按对应接口的字段表准备测试报文。
Cloud API · 关键用例 原文用例号 测试步骤 预期结果 CA-01 正确私钥签名并发送请求 验签通过;业务响应按接口判断 CA-02 / CA-03 错误签名/缺签名 拒绝受理 CB-01 使用有效测试付款码调用 barcodepay PAYSUCCESS,保存平台订单号 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-02 send_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_id 40006/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 断网后调用后台兜底查询 保留原业务键;未确认前不新建支付