目录
一、准备工作
二、后端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({
// appId
appId: '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);
}
}
};
剩下业务逻辑自行填充吧😼