下面是关于Vue项目中实现微信支付和支付宝支付的完整攻略。
简介
在Vue项目中需要实现支付功能,常见的方式有微信支付和支付宝支付。微信支付目前还需要申请微信支付商户号,而支付宝支付可以使用支付宝开放平台提供的接口实现。
在项目中可以将支付功能实现为一个组件,以便在需要支付的地方引入使用。
微信支付
微信支付需要完成以下步骤:
- 申请微信支付商户号;
- 在项目中引入微信支付SDK,并配置好相关参数;
- 调用微信支付的接口生成预支付订单并返回相关参数;
- 使用微信支付的接口完成订单支付;
- 将支付结果同步到服务器端进行验证和记录。
引入SDK和配置参数
可以使用官方提供的微信支付SDK,也可以使用第三方库如weixin-js-sdk。以官方提供的SDK为例,可以在项目中引入以下脚本:
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
同时需要配置以下参数:
// 微信支付参数
const WX_APP_ID = 'your_app_id'; // 替换为自己的APP ID
const WX_MCH_ID = 'your_mch_id'; // 替换为自己的商户号
const WX_API_KEY = 'your_api_key'; // 替换为自己的API KEY
const WX_NOTIFY_URL = 'your_notify_url'; // 替换为自己的回调地址
生成预支付订单
使用微信提供的JSAPI,可以在前端生成预支付订单。以下为示例代码:
// 生成预支付订单
createUnifiedOrder(orderId, amount) {
// 获取OpenID
const openid = getCurrentOpenId(); // 从LocalStorage等缓存中获取
// 请求服务器生成预支付订单,获取到预支付订单号prepay_id
return axios.post('/api/wxpay/createUnifiedOrder', {
openid,
orderId,
amount
}).then(response => {
const data = response.data;
// 使用JSAPI调起微信支付
wx.chooseWXPay({
timestamp: data.timestamp,
nonceStr: data.nonceStr,
package: `prepay_id=${data.prepay_id}`,
signType: 'MD5',
paySign: data.sign,
success: function(res) {
// 支付成功,跳转到订单详情页面
router.push({
name: 'OrderDetail',
params: {
orderId: orderId
}
});
},
fail: function(res) {
// 支付失败,提示用户
Toast.fail(res.errMsg);
}
});
});
}
这里的/api/wxpay/createUnifiedOrder
接口需要在服务器端实现。可以使用官方提供的SDK和第三方库如wechatpay-openapi。下面是一个简单的实现,仅供参考:
// 生成预支付订单
app.post('/wxpay/createUnifiedOrder', async (req, res) => {
const nonceStr = getRandomString(32);
const outTradeNo = uuid.v4().replace(/-/g, '');
const totalFee = req.body.amount;
const {openid, orderId} = req.body;
const order = {
// ...
};
// 省略调用微信支付API生成预支付订单的代码
res.json({
appId: WX_APP_ID,
timeStamp: timestamp,
nonceStr: nonceStr,
package: `prepay_id=${prepayId}`,
signType: 'MD5',
paySign: sign
});
});
完成订单支付
在用户确认支付后,微信会调用预设的回调URL并带上支付结果,我们需要做以下事情:
- 对支付结果进行检验,判断支付流程是否正常;
- 如果支付成功,更新订单状态并保存支付结果。
以下为示例代码:
// 引入微信支付sdk
const WXPay = require('weixin-pay');
// 根据配置参数创建一个微信支付对象
const wxpay = WXPay({
appid: WX_APP_ID,
mch_id: WX_MCH_ID,
partner_key: WX_API_KEY,
});
// 微信支付结果回调处理
app.post('/wxpay/notify', (req, res) => {
// 将XML格式的通知消息解析成JSON格式
wxpay.verifySign(req.rawBody).then((result) => {
// 验证成功
if (result.return_code === 'SUCCESS' && result.result_code === 'SUCCESS') {
const outTradeNo = result.out_trade_no; // 商户订单号
const totalFee = result.total_fee; // 支付金额
const transactionId = result.transaction_id; // 微信支付订单号
// 根据商户订单号查询订单,判断支付是否已完成
return db.collection('orders').findOne({outTradeNo: outTradeNo});
} else {
// 验证失败
console.error(result);
}
}).then((order) => {
if (!order) {
// 订单不存在或已处理过,不作处理
return;
}
// 订单支付成功,更新订单状态
order.status = 2; // 已支付
order.transactionId = transactionId;
order.payTime = new Date();
// 保存订单状态
return db.collection('orders').updateOne({_id: order._id}, {$set: order});
}).then(() => {
// 返回结果
res.send({
return_code: 'SUCCESS'
});
}).catch((error) => {
console.error(error);
res.send({
return_code: 'FAIL'
});
});
});
最后将以上代码保存为一个组件,使用时只需要在需要支付的地方引入使用即可。
支付宝支付
支付宝支付需要完成以下步骤:
- 在支付宝开放平台上创建应用,并获取应用的APP ID和私钥;
- 在项目中引入支付宝支付SDK,并配置好相关参数;
- 调用支付宝支付的接口生成预支付订单并返回相关参数;
- 使用支付宝支付的接口完成订单支付;
- 将支付结果同步到服务器端进行验证和记录。
引入SDK和配置参数
可以使用官方提供的支付宝SDK,也可以使用第三方库如alipay-sdk。以官方提供的SDK为例,可以在项目中引入以下脚本:
<script src="https://appx/web-view.min.js"></script>
同时需要配置以下参数:
// 支付宝支付参数
const ALIPAY_APP_ID = 'your_app_id'; // 替换为自己的APP ID
const ALIPAY_MCH_ID = 'your_mch_id'; // 替换为自己的商户号
const ALIPAY_API_KEY = 'your_api_key'; // 替换为自己的API KEY
const ALIPAY_NOTIFY_URL = 'your_notify_url'; // 替换为自己的回调地址
const ALIPAY_PUBLIC_KEY = 'your_public_key'; // 替换为自己的公钥
const ALIPAY_PRIVATE_KEY = 'your_private_key'; // 替换为自己的私钥
生成预支付订单
使用支付宝提供的SDK,可以在前端生成预支付订单。以下为示例代码:
// 生成预支付订单
createTrade(orderId, amount) {
// 请求服务器生成预支付订单,获取到预支付订单号tradeNo
return axios.post('/api/alipay/createTrade', {
orderId,
amount
}).then(response => {
// 装载配置
let iv = ""; //注意这里先设置一下iv值iv是无所谓的,只是必须要有
let data = {
authInfo: response.data.appAuthToken, // 这里需要使用appAuthToken
orderStr: response.data.tradeStr, // 获取到的订单信息串
};
let resolve = (ret) => {
// 支付成功,跳转到订单详情页面
router.push({
name: 'OrderDetail',
params: {
orderId: orderId
}
});
};
let reject = (error) => {
// 支付失败,提示用户
Toast.fail(error.description);
};
// 打开支付宝客户端并发起支付请求
ap.tradePay({
orderStr: data.orderStr,
}, (res) => {
// 可以在这里查询订单,以确认支付结果
resolve(res);
}, (err) => {
// 失败回调
reject(err);
});
});
}
这里的/api/alipay/createTrade
接口需要在服务器端实现。可以使用官方提供的SDK和第三方库如alipay-sdk。下面是一个简单的实现,仅供参考:
// 生成预支付订单
app.post('/alipay/createTrade', async (req, res) => {
// 省略对参数的解析和检验
const notifyUrl = ALIPAY_NOTIFY_URL;
const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
const outTradeNo = uuid.v4().replace(/-/g, '');
const totalAmount = req.body.amount;
const order = {
// ...
};
const alipaySdk = new AlipaySdk({
appId: ALIPAY_APP_ID,
privateKey: ALIPAY_PRIVATE_KEY,
gateway: 'https://openapi.alipay.com/gateway.do',
alipayPublicKey: ALIPAY_PUBLIC_KEY,
timeout: 5000,
signType: 'RSA2'
});
// 构造请求参数
const bizContent = {
body: '支付宝支付',
subject: '订单支付',
out_trade_no: outTradeNo,
total_amount: totalAmount,
product_code: 'QUICK_MSECURITY_PAY'
};
const extendParams = {
sys_service_provider_id: ALIPAY_MCH_ID
};
const requestParams = {
notify_url: notifyUrl,
method: 'alipay.trade.app.pay',
timestamp: timestamp,
version: '1.0',
app_id: ALIPAY_APP_ID,
biz_content: JSON.stringify(bizContent),
sign_type: 'RSA2',
app_auth_token: 'your_token', // 替换为自己的授权令牌
extend_params: JSON.stringify(extendParams) // 需要传递额外参数时传递
};
// 发起支付宝请求
const result = await alipaySdk.exec('alipay.trade.app.pay', requestParams);
res.json({
tradeStr: result,
appAuthToken: 'your_token' // 替换为自己的授权令牌
});
});
完成订单支付
在用户确认支付后,支付宝会调用预设的回调URL并带上支付结果,我们需要做以下事情:
- 对支付结果进行检验,判断支付流程是否正常;
- 如果支付成功,更新订单状态并保存支付结果。
以下为示例代码:
// 引入支付宝sdk
const AlipaySdk = require('alipay-sdk').default;
// 根据配置参数创建一个支付宝sdk对象
const alipaySdk = new AlipaySdk({
appId: ALIPAY_APP_ID,
privateKey: ALIPAY_PRIVATE_KEY,
gateway: 'https://openapi.alipay.com/gateway.do',
alipayPublicKey: ALIPAY_PUBLIC_KEY,
timeout: 5000,
signType: 'RSA2'
});
// 支付宝支付结果回调处理
app.post('/alipay/notify', async (req, res) => {
// 将form格式的通知消息解析成JSON格式
const data = await alipaySdk.checkNotifySign(req.body);
// 验证成功
if (data.code === '10000' && data.trade_status === 'TRADE_SUCCESS') {
const outTradeNo = data.out_trade_no; // 商户订单号
const totalAmount = data.total_amount; // 支付金额
const tradeNo = data.trade_no; // 支付宝交易流水号
// 根据商户订单号查询订单,判断支付是否已完成
const order = await db.collection('orders').findOne({outTradeNo: outTradeNo});
if (order && order.status === 1) { // 未处理的支付结果才处理
// 订单支付成功,更新订单状态
order.status = 2; // 已支付
order.tradeNo = tradeNo;
order.amount = totalAmount;
order.payTime = new Date();
// 保存订单状态
await db.collection('orders').updateOne({_id: order._id}, {$set: order});
}
// 返回结果
res.send('success');
} else {
// 验证失败
console.error(data);
res.send('fail');
}
});
最后将以上代码保存为一个组件,使用时只需要在需要支付的地方引入使用即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue项目中的支付功能实现(微信支付和支付宝支付) - Python技术站