最近公司的项目里边接入了微信支付, 看着微信官方的文档, 简直没有任何开发的欲望, 便萌生出了自己写一篇博客的想法, 以备下次开发或者同伴们踩坑.
1. 首先不可避免的要在微信开发平台上注册你的App.
(1).注册App其时有点坑, 注册的时候需要填上应用签名, 需要我们把App用正式签名打包好, 装到手机上, 然后把微信官方给的获取签名工具装到手机上, 输入你的应用包名就行了.
2.将微信的依赖添加到gradle中
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
或者
compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
官方对这两个依赖的区别的解释是上面的那种包含统计功能, 后面的不包含,但是两者都可以调起微信支付, 我个人是喜欢下面的那种.
3.在App的入口处向微信注册你在微信开放平台上申请的AppId
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
// 将该app注册到微信
msgApi.registerApp("你的AppId");
然后在你需要调用微信支付的地方写上以下代码
IWXAPI msgapi;
PayReq request = new PayReq();
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId= "1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr= "1101000000140429eb40476f8896f4c9";
request.timeStamp= "1398746574";
request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
msgapi.sendReq(request);
最好在向微信注册AppId的时候把IWXAPI写成静态的, 这样在调用的时候,就可以直接从入口处获取了.
关于参数说明, 看微信官方的说明就好, 我说的也不会比官方更好
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12
但是最后一个sign要特别注意一点, 很多公司的后台会在返回的参数中有一个sign, 这个参数给我们是没有用的, 我们在rqueest.sign时
上传的参数是我们自己跟据微信要求的规则拼出来的.
(1).第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),
使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
(2).第二步,在stringA最后拼接上key得到stringSignTemp字符串(key是你在微信开放平台注册完成后, 平台返回的AppSecret),
并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
可以参考我的工具类, 也可以自己写(当时赶进度没心思写注释, 将就着看)
public static String sortMap(Map paramMap){
Set<Map.Entry<String, String>> mySet = paramMap.entrySet();
List<Map.Entry<String, String>> list = new LinkedList<>(mySet);
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
StringBuilder str_sign = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
str_sign
.append(list.get(i));
if (i != list.size() - 1){
str_sign.append("&");
}
}
String SignTemp= str_sign + "&key=你的AppSecret";
String MD5Str = new MD5FileNameGenerator().generate(SignTemp);
return getMD5(SignTemp);
}
MD5加密的算法是我从百度上找的
//生成MD5
public static String getMD5(String message) {
String md5 = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5"); // 创建一个md5算法对象
byte[] messageByte = message.getBytes("UTF-8");
byte[] md5Byte = md.digest(messageByte); // 获得MD5字节数组,16*8=128位
md5 = bytesToHex(md5Byte); // 转换为16进制字符串
} catch (Exception e) {
e.printStackTrace();
}
return md5;
}
// 二进制转十六进制
public static String bytesToHex(byte[] bytes) {
StringBuffer hexStr = new StringBuffer();
int num;
for (int i = 0; i < bytes.length; i++) {
num = bytes[i];
if(num < 0) {
num += 256;
}
if(num < 16){
hexStr.append("0");
}
hexStr.append(Integer.toHexString(num));
}
return hexStr.toString().toUpperCase();
}
这样微信的调用就完成了, 但是我们的工作还没完成, 还要写支付完成的回调.
在包名的目录下建一个名为wxapi的文件夹, 然后在wxapi里建一个名为WXPayEntryActivity的类, 实现IWXAPIEventHandler的接
口, 重写onReq和onResp方法, onReq方法我没了解过, 便不多说; 在onReap方法中, baseResp.errCode是支付结果状态码
然后跟据状态码执行不同的操作.
哦, 对了, 有一点微信官方文档上没有提到的, 就是要签名打包后才能调起微信支付的功能.