今天来写点什么,就写微信支付吧。哥可是被微信支付接口给折腾惨了。
大概从5月22好开始,进行微信开发,到现在也有个吧月了,老总要求3个月拿出微信会员系统,感觉有点悬,这两天又被微信支付给卡住了。
为了童鞋们能少走弯路,特此公告天下,哪位童鞋微信支付遇到了问题,尽管留言。下面谈谈自己的被坑爹的过程。
1.要使用微信支付,前提是开通微信支付功能(废话!),开通后,就可以拿到商户id和商户api密钥,有了这两个必须的东西,就可以调用微信统一支付接口,拿到微信预支付prepayid了.有了prepayid,就可以在网页中调用jsapi了。
2.重点是怎么拿到prepayid呢?很简单,调用post请求道https://api.mch.weixin.qq.com/pay/unifiedorder地址就可以了,很简单吧。咋一看确实简单,但这里面隐藏了好几个坑。网上一搜,坑一大把,我就把我遇到的两个坑show一下好了
3.要拿到peipayid,需要传递一组xml数据,对应java攻城狮来说,一般都会写个model,填充数据,然后将model转换为xml字符串,然后跟随post请求一起发送出去。
4.在一组xml数据中,有一个签名,初次遇到的人肯定都会蒙。这个签名要怎么签呢,要把你所有要传递给服务器的数据进行处理。记住:是所有要传递给服务器(腾讯)的数据,除了sign这个数据外的所有数据。sign也要被传送到服务器端去。
一般是这样的:
private String appid;// 公众账号ID
private String mch_id;// 商户号
private String device_info;// 设备号
private String nonce_str;// 随机字符串
private String sign;// 签名
private String body;// 商品描述
private String detail;// 商品详情
private String attach;// 附加数据
... ...
将这些字段先进行排序,字典排序,直接调用Arrays.sort(String[]);这样就排序完了,然后再拼接成一个字符串,appid=123&mch_id=123......以此类推,最后在加上商品api密钥key=123.完了之后,进行md5转换,在这,我被坑了一把。
原因很简单,我转换后的md5有时候是29位,而不是32位,这是因为我在讲md5二进制字节流转换为字符串的时候,没有处理字节中小于16的值。也就是应该在小于16的值前面加0,不加的话,md5的结果位数就不对
5,我遇到的下一个坑,也很简单,但折腾了我很久。我将创建好的model转换为xml,使用的是以下代码:XStream xStream = new XStream();
xStream.alias("xml", object.getClass());
转换结果如下:
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0,user-scalable=true">
<title>Bootstrap 模板</title>
<script src="../resource/jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript"
src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '${config_appId}', // 必填,公众号的唯一标识
timestamp: parseInt('${config_timestamp}'), // 必填,生成签名的时间戳
nonceStr: '${config_nonceStr}', // 必填,生成签名的随机串
signature: '${config_signature}',// 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline','chooseWXPay']
});
wx.ready(function(){
wx.chooseWXPay({
timestamp: parseInt('${pay_timestamp}'), // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '${pay_nonceStr}', // 支付签名随机串,不长于 32 位
package: '${pay_package}', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '${pay_paySign}', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}
});
});
wx.error(function(res){
alert(res);
});
</script>
</head>
<body>
<div>
config 参数
<p>appid:${config_appId}</p>
<p>timestamp: ${config_timestamp}</p>
<p>nonceStr: ${config_nonceStr}</p>
<p>signature: ${config_signature}</p>
</div>
<div>
支付参数
<p>timestamp: ${pay_timestamp}</p>
<p>nonceStr: ${pay_nonceStr}</p>
<p>package: ${pay_package}</p>
<p>signType: ${pay_signType}</p>
<p>paySign: ${pay_paySign}</p>
</div>
</body>
</html>