支付宝沙箱支付node
官方文档:https://opendocs.alipay.com/common/02kkv7
node端
npm i alipay-sdk
新建alipay.js
文件
const alipaySdk = require('alipay-sdk').default
const alipaysdk = new alipaySdk({
appId: '2016101500693849',
privateKey: '', // 私钥,生成见官方文档
signType : 'RSA2',
gateway: 'https://openapi.alipaydev.com/gateway.do',
alipayPublicKey: '' // 支付宝公钥
})
module.exports = alipaysdk
提交订单接口
文档:https://www.yuque.com/chenqiu/alipay-node-sdk/page_api
支付会有生成订单接口,提交订单接口,确认订单接口,以下是提交订单接口:使用express框架
// 引入alipay.js
const alipaySdk = require('../utils/alipay')
const alipayFormData = require('alipay-sdk/lib/form').default
router.post('/api/payment', async function(req, res, next) {
// 订单id
let orderId = req.body.orderid
const formData = new alipayFormData()
// 调用 setMethod 并传入 get,会返回可以跳转到支付页面的 url
formData.setMethod('get');
// 付款成功后打开此链接
formData.addField('notifyUrl', 'http://localhost:3000/orderStatus');
// 订单信息
formData.addField('bizContent', {
outTradeNo: orderId,
productCode: 'FAST_INSTANT_TRADE_PAY',
totalAmount: '0.01',
subject: '商品',
body: '商品详情',
});
const result = await alipaySdk.exec(
'alipay.trade.page.pay',
{},
{ formData: formData },
);
// result 为可以跳转到支付链接的 url
console.log(result);
res.json({ msg: 'success', data: { result } });
})
前端请求
使用到vue框架、qs库和axios库
<script setup>
import axios from 'axios'
import qs from 'qs'
const submit = () => {
axios({
url: '/api/payment',
method: 'post',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({
orderid: 'order123456788'
})
}).then(res => {
let payUrl = res.data.data.result
location.href = payUrl
})
}
</script>
<template>
<div>
<button class="btn-submit" @click="submit">提交</button>
</div>
</template>
<style>
.btn-submit{
padding: 10px 20px;
border: none;
background-color: slateblue;
color: #fff;
border-radius: 10px;
}
</style>
点击提交按钮
如果提示支付不安全可以开浏览器隐私窗口测试
账号密码
支付结果页面,支付成功或失败跳转的地址,支付宝帮我们跳转,携带一些url参数过来,此时我们可以请求后端变更订单状态;
out_trade_no
:订单号
trade_no
:后端需要用到,传递给后端
created(){
let data = {
out_trade_no: this.$route.query.out_trade_no,
trade_no: this.$route.query.trade_no
}
axios({
url: '/api/queryOrder',
method: 'post',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
data: qs.stringify(data)
}).then(res => {
console.log(res)
})
}
确认订单接口
router.post('/api/queryOrder', function(req, res, next) => {
let out_trade_no = req.body.out_trade_no
let trade_no = req.body.trade_no
// 支付宝
const formData = new alipayFormData()
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 => {
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
})
})
})
})
1
1
1
1
1
1
1
1
1
1