交易系统组件开发指南

更新时间 2024-08-23 07:48:30
收藏
我的收藏
通过插件的形式,我们预先实现了一些页面模板,例如退款页模板,小程序开发者只需要直接引入相应插件,并且遵循插件约定的规范,与插件之间实现相互通信,即可完成相应的页面,从而提高开发效率。​
交易系统前端模板在页面维度上提供了提单页模板、退款页模板等,模板的入口是一个pay-button 组件,通过该组件实现从小程序跳转到前端模板页面。​
注:提单页即用户点击下单后进入的页面,也叫下单页​

方案1:行业 SDK 交易组件接入指南(推荐使用)​

    1.使用 pay-button 需要行业sdk支持,可以通过以下方法判断。 ​
JavaScript
复制
// 判断是否支持行业sdk 的 pay-button 组件
if (tt.canIUse("industrySDK.pay-button")) {
// do something
}
    2.另外在使用组件时需要在页面 json 文件中进行引入。 ​
JSON
复制
// index.json
{
"usingComponents": {
"pay-button-sdk": "ext://industry/pay-button"
}
}
这样,在页面的 ttml 中就可以像使用自定义组件一样使用行业sdk组件。​
HTML
复制
<pay-button-sdk
mode="{{2}}"
goods-type="{{1}}"
goods-id="xxxx"
bind:getgoodsinfo="getGoodsInfo"
bind:placeorder="userLogin"
bind:pay="onPay"
/>
    3.行业sdk pay-button 对路由逻辑进行了优化,小程序开发者无需主动引入插件页面(即无需修改小程序全局配置文件 package.json 和 app.json),也可实现跳转相应的页面,从而提高开发效率。 ​
    4.直播间直跳场景支持营销能力​
    5.暂不支持在 IDE 上调试,请以真机调试为准。​
更多接入细节详见:pay-button 交易按钮(行业sdk)

方案2:交易组件接入指南(旧版组件使用方式,不建议使用)​

使用限制
使用交易模版页面需要基础库支持,可以通过以下方法判断。​
JavaScript
复制
// 判断是否支持交易模版2.0 和 pay-button 组件
if (tt.canIUse("microapp-trade-plugin")) {
// do something
}

第一步:在小程序中引入插件​

修改小程序全局配置文件 package.json 和 app.json。​
    package.json:​
json
复制
{
"ttPlugins": {
"dependencies": {
// 配置插件名,版本等信息
"microapp-trade-plugin": {
"version": "1.1.2",
"isDynamic": true
}
}
}
}
    app.json:​
json
复制
{
"pages": [
"pages/index/index",
// 提单页
"ext://microapp-trade-plugin/order-confirm",
// 退款申请页配置
"ext://microapp-trade-plugin/refund-apply",
// 退款详情页
"ext://microapp-trade-plugin/refund-detail"
]
}
说明:在插件页面(提单页、申请退款页、退款详情页)想跳转到小程序页面时,需要在页面路径前加 usr://
js
复制
tt.navigateTo({
url: "usr://pages/index/index",
});

第二步:使用组件​

前端模板提供了一个入口组件pay-button,该组件是小程序基础库内置组件,可直接使用。​
具体使用方式,请参见pay-button 交易按钮。​

第三步:挂载 app 方法(可选)​

除了引入插件及使用 pay-button 组件之外,开发者还需要在 app 上挂载以下两个方法,挂载的方法会在不同的特定时机下被前端模板调用。​

getThemeConfig​

在前端模板的页面中,我们面向开发者开放了主题色配置,包括了前端模板内按钮的圆角大小、背景色、文字颜色。若开发者不定义此方法,将使用交易系统默认主题色。​
通过修改 app.js 文件,在该方法中定义主题色。​
js
复制
// app.js
/**
* desc: 主题色配置
* borderRadius:按钮圆角大小,默认 8rpx
* backgroundColor:按钮背景色 + 退款原因选中背景色,默认 #FE2C55
* fontColor:按钮字体颜色,默认 #ffffff
*/
getThemeConfig() {
return {
borderRadius: '8rpx', // string
backgroundColor: '#FE2C55', // string
fontColor: '#ffffff', // string
}
}

getPhoneNumber​

为了保证「一键填写」按钮可用,开发者需传入此方法。​
在提单页中,有一个「一键填写」的按钮,该按钮调用了小程序获取手机号的开放能力,在模板中的实现大致如下:​
html
复制
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
使用本机号码
</button>
/** * desc: 获取手机号 * encryptedData: 包括敏感数据在内的完整用户信息的加密数据
* iv:加密算法的初始向量 */ getPhoneNumber(e) { const { iv, encryptedData } =
e.detail; ... }
当用户在提单页点击该按钮时,会弹出手机号授权弹窗,用户允许授权后,模板会将 ivencryptedData 传递给开发者,开发者需要通过解密后得到手机号,然后以回调的方式通知前端模板,模板收到后将手机号传入输入框。​
注意
    ivencryptedData的含义及解密说明请参考获取手机号。​
js
复制
// app.js
/**
* desc: 获取手机号
* params:加密数据
* success:成功回调
* fail: 失败回调
*/
getPhoneNumber({ params, success, fail }) {
const { iv, encryptedData } = params;
// ...
// 开发者服务端解密 encryptedData,得到手机号
// ...
const result = {
phoneNumber: '13580006666',
}
// 回调前端模板
success(result)
}

第四步:提单页直跳(可选)​

在直播间&短视频场景下,部分开发商希望用户能够直接进入提单页面,无需进入商详页,实现用户下单功能,为实现该功能需要对商品库商品信息及小程序代码进行相关改造。若无相关需求,可暂时不进行相关改造。 ​
支持提单页直跳的抖音版本为 19.7,安卓、iOS 可下载最新线上版本即可测试。 ​
低版本(低于抖音 19.7)用户不支持提单页直跳时,会跳转至 trade_url 配置的地址。 ​
在行业sdk的提单页,直跳场景支持使用营销能力,支持的抖音版本为 27.0(使用行业sdk提单页,需要联系运营配置白名单)。​

商品库商品信息配置 trade_url​

直播间&短视频商品若需实现点击抢购直跳,需要给商品库配置 trade_url 相关信息,需要在 trade_url 的 params 中增加新的字段。注意:该功能并不能免除配置 trade_url 的工作,如果要直播,该值必填。( trade_url数据格式参考:https://bytedance.larkoffice.com/docx/doxcncpgP3vi7QtK4CPX7Ark1sd
字段名​
类型​
默认值​
必传​
说明​
use_template​
boolean​
无​
否​
当前商品是否需要直跳功能​
    true时,商品可直跳交易模版提单页​
    false或未填入时,跳转的地址为trade_url配置的地址​
is_phone_necessary​
boolean​
true​
否​
当前商品手机号为必填​
min_limits​
number​
1​
否​
最小起购份数​
js
复制
const demoData = {
product: {
account_name: "提单页作为首页",
attr_key_value_map: {
appointment:
'{"need_appointment":true, "ahead_time_type":2, "ahead_hour_num":5,"external_link":"urlxxx", "order_appointment_time_url":"urlxxx"}',
auto_renew: "true",
bring_out_meal: "false",
can_no_use_date:
'{"enable": true,"days_of_week": [7, 1, 2, 3, 4],"holidays": [1, 2, 3, 4, 5],"date_list": ["2022-03-08", "2022-03-09"],"holiday_dates": {"1": "2022.01.01-2022.01.03"}}',
customer_reserved_info: '{"allow":false}',
description_rich_text:
'[{"note_type":1,"content":"其他说明信息-美食团购"}]',
detail_image_list: '[{"uri":"aweme-upload-image/7038504987084734508"}]',
dishes_image_list: '[{"uri":"aweme-upload-image/7038504987084734508"}]',
EntryType: "2",
environment_image_list:
'[{"uri":"aweme-upload-image/7038504987084734508"}]',
free_pack: "true",
FrontCategoryTag: '["美食套餐"]',
image_list:
'[{"uri":"aweme-upload-image/7038505021658382380"},{"uri":"aweme-upload-image/7038505050439696428"}]',
IsConfirmImme: "true",
Notification: '[{"title":"标题","content":"内容美食1.1"}]',
private_room: "true",
real_name_info: '{"enable":false,"scene":0}',
RecommendWord: "推荐语",
rec_person_num: "99",
rec_person_num_max: "999",
RefundPolicy: "2",
refund_need_merchant_confirm: "true",
show_channel: "2",
SortWeight: "0",
superimposed_discounts: "true",
TagList: "标签列表-待填写",
trade_url:
'{"app_id":"ttcfdbb96650e33350","params":"{\\"use_template\\":true,\\"is_phone_necessary\\":true,\\"min_limits\\":1,\\"goodsId\\":\\"123456\\"}","path":"page/detail/detail"}',
use_date:
'{"use_date_type":1,"use_start_date":"2021-12-06","use_end_date":"2033-03-03"}',
use_time: '{"use_time_type":1}',
},
biz_line: 5,
out_url:
'{"app_id":"ttcfdbb96650e33350","params":"{\\"productId\\":\\"1\\",\\"packageId\\":2,\\"channelLinkId\\":3}","path":"page/detail/detail"}',
category_id: 1001001,
out_id: "lmc-life-app-006",
poi_list: [
{
supplier_ext_id: "DXQPOI-supplier_ext_id-002",
},
],
product_name: "提单页作为首页-提单页补充参数没有的商品",
product_type: 1,
sold_end_time: 1745607528,
sold_start_time: 1646724999,
telephone: ["1234-4321"],
},
sku: {
actual_amount: 996,
attr_key_value_map: {
code_source_type: "1",
commodity:
'[{"group_name":"测试0001","total_count":1,"option_count":1,"item_list":[{"name":"可乐","price":1998,"count":1,"unit":"份"}]}]',
limit_rule: '{"is_limit":true,"total_buy_num":999999}',
market_price: "900",
settle_type: "1",
use_type: "1",
},
origin_amount: 1399,
sku_name: "测试",
status: 1,
stock: {
limit_type: 0,
stock_qty: 500,
},
},
};

直跳提单页下需挂载的 app 方法​

由于直跳场景下,无 pay-button 组件前置挂载,无法触发 bindgetgoodsinfo、bindpay 等方法,所以需要在 app 的 TradingSystem 对象上挂载相关方法获取相关数据及触发回调。​
userLogin​
由于下单时需要用户在小程序中处于登录态,与 bindplaceorder 方法类似,可复用相关代码,所以提供该回调供小程序校验及提醒用户进行登录,代码示例见下方。​
getExtraInfo​
部分开发者在下单时会透传 extra 信息,直跳场景下会通过 getExtraInfo 获取相关透传数据,与 bindgetgoodsinfo 方法类似,可复用相关代码,代码示例见下方。​
pay​
用户支付成功或取消后相关回调,与 bindpay 方法类似,可复用相关代码,代码示例见下方。​
error​
错误发生时的相关回调,与 binderror 方法类似,可复用相关代码,代码示例见下方。​
代码示例
js
复制
App({
getPhoneNumber({ success }) {
// 获取手机号
},
getThemeConfig() {
// 获取主题色
},
TradingSystem: {
userLogin(event) {
const { goodsId, goodsType } = event.detail;
return new Promise((resolve, reject) => {
tt.login({
success() {
// 用户登录成功并获取信息,用户可正常下单
resolve();
},
fail(res) {
// 用户登录失败,提单页会提示用户登陆,否则无法下单
reject(res);
},
});
});
},
getExtraInfo(event) {
const { goodsId, goodsType } = event.detail;
return new Promise((resolve, reject) => {
resolve(
{
extra: { test: 123, use_trade_delivery: 1 },
marketingReady: true, // 是否需要营销
marketingVersion: 2, // 营销版本
validation: {
phoneNumber: {
required: true, // 手机号是否必填, 为 ture则必填,false选填,默认选填
},
},
}
);
});
},
pay(event) {
const { status, orderId, outOrderNo, result } = event.detail;
if (status === "success") {
const { code } = result;
if (code === 0) {
console.log(
`pay success,orderId = ${orderId}, outOrderNo = ${outOrderNo}, code = ${code}`
);
} else {
// 支付失败(超时、取消、关闭)
console.log(
`pay fail = ${orderId}, outOrderNo = ${outOrderNo}, code = ${code}`
);
}
} else {
const { errMsg } = result;
console.log(
`pay fail,orderId = ${orderId}, outOrderNo = ${outOrderNo}, errMsg = ${errMsg}`
);
}
},
error(event) {
const { errMsg, errNo, errLogId } = event.detail;
console.log(
`error, errMsg = ${errMsg}, errNo = ${errNo}, errLogId = ${errLogId}`
);
},
},
});