啰嗦几句
在调用微信支付接口踩了一些坑,在这里记录下来,希望能帮助一些人,不要继续同样的坑,这也是因为微信文档没有写清楚的地方导致的。
步骤:
- 后台设置
注册APPID
这个根据微信支付开发文档来就可以了,就不多说了.
调起支付
先请求后台调用“统一下单API”
然后拿后台返回参数,调用支付接口
注意:request.sign参数,要求客户端自己签名加密,签名算法规则,签名代码如下:
SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
parameters.put("appid", jsonObject.getString("AppId"));
parameters.put("noncestr", jsonObject.getString("nonceStr"));
parameters.put("package", jsonObject.getString("packageValue"));
parameters.put("partnerid", jsonObject.getString("partnerId"));
parameters.put("prepayid", jsonObject.getString("prepayId"));
parameters.put("timestamp", jsonObject.getString("timeStamp"));
PayReq request = new PayReq();
req.appId = jsonObject.getString("AppId");
req.partnerId = jsonObject.getString("partnerId");
req.prepayId = jsonObject.getString("prepayId");
req.packageValue = jsonObject.getString("packageValue");
req.nonceStr = jsonObject.getString("nonceStr");
req.timeStamp = jsonObject.getString("timeStamp");
req.sign = createSign(parameters);
/**
* 微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
public static String createSign(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while (it.hasNext()) {
@SuppressWarnings("rawtypes")
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k))
{
sb.append(k + "=" + v + "&");
}
}
sb.append("key=KEY是商户后台调用秘钥");
String sign = MD5.getMessageDigest(sb.toString()).toUpperCase();
return sign;
}
public final static String getMessageDigest(String s) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
try {
byte[] btInput = s.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
- 支付结果回调
把微信SDK Sample里net.sourceforge.simcpux.wxapi路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调),放到自己申请项目包里(这个包名是步骤1台后设置),需要把wxapi路径一起拷进出,在WXPayEntryActivity类中实现onResp函数,支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。代码示例如下:
publicvoidonResp(BaseRespresp){
if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
Log.d(TAG,”onPayFinish,errCode=”+resp.errCode);
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
}
}
回调中errCode值列表:
名称 描述 解决方案
0 成功 展示成功页面
-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。