微信支付集成满满都是坑。
一.准备:
1. 在微信开放平台 https://open.weixin.qq.com/ 注册申请账号, 并且开通支付权限。
注意申请的时候需要填写你apk发布的签名。
申请成功后 会发送给你 appid, paySignKey,paySecretKey, partenId, parternId等 其他的比如商户id之类的。
二.开发
总的来说要和完成微信支付需要做以下几步;
1. 生成本地订单信息。
2..向微信 服务器获取新的accessToken。
2. 根据accesToken, 以及定单参数申请prepayId
3.根据prepayid 生成预支付订单。
5. 向微信发起支付申请。
上面的步骤 由于步骤1 需要根据用户操作获取信息, 一般是在前端做, 步骤5需要用户通过微信发起支付所以也在前端做。 其他的步骤都应该在后端做。
步骤2 获取accesToken的时候:
protected static String getTokenReal() {
String requestUrl = ConstantUtil.TOKENURL + "?grant_type=" + ConstantUtil.GRANT_TYPE + "&appid="
+ ConstantUtil.APP_ID + "&secret=" + ConstantUtil.APP_SECRET;
String resContent = "";
TenpayHttpClient httpClient = new TenpayHttpClient();
httpClient.setMethod("GET");
httpClient.setReqContent(requestUrl);
if (httpClient.call()) {
resContent = httpClient.getResContent();
if (resContent.indexOf(ConstantUtil.ACCESS_TOKEN) > 0) {
access_token = JsonUtil.getJsonValue(resContent, ConstantUtil.ACCESS_TOKEN);
} else {
System.out.println("获取access_token值返回错误!!!");
}
} else {
System.out.println("后台调用通信失败");
System.out.println(httpClient.getResponseCode());<pre name="code" class="java"> }
真正求求token之前最后判断token是否过期或则为空:
/**
* 判断传递过来的参数access_token是否过期
* @param access_token
* @return
*/
private static boolean tokenIsExpire(String access_token) {
boolean flag = false;
PrepayIdRequestHandler wxReqHandler = new PrepayIdRequestHandler(null, null);
wxReqHandler.setParameter("appid", ConstantUtil.APP_ID);
wxReqHandler.setParameter("appkey",ConstantUtil.APP_KEY);
wxReqHandler.setParameter("noncestr", WXUtil.getNonceStr());
wxReqHandler.setParameter("package", ConstantUtil.packageValue);
wxReqHandler.setParameter("timestamp", WXUtil.getTimeStamp());
wxReqHandler.setParameter("traceid", ConstantUtil.traceid);
// 生成支付签名
String sign = wxReqHandler.createSHA1Sign();
wxReqHandler.setParameter("app_signature", sign);
wxReqHandler.setParameter("sign_method", ConstantUtil.SIGN_METHOD);
String gateUrl = ConstantUtil.GATEURL + access_token;
wxReqHandler.setGateUrl(gateUrl);
// 发送请求
String accesstoken = wxReqHandler.sendAccessToken();
if (ConstantUtil.EXPIRE_ERRCODE.equals(accesstoken) || ConstantUtil.FAIL_ERRCODE.equals(accesstoken))
flag = true;
return flag;
}
System.out.println(httpClient.getErrInfo());
// 有可能因为网络原因,请求已经处理,但未收到应答。
}
return access_token;
}
其中所需要的字段:
其中 package 表示的是 订单详情,, 具体如何生成参照官方文档。 sign 默认为SHAL, 也可以为MD5.
prepayID 获取成功后,就能生成预支付订单,然后就可以像微信发起支付了。
预支付订单格式:
req.appId req.partnerId req.prepayId req.nonceStr req.timeStamp //fix me req.packageValue = "Sign=WXPay"; //这里官方文档没有说明, 无论是IOS还是ANdroid这里都写死
req.sign;
关于sign的生成方式:
这里用的sign 是用MD5加密。
后端将这些参数获取 后台返回给前端。
前端(Android) 拿到数据后:
PayReq req = new PayReq();req.appId = dataBean.appid; req.partnerId = dataBean.partnerid; req.prepayId = dataBean.prepayid; req.nonceStr = dataBean.nonceStr; req.timeStamp = dataBean.timeStamp; //fix me req.packageValue = "Sign=WXPay"; //这里官方文档没有说明, 无论是IOS还是ANdroid这里都写死req.sign = dataBean.sign;
然后调用微信接口发起支付。
三.注意事项
注意事项:
1.除了1,5步骤 其他都应该放到后台去做。 预支付申请的packageValue和 真正发起支付packageValue("Sign=WXPay") 是不一样的。
2.生成预支付订单prepayid的时候, 最好每当有新的请求的时候 都向微信服务器重新申请, 否则可能前端拿到之前老的预支付订单可能不能发起支付。
3. Android注意wxapi.WXPayEntryActivity 名字和路劲要固定, 且注意在AndroidMainfest中申明
4. Android注意用在官网注册keystore签名对apk进行签名, 否则调用不起支付界面。
详细的参考资料:
http://pan.baidu.com/s/1hr3q7YG