由小程序前端虚拟数据发起的订单(形成预支付订单返回prepay_id)-微信支付-支付成功这么一个过程。没有后台操作,全部是前端操作,只是为了能走通小程序支付流程,菜鸟的尝试,记录一下,(真正做支付,涉及到钱还是要后端支持的,毕竟全部前端操作安全性不高)如果能后台支持,很多步骤是不需要的
不过由于我还不会读取文件去pem文件里面获取秘钥,所以需要手动输入证书秘钥(需要PEM RSA私钥)
wxml页面
<text>下订单(形成预支付订单返回prepay_id)-支付-支付成功这么一个过程</text>
<view class="container">
<form bindsubmit="bindFormSubmit">
<!-- textarea 设置maxlength="-1"是为了不限制长度 -->
<textarea placeholder="填写秘钥" maxlength="-1" name="textarea" value='' style="border: 1px solid #000;"></textarea>
<button type="warn" form-type="submit">下单</button>
</form>
</view>
js页面
var jsrsasign = require('../../utils/jsrsasign-all-min.js'); //引用js
Page({
data: {
appid: '',
mchid: '',
description: '',
out_trade_no: '',
time_expire: '',
attach: '',
notify_url: '',
goods_tag: '',
amount_total: '',
amount_currency: '',
payer: '',
//支付证书秘钥
textarea_text:'',
},
onLoad: function (options) {
},
//下订单
bindFormSubmit: function (e) {
var that = this;
//签名构造
//时间戳
var timestamp = Date.parse(new Date());
timestamp = timestamp / 1000;
//随机数
var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
a = t.length,
n = "";
for (var i = 0; i < 32; i++) n += t.charAt(Math.floor(Math.random() * a));
var data_j = {
//具体参数要求看文档
appid: 'wxXXXX', //小程序appid
mchid: 'XXXX', //商户号
description: '啦啦啦啦',
out_trade_no: '12177525013014070332344368024',//订单号不能重复
time_expire: '2020-12-28T10:34:56+08:00',
attach: '自定义说明:购买章节',
notify_url: 'https://www.baidu.com',//通知URL必须为直接可访问的URL,我随便写了个
goods_tag: '',
amount: {
total: 2,//以分为单位
currency: 'CNY',
},
payer: {
openid: 'o8DAB5SX8oKjvrxCXkL7vUYjheHk',//通过wx.login去获取临时code,然后去兑换用户的openid
//调用auth.code2Session ,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
//请求地址为GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
}
};
var jsonstr = JSON.stringify(data_j) //将值转换为 JSON 字符串。
//拼接成下单需要的签名字符串,header里面要用到
var Signature_str = 'POST\n/v3/pay/transactions/jsapi\n' + timestamp + '\n' + n + '\n' + jsonstr + '\n';
//将证书和签名串一起加密成sha256,再加密64位
var rsa = new jsrsasign.RSAKey();
rsa.readPrivateKeyFromPEMString(e.detail.value.textarea);
var hSig = rsa.sign(Signature_str, 'sha256');
var sign = jsrsasign.hextob64(hSig);
that.setData({
textarea_text:e.detail.value.textarea, //支付时候的签名也需要用到证书,就先更新一下值
})
wx.request({
method: 'POST',
url: 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi',
data: data_j,
header: {
//商户API证书序列号serial_no
'Authorization': 'WECHATPAY2-SHA256-RSA2048 mchid="1509188351",nonce_str="' + n + '",signature="' + sign + '",timestamp="' + timestamp + '",serial_no="31AA736A2BE6D6214B2E989364C7D7CBFFDD86A3"',
},
success: function (res) {
console.log(res)
that.payment(res.data.prepay_id)
},
fail: function (error) {
console.log(error)
},
complete: function () {
that.setData({
loading: false
});
}
});
},
payment:function(e){
var that = this;
//签名构造
//时间戳
var timestamp = Date.parse(new Date());
timestamp = timestamp / 1000;
//随机数
var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
a = t.length,
n = "";
for (var i = 0; i < 32; i++) n += t.charAt(Math.floor(Math.random() * a));
//拼接成支付需要的签名字符串,appid\ntimestamp\n随机数\nprepay_id=XXX\n, prepay_id是刚才预支付订单返回的
var Signature_str = 'wx147a2183a6460527\n' + timestamp + '\n' + n + '\nprepay_id=' + e + '\n';
//将证书和签名串一起加密成sha256,再加密64位
var rsa = new jsrsasign.RSAKey();
rsa.readPrivateKeyFromPEMString(that.data.textarea_text);
var hSig = rsa.sign(Signature_str, 'sha256');
var sign = jsrsasign.hextob64(hSig);
wx.requestPayment({
timeStamp: timestamp+'', //记住,这边的timeStamp一定要是字符串类型的,不然会报错
nonceStr: n,
package: 'prepay_id=' + e,
signType: 'RSA',
paySign: sign,
success: function (event) {
console.log(event);
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
});
},
fail: function (error) {
wx.showToast({
title: '支付失败',
icon: 'success',
duration: 2000
});
console.log(error)
},
complete: function () {
console.log("pay complete")
}
});
},
})
需要引入的jsrsasign-all-min.js
好像不能插入文件,上传在资源那边啦
emm~,其中前端签名的生成和下单的时候需要的header这两个地方走了不少弯路