微信小程序接入微信支付
微信小程序接入微信支付
文章目录
微信小程序接入微信支付
一、准备工作
1. 申请材料
1、营业执照:彩色扫描件或数码照片
2、组织机构代码证:彩色扫描件或数码照片,若已三证合一,则无需提供
3、对公银行账户:包含开户行省市信息,开户账号
4、法人身份证:彩色扫描件或数码照片
2. 费用
申请接入微信支付不收取任何申请费用;
商户交易按费率收取服务费,一般与商家选择的经营类目有关,为0.6%-1%不等。
3.申请流程
- 提交资料
- 签署协议
- 绑定场景
二、技术实现
1. 微信小程序微信支付流程
小程序微信支付主要步骤:
- 小程序提前调用
wx.login()
,接口会返回openid
,这个 openid 是调用微信的下单接口时的必填参数,把 openid 存到本地备用。 - 小程序端调用自己服务端的下单接口,需传
openid
和其他一些后台需要的业务参数。 - 服务端收到小程序端上一步的请求之后,调用微信平台的下单接口进行下单,同时组装好下一步小程序端调起微信支付需要用的一些参数,
timeStamp
,nonceStr
,package
,signType
,paySign
,下单成功之后将这些信息一并返回给小程序端。 - 小程序端拿到上一步服务端给的参数之后,调用
wx.requestPayment()
接口就能调起来微信支付。 - 用户输入支付密码之后,返回小程序中,wx.requestPayment()的回调中有支付结果。
- 在 wx.requestPayment() 支付成功的回调中,调用自己服务端查询订单的接口,这一步是为了触发服务端自主去向微信平台及时查询订单状态。
- 自己服务端主动向微信平台查询订单状态,微信平台也会异步的对支付结果进行通知到服务端,但是通知是异步的。
- 小程序端返回前一个页面刷新支付状态。
微信小程序接入微信之后整体流程挺简单,需要注意的是,第 3 步中,对数据进行加签加密的步骤建议放到服务端进行处理。
2. 业务场景及代码实现
2.1 确认订单
首先需要有一个确认订单的页面,这个页面就是订单详情页,这个页面需要有一个触发用户点击去支付的按钮。
2.2 下单
点击“去付款”,调用自己服务端的下单接口:
placeOrder() {
wx.showLoading({
title: '',
})
const _this = this
const postData = {
goodsID: _this.data.goods_info.goodsID,
userID: wx.getStorageSync('userId'),
openID: wx.getStorageSync('openid')
}
wx.request({
url: 'https://xxx.com/api?xxx=xxx&token=xxx',
method: 'POST',
header: {
"Cookie": "xxx",
"Content-Type": "application/x-www-form-urlencoded"
},
data: postData,
success(res) {
if (res.status === 200) {
_this.goTowxPay(res.data)
}
wx.hideLoading()
},
fail(err) {
wx.hideLoading()
console.log(err)
}
})
}
调用自己的服务端,自己的服务端 ,下单成功后将结果和以下组装好的数据返回给小程序端:
timeStamp
nonceStr
package
signType
paySign
这是在小程序端自己拼接的参数:
const timestamp = Date.now();
const nonceStr = (Math.random()).toString()
const prepay_id = this.data.prepay_id
var signStr = "wx9xxxe39xxx9b4f" + "\n" + timestamp + "\n" + nonceStr + "\n" + "prepay_id=" + prepay_id + "\n"
var publicKey = '';
var key = CryptoJS.enc.Utf8.parse(publicKey);
var plaintext = signStr;
var plainData = CryptoJS.enc.Utf8.parse(plaintext);
var encryptedData = CryptoJS.RSA.encrypt(plainData, key);
var paySign = encryptedData.toString();
wx.requestPayment({
"timeStamp": timestamp,
"nonceStr": nonceStr,
"package": "prepay_id=" + prepay_id,
"signType": "RSA",
"paySign": paySign,
"success": function(res){
},
"fail": function(res){
},
"complete": function(res){
}
})
处理起来还是比较简单的,但是涉及到加密什么的,建议将此步骤放在服务端完成,客户端/前端 接收到参数之后直接调起微信支付就可以了。
参数拼接以及签名方式见文档 。
2.3. 调起微信支付
从上一步下单成功后,拿到此步骤需要的参数之后,直接调用
wx.requestPayment()
方法,调起微信支付输入密码的页面。
goTowxPay(userInfo) {
const _this = this
wx.requestPayment({
"timeStamp": userInfo.timeStamp,
"nonceStr": userInfo.nonceStr,
"package": userInfo.package,
"signType": userInfo.signType,
"paySign": userInfo.paySign,
"success": function(res){
console.log('success', res)
if (res.errMsg === "requestPayment:ok") {
_this.refreshPaymentStatus()
_this.showToast()
_this.queryPayment()
}
},
"fail": function(res){
console.log('fail', res)
},
"complete": function(res){
console.log('complete', res)
}
})
},
会自动弹出微信支付输入密码的遮罩层,用户输入密码之后,会回调成功或者失败,这里的 complete() 回调,不管是成功还是失败都是回调。
支付成功之后我们需要做这几件事:1)刷新页面显示;2)提示用户支付结果;3)查询支付结果。其中1)和 2)根据业务情况,是非必须的。3)是建议最好这么做,通过调用自己服务端的API,触发服务端调用微信平台查询订单支付结果。
2.4. 查询支付结果
queryPayment() {
wx.showLoading({
title: '',
})
const _this = this
const postData = {
goodsID: _this.data.goods_info.goodsID,
userID: wx.getStorageSync('userId'),
}
console.log(postData)
wx.request({
url: 'https://xxx/api?xxx=xxx&token=xxx',
method: 'POST',
header: {
"Cookie": "xxx=xxx",
"Content-Type": "application/x-www-form-urlencoded"
},
data: postData,
success(res) {
console.log(res)
wx.hideLoading()
_this.goToFront()
},
fail(err) {
console.log(err)
wx.hideLoading()
_this.goToFront()
}
})
},
goToFront() {
wx.navigateBack()
}
微信支付完成之后,微信会异步通知到自己的服务端,因为是异步的,所以建议小程序端主动去调接口触发查询支付结果。
服务端至少要做三件事,1)接收微信平台支付通知; 2)接收前端的接口,调用微信平台查询支付结果;3)通过一定的时间机制,定时查寻订单支付状态。
三、一些问题:
- wx.requestPayment(object)调起来微信支付,其中参数是后台生成还是小程序端自己生成?