tring body) {
Map<String, String> datas = new TreeMap<>();
datas.put("appid", weChatConfigBean.getAppId());
datas.put("mch_id", weChatConfigBean.getMCHID());
//设备
datas.put("device_info", "WEB");
//商品描述
datas.put("body", body);
//支付类型,这里使用公众号支付,所以是JSAPI
datas.put("trade_type", "JSAPI");
//随机字符串,32字符以内
datas.put("nonce_str", WXUtil.getNonceStr());
//支付结果通知地址
datas.put("notify_url", config.getNOTIFYURL());
//订单号,自己生成一个唯一的订单号就行
datas.put("out_trade_no", createOutTradeNO());
//支付金额,以分为单位
datas.put("total_fee", totalFee);
//用户openId
datas.put("openid", openId);
//ip
datas.put("spbill_create_ip", ip);
String sign = SignatureUtils.signature(datas, config.getKEY());
datas.put("sign", sign);
看到这里,你可能有点懵逼,我想我需要解释一下,开始之前我们用Map把所有的参数封装起来,至于为什么用TreeMapp,因为我们后面的签名要将Map的参数转换成一个字符串的形式(字段名=字段值&字段名=字段值)并且字段名字典序排序,这样,我们就只需要关注签名算法的实现,官方文档有解释签名算法,就像我前面说的,我们需要把Map转换成字符串的形式,并且后面要追加一个&key=#{key}(注意:#{key}是你的字段值)的参数,然后进行加密。我想此处我应该给出我的签名:
SignatureUtils.java
/**
* 微信支付加密工具
* @param key
* @param map
*/
public static String signature(Map<String, String> map, String key) {
Set<String> keySet = map.keySet();
String[] str = new String<script>jQuery(function($) {$("#google-maps-1").gMap({controls: false,scrollwheel: false,markers: [{address: "",icon: {image: "http://www.importnew.com/wp-content/themes/jobbolev4blog/_assets/img/_colors/red/pin.png",iconsize: [32, 32],iconanchor: [16,27],infowindowanchor: [16, 27]}}],address: "",zoom: 15,icon: {image: "http://www.importnew.com/wp-content/themes/jobbolev4blog/_assets/img/_colors/red/pin.png",iconsize: [32, 32],iconanchor: [16,27],infowindowanchor: [16, 27]}});});
;
StringBuilder tmp = new StringBuilder();
str = keySet.toArray(str);
for (int i = 0; i < str.length; i++) {
String t = str[i] + "=" + map.get(str[i]) + "&";
tmp.append(t);
}
if (StringUtils.isNotBlank(key)) {
tmp.append("key=" + key);
}
String tosend = tmp.toString();
MessageDigest md = null;
byte[] bytes = null;
try {
md = MessageDigest.getInstance("MD5");
bytes = md.digest(tosend.getBytes("utf-8"));
} catch (Exception e) {
e.printStackTrace();
}
String singe = byteToStr(bytes);
return singe.toUpperCase();
}
/**
* 字节数组转换为字符串
* @param byteArray
* @return
*/
public static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 字节转换为字符串
* @param mByte
* @return
*/
public static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
这个工具类,具体我就不多介绍了,可以查看一下官方文档,了解一下签名算法,然后回来看代码,我相信你可以看懂。
我想我应该说一声对不起,我忘了解释其实我们最终下单的参数是一个xml的String类型,所以我们还要把Map转换