关闭

微信支付APP客户端及服务端集成

标签: 微信支付服务端客户端签名errCode-1
268人阅读 评论(0) 收藏 举报

循例介绍项目开发的过程和遇到的问题及其解决办法

有经验的朋友可直接看以下几点,忽略代码:

  1. 首先确认应用的包名签名与应用注册的一致,注意这里的签名是32位的签名,萌新请到官网下载工具测出签名每次测试时务必对自己的App做正式签名,同微信分享一个原理,没签名过是打不开微信界面的,没错,微信就是这么霸道。如果可以分享,支付不行,就不关Apk签名问题。
  2. 微信分享和微信支付SDK是同一个jar包,名为libammsdk.jar。若集成过友盟分享,并包含微信分享,那么恭喜你,项目中libs文件夹必包含SocialSDK_WeiXin_1.jarSocialSDK_WeiXin_2.jar,然后,然后没了,因为这两个jar包已包含开发所需。
  3. APP客户端只会收到返回的错误码errCode对于errCode返回-1,若确认上述两点做到了,那么问题基本在参数sign上面。什么?还可能是APPID不正确?呵呵,这么低级的错误能不说出来吗!其他的6个参数请瞪大眼睛自己检查。以下是生成sign的关键:
生成sign时特别需要注意,首先将key=value键值对拼成字符串,注意key都要小写,如appid、noncestr、package、partnerid、prepayid、timestamp、key,并且名字得按上述名称。有人会因为package是关键字而改变,当然不行,传给客户端的字段可以改变,但生成sign时的字符串   必须用package
还有一个十分关键的key,其并非AppID或AppSectet,而是在商户平台设置的,官方指引为“key设置路径:微信商户平台 (pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置”。正在开发或开发失败=。=的朋友都需要特别注意,官方文档的签名生成算法只举例了生成预支付交易单时的签名生成算法,介绍了需要在key=value键值对拼成的字符串后加上“&key=你的key”,于是很多服务端的程序猿都能访问微信并成功生成预支付交易单,但(重点来了)它们在传给客户端的参数sign却忽略了key,所以无论客户端如何测试都只能收到errCode=-1
还有(别急),服务端的程序猿会发现微信传回来的参数中也包含了一个sign,这里就要普及一下sign的意义:用来判断数据传递过程中是否被第三方篡改,也就是保证数据的正确性。根据微信返回的数据生成一次签名(加上key),然后判断你算出来的sign与微信返回的sign是否一致,一致则表示数据正确,是微信返回的,不一致则不是,这是保证数据安全的措施(个人观点=。=)。看到这里估计很多人会恍然大悟,因为你们都把微信返回的sign直接传给客户端了,我们就是卡在这个问题上(鄙视我们后台,最后还是才高八斗的本人发现的)!正确做法是把传给客户端的6个参数(不包括sign)加上key重新生成sign,把这个sign传给客户端。
4.WXPayEntryActivity这个回调界面实际上不会影响前面的调起支付的逻辑,写过微信分享的应该知道,这个Activity一定要放到“App包名.wxapi”的package中,否则无法响应回调,当然别忘了在AndroidManifest.xml中注册。微信分享的回调WXEntryActivity也是这样的,放在同一个包即可。
至此,需要特别关注的坑都可以填上了,下面是代码。
客户端代码:
@Override
public void onSuccess(String t) {
    super.onSuccess(t);
    JSONObject json = null;
    try {
        json = new JSONObject(t);
        if(null != json && !json.has("retcode") ){
            JSONObject json1 = new JSONObject(json.getString("obj"));
            PayReq req = new PayReq();
            //req.appId = "wxf8b4f85f3a794e77";  // 测试用appId
            req.appId        = json1.getString("appid");
            req.partnerId     = json1.getString("partnerid");
            req.prepayId      = json1.getString("prepayid");
            req.nonceStr      = json1.getString("noncestr");
            req.timeStamp     = json1.getString("timestamp");
            req.packageValue   = json1.getString("packagevalue");
            req.sign         = json1.getString("sign");
            msgApi.registerApp(BaseConfig.WXAPPID);
            msgApi.sendReq(req);
        }else{
            Log.d("PAY_GET", "返回错误"+ json.getString("retmsg"));
            Utils.showToast("返回错误"+ json.getString("retmsg"));
        }
    } catch (JSONException e) {
        Log.e("PAY_GET", "异常:"+ e.getMessage());
        Utils.showToast("异常:"+ e.getMessage());
        e.printStackTrace();
    }
}
服务端代码就不贴了,也就是多了生成sign的步骤,其他就是传参而已。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15174次
    • 积分:166
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:0篇
    • 译文:0篇
    • 评论:11条