前言
通过插件的形式,预先实现了一些页面模板,例如退款页模板,小程序开发者只需要直接引入相应插件,并且遵循插件约定的规范,与插件之间实现相互通信,即可完成相应的页面,从而提高开发效率。
交易系统前端模板在页面维度上提供了提单页模板、退款页模板等,模板的入口是一个pay-button 组件,通过该组件实现从小程序跳转到前端模板页面。
目录
一 、在小程序中引入插件
二、pay-button交易按钮
属性说明
bind:pay 说明
bind:refund 说明
bind:applyrefund 说明
bind:getgoodsinfo 说明
bind:placeorder 说明
bind:error 说明
效果示例
Case 1 :mode 为 1 或 不填 (组件的使用模式:已下单)
Case 2 :mode 为 2 (组件的使用模式:立即抢购)
官方代码示例
Case 1 :mode 为 1 或不填
Case 2 :mode 为 2,立即抢购
三、测试代码示例
(1)下单(须真机调试否则抓取不到信息)
ttml
js
(2)订单详情
ttml
js
四、报错解决
一 、在小程序中引入插件
修改小程序全局配置文件 package.json 和 app.json。
package.json:
{
"ttPlugins": {
"dependencies": {
// 配置插件名,版本等信息
"microapp-trade-plugin": {
"version": "1.1.2",
"isDynamic": true
}
}
}
}
app.json :
{
"pages": [
"pages/index/index",
// 提单页
"ext://microapp-trade-plugin/order-confirm",
// 退款申请页配置
"ext://microapp-trade-plugin/refund-apply",
// 退款详情页
"ext://microapp-trade-plugin/refund-detail"
]
}
二、pay-button交易按钮
https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/component/industry/trading-system/pay-button
属性说明
属性名 |
类型 |
默认值 |
必填 |
说明 |
最低支持版本 |
---|---|---|---|---|---|
mode |
number |
1 |
否 |
组件的使用模式
|
2.43.0.0 |
goods-id |
string |
无 |
否( |
商品id
|
2.43.0.0 |
goods-type |
number |
无 |
否( |
商品类别,
目前只支持商品库商品,非商品库商品需要申请白名单 |
2.43.0.0 |
order-status |
number |
0 |
否 |
已下单场景(
|
2.43.0.0 |
order-id |
string |
无 |
否 |
开发者订单系统的交易订单号,用于继续支付、申请退款 |
2.43.0.0 |
refund-id |
string |
无 |
否 |
开发者订单系统的退款单号,用于查看退款详情 |
2.43.0.0 |
refund-total-amount |
number |
无 |
否 |
退款金额
|
2.43.0.0 |
biz-line |
number |
1 |
否,如果是泛知识类型则必填 |
业务线类型
|
2.54.0.0 |
marketing-ready |
boolean |
false |
否 |
是否配置了营销扩展点
|
2.54.0.0 |
bind:getgoodsinfo |
EventHandle |
无 |
否( |
获取商品信息, 详见 bind:getgoodsinfo 说明 |
2.43.0.0 |
bind:placeorder |
EventHandle |
无 |
否( |
跳转至提单页前的准备工作
详见 bind:placeorder 说明 |
2.43.0.0 |
bind:error |
EventHandle |
无 |
否 |
|
2.43.0.0 |
bind:applyrefund |
EventHandle |
无 |
否 |
透传退款参数
详见 bind:applyrefund 说明 |
2.43.0.0 |
bind:refund |
EventHandle |
无 |
否 |
退款回调
详见 bind:refund 说明 |
2.43.0.0 |
bind:pay |
EventHandle |
无 |
否( |
支付回调
|
2.43.0.0 |
bind:pay 说明
- 继续支付:
// bind:refund 使用示例
handleContinutePay(event) {
const { status, outOrderNo, result } = event.detail;
if (status === 'success') {
const { code } = result;
if (code === 0) {
// 继续支付成功
}
} else {
// 继续支付失败
}
}
- 立即抢购
- 当用户在提单页点击「立即支付」按钮后,会调起小程序收银台,当用户实际完成了支付或选择关闭收银台取消支付,以及预下单接口报错时,前端模板会调用该方法。
- 开发者可以在该方法中,根据支付返回结果,完成开发者自定义的逻辑,如跳转订单列表页等。
/**
* status: 支付状态,'success' | 'fail'
* orderId: 抖音交易系统内部订单号,类型为 string
* outOrderNo:开发者系统交易订单号,类型为 string
* result: 创建订单、tt.pay 支付结果,类型为 object
*/
handlePay(event) {
const { status , orderId , outOrderNo , result } = event.detail;
if (status === 'success') {
const { code } = result;
if (code === 0) {
// 支付成功
} else {
// 支付失败(超时、取消、关闭)
}
} else {
const { errMsg } = result;
}
}
- 事件对象的 detail 为 object 类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
status |
string |
是否成功拉起小程序收银台
|
2.43.0.0 |
orderId |
string |
抖音交易系统内部订单号 |
2.43.0.0 |
outOrderNo |
string |
开发者传入的开发者系统交易订单号 |
2.43.0.0 |
result |
object |
根据 |
2.43.0.0 |
result 属性说明
object 类型,属性如下:
- 当
status
为 success 时:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
code |
number |
只要调起收银台成功,支付都会回调成功,开发者依据返回的 code 值,进行后续业务逻辑处理 |
2.43.0.0 |
orderId |
string |
抖音交易系统内部交易订单号 |
2.43.0.0 |
- 当
status
为 fail 时:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
errMsg |
string |
API 支付错误码
|
2.43.0.0 |
bind:refund 说明
// bind:refund 使用示例
handleRefund(event) {
const { status, result } = event.detail;
if (status === 'success') {
const { refundId, outRefundNo } = result;
} else {
const { errMsg } = result;
}
}
事件对象的 detail 为 object
类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
status |
string |
发起申请退款结果
|
2.43.0.0 |
result |
object |
根据 |
2.43.0.0 |
result 属性说明
object
类型,属性如下:
- 当
status
为 success 时:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
refundId |
string |
抖音交易系统内部退款单号 |
2.43.0.0 |
outRefundNo |
string |
开发者系统退款单号 |
2.43.0.0 |
orderId |
string |
抖音交易系统内部交易订单号 |
2.43.0.0 |
- 当
status
为 fail 时:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
errMsg |
string |
失败错误信息 |
2.43.0.0 |
bind:applyrefund 说明
需要返回 promise,开发者可以在 promise 中做退款参数的设置,并将需要透传的退款参数作为返回值传入 resolve 函数。
- 若无需传入 extra 参数,该方法可不填。
// bind:applyrefund 使用示例
applyRefund(event) {
const { orderId } = event.detail;
const extra = { orderId }; // 开发者需要透传的参数,可自定义内容
return new Promise(resolve => {
resolve(extra);
});
},
- 事件对象的 detail 为
object
类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
orderId |
string |
开发者传入的开发者系统交易订单号 |
2.43.0.0 |
指定金额退款
指定金额退时,需要通过 bind:applyrefund 传入 itemOrderList。
itemOrderList 可和其他透传参数一同通过 bind:applyrefund 传入,可见下方代码说明
itemOrderList 说明
itemOrderList 是一个长度最少为 1 的数组,不可传递 undefined 或 null。
字段名 |
类型 |
是否必传 |
描述 |
最低支持版本 |
---|---|---|---|---|
itemOrderId |
string |
是 |
退款的商品单号 |
2.59.0.3 |
refundAmount |
number |
否 |
该 itemOrderId 需要退款的金额
|
2.59.0.3 |
// bind:applyrefund 指定金额退使用示例
applyRefund(event) {
const { orderId } = event.detail;
const itemOrderList = [
{itemOrderId:'ot423412',refundAmount:100},
{itemOrderId:'ot423413'},
]
const extra = { orderId , itemOrderList };
return new Promise(resolve => {
resolve(extra);// extra 透传至服务端时,当中的 itemOrderList 会被删除
});
},
bind:getgoodsinfo 说明
- 需要返回 promise,开发者可以在 promise 中获取相关商品信息,并将商品信息作为返回值传入 resolve 函数。
// bind:getgoodsinfo 使用示例
// 非商品库商品
getGoodsInfo(event) {
const { goodsId } = event.detail;
return new Promise(resolve => {
// 在此处开发者可以进行商品数据请求,获取商品信息
// 然后将商品信息传入 resolve 函数
resolve({
currentPrice: 9900,
goodsName: '循礼门M+丨【释集烤肉】99元 原价206.4元超值套餐',
goodsPhoto:
'https://p11.douyinpic.com/img/aweme-poi/product/spu/c050f399ac447daf2715e11e6976c2e2~noop.jpeg?from=3303174740',
goodsLabels: [
{type: 'EXPIRED_RETURNS'}, // 过期退
{type: 'REFUND_ANYTIME'}, // 随时退
{type: 'BOOK_IN_ADVANCE', value: 2} // 提前2日预约
],
minLimits: 1,
maxLimits: 2,
dateRule: '周一至周日可用',
validation: {
phoneNumber: {
required: true // 手机号是否必填, 为 ture则必填,false选填,默认选填
}
},
extra: {}
});
});
}
// 商品库商品
getGoodsInfo(event) {
return new Promise(resolve => {
// 在此处开发者可以进行商品数据请求,获取商品信息
// 然后将商品信息传入 resolve 函数
resolve({
minLimits: 1,
maxLimits: 2,
dateRule: '周一至周日可用',
validation: {
phoneNumber: {
required: true // 手机号是否必填
}
}
});
})
}
- 事件对象的 detail 为 object 类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
goodsId |
string |
商品 id |
2.43.0.0 |
goodsType |
number |
商品类型 |
2.43.0.0 |
- 商品信息说明如下:
字段名 |
类型 |
默认值 |
必传 |
说明 |
---|---|---|---|---|
currentPrice |
number |
无 |
否 注意:非商品库商品必传 |
商品单价
|
goodsName |
string |
无 |
否 注意:非商品库商品必传 |
商品名称
|
goodsPhoto |
string |
无 |
否 注意:非商品库商品必传 |
商品图片
|
goodsLabels |
GoodsLabel[] |
无 |
否 |
商品标签
|
minLimits |
number |
1 |
否 |
起购份数
|
maxLimits |
number |
99999 |
否 |
限购份数
|
dateRule |
string |
周一至周日可用 |
否 |
使用规则
|
extra |
object |
无 |
否 |
开发者透传参数
|
GoodsLabel 类型说明
object 类型,属性如下
属性名 |
类型 |
默认值 |
必传 |
说明 |
最低支持版本 |
---|---|---|---|---|---|
type |
string |
无 |
是 |
标签类别 |
2.43.0.0 |
value |
number |
无 |
否 |
天数
|
2.43.0.0 |
type 的合法值
值 |
说明 |
最低支持版本 |
---|---|---|
EXPIRED_RETURNS |
过期退 |
2.43.0.0 |
REFUND_ANYTIME |
随时退 |
2.43.0.0 |
RESERVATION_FREE |
免预约 |
2.43.0.0 |
REFUNDABLE_DAYS |
x 日内可退 |
2.43.0.0 |
BOOK_IN_ADVANCE |
提前 x 日预约 |
2.43.0.0 |
NON_REFUNDABLE |
不可退 |
2.50.0.0 |
最多设置三个标签,并且存在以下互斥关系:
-
REFUND_ANYTIME
与REFUNDABLE_DAYS
互斥,即 “随时退” 与 “x 日内可退” 互斥。 -
RESERVATION_FREE
与BOOK_IN_ADVANCE
互斥,即 “免预约” 与 “提前 x 日预约” 互斥。 -
NON_REFUNDABLE
与REFUNDABLE_DAYS
REFUND_ANYTIME
互斥,即 “不可退”与“随时退” 、 “x 日内可退” 互斥。 - 只做展现。
bind:placeorder 说明
由于在前端模板中进行下单需要用户登录,所以建议在此处完成登录或提醒用户打开设置给予相应权限。
需要返回 promise,开发者可以在 promise 中完成用户登录,然后调用 resolve 函数。
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
goodsId |
string |
商品id |
2.43.0.0 |
- 若无法完成相关逻辑,则一定要触发 reject 方法,否则可能会导致后续跳转失败。
userLogin(event) {
const { goodsId , goodsType } = event.detail
return new Promise((resolve, reject) => {
tt.login({
success() {
// 用户登录成功并获取信息,则调用 resolve 函数,跳转至提单页
resolve();
},
fail() {
// 用户登录失败,则跳转提单页失败
reject();
}
});
});
},
- 事件对象的 detail 为 object 类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
goodsId |
string |
商品 id |
2.43.0.0 |
goodsType |
number |
商品类型 |
2.43.0.0 |
bind:error 说明
- 当错误发生时触发。
- 错误原因可能是因为必填参数不合法,服务端请求错误等。
// 错误信息含义见下文 bind:error报错信息
handleError(event) {
const { errMsg ,errNo} = event.detail;
}
- 事件对象的detail 为 object 类型,属性如下:
属性名 |
类型 |
说明 |
最低支持版本 |
---|---|---|---|
errMsg |
string |
组件内部错误信息,如传入属性类型错误等 |
2.43.0.0 |
<pay-button ... //任意模式下均可使用bind:error bind:error="handleError" />
bind:error 报错信息
errorHandler(event){
const { errNo , errMsg } = event.detail
// do something
// errNo(错误码,对应某种具体报错原因)
// errMsg(报错信息)
}
errNo(错误码) |
含义 |
---|---|
21500 |
mode 非法 |
21501 |
goods-id 非法 |
21502 |
goods-type 非法 |
21503 |
无 bind:getgoodsinfo |
21504 |
无 bind:placeorder |
21505 |
商品库商品获取商品信息,服务端内部错误 |
21506 |
商品库商品获取商品信息,服务端校验参数不通过 |
21507 |
支付能力查询,服务端内部错误 |
21508 |
支付能力查询,服务端校验参数不通过 |
21509 |
开发者 bind:getgoodsinfo 调用失败 |
21510 |
开发者 bind:placeorder 调用失败 |
21511 |
非商品库商品,商品标签校验不通过 |
21512 |
bind:getgoodsinfo 传入数据类型错误 |
21513 |
点击按钮后触发,获取商品信息中 |
21514 |
点击按钮后触发,获取商品信息失败 |
21515 |
点击按钮后触发,无支付能力 |
21516 |
无 bind:pay 方法 |
21517 |
创建订单(预下单),服务端错误 |
21518 |
订单数据错误,无法生成订单 |
21521 |
order-status 非法 |
21522 |
order-id 非法 |
21523 |
refund-id 非法 |
21524 |
订单为 1.0 版本,但缺少 refund-total-amount |
21526 |
继续支付获取订单信息失败,服务端内部错误 |
21527 |
继续支付获取订单信息失败,服务端参数校验不通过 |
21528 |
申请退款获取订单信息失败,服务端内部错误 |
21529 |
申请退款获取订单信息失败,服务端参数校验不通过 |
21530 |
申请退款获取订单信息失败,服务端返回数据缺少商品信息 |
21531 |
申请退款获取订单信息失败,订单无可退款订单,订单可退份数等于0 |
21532 |
查看退款详情 获取退款详情失败 |
21533 |
bind:applyrefund 调用失败 |
21534 |
bind:applyrefund 返回类型错误 |
21535 |
申请退款失败,服务端错误 |
21536 |
获取小程序主体名称失败,服务端错误 |
21537 |
查询退款详情失败,服务端错误 |
21546 |
直跳提单页userLogin调用失败 |
21547 |
直跳提单页getExtraInfo调用失败 |
10000 |
支付失败 |
10001 |
调起微信失败 |
10002 |
微信未安装 |
效果示例
Case 1 :mode 为 1 或 不填 (组件的使用模式:已下单)
Case |
示例 |
操作效果 |
|
---|---|---|---|
|
点击后拉起收银台。 |
||
|
点击后进入申请退款页面。 |
||
|
点击后进入退款详情页面。 |
Case 2 :mode 为 2 (组件的使用模式:立即抢购)
根据 goods-type
商品类别分为:
- 商品库商品:
- 库存大于 0:根据商品售卖时段,展示状态分为:即将开始、立即抢购和已结束。
- 库存等于 0:展示状态为已售罄。
- 非商品库商品:
- 展示状态:立即抢购。
- 操作效果:点击后进入提单页。
Case 3 :KA 解决方案退款场景
- 常用于
order-status
为 1 的情况:
- 操作效果:点击后进入申请退款页面。
官方代码示例
Case 1 :mode 为 1 或不填
- 继续支付:
<pay-button order-status="{{0}}" order-id="xxx" bind:pay="onContinutePay" />
- 申请退款:
- 使用交易系统生成的新订单:
<pay-button
order-status="{{1}}"
order-id="xxx"
bind:refund="onRefund"
bind:applyrefund="applyRefund"
/>
-
- 对于交易系统之前的老订单,需传入 refund-total-amount:
// 示例:老订单申请退款 200 元
<!--
使用交易模板 1.0 生成的老订单,申请退款需要 refudnrefund-total-amount
若无需传入 extra 参数,则无需 bind:applyrefund 方法
-->
<pay-button
order-status="{{1}}"
order-id="xxx"
bind:refund="onRefund"
bind:applyrefund="applyRefund"
refund-total-amount="{{20000}}"
/>
- 退款中:
<pay-button order-status="{{2}}" refund-id="xxx" />
- 退款成功:
<pay-button order-status="{{3}}" refund-id="xxx" />
- 退款失败:
<pay-button order-status="{{4}}" refund-id="xxx" />
Case 2 :mode 为 2,立即抢购
<!-- 商品库商品 -->
<pay-button
mode="{{2}}"
goods-type="{{1}}"
goods-id="xxxx"
bind:getgoodsinfo="getGoodsInfo"
bind:placeorder="userLogin"
bind:pay="onPay"
/>
<!-- 非商品库商品 -->
<pay-button
mode="{{2}}"
goods-type="{{2}}"
goods-id="xxxx"
bind:getgoodsinfo="getGoodsInfo"
bind:placeorder="userLogin"
bind:pay="onPay"
/>
三、测试代码示例
(1)下单(须真机调试否则抓取不到信息)
ttml
<pay-button
mode="{{2}}"
goods-type="{{1}}"
goods-id="xxx"
bind:getgoodsinfo="getGoodsInfo"
bind:placeorder="userLogin"
bind:pay="onPay"
bind:error="bindError"
/>
js
Page({
data: {
goodId:''
},
getGoodsInfo(event) {
return new Promise(resolve => {
// 在此处开发者可以进行商品数据请求,获取商品信息
// 然后将商品信息传入 resolve 函数
resolve({});
})
},
bindError(event){
const { errNo , errMsg } = event.detail
console.log('errMsg')
console.log(event.detail)
console.log(errMsg)
console.log(errNo)
},
onPay(event) {
console.log(event.detail);
const { status, outOrderNo, result,orderId } = event.detail;
if (status === 'success') {
const { code } = result;
console.log(result);
if (code === 0) {
// 继续支付成功
console.log('支付成功');
setTimeout(() => {
tt.redirectTo({
url: `usr://pages/orderDetail/orderDetail?orderId=${orderId}`,
success: (res) => {
console.log("redirectTo调用成功 ", res);
},
fail: (res) => {
console.log("redirectTo调用失败 ", res);
},
});
}, 1000)
}
} else {
console.log('支付失败')
}
},
userLogin(event) {
console.log('用户登录');
console.log(event);
const { goodsId , goodsType } = event.detail
return new Promise((resolve, reject) => {
tt.login({
success() {
// 用户登录成功并获取信息,则调用 resolve 函数,跳转至提单页
resolve();
},
fail() {
// 用户登录失败,则跳转提单页失败
reject();
}
});
});
},
onShow(){
},
onReady: function () {
},
onLoad:function(options){
});
(2)订单详情
ttml
<view class="order_wrap">
<view class="order_top">
<view class="title">订单已支付</view>
<view class="btn">
<view tt:if="{{orderOutId}}">
<pay-button
order-status="{{1}}"
order-id="{{orderOutId}}"
bind:refund="onRefund"
bind:error="bindError"
bind:applyrefund="applyRefund"
/>
<pay-button order-status="{{2}}" refund-id="{{orderOutId}}" />
</view>
</view>
</view>
<view class="task_list">
<view class="task_list_l">
<image src="https://p11.douyinpic.com/img/aweme-poi/product/spu/c050f399ac447daf2715e11e6976c2e2~noop.jpeg?from=3303174740"></image>
</view>
<view class="task_list_r">
<view class="task_rtop">
<view class="task_list_tit">测试商品</view>
<view class="task_list_concesson">
</view>
<view class="task_rbot" tt:if="{{orderOutId}}">
<view class="rbot_time">orderid:{{orderOutId}}</view>
</view>
</view>
</view>
</view>
<view>
<consume-card
order-id="{{orderOutId}}"
bind:consume="orderChangeHandler"
bind:refund="onRefund"
bind:applyrefund="applyRefund"
bind:error="bindError"
></consume-card>
</view>
<view class="apply_shop">
<view>适用门店(1)</view>
<view>测试</view>
<view>营业时间 11:00-次日00:00</view>
<view>世纪大厦8层</view>
<view>商家资质信息展示</view>
</view>
</view>
js
Page({
data: {
orderInfo:{},
orderOutId:''
},
orderChangeHandler(event){
const { orderId } = event.detail
//do something
},
bindError(event){
const { errNo , errMsg } = event.detail
console.log('errMsg')
console.log(event.detail)
console.log(errMsg)
console.log(errNo)
},
// bind:applyrefund 使用示例
applyRefund(event){
const { orderId } = event.detail;
const extra = { orderId }; // 开发者需要透传的参数,可自定义内容
console.log(orderId)
console.log(111)
return new Promise(resolve => {
resolve(extra);
});
},
// bind:refund 使用示例
onRefund(event) {
const { status, result } = event.detail;
console.log(event.detail);
if (status === 'success') {
const { refundId, outRefundNo } = result;
console.log(result);
} else {
const { errMsg } = result;
}
},
//核销订单后触发
orderChangeHandler(event){
const { orderId } = event.detail
//do something
},
onLoad: function (options) {
let that=this
console.log(options);
if(options.orderId){
that.setData({
orderOutId:options.orderId
})
console.log('调用接口');
}
}
})
四、报错解决
由于在pay-button组件内部使用的原生跳转方法不生效,在路径前加上user://即可
文章来源:https://www.toymoban.com/news/detail-415078.html
其他服务端错误不做叙述了,有问题可以留言交流文章来源地址https://www.toymoban.com/news/detail-415078.html
到了这里,关于字节小程序交易组件使用指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!