最近在做一个微信小程序的蓝牙项目。用户通过微信小程序支付后,通过蓝牙将指定的数据包写入设备,设备启动。
大致的流程图就是这样子:
这里面涉及到两个部分,一个小程序的蓝牙通讯,一个是小程序的支付。我今天就记录一下小程序的支付
(一)小程序的准备工作
小程序的申请配置等是在微信公众号里面的,所以你需要申请公众号,去配置。具体可以参考
https://jingyan.baidu.com/article/4f34706e2f9744e387b56d27.html
(二)小程序代码开发
1.我开发小程序支付的时候,最大的感触就是多看微信给出的文档
注意:发布小程序时,是需要你服务器安装ssl证书的,也就是https这种方式访问服务器。
但是你开发的时候可以勾选 <不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书> 这个选项来开发。
2.小程序支付流程图如下
2.1通过调用微信小程序的登录方法获取到code,然后去服务器获取prepareid
2.1.1小程序前端代码
wx.login({
success:function(res){
if (res.code) {
//发起网络请求
wx.request({
url: '你的服务器地址',
data: {
code: res.code,
money: that.data.money,//此次付款金额
dataType:'json'
},
success:function(res){
console.log("获取prepareId成功")
var out_trade_no = res.data.out_trade_no;
var prepay_id = res.data.prepay_id;//服务器返回的id
}
})
}
}
2.1.2服务器端返回prepareid代码
/**
* 获取prepareid
* */
public String getPrepareid(String code,String money,String spbill_create_ip) {
//获取openid
String getOpenidPath = "https://api.weixin.qq.com/sns/jscode2session?appid="+WXPayConfig.appId+"&secret="+WXPayConfig.appSecret+"&js_code="+code+"&grant_type=authorization_code";
JSONObject jsonObject = null;
try {
jsonObject = (JSONObject) JSONObject.parse(WeiXinUtils.getRequest(getOpenidPath));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String openid = jsonObject.getString("openid");
if (openid == null) {
return null;
}
/**
* 小程序id appid
* 商户号 mch_id
* 随机字符串 nonce_str
* 签名 sign
* 商品描述 body
* 商户订单号 out_trade_no
* 标价金额 total_fee
* 终端IP spbill_create_ip
* 通知地址 notify_url
* 交易类型 trade_type 小程序取值如下:JSAPI
* 用户标识 openid trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
*/
String nonce_str = UUID.randomUUID().toString().replaceAll("-","");
String body="设备充值";
String out_trade_no = WeiXinUtils.creatOut_trade_no();
Float float1 = new Float(money);
Integer total_fee = (int) (float1 * 100);
//---------
//终端IP
//spbill_create_ip
//这是你设置的支付成功后,微信服务器向你服务器发送通知的地址
String notify_url = "http://xxx.xxx.xxx";
//组装数据 md5加密
//组装数据排序后 md5加密
SortedMap<String,String> packageParams = new TreeMap<>();
packageParams.put("appid", WXPayConfig.appId);
packageParams.put("mch_id", WXPayConfig.partner);
packageParams.put("nonce_str",nonce_str );
packageParams.put("body", body);
packageParams.put("out_trade_no",out_trade_no);
packageParams.put("total_fee",total_fee+"");
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", notify_url);
packageParams.put("trade_type", WXPayConfig.trade_type);
packageParams.put("openid", openid);
//sign
String sign = WeiXinUtils.createWeiXinSign(packageParams);
String xml = "<xml>"+
"<appid>"+WXPayConfig.appId+"</appid>"+
"<mch_id>"+WXPayConfig.partner+"</mch_id>"+
"<nonce_str>"+nonce_str+"</nonce_str>"+
"<sign>"+sign+"</sign>"+
"<body><![CDATA["+body+"]]></body>"+
"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
"<total_fee>"+total_fee+""+"</total_fee>"+
"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
"<notify_url>"+notify_url+"</notify_url>"+
"<trade_type>"+WXPayConfig.trade_type+"</trade_type>"+
"<openid>"+openid+"</openid>"+
"</xml>";
//下单接口
String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String prepay_id = "";
prepay_id = WeiXinUtils.getPayNo(createOrderURL,xml);
if (prepay_id.equals("")) {
return null;
}
//组装json
HashMap<String, String> map = new HashMap<>();
map.put("prepay_id", prepay_id);
map.put("out_trade_no",out_trade_no);
String json = JSON.toJSONString(map);
return json;
}
2.2 小程序调起支付,成功后去后台查账单
2.2.1 小程序前端代码
/*
appId
timeStamp
nonceStr
package
signType
paySign
*/
var timeStamp = util.getTimeStamp();
var nonceStr = util.creatNonceStr();
prepay_id = 'prepay_id=' + prepay_id;
/*
nonceStr,timeStamp,prepare_id
*/
var sign = util.creatPaySign(nonceStr, timeStamp, prepay_id);
/*
调起支付
*/
wx.requestPayment({
'timeStamp': timeStamp,
'nonceStr': nonceStr,
'package': prepay_id,
'signType': 'MD5',
'paySign': sign,
success: function (res) {
/*
查询账单并跳转
*/
wx.request({
url: '我的服务器上的查询账单的地址',
data: {
out_trade_no: that.data.out_trade_no,
money: that.data.money
},
success: function (res) {
console.log("查询到账单");
},
fail:function(){
}
})
},
fail: function (res) {
console.log('调起支付返回结果失败>>>' + res);
},
complete: function (res) {
console.log('调起支付返回结果complete>>>' + res);
}
})
2.2.2 服务器通知代码
注意:服务器收到通知后,应该给微信的服务器回复收到消息的通知。如果不回复,微信服务器还会跟你推送支付完成的消息,一共会推送8次。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String xml_review_result = WeiXinUtils.getXmlRequest(request);
Map resultMap = null;
try {
resultMap = XMLUtil.doXMLParse(xml_review_result);
if (resultMap != null && resultMap.size() > 0) {
String result_code = (String) resultMap.get("result_code");
// 返回成功
if (result_code.equals("SUCCESS")) {
// 微信回复支付成功
String xml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
response.getWriter().write(xml);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
2.2.3 服务器上的查询账单的代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String out_trade_no = request.getParameter("out_trade_no");
String price = request.getParameter("money");
Map resultMap;
try {
resultMap = WeiXinUtils.checkWxOrderPay(out_trade_no);
String return_code = (String) resultMap.get("return_code");
if ("SUCCESS".equals(return_code)) {
//自己去做一些逻辑操作
response.getWriter().write("ok");
}else {
response.getWriter().write("faild");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(三)微信小程序支付所用到的工具类
(四)后台代码所用到的工具类
md5
WeiXinUtils
XMLUtil
如果没有积分了,直接留言或者加我qq:1455859842,我看到了会把工具类直接发给你。