Vue2项目中的交易流程与Alipay支付

358 阅读1分钟

交易流程大概如下,前端的话,还是关于路由跳转,页面渲染,传递表单数据的问题。

此处的对应的store仓库和api工厂就不进行展示,派发action只包含调用对应接口的操作。

在购物车中点击结算:

image.png

在购物车组件中的结算方法:

...
// 结算
pay(){
    if(this.realShopcart.every(item => item.isCheck === false)){
        this.$message.warning('请选择要结算的商品!');
        return ;
    }
    // 过滤
    const payList = this.realShopcart.filter(item => item.isCheck);
    // 重构
    const confirmOrders = payList.map(item => item = {shopcarId:item.id,number:item.number});
    // 派发action生成确认单
    this.$store.dispatch('reqComfirmForm',confirmOrders).then(()=>{
        this.$router.push('/comfirmshop'); // 跳转到确认单
    }).catch((error) => {
        this.$message.error(`${error}`);
    })
},
    ...

生成确认单,对确认单的缓存,注意此处可以在派发action后,把确认单缓存到localStorage中,防止刷新导致数据丢失。

因为确认单是没有存在数据库里,只缓存在后端的redias中。

跳转到确认单页面,此处还可以修改备注和收件人的姓名和联系方式:

image.png

点击提交订单,产生新的支付页面,我们可以直接支付:

image.png

可以输入测试的账号密码,也可以关闭。如果关闭,原来的页面就跳转到订单页面:

image.png

关于确认单数据这一块,前端是采用localStorage进行缓存,在对应页面的Comfirm.vue组件中:

    ...
   watch:{
        // 监视是否添加了备注,也一起缓存进去
        comfirmList:{
            deep:true,
            handler(newValue, oldValue){
                localStorage.setItem('comfirmList', JSON.stringify(this.comfirmList))
            }
        }
    },
    methods:{
        comfirm(){
            const orders = this.comfirmList.map(item => { // 封装订单对象
                return {
                    confirmOrderId: item.id,
                    userId:this.userId,
                    remark: item.remark,
                    address:this.confirmShopcartUser.address,
                    phone:this.confirmShopcartUser.phone
                }
            });
            this.$store.dispatch('reqOrder',orders).then((res) => { // 派发actions,把数据发给后端,接收支付表单页面
                // 借助localStorage传送支付表单页
                localStorage.setItem('alipay',res.data.form);
                // 先产生新的页面
                let routeData = this.$router.resolve({name:'pay'});
                window.open(routeData.href,'_blank');
                // 再跳转到我买到的
                this.$router.push({name:'mybuy'});
                // 把暂存的确认单也清除了
                localStorage.removeItem('comfirmList');
            }).catch((error) => {
                this.$message.error(`${error}`);
            })
        }
    },
       ...

在订单页面order.vue中,我们也得有相应的继续支付的操作:

      ...
        // 继续付款
        pay(){
            this.$store.dispatch('reqOrderInfo',this.$route.params.orderId);
            const data = {
                tradeNo: this.order.id
            }
            this.$store.dispatch('continueToPay',data).then((res) => { // 派发,通过订单id,获取支付表单
                // 渲染支付页面
                // 借助localStorage传送表单
                localStorage.setItem('alipay',res.data.form);
                // 跳转到新的页面
                let routeData = this.$router.resolve({name:'pay'});
                window.open(routeData.href,'_blank');
            }).catch((error) => {
                this.$message.error(`${error}`);
            })
        },
            ...

我们输入测试的账号密码并完成支付:

image.png

关闭支付页面,回到原来的订单页面:

image.png

关于Alipay后端的搭建,可以看这篇,做后端同学写的:springboot整合支付宝沙箱支付

在渲染支付页面的时候,前端是跳转到pay页面,再在此页面中渲染后端发过来的表单:

<template>
    <div>
        <div ref="alipayWap" v-html="alipay" />
    </div>
</template>
<script>
export default{
    data(){
        return{
            alipay:''
        }
    },
    mounted(){
        // 渲染支付页面
        this.alipay = localStorage.getItem('alipay');
        // 防抖避免重复支付
        this.$nextTick(() => {
            // 提交支付表单
            this.$refs.alipayWap.children[0].submit();
            setTimeout(() => {
                // this.toPayFlag = false;
            }, 500);
        });
    },
}
</script>