0


uniapp前端支付篇(微信、抖音、快手、h5)四个平台支付

前言

微信、快手、h5支付步骤大致相同,只有抖音是有自己的支付组件
项目同时支持多个(微信、快手、h5)平台支付,后端那边代码可以封装的

各平台支付大致流程都是相同的,总结了一下分为五个步骤

  1. 点击支付
  2. 创建订单
  3. 生成密钥和支付所需要的参数
  4. 支付成功
  5. 查询订单状态

一、微信支付

1.支付按钮

<button@click="payTap">立即抢购</button>

2.支付事件

payTap(){let that =this// 这些参数后端一般要的let data ={openid:this.openId,//用户id 必需courseId:this.detailsObj.id,//课程id(商品id)必需promoterId:this.promoterShareId ?this.promoterShareId :'',// 分销员idcouponId:this.detailsObj.receiveCouponId ?this.detailsObj.receiveCouponId :'',// 优惠卷id}// 如果一个项目里有多个平台支付,可以用传值来区分// #ifdef MP-WEIXIN
    data.platform =1// #endif// #ifdef MP-KUAISHOU
    data.platform =2// #endif//创建订单createWendaoOrder(data).then(res=>{// 返回密钥createOrder({orderId: res.data.orderId,// 订单idopenid:this.openId,// 用户id}).then(res1=>{// #ifdef MP-WEIXINlet twoData = res1.data
            // 微信支付api// 参数向后端要 要确保每个值就有
            uni.requestPayment({appId: twoData.appId,timeStamp: twoData.timeStamp,nonceStr: twoData.nonceStr,package: twoData.packageValue,signType: twoData.signType,paySign: twoData.paySign,success(result){// 调起支付密码if(result.errMsg =="requestPayment:ok"){// 支付成功
                         uni.showLoading({title:'获取订单状态..',mask:true,})orderSuccess({openid: that.openId,// 用户idorderId: res.data.orderId // 订单id}).then(res=>{
                            uni.hideLoading();
                            uni.showToast({title:'支付成功',icon:'none'});// 重新请求下商品详情
                            that.detailFn()})}else{
                        uni.showModal({title:'',content:'支付失败',showCancel:false,icon:'none',success(res){}})}},fail(result){
                    console.log(result)
                    uni.showModal({title:'',content:'支付失败',showCancel:false,icon:'none',success(res){}})},})// #endif}).catch(res=>{
            console.log(res)})})}

二、快手支付

1.支付按钮

<button@click="payTap">立即抢购</button>

2.支付事件

payTap(){let that =this// 这些参数后端一般要的let data ={openid:this.openId,//用户id 必需courseId:this.detailsObj.id,//课程id(商品id)必需promoterId:this.promoterShareId ?this.promoterShareId :'',// 分销员idcouponId:this.detailsObj.receiveCouponId ?this.detailsObj.receiveCouponId :'',// 优惠卷id}// 如果一个项目里有多个平台支付,可以用传值来区分// #ifdef MP-WEIXIN
    data.platform =1// #endif// #ifdef MP-KUAISHOU
    data.platform =2// #endif//创建订单createWendaoOrder(data).then(res=>{// 返回密钥createOrder({orderId: res.data.orderId,// 订单idopenid:this.openId,// 用户id}).then(res1=>{// 后端返回的是这些数据// res1.data = {// order_no: "1231xxxxxxxxxxxxxxx450" // order_info_token: "ChJrc01wUGF5LmxxxxxxxxxxxxxxxWYYeulijTrRyDdowh6Lvtp2MIm-t5nlq4s3xxxxxxxxxxxxxxxxxxxuh217_-giIIHDQ8yTqZqghjVraGC_NjxxxxxxxxxxxxxxKAUwAQ"// {// 快手支付api// #ifdef MP-KUAISHOU
            ks.pay({serviceId:'1',orderInfo: res1.data,success:functionsuccess(res2){// 调起支付密码// 支付成功
                     uni.showLoading({title:'获取订单状态..',mask:true,})orderSuccess({openid: that.openId,// 用户idorderId: res.data.orderId // 订单id}).then(res=>{
                        uni.hideLoading();
                        uni.showToast({title:'支付成功',icon:'none'});// 重新请求下商品详情
                        that.detailFn()})},fail:functionfail(res){
                    uni.showToast({title:'支付失败',icon:'none'})}})// #endif}).catch(res=>{
            console.log(res)})})}

三、抖音支付

抖音有自己的支付组件和自己的下单页面,所以需要创建一个专属于抖音的组件,并把需要的参数进行传递

1.创建组件

1.新建ttcomponents文件夹,创建完后在ttcomponents下面再新建DyPayButton文件夹,然后在DyPayButton下面创建四个文件,分别为index.js、index.json、index.ttml、index.ttss
2.要创建在App.vue同级

在这里插入图片描述

先在App.vue 写baseUrl和getPhoneNumber函数

<script>exportdefault{onLaunch:function(){},onShow:function(){
            console.log('App Show')},onHide:function(){
            console.log('App Hide')},methods:{// 这个是接口基地址baseUrl(){return'https://kspaycallback.wendao101.com/douyin'},/**
             * desc: 获取手机号
             * params:加密数据
             * success:成功回调
             * fail: 失败回调
             */// 这个是抖音下单页获取手机号调用的函数getPhoneNumber({
                params,
                success,
                fail
            }){const{
                    iv,
                    encryptedData
                }= params;miniLogin().then(data=>{getTtOpen(data).then(data1=>{// 获取手机号函数savePhone({openid: data1.data.data.openId,
                            iv,
                            encryptedData
                        }).then(data4=>{miniLogin().then(data6=>{getTtOpen(data6).then(data5=>{const result ={phoneNumber: data5.data.data.telNumber,}// 回调前端模板success(result)})})})})})},},}</script><style lang="scss">
    @import"@/uni_modules/uview-ui/index.scss";

    @import'@/utlis/index.scss';/*每个页面公共css */</style>

下面是那四个文件的内容
index.js

// 可以调用到app.vue里的方法const app =getApp();Component({properties:{mode: Number,openId:{type:[String, Number],},orderStatus:{type:[String, Number],},detailsObj:{type: Object,},goodsId:{type: String,value:"",},promoterShareId: Number,},data:{},methods:{// 提交商品信息 这个函数一进页面就会调用的getGoodsInfo(event){const that =thisreturnnewPromise(resolve=>{// 定时器是为解决 优惠卷id获取不到问题setTimeout(()=>{
                    tt.getSystemInfo({success:(resPlatform)=>{let pay = that.data.detailsObj.price *100// 价格单位是分let promoterShareId = that.data.promoterShareId // 分销员idlet required = that.data.detailsObj.giveEntityIsNeedPhone // 是否强制获取手机号let CouponId = that.data.detailsObj.receiveCouponId // 优惠卷id// 用不到的值就不用传let data ={currentPrice: pay,GoodsLabel:[{type:'NON_REFUNDABLE'}],minLimits:1,maxLimits:1,dateRule:'周一至周日可用',extra:{promoterId: promoterShareId,receiveCouponId: CouponId
                                },validation:{phoneNumber:{required: required // 手机号是否必填}},marketingVersion:1,}// im客服需要提前开通// 判断如果用户手机是ios就走客服支付, 把imId传上就自动跳转im客服页面了,安卓不要传这个id,否则可能会导致支付不了if(resPlatform.platform =='ios'){
                                data.imId ='3xxxxxxxx42'}// 然后将商品信息传入 resolve 函数resolve(data);}});},600)})},onError(e){const{
                errNo,
                errMsg
            }= e.detail;if(errNo ===21514){
                tt.showToast({title:"失败",// 内容icon:"none",// 图标});}elseif(errNo ===21513){
                tt.showToast({title:"获取中",// 内容icon:"none",// 图标});}},userLogin(event){const{
                goodsId,
                goodsType
            }= event.detail
            returnnewPromise((resolve, reject)=>{
                tt.login({success(e){// 用户登录成功并获取信息,则调用 resolve 函数,跳转至提单页resolve();},fail(){// 用户登录失败,则跳转提单页失败
                        _this.showTost("登录失败")}});});},payError(event){this.showTost(event.errMsg)},// 继续支付handleContinutePay(event){const{ status, outOrderNo, result }= event.detail;if(status ==='success'){const{ code }= result;if(code ===0){// 继续支付成功// 刷新页面this.triggerEvent("refreshData")
                    tt.showToast({title:"支付成功",});}}else{// 继续支付失败
                tt.showToast({title:"继续支付失败",icon:"none"});}},// 正式支付newButtonPay(event){const{
                status,
                orderId,
                outOrderNo,
                result
            }= event.detail;if(status ==='success'){const{
                    code
                }= result;if(code ===0){
                    tt.showLoading({title:"订单确认中...",});this.getOrderIsHaveData(outOrderNo)}else{// 支付失败(超时、取消、关闭)this.showTost('支付失败(超时、取消、关闭)')}}else{const{
                    errMsg
                }= result;this.showTost(errMsg)}},showTost(tit, timeMs){let time = timeMs >0? timeMs :1500;
            tt.showToast({title: tit,icon:"none",duration: time,});},// 重新订单getOrderIsHaveData(orderId){let data ={openid:this.data.openId,
                orderId,}
            tt.request({url: app.baseUrl()+"/order/order_success",method:'POST',
                data,success:(res)=>{this.setOrderIsHaveData(res.data.orderStatus, orderId)}})},setOrderIsHaveData(data, orderId){if(data ==0){setTimeout(()=>{
                    _this.getOrderIsHaveData(orderId)},1000);}else{
                tt.hideLoading();
                tt.navigateBack(-1);this.triggerEvent("refreshData")}},// 退款onApplyrefund(event){
            console.log(event)const{
                orderId
            }= event.detail;const extra ={
                orderId
            };// 开发者需要透传的参数,可自定义内容returnnewPromise(resolve=>{resolve(extra);});},onRefund(event){
            console.log(event)const{
                status,
                result
            }= event.detail;if(status ==='success'){const{
                    refundId,
                    outRefundNo
                }= result;}else{const{
                    errMsg
                }= result;
                tt.showToast({title: e.detail.errMsg ? e.detail.errMsg :'失败',icon:"none"});}},refundError(e){
            console.log(e)if(e.detail.errNo ==21531){
                tt.showToast({title:"不符合退款要求",icon:"none"});}else{
                tt.showToast({title: e.detail.errMsg ? e.detail.errMsg :'失败',icon:"none"});}},},});

index.json

{"component":true,"usingComponents":{}}

index.ttml

<!-- 立即抢购 --><blocktt:if="{{mode==2}}"><pay-buttonclass="{{classsname}}"mode="{{2}}"goods-id="{{detailsObj.productId}}"goods-type="{{1}}"biz-line="{{2}}"bind:getgoodsinfo="getGoodsInfo"bind:placeorder="userLogin"marketing-ready="{{true}}"bind:pay="newButtonPay"bind:error="onError"></pay-button></block><blocktt:if="{{mode==1}}"><!-- 继续支付 --><pay-buttontt:if="{{orderStatus==0}}"class="{{classsname}}"order-status="{{0}}"order-id="{{orderData.orderId}}"bind:pay="handleContinutePay"></pay-button><!-- 退款 --><pay-buttonclass="order_ljzf"mode="{{1}}"goods-type="{{1}}"order-status="{{1}}"order-id="{{orderData.orderId}}":refund-total-amount="{{orderData.coursePrice}}"biz-line="{{2}}"marketing-ready="{{true}}"catch:applyrefund="onApplyrefund"catch:refund="onRefund"catch:error="refundError"tt:if="{{orderData.orderStatus==1}}"></pay-button><!-- 退款状态 --><pay-buttonclass="order_tk"mode="{{1}}"goods-type="{{1}}"order-status="{{orderData.orderStatus=='4'?2:orderData.orderStatus=='2'?3:orderData.orderStatus=='5'?4:4 }}"refund-id="{{orderData.orderId}}"biz-line="{{2}}"marketing-ready="{{true}}"catch:applyrefund="onApplyrefund"catch:refund="onRefund"catch:error="refundError"tt:if="{{orderData.orderStatus!=1 && orderData.orderStatus!=0}}"></pay-button></block>

index.ttss

按钮样式根据自己的来

.save_one{width: 100%;height: 100%;}.payButton{display: flex;align-items: center;justify-content: center;width: 310rpx;height: 90rpx;border-radius: 45rpx;box-sizing: border-box;background-color: #E10000;color: #fff;border: 2rpx solid #E10000;}.payButtonItem{display: flex;align-items: center;justify-content: center;width: 183rpx;height: 57rpx;background: #E10000;border-radius: 29rpx;border: 1rpx solid #E10000;font-size: 26rpx;font-family:"Noto Sans SC";font-weight: 600;color: #fff;line-height: 37rpx;box-sizing: border-box;margin-right: 16rpx;}

2.在pages.json给商品详情页面注册组件

"pages":[{"path":"details/details","style":{// #ifdef MP-TOUTIAO// 这个是需要加的,否则显示不出来"usingComponents":{"zijie-pay-button":"/ttcomponents/DyPayButton/index"},//#endif"navigationBarTitleText":"xxxx","enablePullDownRefresh":false}}]

3.在商品详情页面中使用组件

components:{// #ifdef MP-TOUTIAO"zijie-pay-button":"../../ttcomponents/DyPayButton/index",//#endif}
<zijie-pay-buttonv-if="detailsObj.productId":openId="openId":mode='2':detailsObj="detailsObj":classsname="'save_one'":promoterShareId="promoterShareId"@refreshData="refreshData"></zijie-pay-button>
>
// v-if: 判断有没有商品id
// openId: 用户id
// mode: 商品类型
// detailsObj: 商品详情页的数据
// classsname: 按钮类名
// promoterShareId: 分销员id
// @refreshData: 用于支付成功回调刷新页面

4.h5支付

主要是为解决微信ios无法支付的问题,ios走h5支付渠道

1.创建按钮

// 这个按钮是uView组件
<u-buttontext="联系老师"v-if="isIosDouYin"shape="circle"color="#E10000":send-message-title="detailsObj.title?detailsObj.title:''":send-message-img="detailsObj.coverPicUrl":send-message-path="'/pages_details/details/details?courseId=' + detailsObj.id + '&promoterId=' + promoterShareId + '&couponId=' + detailsObj.receiveCouponId + '&appNameType=1&platform=1&openid=' + openId"show-message-card="true"open-type="contact"></u-button>

// isIosDouYin: 判断是否为ios系统
// send-message-title: 商品标题
// :send-message-img: 商品封面
// :send-message-path: 跳转路径
// show-message-card: 发送卡片

2.创建页面

在详情页同级目录创建一个页面detailsContact.vue,后端可以重定向到这个页面

var _this;exportdefault{data(){return{openid:'',// 用户idh5PayData:{},// h5提交的参数h5OrderId:''// 订单id}},onLoad(options){
            _this =this// 页面一进来就调用支付 带上路径传的值this.payTap(options)},methods:{payTap(queryObj){let that =this
                that.openid = queryObj.openid
                let data ={openid: queryObj.openid,// 用户idcourseId: queryObj.courseId,// 课程idpromoterId: queryObj.promoterId ? queryObj.promoterId :0,// 推广员idcouponId: queryObj.couponId ? queryObj.couponId :0,// 优惠卷idappNameType: queryObj.appNameType,// 区分哪个小程序platform: queryObj.platform // 区分平台}createWendaoOrder1(data).then(res=>{createOrder1({orderId: res.data.orderId,openid: queryObj.openid,}).then(res1=>{// #ifdef H5
                        that.h5PayData = res1.data
                        that.h5OrderId = res.data.orderId
                        that.getWxOfficePay()// #endif}).catch(res=>{
                        console.log(res)})})},getWxOfficePay(){if(typeof WeixinJSBridge =="undefined"){if(document.addEventListener){
                        document.addEventListener('WeixinJSBridgeReady', _this.getWxOfficePayPage,false);}elseif(document.attachEvent){
                        document.attachEvent('WeixinJSBridgeReady', _this.getWxOfficePayPage);
                        document.attachEvent('onWeixinJSBridgeReady', _this.getWxOfficePayPage);}}else{
                    _this.getWxOfficePayPage()}},getWxOfficePayPage(){const that =this
                console.log("h5支付调起支付面板 ")
                WeixinJSBridge.invoke('getBrandWCPayRequest',{appId: _this.h5PayData.appId,timeStamp: _this.h5PayData.timeStamp,nonceStr: _this.h5PayData.nonceStr,package: _this.h5PayData.packageValue,signType: _this.h5PayData.signType,paySign: _this.h5PayData.paySign,},function(res){if(res.err_msg =="get_brand_wcpay_request:ok"){
                            uni.showLoading({title:'获取订单状态..',mask:true,})// 确认订单
                            uni.request({url: app.baseUrl()+"/order/order_success",method:'POST',data:{openid: that.openId,orderId: that.h5OrderId
                                },success:(res)=>{
                                    uni.hideLoading();
                                    uni.showModal({title:'',content:'支付成功,请返回小程序查看课程',showCancel:false,icon:'none'})}})}else{
                            uni.showModal({title:'',content:'支付失败',showCancel:false,icon:'none',success(res){}})}});},}}
标签: uni-app 前端 微信

本文转载自: https://blog.csdn.net/weixin_46124693/article/details/134711710
版权归原作者 伴梦123 所有, 如有侵权,请联系我们删除。

“uniapp前端支付篇(微信、抖音、快手、h5)四个平台支付”的评论:

还没有评论