小程序支付,涉及一些知识。
在微信提供的接口文档中提供了一个微信支付接口,应该是直接调用这个接口就可以发起微信支付
文档路径:https://developers.weixin.qq.com/miniprogram/dev/api/api-pay.html#wxrequestpaymentobject
但是,当开始信心满满的去看所需参数时,懵逼了,这些参数是什么
在这些参数中最难理解和获取的就是这两个了,仔细研究后发现,package这个参数的获取要调用微信提供的另一个接口,统一下单接口。原来在微信中支付需要先进行一下预下单。这里的时间戳使用的是秒值,不是毫秒值
(统一下单接口 这个接口就需要后台通过http请求来调了)
统一下单接口 请求参数
而在这些参数中,有两个参数很眼熟,在第一步发起微信请求时也有这两个参数,后发现这里的随机字符串就是调起支付时用到的随机字符串,而且是必须一致,那么签名呢,要是也认为一样就完全调沟里了,这里的签名我称为一次签名,因为支付的时候要进行第二次签名。
把这些必填的参数都准备好
很重要的是你要首先有个店铺,就有商户号了
订单号必须唯一哦,通知地址就是当支付成功后微信会回调这个地址,在这里你可以做一些事,比如修改订单状态什么的。
然后就是签名生成,这个很重要:把需要的参数都放到一个map中,然后对这些参数进行排序,然后把商品key拼接到后面进行MD5加密就生成签名了,我还是建议仔细看看签名生成算法,不要想太复杂,就是排序,拼接,加密三步完成。
最后就是准备参数传输了,这里的参数传输是以xml的方式传输,下面就是传输的数据,其实就是一个大的字符串,
你可以这样
我就意思一下了,大家懂就行,其实就是一个字符串,完全可以通过遍历参数map来自己拼接的。
然后就是把这个大字符串传过去,以上没问题的话就会返回一个字符串的xml,格式类型咱们拼接的参数。
从中取出我们需要的东西,最重要的应该就是这个,预下单id,这就是之前咱们需要的package
使用时是这样的:package='prepay_id=201411109120471241k1241240124bk1k24'
然后就是二次签名了,签名生成顺序和第一次是一样的,主要要确定需要哪些参数。
----------------------------------------------------------------------------------------
html部分
<view class='container'>
<view class="money">
<text class="money-font">{{money}}</text>
<text class="title">支付金额</text>
</view>
<view class="product">
<view class="item">
<view class="item-left">产品名称</view>
<view class="item-right">{{productName}}</view>
</view>
<view class="item">
<view class="item-left">订单号</view>
<view class="item-right">{{order}}</view>
</view>
</view>
<view class="footer">
<view class="pay-number">
<view class="pay-title">付款</view>
<view class="pay-money">¥{{money}}</view>
</view>
<view class="btn-area">
<view class="submit" bindtap="sendPayment" hover-class='btn-hover'>去支付</view>
</view>
</view>
</view>
js部分
/**
* 页面的初始数据
*/
data: {
money: '',
productName: '',
order: ''
},
// 调起微信原生支付
openPayment: function(obj) {
let that = this;
let prepay_id = obj.packageStr.split('=')[1];
wx.requestPayment({
'timeStamp': obj.timeStamp,
'nonceStr': obj.nonceStr,
'package': obj.packageStr,
'signType': obj.signType || 'MD5',
'paySign': obj.paySign,
'success': function(res) {
console.log(res)
},
'fail': function(res) {
console.log(res)
},
'complete': function(res) {
if (res.errMsg == 'requestPayment:ok') {
wx.redirectTo({
url: '../paymentResult/paymentResult?code=1&prepay_id=' + prepay_id
});
} else {
wx.redirectTo({
url: '../paymentResult/paymentResult?code=0'
});
}
}
})
},
// 点击支付按钮,
sendPayment: function() {
let that = this;
let openid = wx.getStorageSync('openid');
let linkParam = this.data.linkParam;
let a2realName = true; // a2实名开关,默认打开的
if (linkParam.miniSource == 'A2') {
this.wechartpay()
}
},
// 调用后台支付接口,后台会把信息传到微信、微信传到资金。再依次返回
wechartpay: function() {
let that = this;
let openid = wx.getStorageSync('openid');
let linkParam = this.data.linkParam;
let platNo = linkParam.platNo;
if (platNo) {
platNo = TrimAll(platNo);
platNo = linkParam.platNo.substring(0, 2);
}
ajax({
url: api.wechartpay,
data: {
policyInfo: linkParam.branchCode == '5020100' ? JSON.stringify( // 深圳地区车险自然人新保传
linkParam.policyInfo //商业险投保单号
) : null,
systemInfo: '', //签名来源时间戳等信息
type: null, //支付方式
branchCode: linkParam.branchCode || '', //
checkCode: '-', //校验码
payApplyNo: linkParam.payApplyNo || '', //支付申请号
orderAmount: linkParam.orderAmount || '', //订单金额
productNum: linkParam.productNum || '', //订单数量
//资金平台用户名 A2用户名:PWF_017 电销三期:PTW_008 码上保:PMS_010 s=pwf (全流程 A2用户名), s=ptw(支付号 电销三期)
capitalName: linkParam.s == 'pwf' ? 'PWF_017' : linkParam.s == 'ptw' ? 'PTW_008' : 'PMS_010',
// capitalName:'PWF_017',
productCode: linkParam.productCode || '', //
productName: linkParam.productName || '', //
successUrl: null, //
failUrl: null, //
isUserPid: '0', //(不为空传1代表需要通过微信校验身份证姓名信息,则userPid和userName必传,否则不校验。通过产险微信号支付必传,否则无法支付成功。)
userPid: linkParam.userPid || '0', //支付人身份证
userName: linkParam.userName || '',
friendPay: '1', //0不支持代付
showPolicy: '0', //0不显示
openid: openid || '', // openid oIVq0ji6oXEn0hqBnlTpydxf4PX0
coverageInfo: JSON.stringify([]), // 子险(非车信息)
vehicle: linkParam.miniSource == 'A2' ? true : false, // 车险为true,非车为false;
isYZ: platNo == '粤Z' ? '1' : '0', // 是否是粤Z车牌
attr1: linkParam.branchCode == '5020100' ? '1' : null // 深圳地区车险自然人新保传1 其它情况不传
}
}).then(function(re) {
console.log(re)
if (re.code == 1 && re.data.data) {
// re.data.data 需要支付的信息
that.openPayment(re.data.data)
} else {
//失败页面 code = 0
wx.redirectTo({
url: `../paymentResult/paymentResult?code=0&msg=${re.data.msg}`
});
}
})
},
wxss 样式
/* pages/payment/payment.wxss */
page {
background-color: #eee;
}
.money {
display: flex;
flex-direction: column;
width: 100%;
background-color: #ffffff;
align-items: center;
border-top: 1rpx solid #cccccc;
padding: 80rpx 0;
box-sizing: border-box;
}
.money-font {
font-size: 58rpx;
}
.title {
font-size: 32rpx;
color:#555555;
}
.product {
width: 100%;
background-color: #ffffff;
}
.item {
border-top: 1rpx solid #cccccc;
padding: 26rpx 20rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
}
.item-left {
width: 30%;
}
.footer {
width: 100%;
position: fixed;
bottom: 0;
left:0;
display: flex;
background-color: #ffffff;
height:100rpx;
align-items: center;
justify-content: space-between;
}
.pay-number {
display: flex;
flex: 1;
}
.pay-title {
padding: 0 26rpx;
box-sizing: border-box;
}
.btn-area {
height:100rpx;
flex:1;
text-align: center;
}
.pay-money {
color:darkorange;
}
.btn-area .submit {
height:100rpx;
line-height: 100rpx;
color: #fff;
font-size: 34rpx;
background: -webkit-linear-gradient(left, #0094d5, #005bac);
background: linear-gradient(to right, #0094d5, #005bac);
}
.btn-hover {
opacity: 0.6;
}