1. 支付触发页面(WXML)
2. 调用统一下单接口(JavaScript)
// pages/pay/demo.js
Page({
data: { orderId: '20250326001' },
async requestPayment() {
// 调用后端接口获取预支付参数
const res = await wx.request({
url: 'https://your-api.com/wxpay/unifiedOrder',
method: 'POST',
data: { orderId: this.data.orderId }
});
const { timeStamp, nonceStr, package: prepayId, signType, paySign } = res.data;
// 调起微信支付
wx.requestPayment({
timeStamp,
nonceStr,
package: prepayId,
signType,
paySign,
success: () => wx.showToast({ title: '支付成功' }),
fail: err => console.error('支付失败', err)
});
}
});
2. 后端服务实现(Node.js示例)
1. 统一下单接口(核心代码)
// server.js
const axios = require('axios');
const crypto = require('crypto');
// 微信支付配置
const config = {
appId: 'YOUR_APPID',
mchId: 'YOUR_MCHID',
apiKey: 'YOUR_API_KEY' // 商户平台API密钥
};
// 生成签名
function createSign(params) {
const sortedParams = Object.keys(params).sort().reduce((acc, key) => {
if (params[key]) acc[key] = params[key];
return acc;
}, {});
const stringA = Object.entries(sortedParams).map(([k, v]) => `${k}=${v}`).join('&');
const stringSignTemp = `${stringA}&key=${config.apiKey}`;
return crypto.createHash('md5').update(stringSignTemp).digest('hex').toUpperCase();
}
// 统一下单接口
router.post('/wxpay/unifiedOrder', async (req, res) => {
const { orderId } = req.body;
const params = {
appid: config.appId,
mch_id: config.mchId,
nonce_str: crypto.randomBytes(16).toString('hex'),
body: '测试商品',
out_trade_no: orderId,
total_fee: 990, // 单位:分
spbill_create_ip: req.ip,
notify_url: 'https://your-domain.com/wxpay/notify',
trade_type: 'JSAPI',
openid: '用户openid' // 需提前通过wx.login获取
};
params.sign = createSign(params);
try {
const { data } = await axios.post('https://api.mch.weixin.qq.com/pay/unifiedorder', params);
res.json({
timeStamp: Math.floor(Date.now() / 1000),
nonceStr: crypto.randomBytes(16).toString('hex'),
package: `prepay_id=${data.prepay_id}`,
signType: 'MD5',
paySign: createSign({
...params,
prepay_id: data.prepay_id
})
});
} catch (error) {
res.status(500).json({ error: '支付请求失败' });
}
});
三、支付回调处理
// 回调接口示例
router.post('/wxpay/notify', async (req, res) => {
const data = req.body;
if (this.checkSign(data)) { // 验证签名
if (data.result_code === 'SUCCESS') {
// 更新订单状态为已支付
await updateOrderStatus(data.out_trade_no, 'paid');
res.send('');
}
} else {
res.send('');
}
});
// 签名验证函数
function checkSign(data) {
const sign = data.sign;
delete data.sign;
const calculatedSign = createSign(data);
return sign === calculatedSign;
}