uni.app实现微信小程序支付
uni.app实现微信小程序支付
·
一、uni.app支付
uni.requestPayment是一个统一各平台的客户端支付API,不管是在某家小程序还是在App中,客户端均使用本API调用支付。
uni.requestPayment运行在各端时,会自动转换为各端的原生支付调用API。
- 注意支付不仅仅需要客户端的开发,还需要服务端开发。虽然客户端API统一了,但各平台的支付申请开通、配置回填仍然需要看各个平台本身的支付文档。
- 比如微信有App支付、小程序支付、H5支付等不同的申请入口和使用流程,对应到uni-app,在App端要申请微信的App支付,而小程序端则申请微信的小程序支付。
1.uni.requestPayment参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
provider | String | 是 | 服务提供商,通过 uni.getProvider 获取。 | |
orderInfo | String/Object | 是 | 订单数据, | App、支付宝小程序、百度小程序、抖音小程序 |
timeStamp | String | 微信小程序必填 | 时间戳从1970年1月1日至今的秒数,即当前的时间。 | 微信小程序 |
nonceStr | String | 微信小程序必填 | 随机字符串,长度为32个字符以下。 | 微信小程序 |
package | String | 微信小程序必填 | 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=xx。 | 微信小程序 |
signType | String | 微信小程序必填 | 签名算法,应与后台下单时的值一致 | 微信小程序 |
paySign | String | 微信小程序必填 | 签名 具体签名方案参见 微信小程序支付文档 | 微信小程序 |
bannedChannels | Array<String> |
否 | 需要隐藏的支付方式 | 百度小程序 |
service | Number | 抖音小程序必填 | 固定值:5(拉起小程序收银台)开发者如果不希望使用抖音小程序收银台,service设置为3/4时,可以直接拉起微信/支付宝进行支付:service=3: 微信API支付,不拉起小程序收银台;service=4: 支付宝API支付,不拉起小程序收银台。其中service=3、4,仅在1.35.0.1+基础库(头条743+)支持 | 抖音小程序 |
_debug | Number | 否 | 仅限调试用,上线前去掉该参数。_debug=1时,微信支付期间可以看到中间报错信息,方便调试 | 抖音小程序 |
getOrderStatus | Function | 抖音小程序必填 | 商户前端实现的查询支付订单状态方法(该方法需要返回个Promise对象)。 service=3、4时不需要传。 | 抖音小程序 |
success | Function | 否 | 接口调用成功的回调 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
- signType 说明
合法值 说明 MD5 仅在 v2 版本接口适用 HMAC-SHA256 仅在 v2 版本接口适用 RSA 仅在 v3 版本接口适用 - signType 注意事项
- APP端,如果你的应用在用户完成支付后;立即给支付的用户push消息通知。会与前端支付回调相互冲突,请延迟执行推送。
- 抖音小程序支付接口调整使用时请注意 头条支付。
- orderInfo 注意事项
二、微信小程序支付
1.微信小程序支付时序图
商户系统和微信支付系统主要交互:
1. 小程序内调用登录接口,获取到用户的openid
2. 商户server调用支付统一下单,
3. 商户server调用再次签名,
4. 商户server接收支付通知,
5. 商户server查询支付结果,如未收到支付通知的情况,商户后台系统可调用 查询订单API
6. 商户小程序内使用小程序调起支付API(uni.requestPayment)发起微信支付,
2.示例
// 仅作为示例,非真实参数信息。
uni.requestPayment({
provider: 'wxpay',
timeStamp: String(Date.now()),
nonceStr: 'A1B2C3D4E5',
package: 'prepay_id=wx20180101abcdefg',
signType: 'MD5',
paySign: '',
success: function (res) {
console.log('success:' + JSON.stringify(res));
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
});
3.案例
-
前端项目代码
// 获取openid async getOpenidHandler() { let { code } = await uni.login(); // 这个 api 支持 Promise 方式调用 console.log("code: ", code); // 请求后端的接口,获取 openid let url = `https://baidu.com/xcx/openid?code=${code}`; uni.request({ url, success: (response) => { console.log("response: ", response); /* { "code": 0, "msg": "success", "data": { "session_key": "xxxxxx====", "openid": "oZpya5S6Mk6cccccccccccccccccccc" } } */ } }) }
payHandler() { // 获取支付信息 let url = `https://baidu.com/xcx/buy`; uni.request({ url, success: (response) => { console.log("response: ",response); /* appId: "wx1cxxxxxxxx" nonceStr: "xxxxxxxxxxxx" package: "prepay_id=wx182045498482360e7cccccccccccccc" paySign: "9A8226D2424cccccccccccccccccccc" signType: "MD5" timeStamp: "1681821949" */ // package 是 js 里面的保留字 let {timeStamp, nonceStr, package: packageParam, signType, paySign } = response.data.data; wx.requestPayment({ timeStamp, nonceStr, package: packageParam, signType, paySign, success(res) { console.log("res: ", res); }, fail(res) { console.log('error', res); } }) } }) // 调用微信支付的 api /* */ }
-
node.js Sever项目代码
const express = require('express')
const tenpay = require('tenpay');
const siteConfig = require('./payConfig.js');
const path = require('path');
const md5 = require('md5');
const axios = require('axios')
const app = express()
const port = 8001
app.use(express.static('public'))
app.engine('html', require('express-art-template'));
app.set('view options', {
debug: process.env.NODE_ENV !== 'production'
});
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
const config = {
// appid: siteConfig.appid,
appid: siteConfig.xcxid,
mchid: siteConfig.mchid,
partnerKey: siteConfig.partnerKey,
notify_url: 'https://api.52kfw.cn/notify', // 买家成功支付后,微信系统通知商户后台系统的url地址 一般在这个里面去更改用户的订单的状态为 已支付
spbill_create_ip: '106.52.75.114'
};
// 调试模式(传入第二个参数为true, 可在控制台输出数据)
const api = new tenpay(config, true);
/**
* 根据小程序的 code 换取用户的 openid
*
*/
app.get('/xcx/openid', async (req, res) => {
// 客户端要传递一个 code
let code = req.query.code;
if (!code) {
res.json({
code: -1,
msg: 'code必传'
});
return;
}
let appid = siteConfig.xcxid;
let secret = siteConfig.xcxsecret;
// 使用code 换取openid
let codeToOpenidUrl = `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code `;
try {
const response = await axios.get(codeToOpenidUrl);
res.json({
code: 0,
msg: 'success',
data: response.data
})
} catch (e) {
res.json({
code: -1,
msg: 'failure',
data: null
})
}
})
app.get('/xcx/buy', async (req, res) => {
let goodsId = Date.now().toString();
let trade_no = md5(Math.random() + goodsId);
let openid = 'oZpya5S6Mk6ufOWW84eIYksSsJUc';
// appid和openid不匹配 tenpay 其他的 支付方式(pc h5 公众号 使用的服务号的 appid ,但是如果要做小程序支付,则要使用小程序的 appid)
let result = await api.getPayParams({
out_trade_no: trade_no,
body: '微信小程序支付测试',
total_fee: '1',
openid: openid, // 微信小程序支付则和微信公众号里面网页支付一样,需要一个openid
// openid 是什么? 当前微信小程序使用者的唯一身份标识符,在做支付的时候需要这个 openid
// 知道这个 openid 就知道是哪个微信用户在付钱?
// 如何获取到 openid
// wx.login api 是小程序提供的一个登录 api 返回一个 code, 然后我们可以通过这个code换取到用户的openid
// 如何换?
});
console.log(result);
res.json({
code: 0,
msg: 'success',
data: result
})
})
app.listen(port, () => {
console.log(`pay app listening on port ${port}`)
})
三、总结
- 小程序不能通过拉起H5页面做jsapi支付,小程序内只能使用小程序支付
更多推荐
所有评论(0)