小程序支付,涉及一些知识。
在微信提供的接口文档中提供了一个微信支付接口,应该是直接调用这个接口就可以发起微信支付
文档路径: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; 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 { 100%; background-color: #ffffff; } .item { border-top: 1rpx solid #cccccc; padding: 26rpx 20rpx; box-sizing: border-box; font-size: 32rpx; display: flex; } .item-left { 30%; } .footer { 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; }