目录
一、准备工作
二、后端node
1、添加支付宝配置文件
2、开始写支付提交接口
3、前端部分(点击提交订单)
3.1、写axios请求
3.2、点击提交订单按钮后发送网络请求
3.3、付款成功跳转的页面的路径是下面这样的:
4、后端向支付宝发请求,拿到订单的状态
5、交易成功跳转后(前端部分)
在vue项目中,要对接支付宝完成支付功能,首先需要做如下准备:
一、准备工作
先登录到支付宝开发平台https://open.alipay.com/develop/sandbox/app
下载支付宝开发平台密钥工具https://opendocs.alipay.com/open/02kipk https://opendocs.alipay.com/open/291/106097/
打开支付宝开发平台密钥工具,生成密钥
这里需要注意:拿到的私钥需要转换格式,不然是用不了的
4.需要对刚才生成的私钥进行转换
5.配置完成后,需要返回开放平台,将公钥复制进去
二、后端node
需要安装的依赖:
npm i alipay-sdk -S
npm i express -S
1、添加支付宝配置文件
注意:下面的应用私钥是需要进行格式转换的(上面有说)
const AlipaySdk = require('alipay-sdk').default;
const alipaySdk = new AlipaySdk({// appIdappId: 'xxx',// 签名算法signType: 'RSA2',// 支付宝网关地址gateway: 'https://openapi.alipaydev.com/gateway.do',// 支付宝公钥alipayPublicKey: 'xxx',// 应用私钥privateKey: 'xxx'
})module.exports = alipaySdk;
2、开始写支付提交接口
// 引入支付宝配置信息
const alipaySdk = require('../zfb/zfb_config')
const AlipayFromData = require('alipay-sdk/lib/form').default;router.post('/pay', (req, res) => {// 前端给后端的数据(订单号,金额,商品描述等信息)let orderId = req.body.orderId;let orderMoney = req.body.orderMoney;let orderTitle = req.body.orderTitle;let orderInfo = req.body.orderInfo;// 对接支付宝const formData = new AlipayFromData()formData.setMethod('get')formData.addField('returnUrl', 'http://localhost:8080/#/paysuccess'); // 付款成功打开的链接formData.addField('bizContent', {// 传递的订单号outTradeNo: orderId,productCode: 'FAST_INSTANT_TRADE_PAY',// 金额total_amount: orderMoney,// 商品标题subject: orderTitle,// 商品描述body: orderInfo,});const result = alipaySdk.exec('alipay.trade.page.pay',{},{ formData: formData },);result.then((resp) => {res.send({success: '支付成功',code: 200,result: resp});});
})
3、前端部分(点击提交订单)
3.1、写axios请求
需要安装query-string,因为需要对请求中的对象转字符串
import querystring from 'query-string';
// 或者安装qs也行
export const reqZfbPay = (orderObj) => requset({url: '/pay', method: 'post', data: querystring.stringify(orderObj)})
3.2、点击提交订单按钮后发送网络请求
async PaySuccess() {/*** let orderId = req.body.orderId;let orderMoney = req.body.orderMoney;let orderTitle = req.body.orderTitle;let orderInfo = req.body.orderInfo;*/let orderTitle = [];let orderInfo = [];this.orderList.forEach((item) => {orderTitle.push(item.goods_name);orderInfo.push(item.goods_choose);});let orderObj = {orderId: this.order_code,orderMoney: this.total,orderTitle: orderTitle.toString(),orderInfo: orderInfo.toString(),};let res = await reqZfbPay(orderObj);// console.log(res)if (res.code === 200) {// 支付成功后,需要将购物车中的数据进行删除this.delAllGoods();Toast("正在支付,请稍等~");// 进行支付宝支付页面跳转window.location.href = res.result;}
}
控制台可以拿到返回的信息
返回的result数据就是需要跳转支付宝支付的页面
等输入支付密码支付完成后,就会跳转到之前node后端写的地址
3.3、付款成功跳转的页面的路径是下面这样的:
里面有需要的参数,可以通过$route.query拿到
跳转新页面后,并没有结束,还前端还需要向后端发送请求,获取订单数据
4、后端向支付宝发请求,拿到订单的状态
在后端安装axios
// 引入网络请求(向支付宝发请求)
const axios = require('axios')
router.post('/pay/orderStatu', (req, res) => {let out_trade_no = req.body.out_trade_no;let trade_no = req.body.trade_no;// 对接支付宝const formData = new AlipayFromData()formData.setMethod('get')formData.addField('bizContent', {out_trade_no,trade_no});const result = alipaySdk.exec(// 这个地方和前面的不同'alipay.trade.query',{},{ formData: formData },);result.then((resData) => {axios({url: resData,method: 'get'}).then(data => {// console.log(data);let r = data.data.alipay_trade_query_response;if (r.code === '10000') {switch (r.trade_status) {case 'WAIT_BUYER_PAY':res.send({success: true,code: 200,msg: '支付宝有交易记录,没付款'})break;case 'TRADE_FINISHED':res.send({success: true,code: 200,msg: '交易完成,不能退款'})break;case 'TRADE_SUCCESS':res.send({success: true,code: 200,msg: '刚交易完成,可以退款'})break;case 'TRADE_CLOSED':res.send({success: true,code: 200,msg: '交易关闭,没有支付成功'})break;}} else if (r.code === '40004') {res.json('交易不存在')}}).catch(err => {res.json({msg: '查询失败',err})})});
})
这里需要知道支付宝通知返回时的交易状态列表信息
WAIT_BUYER_PAY 支付宝有交易记录,但是没有付款
TRADE_FINISHED
交易完成,时间过了不能退款
TRADE_SUCCESS
刚交易完成,可以退款
TRADE_CLOSED
交易关闭,没有支付成功
5、交易成功跳转后(前端部分)
export const reqPaySuccess = (data) => requset({url: '/pay/orderStatu', method: 'post', data: querystring.stringify(data)})
import { reqPaySuccess } from "@/api";
export default {mounted() {let data = {// 跳转后的url里面的参数out_trade_no: this.$route.query.out_trade_no,trade_no: this.$route.query.trade_no,};this.paySuccess(data);},methods: {async paySuccess(data) {let res = await reqPaySuccess(data);console.log(res);}}
};
剩下业务逻辑自行填充吧😼