业务说明
商户使用该接口下单后,使用接口返回的预下单订单号和小程序参数结合业务实际场景,选择不同的方式使用支付收银台完成支付。
交易请求报文
JSON:
{
"request_type": "miniapporder_request",
"isspid": "39493002",
"pos_id": "1511300001",
"store_id": "1511300001",
"pos_seq": "1511300000002",
"user_id": "user01",
"system_id": "8888",
"memo": "订单备注",
"miniapporder_request": {
"pay_type": "515",
"sub_appid": "wxa138a13aca591b95",
"tx_amt": "1",
"body": "商品描述",
"notify_url": "http://www.baidu.com/",
"extend_params": {
"split_flag": "R",
"plan_split_date": "20230418",
"split_info": {
"keep_amt": "800",
"split_list": [
{
"merchant_id": "10000000000001",
"div_amt": "150"
},
{
"merchant_id": "10000000000002",
"div_amt": "50"
}
]
}
}
},
"sign": "59B62BEBCA649C24DC25C44706677423"
}
XML:
<?xml version="1.0" encoding="GBK"?>
<business_trans>
<request_type>miniapporder_request</request_type>
<isspid>39493002</isspid>
<pos_id>1511300001</pos_id>
<store_id>1511300001</store_id>
<pos_seq>1511300000002</pos_seq>
<user_id>user01</user_id>
<system_id>8888</system_id>
<memo>订单备注</memo>
<miniapporder_request>
<pay_type>515</pay_type>
<sub_appid>wxa138a13aca591b95</sub_appid>
<tx_amt>1</tx_amt>
<body>商品描述</body>
<notify_url><![CDATA[http://www.baidu.com/]]></notify_url>
<extend_params><![CDATA[扩展参数]]></extend_params>
</miniapporder_request>
</business_trans>
交易请求报文说明
节点名称 | 中文名称 | 类型 | 说明 | 是否必填 |
---|---|---|---|---|
sign | 报文签名 | String(32) | 请求报文格式为JSON时必填计算签名方式请看2.1章节 | 可选 |
request_type | 请求类型 | String(32) | 固定值:miniapporder_request | 必填 |
isspid | 商户号 | String(8) | 翼码商户号,由翼码提供 | 必填 |
pos_id | 终端号 | String(20) | 商户自定义终端号 | 必填 |
store_id | 门店号 | String(20) | 商户自定义门店号 | 必填 |
pos_seq | 支付请求流水号 | String(32) | 同一个翼码商户号下唯一,不可重复使用,且大于12位 | 必填 |
user_id | 操作员标识 | String(20) | 操作员号 | 可空 |
system_id | 系统平台号 | String(4) | 由翼码提供 | 必填 |
memo | 订单备注 | String(128) | 可空 | |
miniapporder_request ->pay_type | 支付类型 | String(3) | 515:微信小程序 | 必填 |
miniapporder_request ->sub_appid | 子商户应用ID | String(32) | 发起交易商户号所绑定的小程序appid 如果有传appid就使用传的appid进行交易 如果没传就使用系统中配置的appid进行交易 | 可空 |
miniapporder_request ->tx_amt | 交易金额 | Number(9) | 支付金额,单位为分,不支持小数点 | 必填 |
miniapporder_request ->body | 商品描述 | String(64) | 不传,则默认为“商户简称(门店名称)” | 可空 |
miniapporder_request ->notify_url | 异步通知地址 | String(256) | 异步通知文档见4.20 使用XML格式报文时,建议使用CDATA标签包裹内容 | 可空 |
miniapporder_request ->extend_params | 扩展参数 | JSON | 用于扩展一些特殊的支付参数字段,详细参数见下表 使用XML格式报文时,建议使用CDATA标签包裹内容 | 可空 |
自定义门店号(store_id)和自定义终端号(pos_id)需经过4.1终端绑定交易接口绑定成功过的值才可以调用,绑定一次即可不需要重复绑定。
extend_params 扩展参数 (JSON)
JSON节点 | 类型 | 说明 | 是否必填 | 范例 |
---|---|---|---|---|
split_flag | String | 分账标识 N:不分账 R:实时分账 D:延时分账 不传该节点时,将按控制台配置处理 该节点与分账功能相关具体联系业务确认开通功能 | 可空 | R |
plan_split_date | String | 预分账日期,格式:yyyymmdd 仅延时分账类型(split_flag=D)时支持传入 | 可空 | 20230418 |
split_info | JSON | 分账信息 仅支持请求实时分账split_flag=R 该节点与分账功能相关具体联系业务确认开通功能 | 可空 |
分账业务相关的特别说明:
1. split_flag=N 不分账时,split_info不允许传入;
2. split_flag=R 实时分账时,split_info必传,其中keep_amt与div_amt叠加必须全额分完整笔订单;
3. split_flag=D 延时分账时,split_info不允许传入,在后续流程中调用延迟交易确认接口完成分账,或使用翼码分账系统界面进行分账。
split_info 分账信息
JSON节点 | 类型 | 说明 | 是否必填 | 范例 |
---|---|---|---|---|
is_clean_split | String | N:不使用净值分账 Y:使用净值分账 不传默认为N,即不使用净值分账 净值分账目前仅对部分通道开放,使用此能力前请先与技术支持确认 净值分账仅在交易手续费内扣时才起作用 当使用净值分账时,分账信息和分账明细必须要传分账比例,且分账方自留比例(keep_percentage)与所有分账比例(div_percentage)之和必须要为100% | 可空 | Y |
keep_amt | String | 分账方自留金额,单位为分,可传0表示不自留 不使用净值分账(is_clean_split=N)时,该节点必填,分账方自留比例(keep_percentage)节点无效 | 可空 | 1000 |
keep_percentage | String | 分账方自留比例,单位为%,最多支持小数点后两位,可传0表示不自留 使用净值分账(is_clean_split=Y)时,该节点必填,分账方自留金额(keep_amt)节点无效 | 可空 | 50.26 |
split_list | Array | 分账明细 | 必填 |
split_list 分账明细
JSON节点 | 类型 | 说明 | 是否必填 | 范例 |
---|---|---|---|---|
merchant_id | String | 分账接收方的分账商户号 | 必填 | 10000000000001 |
div_amt | String | 分账金额,单位为分,必须大于0 不使用净值分账(is_clean_split=N)时,该节点必填,分账比例(div_percentage)节点无效 | 可空 | 1000 |
div_percentage | String | 分账比例,单位为%,最多支持小数点后两位,必须大于0 使用净值分账(is_clean_split=Y)时,该节点必填,分账金额(div_amt)节点无效 | 可空 | 23.55 |
若业务涉及100%分账给接收方,请于业务对接人联系申请使用净值分账功能。
extend_params 样例:
{
"split_flag": "R",
"plan_split_date": "20230418",
"split_info": {
"keep_amt": "800",
"split_list": [
{
"merchant_id": "10000000000001",
"div_amt": "150"
},
{
"merchant_id": "10000000000002",
"div_amt": "50"
}
]
}
}
交易返回报文
{
"response_type": "miniapporder_response",
"isspid": "39493002",
"pos_id": "1511300001",
"pos_seq": "1511300000002",
"sys_seq": "0311095321465179",
"trans_time": "20160311095321",
"pay_type": "515",
"pre_order_id": "1FN68A1A66OGS",
"miniapp_data": "{\"gh_id\":\"gh_35df7973927b\",\"path\":\"pages/index/embedded\",\"scheme_code\":\"weixin://dl/business/?t=tGzuz08reKu\"}",
"result": {
"id": "9998",
"comment": "下单成功,等待用户支付"
},
"sign": "D2E991C64AE4B6AD857A94904BDDB608"
}
<?xml version="1.0" encoding="GBK"?>
<business_trans>
<response_type>miniapporder_response</response_type>
<isspid>39493002</isspid>
<pos_id>1511300001</pos_id>
<pos_seq>1511300000002</pos_seq>
<sys_seq>0311095321465179</sys_seq>
<trans_time>20160311095321</trans_time>
<pay_type>515</pay_type>
<pre_order_id>1FN68A1A66OGS</pre_order_id>
<miniapp_data><![CDATA[{"gh_id":"gh_35df7973927b","path":"pages/index/embedded","scheme_code":"weixin://dl/business/?t=tGzuz08reKu"}]]></miniapp_data>
<result>
<id>9998</id>
<comment>下单成功,等待用户支付</comment>
</result>
</business_trans>
交易返回报文说明
标准接口会因业务升级需要而新增节点,请在解析返回报文时避免新增未知节点产生的程序出错!
节点名称 | 中文名称 | 类型 | 说明 | 是否必填 |
---|---|---|---|---|
sign | 报文签名 | String(32) | 请求报文格式为JSON时必填计算签名方式请看2.1章节 | 可选 |
response_type | 返回类型 | String(32) | 固定值:miniapporder_response | 必填 |
isspid | 商户号 | String(8) | 翼码商户号,由翼码提供 | 必填 |
pos_id | 终端号 | String(20) | 商户自定义终端号 | 必填 |
pos_seq | 支付请求流水号 | String(32) | 支付请求流水号,和请求报文相同 | 必填 |
sys_seq | 随机串号 | String(16) | 随机生成串号,仅用于日志跟踪用,不保存 | 必填 |
trans_time | 接口返回时间 | String(14) | 接口返回时间,格式:yyyyMMddHHmmss | 必填 |
pay_type | 支付类型 | String(3) | 515:微信小程序 | 必填 |
pre_order_id | 预下单订单号 | String(64) | 下单成功时必填 | 可空 |
miniapp_data | 小程序参数 | String | JSON字符串 下单成功时必填 使用XML格式报文时,内容将使用CDATA标签包裹 | 可空 |
result ->id | 响应码 | String(4) | 9998 - 下单成功等待用户支付,需调用查询接口确认交易 其它失败,错误信息说明见“响应码解释”字段 | 必填 |
result ->comment | 响应码解释 | String(64) | 响应码对应中文注解,用于显示提示 | 必填 |
标准接口会因业务升级需要而新增节点,请在解析返回报文时避免新增未知节点产生的程序出错!
miniapp_data 小程序参数
JSON节点 | 类型 | 说明 | 是否必填 | 范例 |
---|---|---|---|---|
gh_id | String | 小程序原始ID | 可空 | gh_35df7973927b |
path | String | 小程序页面支付路径 | 可空 | pages/index/embedded |
scheme_code | String | 小程序跳转码 | 可空 | weixin://dl/business/?t=tGzuz08reKu |
微信小程序支付收银台使用说明
方式一:使用商户自有小程序,跳转旺财收银台小程序完成支付
步骤一:拼接小程序页面路径
取下单成功后接口返回的【预下单订单号(pre_order_id)】节点和【小程序参数(miniapp_data)】中的【小程序页面支付路径(path)】节点,拼接为形如“pages/index/embedded?pre_order_id=XXX”的小程序页面路径。
其中:
- “pages/index/embedded” 是接口返回的小程序页面支付路径【path】
- “XXX” 是预下单订单号【pre_order_id】;
例如下单接口返回:
...
"pre_order_id": "1FN68A1A66OGS",
"miniapp_data": "{\"gh_id\":\"gh_35df7973927b\",\"path\":\"pages/index/embedded\",\"scheme_code\":\"weixin://dl/business/?t=tGzuz08reKu\"}",
...
拼接完成后的小程序页面路径为:pages/index/embedded?pre_order_id=1FN68A1A66OGS
步骤二:跳转旺财收银台小程序
根据用户体验设计和小程序基础库版本,按需选择半屏打开小程序或全屏跳转小程序
1. 半屏打开小程序
可用前提:从小程序基础库 2.20.1 开始支持;
(1) 开发者需在 小程序管理后台「设置」-「第三方设置」-「半屏小程序管理」板块发起申请,申请添加小程序的APPID为wxa138a13aca591b95;
(2) 2.23.1以下版本基础库,开发者需要在全局配置 app.json 的 embeddedAppIdList 字段中声明需要半屏打开的小程序,若不配置将切换为普通的全屏跳转小程序。2.23.1及以上版本起无需配置,跳过此步。
配置示例:
{
"embeddedAppIdList": ["wxa138a13aca591b95"]
}
(3) 开发者通过调用 wx.openEmbeddedMiniProgram 半屏打开小程序。
示例代码:
wx.openEmbeddedMiniProgram({
appId: 'wxa138a13aca591b95', //填写旺财收银台小程序appid:wxa138a13aca591b95
envVersion: 'release', //release-正式版:翼码生产环境,trial-体验版:翼码测试环境
path: 'pages/index/embedded?pre_order_id=1FN68A1A66OGS' //填写步骤一中拼接出的小程序页面路径
})
参数 envVersion 代表小程序版本
对接翼码测试环境时为体验版小程序:envVersion=trial
对接翼码生产环境时为正式版小程序:envVersion=release
更多方法及使用限制请参考微信官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/openEmbeddedMiniProgram.html
特别注意:半屏打开小程序必须要在点击触发后同步调用,否则会降级成普通的全屏跳转小程序,例如以下错误代码将出现全屏跳转小程序:
openEmbeddedMiniProgramHandle(){
// 此时会全屏跳转小程序,不是半屏打开小程序
// 微信错误提示:openEmbeddedMiniProgram will fallback to navigateToMiniProgram. (reason: invalid platform)
setTimeout(() => {
wx.openEmbeddedMiniProgram({
appId: 'wxa138a13aca591b95', //填写旺财收银台小程序appid:wxa138a13aca591b95
envVersion: 'release', //release-正式版:翼码生产环境,trial-体验版:翼码测试环境
path: 'pages/index/embedded?pre_order_id=1FN68A1A66OGS' //填写步骤一中拼接出的小程序页面路径
})
}, 100);
}
2. 全屏跳转小程序
可用前提:从小程序基础库 1.3.0 开始支持;
示例代码:
wx.navigateToMiniProgram({
appId: 'wxa138a13aca591b95', //填写旺财收银台小程序appid:wxa138a13aca591b95
envVersion: 'release', //release-正式版:翼码生产环境,trial-体验版:翼码测试环境
path: 'pages/index/embedded?pre_order_id=1FN68A1A66OGS' //填写步骤一中拼接出的小程序页面路径
})
参数 envVersion 代表小程序版本
对接翼码测试环境时为体验版小程序:envVersion=trial
对接翼码生产环境时为正式版小程序:envVersion=release
更多参数及使用限制请参考微信官方文档:
https://developers.weixin.qq.com/miniprogram/dev/api/navigate/wx.navigateToMiniProgram.html
步骤三:支付结果数据获取
在当前页面的show生命周期函数内监听onAppShow事件,返回的支付结果数据在referrerInfo.extraData中,但是由于意外原因可能出现未返回结果,所以推荐使用重新查询支付订单的状态来作为依据。
示例代码:
// 可在page的onShow中监听订单状态(推荐)
// uniapp
onShow(e) {
uni.onAppShow((e)=>{
// 重新请求订单状态,根据后端查询状态处理后续业务逻辑,或者直接跳转订单结果页,在订单结果页上重新查询订单状态显示是否支付成功
})
}
// 微信原生
show(e) {
wx.onAppShow((e)=>{
// 重新请求订单状态,根据后端查询状态处理后续业务逻辑,或者直接跳转订单结果页,在订单结果页上重新查询订单状态显示是否支付成功
})
}
// 在page的onShow使用返回状态判断(仅半屏打开中可获取)
// uniapp
onShow(e) {
uni.onAppShow((e)=>{
console.log('onAppShow', e)
let { referrerInfo={} } = e
let { extraData={} } = referrerInfo
/*
返回小程序时会返回extraData字段,格式如下
extraData = {
ym_pay_status: "success", // success:支付成功,error:失败
ym_pay_msg: "订单不存在", // 失败原因
ym_pay_id: "1FN681TQTV79L", // 接口中的 pre_order_id
}
*/
// 之后根据支付状态处理后续业务逻辑
})
}
// 微信原生
show(e) {
wx.onAppShow((e)=>{
console.log('onAppShow', e)
let { referrerInfo={} } = e
let { extraData={} } = referrerInfo
/*
返回小程序时会返回extraData字段,格式如下
extraData = {
ym_pay_status: "success", // success:支付成功,error:失败
ym_pay_msg: "订单不存在", // 失败原因
ym_pay_id: "1FN681TQTV79L", // 接口中的 pre_order_id
}
*/
// 之后根据支付状态处理后续业务逻辑
})
}
更多参数及使用限制请参考微信官方文档:
https://developers.weixin.qq.com/miniprogram/dev/api/base/app/app-event/wx.onAppShow.html
方式二:不使用商户自有小程序,由商户App直接跳转支付通道小程序完成支付
使用微信原生SDK,APP拉起小程序功能,需要使用下单成功后接口返回的 miniapp_data 与 pre_order_id 节点的参数。
开发示例中的“小程序原始id”,即下单接口返回的 miniapp_data 中的 gh_id 节点。
开发示例中的“拉起小程序页面的可带参路径”,即下单接口返回的 miniapp_data 中的 path 节点拼接上参数后的值。
具体拼接规则如下:
取接口返回 path 拼接上 “?pre_order_id=xxx”,其中 xxx 为接口返回的pre_order_id。
例如下单接口返回:
...
"pre_order_id": "1FN68A1A66OGS",
"miniapp_data": "{\"gh_id\":\"gh_35df7973927b\",\"path\":\"pages/index/embedded\",\"scheme_code\":\"weixin://dl/business/?t=tGzuz08reKu\"}",
...
拼接完成后的path为:pages/index/embedded?pre_order_id=1FN68A1A66OGS
方式三:不使用商户自有小程序,由短信、邮件、外部网页、微信内等场景直接跳转支付通道小程序完成支付
使用下单成功后接口返回的 miniapp_data 中的 scheme_code 节点进行跳转。
微信官方对使用此方法跳转,提示的部分注意事项:
- 微信内的网页如需打开小程序请使用微信开放标签-小程序跳转按钮,无公众号也可以直接使用小程序身份开发网页并免鉴权跳转小程序,见云开发静态网站跳转小程序。
- 通过 URL Scheme 跳转到微信时,可能会触发系统弹框询问,若用户选择不跳转,则无法打开小程序。请开发者妥善处理用户选择不跳转的场景
- 部分浏览器会限制打开网页直接跳转,可参考示例网页设置跳转按钮
方式四:使用商户自有小程序,调用小程序支付插件完成支付
当微信认为商户小程序使用支付插件完成支付绕过了微信的订单管理不合规时,会进行管控,造成一些商户小程序调用支付插件时被拦截。出现此情况商户,需使用方式一完成支付。
一、准备工作
1. 小程序添加插件
请在 「小程序后台 - 设置 - 第三方设置 - 插件管理 中搜索并添加 appid 为【wx11361ccf7f47b948】的插件。联系翼码运营,告知小程序名称,翼码审核通过后即可添加成功。
在小程序配置 app.json 文件中加入如下配置
{
"plugins": {
"dg-bill": {
"version": "latest",
"provider": "wx11361ccf7f47b948"
}
}
}
2. 联系翼码运营开通功能
告知商户自己的小程序appid,翼码营运开通功能。
二、支付插件使用
1. 调用本接口进行小程序支付插件的下单
使用本接口进行预下单,获取响应的预下单订单号(pre_order_id)。
2. 接入斗拱插件
本插件支持两种接入方式
- (1) 调用插件JS接口调用支付
在支付提交页(调用微信支付的页面),添加以下代码,使用预下单响应信息 pre_order_id 作为参数调用 DGBillPlugin.requestPay 发起插件支付,使用 paySuccess、payError 作为支付结果回调接收支付回调信息处理后续逻辑。
// 支付提交页
const DGBillPlugin = requirePlugin('dg-bill');
Page({
...,
paySuccess() {
},
payError() {
},
handlePluginPay() {
const orderInfo = this.data.orderInfo;
if (orderInfo.pre_order_id) {
DGBillPlugin.requestPay(orderInfo.pre_order_id, this.paySuccess, this.payError);
}
},
});
- (2) 引用插件支付页面完成支付流程
引用斗拱收银插件组件
{
"usingComponents": {
"pay-item": "plugin://dg-bill/pay-component"
}
}
定义支付回调方法
onsuccess(e) {
console.log('小程序成功回调', e.detail);
},
onfail(e) {
console.log('小程序失败回调', e.detail);
},
支付页面展示组件
<pay-item wx:if="{{preOrderId}}" preOrderId="{{preOrderId}}" bind:onsuccess="onsuccess" bind:onfail="onfail"/>
参数说明
参数名称 | 参数类型 | 参数说明 |
---|---|---|
amt | Number | 订单金额 |
preOrderId | String | 下单接口返回的预下单订单号pre_order_id |
onsuccess | Function | 成功回调 |
onfail | Function | 失败回调 |