第一步前端:点击去结算,前端将商品的信息传递给后端,后端返回一个商品的订单号给到前端,前端将商品的订单号进行存储。
对应的前端代码:然后再跳转到支付页面
// 第一步 点击去结算 然后生成一个订单号
// 将选中的商品 商品的id 数量 名称 传递给后端
const payMoney = async () => {const res = await addOrderApi({ arr: [{ id: 1, name: '云南普洱', count: 10, price: 160 }] })const order = res.data.dataconsole.log(order)// 将订单号存储到pinia中orderStore.setOrder(order)router.push('/order')
}
后端对应的代码:
// 生成订单号的接口
router.post('/addOrder',(req,res)=>{console.log(req.body.arr)// 生成订单号 年份+月份+日+分 + 6位的随机石// 将前端传递过来的数据存储到数据库中// 订单号的状态: 1 代表未支付 2代码等待支付 3代表成功 4代表失败res.send({status:200,message:'ok',data:'202405041050123456'})
})
第二步:点击提交订单: 这时候判断是否选择了收货地址。
01 前端将订单号发送给后端,后端修改订单号的状态,
02 后端将购物车的商品进行删除,并提交到待支付的数据库中
03 接着将商品信息 订单号 价格 传递给后端,请求支付的接口
04 后端这时候会返回跳转的链接,直接进行链接的跳转
05 支付宝链接支付是否成功都会跳转到传递跳转路由的界面
06 从跳转路由界面的url地址上面获取支付宝携带的参数订单号等,进行接口请求查询是否支付成功
前端代码如下:
const onSubmit = async () => {const order = orderStore.orderconsole.log(order)console.log('提交订单')// 发送请求 修改订单的状态, 修改为待支付// 第二步将购物车该商品的数据进行清空,const res = await submitOrderApi({orderId: order})// 接着再调用支付的api, 参数包括订单号 总金额 买的商品的详情const res1 = await paymentApi(qs.stringify({orderId: order,name: '普洱茶叶300g',price: 100}))console.log(res1.data) // 返回的支付宝跳转的地址window.location.href = 'res1.data' // 跳转到支付宝支付的界面}
后端代码如下:
01 修改订单的状态,以及将准备结算的商品,从购物车的数据表删除
// 修改订单号状态的接口 将订单号的状态修改为2 // 再将以及提交的订单的数据 从数据表中的购物车的表中删除
router.post('/submitOrder',(req,res)=>{// 这里通过mysql语句根据订单的条件 然后将状态进行修改res.send({success:true})
})
02 对接支付宝的沙箱环境将跳转的地址返回给后端。
配置沙箱的信息参数:
单独创建的allpay.js文件中进行配置const AlipaySdk = require('alipay-sdk').default
const alipaySdk = new AlipaySdk({appId:'9021000136669436', // appidsignType:'RSA2', // 签名算法gateway:'https://openapi-sandbox.dl.alipaydev.com/gateway.do', //支付宝网关alipayPublicKey:'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi5tQOLjk5pIFH40bOdglT5FS5QG/QrqsFG1VuJ3UH0Z18nqbOKm26G2zizwou2Ur6ycYcYWPg4NFgnSSoSGjobqLhr0WHqJ78rkmCUVDbhHYb+Co5qRKPPwCGfvQ1v0pgivq7SKVcBtf7SMdyDkufSWaAzZipSEr8fvn3tL+G/oIAA8hWUW5Rkb8rImvq/VjYHTusK0+YQFGrdgC5jIAAqm/YOyxJXGzDpUiFFc1DqquVrrZ0Sca+Fwtdos+HirMEjcm8K8Jv5FGUIzESTVqA+B9EDMn22KOio/bM0M09L+fCMix3BA/HcnTVkdzclfchrz2ZvvnLXzu81EIU3jz4QIDAQAB',// 支付宝公钥privateKey:'MIIEogIBAAKCAQEAgbOCYNKGGwQnjPOdTDZZ+fz6c6Gt66QK7/RzjWWxlXmUSP8Hc5MRFupwWJscM+2NjJOQmpI0hjeJcyo9M3h6rZXIkCqiWpeg+hDAj01TouO/woxQIZHvIpe1flAa1pgHzha0rBU7keyYLipkYda+nrbeKLDE5RJ3J8ANaHlCjKcisyFOs5JLd+CQ2gX7OZM2eTAwtL6G8BNHndZd9m9kV01WWkrAjl6KMNNLAgFzOBAMvcs4UuUjCW58RylkhhEpxEjpmhpga/9mXq7k1p5m9YJr/up5kpvLG7trqTZg6VSHutDnRypCdx2yNmLpQz7NEZo4aa2HUKQsCztLhu9zLwIDAQABAoIBAB3UCsf5op3T9sSTwjkkxsyXQYIWTMlEkL9emLSMDqsxqsie3jfWOrfqcqvuAC5xE3yg80CZHzs+yn2R2UFdE9mX+Ogu5eevt3XLJH3QasurVQ6I9mTCCx0JhtPl2EZB8ImU7zgkKe8FWnpDhZJ6sJwPskfpX17PQFgD8xFz0bpG4bVCgtRepsOpaRpba5yNtv61G0In0GviRcS4WD2shQMkPrSz0y0IZi/hkcBn8ZK2kF01Jl4OstMwD46d0iQgQM3L0xC7iQFPKYlpZTM9DKdgz/s8ncehtZH1AN7KFGB5aHARfKRVXTBzbI2F4oHaTr747LcnziBJ6Ecf4Y4zgwECgYEAxn9DL3zWFam1nzGzboBADhal8hglmp4j0I9ZB2JeXukscm/2C/KjlK0Aki8KxNFb+SiTtv561oDr5KN9GbzJBaQCN7+Svtbmlyq4VlGo8YrIOgcpzWz5dkFs9/SeaCJtdpqm/S+ii3jxvr7T5BW+mrLdDKI2VVeximMDbBNDc9MCgYEAp0ZGnOw/SD7yM1wm92Qa17t49EwagoqwHczBVJLmCYMrL5XFFMwt3Bm0QcI4r5Q4pOlelAbggCLScZ13jrGZCuKktbd/ColFvNlqn20BawPFwYZ8TpayJCUiG1F8eFNw+IGOy0ivXcGO7GKXccBOdEAr2fo1VsttUo6Iteeg1bUCgYB9NOsxOiJkWb9polUXX6iH+ntEgTy/Ef9vX+x9fuweHCDgMoVWNgA/GP1iOHAnhBPqz1CVvmHHilzBxOp1YKLAfxqzBZFP9YhQVC8gq7PQYIU6LSiOHq4gjNZqdY+yCf1YMechj3mNVoXOltpbZefr9uT+QhfZr04bB6ex9Vi35wKBgFQdpsyqkHgID0t8f6vQDx+FCqHu0zXp//48RMv+wubtqv3W1rBKrJUN5/NZc5/3bTSglgriGmrVF/ZCNSjwbgFnT2SBzcTCmusIefGJozjpQLy8oC304cgDVE9gfrMTYq/UlrXq6yS+fNyqB3YQOmODEYofpErtKSBmxKCUxfAxAoGANFkMzolsqKp6rRH6aCXnC0zpbdqr7yX2UVbhjRTBaRRKkbixIqik8J6qOAabDLc6bfOnnTfU7bSEh1yHWZgobpsQ3s/2tGRZU3hLYHjLo6IUBvZdj/mcwa/ZvQmjYBH5SCZdV0MwnMctBRZHctU2DYgDViD6yaGauDXB5xxDwu8='//应用私钥
})
module.exports = alipaySdk
03 路由文件中导入并使用
var alipaySdk = require('../db/allpay.js');var AlipayFormData = require('alipay-sdk/lib/form.js').default// 支付的接口 需要对接支付宝的砂箱环境
router.post('/payment',(req,res)=>{console.log(req.body) // 获取到订单号 商品名称 总金额let orderId = req.body.orderIdlet price = req.body.pricelet name = req.body.name// 开始对接支付宝APIconst formDate = new AlipayFormData()// 这里调用setMethod并传入get 会返回跳转到支付页面的urlformDate.setMethod('get')// 支付信息formDate.addField('bizContent',{outTradeNo:orderId,productCode:'FAST_INSTANT_TRADE_PAY', //这里是固定写死的subject:name})// 支持成功或失败跳转的链接formDate.addField('returnUrl','http://localhost:4000/payment')// 返回promiseconst result = alipaySdk.exec('alipay.trade.page.pay',{},{formData:formDate},);result.then(ress=>{res.send({code:200,data:ress // 这个就是支付宝返回的地址})})
})
04 在跳转之后的页面中也就是http://localhost:4000/payment的界面中获取url参数,请求接口查询支付的状态
const res = await submitOrderApi(qs.stringify({// 里面的参数是支付宝跳转之后会跳转的地址上面拼接的有out_trade_no: router.query.out_trade_no, //订单号trade_no: router.query.trade_no
}))
05 后端需要再向支付宝请求 获取订单最后的支付状态 返回给前端
router.post('/successpayment',(req,res)=>{//订单号let out_trade_no = req.body.out_trade_nolet trade_no = req.body.trade_no// 后端要和支付宝进行比对和校验const formDate = new AlipayFormData()formDate.setMethod('get')formDate.addField('bizContent',{out_trade_no,trade_no})const result = alipaySdk.exec('alipay.trade.query',{},{formData:formDate},);result.then(resData=>{axios({method:'GET',url:resData}).then(data=>{let responseCode = data.data.alipay_trade_query_response;if(responseCode.code==='10000'){switch(responseCode.trade_status){case 'WAIT_BUYER_PAY':res.send({data:{code:0,data:{msg:'支付有交易 没有付款'}}})break;case 'TRADE_CLOSED':res.send({data:{code:0,data:{msg:'交易关闭'}}})break;}}})})})