针对"nodejs微信扫码支付功能实现",以下是一个完整攻略:
一、准备工作
-
创建微信开发者账号,获取AppID和AppSecret,并申请商户号和API密钥。
-
安装Node.js,配置npm。
-
在本地创建node.js项目,使用npm初始化项目,并安装需要的模块。
-
下载微信支付的开发工具包。
二、请求access_token和openid
-
在Node.js中使用request模块请求获取access_token和openid,需要使用微信提供的API。
-
返回值中包含access_token和openid,需要保存下来。
三、生成预支付订单
-
在服务器端使用生成签名的工具算出签名。
-
拼接成XML格式的数据,并且用MD5加密后发送给微信服务器。
-
返回的数据再用签名工具签名,发送给客户端,用于唤起微信支付。
四、接收微信支付回调
-
在Node.js服务器端编写接收微信支付结果通知的代码,需要先去商户平台设置回调地址。
-
验证回调的合法性,判断支付状态。
-
返回给微信服务器成功或者失败的信息,避免微信服务器多次通知。
示例1:
const request = require('request')
const signUtil = require('./signUtil')
// 获取access_token和openid
function getAccessTokenAndOpenid(code) {
return new Promise((resolve, reject)=>{
request.get('https://api.weixin.qq.com/sns/oauth2/access_token?appid=' + APPID + '&secret=' + APPSECRET + '&code=' + code + '&grant_type=authorization_code', function(err, response, body) {
if (!err && response.statusCode == 200) {
const result = JSON.parse(body)
// success
if (result.errcode) {
resolve(result.errmsg)
} else {
resolve(result)
}
} else {
reject(err || '请求失败')
}
})
})
}
// 生成预支付订单
function generatePayOrder(openid, product, amount) {
const sign = signUtil.signNonceStr(openid, amount, product, API_KEY)
const data = signUtil.generateXml(OPENID, amount, '测试商品', sign)
return new Promise((resolve, reject)=>{
request.post('https://api.mch.weixin.qq.com/pay/unifiedorder', {body: data}, function(err, response, body) {
if (!err && response.statusCode == 200) {
const result = signUtil.parseXml(body)
// success
if (result.result_code === 'SUCCESS') {
const returnData = signUtil.signNonceStr(result.prepay_id)
resolve(returnData)
} else {
resolve(result.err_code_des || '请求失败')
}
} else {
reject(err || '请求失败')
}
})
})
}
module.exports = {
getAccessTokenAndOpenid,
generatePayOrder
}
示例2:
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const payUtil = require('./payUtil')
app.use(bodyParser.urlencoded({ extended: false }));
// 支付结果通知地址
app.post('/pay/notify', function (req, res) {
const data = req.body
if (!data.xml) {
res.send('未接收到数据')
return
}
const result = payUtil.validateSign(data.xml)
if (result) {
// 处理支付结果
console.log('支付成功')
res.send(buildSuccess())
} else {
console.log('支付失败')
res.send(buildFail())
}
})
function buildSuccess() {
const data = {
return_code: 'SUCCESS',
return_msg: 'OK'
}
return payUtil.generateXml(data)
}
function buildFail() {
const data = {
return_code: 'FAIL',
return_msg: '签名错误'
}
return payUtil.generateXml(data)
}
app.listen(3000, function () {
console.log('app is listening at port 3000')
})
请注意示例代码中的一些变量,如APPID、APPSECRET、API_KEY、OPENID等,需要根据自己的实际情况设置。同时示例代码中调用了几个工具函数,如signUtil.signNonceStr()、signUtil.generateXml()、signUtil.parseXml()、payUtil.validateSign()等,需要根据自己的需求自行编写对应的工具函数。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:nodejs微信扫码支付功能实现 - Python技术站