场景:在购物车页面,用户选中了商品,点击结算,则跳转到结算页面
1.在结算页面初加载时 =》发送获取支付方式的请求
前端:传商品id(token一直带在请求头里)
后端:商品信息、总价、拿到**可选的支付方式
2.用户选择支付方式后,点击确认订单时 =》发送获取订单号的请求
前端:传支付方式、商品id
后端:拿到**订单号orderinfo
3.紧接着,在.then中判断res.meta.code===‘200’,就使用uni-app提供的uni.requestPayment =》发送支付请求
前端:传订单号、支付方式
uni.requestPayment返回:返回用户支付成功或者失败。支付成功——跳转页面(包括订单号、支付方式等);支付失败——支付失败的页面。
pay.vue
<template>
<view class="pay">
<u-navbar title="确认购买"></u-navbar>
<scroll-view scroll-y="true" :style="'height:'+clientHeight+ 'px;'">
<view class="pay-main" :style="'height:'+clientHeight+ 'px;'">
<view class="pay-container">
<view class="pay-header">商品信息</view>
<view class="pay-list">
<view class="pay-item" v-for="item in coursesList" :key="item.id">
<view class="pay-img">
<image :src="item.courseCover" mode=""></image>
</view>
<view class="pay-desc">
<view class="pay-title">{{item.courseName}}</view>
<view class="pay-price">¥{{item.discountPrice}}</view>
</view>
</view>
</view>
</view>
<view class="pay-discount">
<view class="discount">商品价格</view>
<view class="discount-btn">¥{{totalPrice}}</view>
</view>
<view class="pay-methods">
<view class="p-m-title" style="padding: 36rpx 0;">支付方式</view>
<view class="discount-btn" v-for="item in payment" :key="item.code" @tap="changePay(item.code)">
<view class="discount">
<u-icon class="icon" name="weixin-circle-fill" color="#01af37" size="50" v-if="item.code === 'wxpayment'">
</u-icon>
<u-icon class="icon" name="zhifubao-circle-fill" color="#01a8eb" size="50"
v-else-if="item.code === 'alipayment'"></u-icon>
{{item.description}}
</view>
<view class="discount-btn">
<label class="footer-radio">
<radio color="rgba(102, 228, 146, 1)" :checked="item.code === currentPaymentCode" />
</label>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="pay-footer">
<view class="pay-actual">实付:¥{{totalPrice}}</view>
<!-- #ifdef APP-PLUS -->
<view class="pay-submit" @tap="submit">确认订单</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="pay-submit" @tap="submitH5">确认订单</view>
<!-- #endif -->
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
import {
mapState,
mapMutations,
mapActions
} from 'vuex'
import api from '@/service/pay.js'
export default {
data() {
return {
isChecked: false,
clientHeight: 800,
coursesList: [], // 选择商品的
totalPrice: 0, // 总价格
payment: [], // 承载支付方式的
currentPaymentCode: "",
immediately: null,
}
},
computed: {
...mapState({
selectList: state => state.cart.selectList,
singleList: state => state.cart.singleList
})
},
onReady() {},
onLoad(payload) {
if (payload) {//如果是从课程详情页直接跳转到结算页,payload就是详情页的singleList
this.immediately = payload
}
this.__init()
},
methods: {
...mapMutations(['removeDetailPay']),
__init() {
let params = null
if (this.immediately) {
params = this.singleList
} else {
params = this.selectList
}
//1. 在结算页面初加载时 =》发送获取支付方式的请求
api.settlement(params).then(res => {
if (res.meta.code = "200") {
this.coursesList = res.data.courses
this.totalPrice = res.data.totalPrice
this.payment = res.data.payModes
} else {
this.$refs.uToast.show({
title: res.meta.msg,
type: 'error',
icon: false
})
}
}).catch(err => {
this.$refs.uToast.show({
title: err.meta.msg,
type: 'error',
icon: false
})
})
},
// 切换支付方式
changePay(code) {
this.currentPaymentCode = code
},
// h5支付
submitH5() {
},
// app 提交订单 支付
submit() {
let params = null
if (this.immediately) {
params = this.singleList
} else {
params = this.selectList
}
if (this.currentPaymentCode === 'alipayment') {
//2. 用户选择支付方式后,点击确认订单时 =》发送获取订单号的请求
api.alipay({
courses: params,
payModes: this.currentPaymentCode
}).then(res => {//拿到订单号
if (res.meta.code === '200') {
this.removeDetailPay()
if (res.data.isFree) { //免费课
uni.switchTab({
url: '../study/study'
})
} else { //非免费课
let orderNumber = res.data.orderNumber
//3. 拿到订单号后 使用uni-app提供的uni.requestPayment =》发送支付请求
uni.requestPayment({
provider: 'alipay',
orderInfo: res.data.orderInfo,
success: (ress) => {
console.log(ress);
if (ress.errMsg === 'requestPayment:ok') { //支付成功
uni.navigateTo({
url: '../pay-info/pay-info?isSuccess=' + true + '&orderNumber=' + orderNumber +
'&payCode=' + this.currentPaymentCode
})
} else { //支付失败
uni.navigateTo({
url: '../pay-info/pay-info?isSuccess=' + false + '&orderNumber=' + orderNumber +
'&payCode=' + this.currentPaymentCode
})
}
},
fail: (err) => {
console.log(err);
}
});
}
}
}).catch(err => {
console.log(err)
})
} else if (this.currentPaymentCode === 'wxpayment') {
//微信支付
}
}
}
}
</script>
class-detail.vue 课程详情页直接跳转至结算页
<template>
<view class="class-detail">
<!-- 导航 -->
<u-navbar title="">
<view class="detail-footer">
<view class="shopcart btn" @tap="addCart">加入购物车</view>
<view class="buy btn" @tap="goPay">立即购买</view>
</view>
{{classId}}
<u-toast ref="uToast" />
</view>
</template>
<script>
import api from '@/service/coursedetail.js'
import tokenApi from '@/service/token.js'
import {
mapState,mapMutations
} from 'vuex';
import CourseItem from '@/common/course/course-item.vue'
import Catalogue from '@/common/course-detail/catalogue/index.vue'
import Download from '@/common/course-detail/download/index.vue'
export default {
components: {
CourseItem,
Catalogue,
Download
},
data() {
return {
classId: null, //详情页课程id
}
},
computed: {
...mapState({
userInfo: state => state.user.userInfo
})
},
onLoad() {
this.classId = params.classId //上页接收到的
this.__init()
},
methods: {
...mapMutations(['classDetailPay']),
//立即购买
goPay() {
if(uni.getStorageSync('token')){
//已登录
this.classDetailPay(this.classId)//传给mutation 改变singleList
uni.navigateTo({
url:'../pay/pay?single='+'pay-detail'
})
}else{
this.$refs.uToast.show({
title: '请先登录',
type: 'error',
icon: false,
url: '/pages/login/login'
})
}
}
}
}
</script>
store > modules > cart.js
import api from "@/service/shopcart.js"
export default {
state: {
shopList: [], //购车数据 全部
selectList: [], // 选中数据 [{id:'',shopcartid:'',number:''},..,..]
singleList: [], //从课程详情去结算页的选中数据
},
getters: {
},
mutations: {
//课程详情页结算
classDetailPay(state, payload) { //classId
//防止重复添加
let i = state.singleList.findIndex(item => item.id === payload)
if (i > -1) {
return
} else {//此条不存在再添加
state.singleList = [{
id: payload, //课程id
number: 1
}]
}
},
//清空singleList
removeDetailPay(state){
state.singleList=[]
}
},
actions: {
}
}