抖音小程序商城类什么的与微信的支付方式没啥区别,但是如果是知识付费类的话有很大区别要用到抖音的支付模板。刚开始对这个东西一窍不通在网上找了好久才搞好。 用uiapp开发的话里面并没有pay-button这个组件所以需要使用原生组件混合的方式接入。
1、 在根目录新建vue.config.js文件。
// vue.config.js
const UniappToGroup = require('uniapp-to-group')
module.exports = {
configureWebpack: {
plugins: [
new UniappToGroup({
// 对应 package.json 中引入插件步骤
package: {
'ttPlugins': {
'dependencies': {
// 注册交易模版插件
'microapp-trade-plugin': {
'version': '1.0.0',
'isDynamic': true
}
}
}
},
app: {
'pages': [
// 下单页
"ext://microapp-trade-plugin/order-confirm",
// "ext://allpage/orders/orders",
// 退款申请页
"ext://microapp-trade-plugin/refund-apply",
// 退款详情页
"ext://microapp-trade-plugin/refund-detail"
]
}
})
]
}
}
2.npm install uniapp-to-group -D
3. 引入组件 新建ttcomponents文件夹,如下
index.html
<!-- 立即抢购 继续支付-->
<!-- 注意使用这个组件 你的课程必须是抖音已经审核通过 -->
<pay-button
mode="{{mode}}"
goods-id="{{goodsId}}"
order-id="{{orderId}}"
order-status='{{orderStatus}}'
goods-type="{{1}}"
bind:getgoodsinfo="getGoodsInfo"
bind:placeorder="userLogin"
bind:pay="onPay"
bind:error="onError"
biz-line="{{2}}"
marketing-ready="{{true}}"
class="{{classname}}"
/>
index.js
Component({
properties: {
mode: Number,
goodsId: {
type: String,
value: "",
},
orderId: {
type: String,
value: "",
},
classname: {
type: String,
value: "",
},
cid: {
type: Number
}
},
data: {},
methods: {
// 非商品库商品
getGoodsInfo(event) {
return new Promise(resolve => {
//我这里因为项目需求课程数据是登陆后拿到,所以在这里写了接口
wx.login({
success: function(res) {
wx.request({
url:接口的请求的url,
method: 'POST',
data: {
code: res.code
},
success: (res) => {
if(res.data.code == 200){
wx.setStorageSync('token', res.data.token)
wx.setStorageSync('userInfo', res.data.date)
wx.setStorageSync('isteacher', res.data.promotion_id)
const {
goodsId
} = event.detail;
let token = wx.getStorageSync('token')
// 在此处开发者可以进行商品数据请求,获取商品信息
wx.request({
url:接口的请求的url,
method: 'POST',
header: {
'token': token
},
data: {
product_id: goodsId
},
success: (res) => {
console.log(res, 'res');
//然后将商品信息传入 resolve 函数
resolve({
currentPrice: 10000,
goodsName: res.data.info.title, //商品标题
goodsPhoto: res.data.info.course_img,//商品图片
goodsLabels: [{
type: 'EXPIRED_RETURNS'
}, // 过期退
{
type: 'REFUND_ANYTIME'
}, // 随时退
{
type: 'BOOK_IN_ADVANCE',
value: 2
} // 提前2日预约
],
minLimits: 1,
maxLimits: 2,
dateRule: '周一至周日可用',
validation: {
phoneNumber: {
required: false // 手机号是否必填, 为 ture则必填,false选填,默认选填
}
},
extra: {
brand:wx.getStorageSync('brand'), //手机型号
appName:wx.getStorageSync('appName'), //app名称
promotion_id:wx.getStorageSync('promotion_id'), //推广号id
source:wx.getStorageSync('source'), //进入小程序方式
}
});
}
})
}else{
// let course_id = wx.getStorageSync('cid')
// let promotion_id= wx.getStorageSync('promotion_id')
// console.log('支付模板失败了111111111111');
// if(promotion_id){
// wx.redirectTo({
// url: `/allpage/details/details?course_id=${course_id}&promotion_id=${promotion_id}`
// })
// }else{
// wx.redirectTo({
// url: `/allpage/details/details?course_id=${course_id}`
// })
// }
}
},
fail:(err)=>{
}
})
}
})
});
},
// 组件传入属性异常、组件内部发生异常时触发
onError(e) {
const {
errNo,
errMsg
} = e.detail;
console.log("errNo", errNo, "errMsg", errMsg);
if (errNo === 21514) {
tt.showToast({
title: "失败", // 内容
icon: "none", // 图标
});
} else if (errNo === 21513) {
tt.showToast({
title: "获取中", // 内容
icon: "none", // 图标
});
}
},
// 支付回调
onPay(options) {
const {
status,
outOrderNo,
result
} = options.detail;
console.log(options.detail, '调用了');
if (status === 'success') {
const {
code
} = result;
if (code === 0) {
// 支付成功后要跳转的页面 注意跳转页面要加上 usr:
//这里就不能用uiapp的东西了 咱们可以用wx原生 或者抖音相关的api
if(options.detail.outOrderNo && options.detail.orderId){
wx.reLaunch({
url: `usr://allpage/payyes/payyes?id=${options.detail.outOrderNo}`
})
}else{
wx.reLaunch({
url:`/allpage/payyes/payyes?id=${options.detail.outOrderNo}`
})
}
} else {
//这里是支付失败或者支付取消后要跳转的地方
if(options.detail.outOrderNo && options.detail.orderId){
wx.navigateTo({
url: `usr://allpage/pay/pay?id=${options.detail.outOrderNo}`
})
}else{
wx.showToast({
icon:'none',
title:'支付失败'
})
}
}
} else {
const {
errMsg
} = result;
}
},
// 由于在前端模板中进行下单需要用户登录,所以建议在此处完成登录或提醒用户打开设置给予相应权限
userLogin(event) {
console.log("place order", event);
return new Promise((resolve) => {
tt.login({
success() {
tt.getUserInfo({
success(res) {
console.log("login success", res);
resolve();
},
fail(res) {
console.log("fail", res);
tt.openSetting({
success: (res) => {
console.log("打开设置页面成功: ", res
.errMsg);
},
fail: (res) => {
console.log("打开设置页面失败: ", res
.errMsg);
},
complete: (res) => {
console.log("接口已调用: ", res.errMsg);
},
});
},
});
},
// setTimeout(() => {
// resolve();
// }, 0);
});
});
},
},
});
index.css 自定义按钮样式 按钮文字不可以修改样式背景可以更改
.xiaozujian {
width: 480rpx;
height: 80rpx;
background: #FA2B3F;
border-radius: 10rpx;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
}
.xiaozujian1 {
width:660rpx;
height: 90rpx;
background: #FA2B3F;
border-radius: 10rpx;
line-height: 90rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
margin-top: 20rpx;
}
.smallxiaozujian {
width: 480rpx;
height: 80rpx;
background: #FA2B3F;
line-height: 80rpx;
text-align: center;
border-radius: 55rpx;
font-size: 32rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
}
.shop{
width:300rpx;
height: 80rpx;
background: #FA2B3F;
border-radius: 40rpx;
line-height: 80rpx;
text-align: center;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
}
index.json
{
"component": true,
"usingComponents": {}
}
4.下单页面获取手机号 此方法写在(App.vue)
<script>
import {
getlogin
} from '@/common/http.api.js';
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
//检测小程序是否更新新版本
const updateManager = tt.getUpdateManager();
updateManager.onUpdateReady(function(res) {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
showCancel: true,
success(res) {
if (res.confirm) {
updateManager.applyUpdate();
}
}
});
});
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
methods: {
getThemeConfig() {
return {
borderRadius: "8rpx", // string
backgroundColor: "#FE2C55", // string
fontColor: "#ffffff", // string
};
},
getPhoneNumber({
params,
success,
fail
}) {
uni.login({
success: function(res) {
let dats = {
code: res.code,
encrypt: params.encryptedData,
iv: params.iv
}
getlogin(dats).then(res => {
if (res.code == 200) {
let result = {
phoneNumber: res.date.phone
}
console.log(result);
success(result)
}
})
}
});
}
},
}
</script>
<style>
/*每个页面公共css */
.z-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.z-flex-con {
display: flex;
align-items: center;
}
.z-flex-aro {
display: flex;
align-items: center;
justify-content: space-around;
}
.rig {
width: 26rpx;
height: 32rpx;
}
button::after {
border: none;
}
</style>
5.开始使用组局,需要在pages.json里面配置 一般来说这个页面就是你的落地页,也就是课程的详情页。
6.在对应页面使用组件 记得goodsId必传
<view class="btnss" v-if="kcisok == 0">
<!-- xiaozujian 在index.ttss 里面定义的样式 -->
<zijie-pay-button classname="xiaozujian" :mode='2' :goodsId="goodsId"
bind:pay="onPay"></zijie-pay-button>
</view>
7.继续支付 继续支付和立即抢购区别不大主要是 orderStatus 这个值有变化 具体可以查看官方文档 pay-button 交易按钮_小程序_抖音开放平台
<view class="footerbtn" >
<zijie-pay-button classname="smallxiaozujian" :orderStatus='0' :orderId="orderId" bind:pay="onPay"></zijie-pay-button>
</view>
这样基本就完事了。需要注意的点
1.泛知识商品类别是商品库商品,接入可以不用关心库存。
2.在开发工具会报错,需要真机调试才可以使用。
3.课程必须已经通过抖音审核已经入库,没有入库的商品无法进行调试。