android微信支付脱坑指南(WXPay)
—————————(纯手打,实战经验)
create by popovich(作者)
第一步:登录开放平台(找公司要账号密码)
第二步:点击查看
- 可以获取到产品的AppID:wx74cxxxxfcddsasdxxxxxxx
同时可以看到应用签名和包名(这个需要修改)
1.点击修改按钮:进入修改页面
- 2根据签名xxx.jks文件和密码xxx.txt
应用签名是根据jks文件生成的32位签名,字母改成小写(本人测试或许大写也可以)去掉冒号
生成的操作方法有两种,一个是用命令行:
(黑色部分是jks文件存放路径)F:xxx> keytool -list -v -keystore xxx.jks
别名:xxx
创建日期: 2016-11-10
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=fdsafds, OU=fdsafds, O=dfswafew, L=rfewfew, ST=rewfrew, C=efw3rfew
发布者: CN=fdsafds, OU=fdsafds, O=dfswafew, L=rfewfew, ST=rewfrew, C=efw3rfew
序列号: 147e1f09
有效期开始日期: Thu Nov 10 15:03:19 CST 2016, 截止日期: Mon Nov 04 15:03:19 CST
2041
证书指纹:
MD5: 43:61:1F:75:75:51:B6:A4:EE:67:81:F5:44:DA:00:xx
SHA1: Ex:02:16:x2:A3:D8:x1:BD:5D:AC:35:86:9D:xx:FF:65:53:E0:97:xx
SHA256: x2:Fx:Ex:Exx:1:69:6A:7A:xx:5F:s4:28:60:7E:x1:AC:11:77:E5:Ax:73:
6s:s8:s3:sD:s0:s9:6A:0A:1s:C8:8d
签名算法名称: SHA256withRSA
第三步:登录商户平台
- 1,这个密钥是申请支付的时候邮件返回的密钥,可以修改,但要与后台配置一致,获取到这个密钥
(至关重要)api_key
然后这个配置也结束了,
下面进入支付代码时刻,
第四步: 导包:导入微信官方的支付包
- libammsdk.jar
- 现在由于微信官方改版,用AndroidStudio导包才能获取到最新版的。方式如下:
jar包不支持最新版的了,只能用老版的jar包
最新版的如下方式可以获得
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//这里是导包最新版的微信支付sdk
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
- 然后将wxapi.WXPayEntryActivity.java的文件拷贝到你自己工程包名下的wxapi包中(注意包名必须命名为wxapi(不解释照做就行))
- 示例:我的包名为com.popovich.demo(在此包名下建一个包命名为wxapi,然后将WXPayEntryActivity.java文件拷贝到此包下);
在清单文件mainfest文件中注册activity
2,然后是代码
- 2所指的方法为支付后的结果回调
里面的方法可以自己写返回 :
0:支付成功
-1:支付失败
-2:用户取消
这些配置好后,进入支付的类中编写支付的代码
在activity的onCreate方法中需要注册api
appId就是开放平台的那个appid=wx74cxxxxfcddsasdxxxxxxx;
支付方法
private void weixinPay(int orderInfoId) {
//发起网络请求获取prepayId
OkHttpUtils.postRequestBodyAsync(URLConstant.URL_WEIXIN_PAY, rb, new Callback() {
@Override
public void onFailure(Request request, IOException e) {}
@Override
public void onResponse(Response response) throws IOException {
//这里是获取后台得到的prepayId除了prepayid什么参数都不需要除非所有参数都由后台传递过来
String s = response.body().string();
req = new PayReq();
try {
JSONObject obj = new JSONObject(s).getJSONObject("data").getJSONObject("payData");
//绿色是重点代码
req.appId = URLConstant.appid;
req.partnerId = URLConstant.partnerid;
req.prepayId = obj.getString("prepay_id");//就这一个参数是获取来的,其他的需要自己生成
req.nonceStr = getNonceStr();
req.timeStamp = String.valueOf(getTimeStamp());
req.packageValue = "Sign=WXPay";
//生成签名
List<NameValuePair> signParams = new LinkedList<>();
signParams.add(new BasicNameValuePair("appid",req.appId));
signParams.add(new BasicNameValuePair("noncestr",req.nonceStr));
signParams.add(new BasicNameValuePair("package", req.packageValue));
signParams.add(new BasicNameValuePair("partnerid",req.partnerId));
signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
req.sign = getAppSign(signParams);
api.sendReq(req);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
//获取系统时间
private long getTimeStamp() {
return System.currentTimeMillis() / 1000;
}
//随机生成NonceStr(32位)
private String getNonceStr() {
Random random = new Random();
return MD5GET.getMessageDigest(
String.valueOf(random.nextInt(10000))
);
}
//生成签名的方法
private String getAppSign(List<NameValuePair> params) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.size(); i++) {
sb.append(params.get(i).getName());
sb.append('=');
sb.append(params.get(i).getValue());
sb.append('&');
}
sb.append("key="); //注意key字母必须小写
sb.append(Constant.API_KEY); //这里必须得注意坑就在这,API_KEY的值就是在商户平台的api安全中获取的api密钥,不可以设置错了;
String appSign =
MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); //这个必须转为大写
return appSign;
}