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 - 钻石支付
注意:
    目前安卓端仅支持 cash ,iOS端仅支持 diamond
    iOS 端必传 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
商品价格
    当scene=空或cash时,单位为人民币(分)
    当scene=diamond时,单位为钻石数量(颗)
注意:
    需保证所有商品价格和等于 bind:requestorder 返回的 data.totalAmount
title
string
商品标题,长度 <= 256字节
type
number
商品类型,详细查看
tagGroupId
string
标签组 id ,点此查看枚举
注意:
    根据接入规范,选择适合的标签组ID传入,该标签组对应的标签将在组件上展示。
    需保证 tagGroupId 等于 bind:requestorder 返回的 data.skuList[0].tagGroupId

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
是否成功拉起小程序收银台
    success: 成功
    fail: 失败
result
object
根据 status 属性返回支付结果,详见 result 属性说明
result 属性说明:
    当 status 为 success 时:
属性名
类型
说明
code
number
    0:支付成功
    1:支付超时
    2:支付失败
    3:支付关闭
    4:支付取消
    9:订单状态开发者自行获取
orderId
string
抖音交易系统内部交易订单号
    如果有实现订单继续支付的功能,可凭借 orderId 调用 tt.getOrderPayment 继续支付
    当 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的格式是否满足此要求
签名校验异常
请开发者自行查阅此文档FAQ排查
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

请先确认已开通通用交易系统《接入指引》。