payment-channel-select 前置支付组件收藏我的收藏
收藏
我的收藏payment-channel-select 组件用于将支付渠道内嵌到小程序页面,免去拉起收银台步骤,缩短交易链路,提升交易转化。
使用说明
- •使用场景:开发者可将此组件引入提单页或充值面板页,提前为用户展示支付列表,当用户点击立即支付时,将直接拉起支付而不再需要唤起收银台。
- •关键区别:使用该组件后,当用户点击支付时,开发者是通过组件的 bind:requestorder 参数来传递下单参数,并由组件主动唤起支付,而不再需要使用 tt.requestOrder 和 tt.getOrderPayment 。
效果示例
使用限制
注意:
- •最低支持版本上注明行业 SDK ,表示仅在行业 SDK 上才支持,需要在代码中配置行业 SDK 的权限:行业 SDK 的权限配置。当完成行业 SDK 的权限配置后,可通过版本校验判断是否可用。
- •IDE 上不支持 payment-channel-select 组件渲染,建议使用真机调试。
版本校验
- •支持方案:仅通用交易系统
- •支持设备:安卓、iOS
- •支持宿主版本: 抖音,30.2 及以上版本
重要:使用前必须通过 tt.canIUse 来校验当前客户端能否使用。
tt.canIUse('payment-channel-select')
使用流程
正常流程:
渲染出错:
支付出错:
属性说明
注意:
当 bind:error 出现错误时,请根据下文 bind:error 说明以及代码,回退到原 tt.requestOrder + tt.getOrderPayment 链路。
属性名 | 类型 | 默认值 | 必填 | 说明 |
scene | string | 'cash' | 条件选填 (在iOS情况下必填) | 组件支付场景,有现金支付和钻石支付两种。 枚举说明: cash - 现金支付; diamond - 钻石支付 注意:
|
sku-list | SkuList[] SkuList 说明见下文 | 无 | 是 | 用户选择的商品信息 注意:目前只支持传入一项 |
merchant-uid | string | 无 | 否 | 开发者自定义收款商户号, 若使用默认收款商户号可忽略该参数 |
limit-pay-way-list | number[] | 无 | 否 | 以订单维度指定屏蔽的支付方式。如: [1,2] 表示该笔订单屏蔽微信和支付宝 。枚举说明: 1 - 微信 2 - 支付宝 注意: scene=diamond时,该参数无效 |
custom-style | object | 无 | 否 | 自定义样式 详见下文说明 |
bind:requestorder | EventHandle | 无 | 是 | 用户点击立即支付触发 详见 bind:requestorder 说明 |
bind:getpaymentresult | EventHandle | 无 | 否 | 获取支付结果,支付成功和失败都会触发 详见 bind:getpaymentresult 说明 |
bind:error | EventHandle | 无 | 否 | 组件传入属性异常、组件内部发生异常时触发 详见 bind:error 说明 |
sku-list 说明
object 类型,属性如下:
属性名 | 类型 | 默认值 | 必填 | 说明 |
skuId | string | 无 | 是 | 外部商品id,如:号卡商品id、会员充值套餐id、某类服务id、付费工具id等 |
price | number | 无 | 是 | 商品价格
注意:
|
title | string | 无 | 是 | 商品标题,长度 <= 256字节 |
type | number | 无 | 是 | 商品类型,详细查看 |
tagGroupId | string | 无 | 是 | 注意:
|
custom-style 说明
属性名 | 类型 | 默认值 | 必填 | 说明 |
backgroundColor | string | 无 | 否 | 组件背景颜色 |
fontSize | string | 无 | 否 | 组件文字大小 |
retryTextColor | string | 无 | 否 | 重试文字颜色 |
buttonBackgroundColor | string | 无 | 否 | 支付按钮背景颜色 |
buttonColor | string | 无 | 否 | 支付按钮文字颜色 |
payChannelCell | object | 无 | 否 | 支付方式栏样式配置 详见下文说明 |
payTagCell | object | 无 | 否 | 交易保障栏样式配置 详见下文说明 |
payDiscountCell | object | 无 | 否 | 支付优惠栏样式配置 详见下文说明 |
payChannelCell, payTagCell, payDiscountCell 配置说明:
属性名 | 类型 | 默认值 | 必填 | 说明 |
titleColor | string | 无 | 否 | 左侧标题文字颜色 |
textColor | string | 无 | 否 | 右侧内容文字颜色 |
bind:requestorder 说明
需要返回 promise ,将 data 和 byteAuthorization 传入 resolve 函数 。(data、byteAuthorization 与原 tt.requestOrder 的参数一致)。
使用示例:
// bind:requestorder 使用示例 handleRequestOrder(event) { // 开发者服务端下单 // 返回一个 promise return new Promise(resolve => { resolve({ data, byteAuthorization }); }); }
bind:getpaymentresult 说明
使用示例:
// bind:getpaymentresult 使用示例 handleGetPaymenResult(event) { const { status, result } = event.detail; if (status === 'success') { const { code } = result; if (code === 0) { // 支付成功 } else { // 支付失败、超时、取消、关闭 } } else { // 支付失败 } }
事件对象的 event.detail 为 object 类型,属性如下:
属性名 | 类型 | 说明 |
status | string | 是否成功拉起小程序收银台
|
result | object | 根据 status 属性返回支付结果,详见 result 属性说明 |
result 属性说明:
- •当 status 为 success 时:
属性名 | 类型 | 说明 |
code | number |
|
orderId | string | 抖 音交易系统内部交易订单号
|
- •当 status 为 fail 时:
属性名 | 类型 | 说明 |
errMsg | string | 错误信息 |
errNo | number | 错误码 |
bind:error报错信息
// bind:error 使用示例 handleError(event){ const { errNo , errMsg } = event.detail // errNo(错误码,对应某种具体报错原因) // errMsg(报错信息) }
组件初始化错误
errNo | errMsg | 说明 |
20000 | skuList.skuId should be string, but got undefined | skuList.skuId 未传。其他字段 skuList 校验失败也会有类似错误信息 |
20000 | bindrequestorder should be function, but got undefined | 未绑定 bindrequestorder |
10601 | not login | 用户未登录,组件无渲染 |
169006 | render multiple components | 一个页面同时渲染多个支付前置组件,组件无渲染 |
169007 | component init fail | 组件初始化失败 |
169008 | fail to get cashier info | 获取组件渲染数据失败 |
169009 | unable to use component | 无法使用组件,组件无渲染 |
169021 | unknown scene: ${scene} | 未知 scene,目前仅支持 cash 和 diamond。 |
默认情况下,当组件初始化失败时会给用户重试按钮,用户可点击重试。
为保证支付链路稳定性,当出现以下错误时,建议使用 tt:if 隐藏组件,并回退到 tt.requestOrder + tt.getOrderPayment 支付,errNo 如下:20000、169006、169007、169009。
支付错误
errNo | errMsg | 说明 |
169015 | bind:requestorder method call error | 调用开发者 bind:requestorder 报错 |
169016 | server error, no "sdkInfo" in response | 支付失败,服务端错误 |
169017 | payment failed | 支付失败,组件内部错误 |
169018 | component price is different from the bind:requestorder totalAmount | 传入组件的 skuList price 和 bind:requestorder 返回的 totalAmount 不一致 |
169019 | component tagGroupId is different from the bind:requestorder tagGroupId | 传入组件的 skuList tagGroupId 和 bind:requestorder 返回的 tagGroupId 不一致 |
169020 | bind:requestorder data or byteAuthorization validate error | bind:requestorder 返回值中的 data 或 byteAuthorization 校验失败 |
10000 | 参数错误 | 参数错误 |
商品不符合行业要求 | ||
iOS前置支付组件仅支持钻石场景 | iOS使用payment-channel-select组件仅支持钻石,该报错原因在于bind:requestorder中开发者传入的下单参数data未指定使用钻石下单 | |
10401 | internal error | 请求异常,可重试或升级APP |
11004 | 签名参数异常 | 请开发者自行检查byteAuthorization的格式是否满足此要求 |
签名校验异常 | ||
11001 | 访问未授权 | 该JSAPI依赖用户登录,使用前请确保用户已经完成登录 |
12002 | 账号行为异常 | 账号行为异常 |
13000 | 系统错误 | 系统错误 |
21012 | 创建订单失败,请稍后重试 | 创建订单失败,请稍后重试 |
21016 | 外部单号已存在 | 外部单号已存在 |
21046 | 订单收款商户号不合法 | 订单收款商户号不合法 |
21550 | not login | 请用真机调试或者参考常见问题 |
26001 | 当前订单状态不可支付 | 当前订单状态不可支付 |
26003 | 小程序违规,支付能力被封禁 | 小程序违规,支付能力被封禁 |
26005 | 无可用支付方式 | 无可用支付方式 |
26006 | 商户号与小程序的支付产品不一致 | 商户号与小程序的支付产品不一致 |
为保证支付链路的稳定性,如果出现支付相关错误时,建议回退到 tt.requestOrder + tt.getOrderPayment 支付,errorNo 如下:169015、169016、169017、169018、169019、169020。
代码示例
- 1.页面 json 引入。
{ "usingComponents": { "payment-channel-select": "ext://industry/payment-channel-select" } }
- 2.ttml 引入组件
- a.传入 sku-list 和相应处理回调,当商品变更时,需重新传递商品信息 sku-list 给 payment-channel-select 组件。
- b.使用 tt.canIUse('payment-channel-select') 判断是否支持组件。
<!-- 传递商品信息和绑定回调 --> <payment-channel-select tt:if="{{showPaymentChannelSelect}}" sku-list="{{skuList}}" bind:requestorder="handleRequestOrder" bind:getpaymentresult="handleGetpaymentresult" bind:error="handleError" > </payment-channel-select>
- 3.实现 bind:requestorder 回调,在回调中返回下单参数,参数和 tt.requestOrder 一致。
// bind:requestorder 使用示例 handleRequestOrder(event) { // 开发者服务端下单 // 返回一个 promise return new Promise(resolve => { resolve({ data, byteAuthorization }); }); }
- 4.实现 bind:getpaymentresult 回调,在支付成功或者支付失败时,toast 提示用户,在 code 为 9 时,自行查询订单状态。
// bind:getpaymentresult 使用示例 handleGetPaymenResult(event) { const { status, result } = event.detail; if (status === 'success') { const { code } = result; if (code === 0) { tt.showToast({ icon: 'success', title: '支付成功', }); } else if( code === 9) { // code 为 9,开发者自行查询订单状态 } else { // 支付失败、超时、取消、关闭 tt.showToast({ icon: 'success', title: '支付失败', }); } } else { // 支付失败 tt.showToast({ icon: 'success', title: '支付失败', }); } }
- 5.实现 bind:error 回调,在出现错误时,回退到 tt.requestOrder + tt.getOrderPayment 支付
// bind:error 使用示例 handleError(event){ // errNo(错误码,对应某种具体报错原因) // errMsg(报错信息) const { errNo, errMsg } = event.detail const componentInitError = [169007, 20000] const payError = [169015, 169016, 169017, 169018, 169019, 169020] if (componentInitError.includes(errNo)) { this.setData({ showPaymentChannelSelect: false }) } else if(payError.includes(errNo)) { // 使用 tt.requestOrder + tt.getOrderPayment } }
Bug & Tip
暂无。
常见问题
1.使用 uniapp 脚手架时,接入组件时出现报错: bind:requestorder data or byteAuthorization validate error
原因:bind:requestorder 要求绑定函数的返回值,但是 uniapp 处理的时候,会把这个函数给吞掉,具体可参考:https://ask.dcloud.net.cn/question/189088。
解决方案:
// 在 template 中, 将 @requestorder 改写成 bind:requestorder <payment-channel-select ... bind:requestorder="handleRequestOrder" /> // 在 js 中,在小程序容器上挂上 vue 实例 export default { //... created: { this.$scope.handleReqeustOrder = this.handleReqeustOrder.bind(this) }, methods: { handleReqeustOrder: function handleReqeustOrder() { return new Promise(resolve => { resolve(...) }) } } }
2.组件返回异常 unable to use component
unable to use component