【金莎娱乐电子游戏网】Android集成微信支付

迄今微信集成结束,坑的地点正是 app端调用微信支付时的签名参数sign一定要重新生成,不要使用统一下单接口返回的sign,切记!!!!

记录点滴,与君共勉。

前言

后面做过一回微信支付的合併,然而未有下结论。近来贰个App又要合并微信支付,又要重新下载demo,重新看支出文档,重新写代码。相信全数的程序猿遭遇这种业务都会抓狂。观看了一晃微信支付并不规划职业逻辑,完全能够封装成三个工具。

上面初叶详解:

配置

这是官方的app支付开辟步骤,别的这里由于自己一向不可用的支付所以,写demo小编用的包名和key都以微信demo的

配置权力

配置activity

<uses-permission android:name="android.permission.INTERNET"/>

配备回调activity

<activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"/>

调用支付

public void testWxPay(View view) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            String url = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android";
            ToastUtil.shortToastInBackgroundThread(getActivity(), "获取订单中...");
            try {
                byte[] buf = Util.httpGet(url);
                if (buf != null && buf.length > 0) {
                    String content = new String(buf);
                    Log.e("get server pay params:", content);
                    JSONObject json = new JSONObject(content);
                    if (null != json && !json.has("retcode")) {
                        req = new PayReq();
                        //req.appId = "wxf8b4f85f3a794e77";  // 测试用appId
                        req.appId = json.getString("appid");
                        req.partnerId = json.getString("partnerid");
                        req.prepayId = json.getString("prepayid");
                        req.nonceStr = json.getString("noncestr");
                        req.timeStamp = json.getString("timestamp");
                        req.packageValue = json.getString("package");
                        req.sign = json.getString("sign");
                        req.extData = "app data"; // optional
                        ToastUtil.shortToastInBackgroundThread(getActivity(), "正常调起支付");
                        toPay();
                    } else {
                        Log.d("PAY_GET", "返回错误" + json.getString("retmsg"));
                        ToastUtil.shortToastInBackgroundThread(getActivity(), "返回错误" + json.getString("retmsg"));
                    }
                } else {
                    Log.d("PAY_GET", "服务器请求错误");
                    ToastUtil.shortToastInBackgroundThread(getActivity(), "服务器请求错误");
                }
            } catch (Exception e) {
                Log.e("PAY_GET", "异常:" + e.getMessage());
                ToastUtil.shortToastInBackgroundThread(getActivity(), "异常:" + e.getMessage());
            }
        }
    }).start();

}

private void toPay() {
    // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
    api.sendReq(req);
}

到此处即使你遵照本身的配备来说,寻常景况下试可用调起支付界面了,若是出现-1,请检查是还是不是替换了debug.keystore,假使替换了,照旧这么回忆清空微信缓存

如上测量试验代码都在github上,官方的下载的sdk包也在该酒馆的docs目录下

要是本身的稿子对来拉动的帮手,可加小编微信,新浪,QQ什么什么的交个朋友也是正确的,其他微信,天涯论坛都会不定期发一些优质的稿子,感激大家的帮忙~~,联系格局在小编的村办介绍里啊

2.收下微信的央浼及重临值(坑点)

合併文书档案是那样描述的

金莎娱乐电子游戏网 1

Paste_Image.png

看图是天公地道关系,但是并非那样,应该这么

金莎娱乐电子游戏网 2

Paste_Image.png

注意

1.微信开销以后一度很省心了,提供了统一下单接口,自个儿的后台服务器调用该接口,获取prepayId2.最要害的一步,也是网络以往坑最多的一步,调用统一下单接口后,微信再次来到格式如下,而那般多多少中,真正对大家有用的唯有预支付订单号prepayId,微信重回的sign未曾其他用,大家得依照签订协议标准重新生成具名(关于那一点,下边包车型客车流水生产线交互中就有提到),然后将再一次生成的签名重返给应用软件端,用于应用软件端调用微信支付。(当然重新生成签字的步调也能够放在应用程式端来做,可是为了安全着想,提议坐落服务端管理,上边也会给出应用软件端签字的代码)

金莎娱乐电子游戏网 3调用统一下单接口
微信再次来到数据金莎娱乐电子游戏网 4确实无疑要重新生成具名

好多人都高出这么的难题,参数都管理好调用微信支付,结果步入微信分界面后发掘唯有三个分明开关,重返后错误码为
-2,产生这么些原因的就是因为参数不对,并且基本上是都以因为签字 sign
不对,未有进行一回签订协议,而一直拿微信再次来到的sign当作参数 ,
所以调用微信支付接口时,应当要用 重新签字的sign!!!!

  • 应用程式端调用支付时,sign不要用调用统一下单接口重返的sign,而要本人再也生成,生成法规见微信提供的签名生成算法金莎娱乐电子游戏网 5Paste_Image.png

有关代码如下:

  • 应用程式端张开微信微信支付代码

#pragma mark - 微信支付- wechatPay:(WechatOrderModel *)model{ //调起微信支付 model 为自己服务器返回的参数 PayReq *req = [[PayReq alloc] init]; req.partnerId = model.partnerid; req.prepayId = model.prepayid; req.nonceStr = model.noncestr; req.timeStamp = model.timestamp.intValue; req.package = model.package; req.sign = model.sign;//sign 为自己服务器获取到预支付订单号prepayId后,重新生成的签名,当然本地也可以生成签名,签名代码如下 [WXApi sendReq:req]; //日志输出 NSLog(@"微信支付请求参数 ===== appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",model.appid,req.partnerId,req.prepayId,req.nonceStr,req.timeStamp,req.package,req.sign);}
  • 应用软件端重新生成签名(提出坐落服务端管理)

#pragma mark - 微信支付本地签名//创建发起支付时的sign签名-(NSString *)createMD5SingForPayWithAppID:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:timestamp_key{ NSMutableDictionary *signParams = [NSMutableDictionary dictionary]; [signParams setObject:appid_key forKey:@"appid"];//微信appid 例如wxfb132134e5342 [signParams setObject:noncestr_key forKey:@"noncestr"];//随机字符串 [signParams setObject:package_key forKey:@"package"];//扩展字段 参数为 Sign=WXPay [signParams setObject:partnerid_key forKey:@"partnerid"];//商户账号 [signParams setObject:prepayid_key forKey:@"prepayid"];//此处为统一下单接口返回的预支付订单号 [signParams setObject:[NSString stringWithFormat:@"%u",timestamp_key] forKey:@"timestamp"];//时间戳 NSMutableString *contentString =[NSMutableString string]; NSArray *keys = [signParams allKeys]; //按字母顺序排序 NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }]; //拼接字符串 for (NSString *categoryId in sortedArray) { if ( ![[signParams objectForKey:categoryId] isEqualToString:@""] && ![[signParams objectForKey:categoryId] isEqualToString:@"sign"] && ![[signParams objectForKey:categoryId] isEqualToString:@"key"] ) { [contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]]; } } //添加商户密钥key字段 API 密钥 [contentString appendFormat:@"key=%@", @"商户密钥"]; NSString *result = [contentString md5String];//md5加密 return result;}
  • MD5 加密方法

/** * MD5 加密 * * @return 加密后字符串 */- (NSString *)md5String{ if(self == nil || [self length] == 0) return nil; unsigned char digest[CC_MD5_DIGEST_LENGTH], i; CC_MD5([self UTF8String], [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest); NSMutableString *ms = [NSMutableString string]; for(i=0;i<CC_MD5_DIGEST_LENGTH;i++) { [ms appendFormat: @"%02x", (digest[i])]; } return [ms copy];}

一、集成微信支付SDK

在合龙第三方的时候,首先是要在融洽的门类中合拢对应的SDK后才方可付出的。这几个不用置疑。这里给出微信官方的购并文书档案,读者可机关查看,我在这里只对根当位置做出表明。微信官方集成文书档案:

简介

率先我们赶到微信支付官方网站瞅瞅:

Paste_Image.png

能够看来那就是微信支付首页,上边有二种支付办法,而大家今日的才识过人正是应用程式支付,咱们得以直接点进去,也许从左上角接入指引-APP支付,进去的文书档案式样的,这是其一文书档案的地点如下图所示:

Paste_Image.png

没有什么可争辨的有的人讲,你贴这么有毛用呀,还浪费本身流量…

别急让自家给您说说那图有啥样用,首先从那图你能见到从登记开采平台账号到完毕开拓接入供给什么步骤,哪些材质,那样您能够让有关的人口先行去准备那些资料,并非填完一步资料,在去找下一步资料,记住时间正是金钱,别的你领导说来给自家讲讲微信支付那盘算什么材质,你没看过那文书档案,那笔者就不得不呵呵了O(∩_∩)O。另外哪些说支付简单的,有几个知道这张图,又有谁认真看过~

能够见到是要加300块的,还索要商家的部分质地。

别的微信支付有七个平台独家是开荒者平台和商人平台

开荒者平台:重如若本着开荒者,比如:创立应用,获取appid
商人平台:主纵然经纪人上边包车型客车一部分管制,比如:能够查阅流水,订单呀

4.微信支付的回调

管理微信支付的回调便是在创建的WXEntryActivity中拍卖。要求贯彻IWXAPI伊夫ntHandler接口,这些接口会供给您达成onResp方法,就在那一个艺术中拍卖回调。

 @Override
  public void onResp(BaseResp resp) {

    if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
        if(resp.errCode==0){
            Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(this, "支付失败", Toast.LENGTH_LONG).show();
        }
        finish();
    }
}

前言

平昔以为支付宝的文书档案写的早就够烂了,后来本身才察觉小编太年轻气盛了,那是因为本人还并未有汇合微信的文书档案,差不离坑爹。。。<心中贰仟0只草泥马…>

  • 微信支付文档地址
  • 微信支付SDK下载地址
  • 微信支付API列表
  1. 开辟业务流程

商户系统和微信支付系统主要交互说明:步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【[统一下单API](https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1)】。步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay步骤4:商户APP调起微信支付。api参见本章节【[app端开发步骤说明](https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5)】步骤5:商户后台接收支付通知。api参见【[支付结果通知API](https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_7)】步骤6:商户后台查询支付结果。,api参见【[查询订单API](https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_2)】

金莎娱乐电子游戏网 6Paste_Image.png

3.调起微信应用程式进行支付

调起微信应用程式是急需央求参数的,也便是上一步中聊到的那多个参数,当你把那么些参数都凑够了,那么这一步也就没怎么难度了,正是照着沙盘写了:

 private IWXAPI iwxapi; //微信支付api /** *调起微信支付的方法 **/ private void toWXPay() { iwxapi = WXAPIFactory.createWXAPI(this, null); //初始化微信api iwxapi.registerApp; //注册appid appid可以在开发平台获取 Runnable payRunnable = new Runnable() { //这里注意要放在子线程 @Override public void run() { PayReq request = new PayReq(); //调起微信APP的对象 //下面是设置必要的参数,也就是前面说的参数,这几个参数从何而来请看上面说明 request.appId = appid; request.partnerId = partnerId; request.prepayId = prepayId; request.packageValue = "Sign=WXPay"; request.nonceStr = nonceStr; request.timeStamp = timeStamp; request.sign = sign; iwxapi.sendReq;//发送调起微信的请求 } }; Thread payThread = new Thread(payRunnable); payThread.start(); }

后日来聊聊,android中连着微信支付的供给,肯定有人会说,那多轻便呀,还在此间扯什么,飞速去洗洗睡呢~~

3..调起微信电脑软件进行开荒

调起支付须要传递参数,供给央浼本身服务器重回如下参数:

金莎娱乐电子游戏网 7

Paste_Image.png

归来参数后,调起微信

  //微信支付api
  private IWXAPI iwxapi;
     /**
        *调起微信支付的方法
        **/
 private void toWXPay() {
 //初始化微信api
    iwxapi = WXAPIFactory.createWXAPI(this, null);
 //注册appid  appid可以在开发平台获取
    iwxapi.registerApp(appid); 

    Runnable payRunnable = new Runnable() {  //这里注意要放在子线程
        @Override
        public void run() {
            PayReq request = new PayReq(); //调起微信APP的对象
            //下面是设置必要的参数,也就是前面说的参数,这几个参数从何而来请看上面说明
            request.appId = appid;
            request.partnerId = partnerId;
            request.prepayId = prepayId;
            request.packageValue = "Sign=WXPay";
            request.nonceStr = nonceStr;
            request.timeStamp = timeStamp;
            request.sign = sign;
            iwxapi.sendReq(request);//发送调起微信的请求
        }
    };
    Thread payThread = new Thread(payRunnable);
    payThread.start();
}

签约sign 参数,又时供给我们客商端来扭转,来看一下变型法规

金莎娱乐电子游戏网 8

Paste_Image.png

变迁事例:

               //签名
            LinkedHashMap<String, String> signParams = new LinkedHashMap<>();
            signParams.put("appid", request.appId);
            signParams.put("noncestr", request.nonceStr);
            signParams.put("package", request.packageValue);
            signParams.put("partnerid", request.partnerId);
            signParams.put("prepayid", request.prepayId);
            signParams.put("timestamp", request.timeStamp);
            request.sign = genPackageSign(signParams,key);
            iwxapi.sendReq(request);//发送调起微信的请求
 /**
 * 调起微信APP支付,签名
 * 生成签名
 */
private   String genPackageSign(LinkedHashMap<String, String> params,String key) {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String,String> entry: params.entrySet()) {
        sb.append(entry.getKey());
        sb.append('=');
        sb.append(entry.getValue());
        sb.append('&');
    }
    sb.append("key=");
    sb.append(key);

    String packageSign = getMessageDigest(sb.toString().getBytes()).toUpperCase();
    return packageSign;
}

/**
 * md5加密
 * @param buffer
 * @return
 */
private String getMessageDigest(byte[] buffer) {
    char hexDigits[] = { 'a', 'b', 'c', 'd', 'e', 'f' , 'g', 'h', 'l', 'm', 'n', 'o' };
    try {
        MessageDigest mdTemp = MessageDigest.getInstance("MD5");
        mdTemp.update(buffer);
        byte[] md = mdTemp.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) {
        return null;
    }
}
/**
 * 获取随机数
 *
 * @return
 */
private String genNonceStr() {
    Random random = new Random();
    return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}


/**
 * 获取时间戳
 *
 * @return
 */
private long genTimeStamp() {
    return System.currentTimeMillis() / 1000;
}

相关文章