微信支付Java后台和Android的接入

来源:互联网 发布:尼尔森零售监测数据 编辑:程序博客网 时间:2024/05/17 08:27

1 微信支付业务流程

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3

         商户系统和微信支付系统主要交互说明:

         步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。(在商户后台生成订             单)。

         步骤2:商户后台根据1生成的订单,调用微信支付统一下单接口。(统一下单接口返    回正常的prepay_id,注:这里要处理数据签名)。

         步骤3:商户后台根据 prepay_id,再按签名规范重新生成签名后,将数据(这个数据    是APP支付要的数据,注:这里要处理数据签名)传输给APP。

         步骤4:商户APP调起微信支付。(把3的数据传给微信,用户输入密码,支付成功)。

         步骤5:商户后台接收支付通知。(后台收到微信的异步回调,商户后台处理业务逻辑)。

         完成(前台做的东西不多的,调用统一下单接口,生成APP要的支付参数都放后台)


2 统一下单接口

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

         直接上代码:(我添加的参数都是微信必须的,不是必须的自己定的)

         我写在Servlet里的doGet里面了

       String url ="https://api.mch.weixin.qq.com/pay/unifiedorder";         SortedMap<String,    String> map =new TreeMap<String, String>();         //appid在你创建APP的时候有的,是在微信的开放平台能看到         //https://open.weixin.qq.com/   管理中心         map.put("appid", "wx3333");         //在微信支付商户平台看到         //https://pay.weixin.qq.com/  账户中心--个人中心--登录账号(登录账号就是你的     mch_id)         map.put("mch_id", "136692222");         //随机生成         map.put("nonce_str", String.valueOf(System.currentTimeMillis()));         //自已定义         map.put("body","lidongliang");         //是你商户后台生成的订单号(我这是随便生成的,这个要改为你后台生成的订单号)         map.put("out_trade_no",String.valueOf(System.currentTimeMillis()));         //钱         map.put("total_fee","1");         //IP随便写了一个         map.put("spbill_create_ip","123.12.12.123");         //微信支付成功后的回调接口(就是支付成功后,微信调你商户后台的接口,你在后台 //改订单的状态,例如,改为“成功”)         map.put("notify_url","http://www.weixin.qq.com/wxpay/pay.php");         //APP支付,这是固定的         map.put("trade_type","APP");         //生成签名(重要,把上面的map传到方法里面,返回一个sign信息,诸多人都是在     这里坑了,方法在下面)         String sign = createSign(map);         map.put("sign",sign );//因为微信要的是XML的形式,所以拼成XML参数形式,如下:         // 生成XMl         Set set = map.entrySet();         Iterator it = set.iterator();         tringBuffer sb = new StringBuffer();         sb.append("<xml>");         while (it.hasNext()) {                   Map.Entry entry = (Map.Entry)it.next();                   String key = (String)entry.getKey();                   String value = (String)entry.getValue();                   sb.append("<" +key + "><![CDATA[");                   sb.append(value);                   sb.append("]]></"+ key + ">");         }         sb.append("</xml>");         //这里不说了,调用接口         String postData = NetUtil.doPost(url,sb.toString());

         //返回正确的结果如下:

       

    <xml>             <return_code><![CDATA[SUCCESS]]></return_code>             <return_msg><![CDATA[OK]]></return_msg>             <appid><![CDATA[wx3333]]></appid>             <mch_id><![CDATA[136692222]]></mch_id>             <nonce_str><![CDATA[vN2FK21GSccXRU6j]]></nonce_str>             <sign><![CDATA[6AF542F0086A0094D904549736564072]]></sign>             <result_code><![CDATA[SUCCESS]]></result_code>             //很显然这个是prepay_id,是APP端调用微信支付要的参数             <prepay_id><![CDATA[wx20170517120117dda20d35ab0540951436]]></prepay_id>             <trade_type><![CDATA[APP]]></trade_type>     </xml>

         先把XML转成JSON,用到了一个工具,不过用其它的方法也行的,到时候我会上传一  个demo的。

         JSONObject json =XML.toJSONObject(postData).getJSONObject("xml");

2 生成APP端调起支付的参数

 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2

         接上面的代码

      SortedMap<String, String> test =new TreeMap<String, String>();         // appid是APP端要的参数,是从上面返回的XML中取得         test.put("appid",json.getString("appid"));         // partnerid显然是商户的mch_id也从上面返回的XML中取得         test.put("partnerid",json.getString("mch_id"));         // prepayid微信返回的支付交易会话id, 也从上面返回的XML中取得         test.put("prepayid",json.getString("prepay_id"));         //暂填写固定值Sign=WXPay(微信要求固定就固定的)         test.put("package","Sign=WXPay");         //随机字符串         test.put("noncestr", String.valueOf(System.currentTimeMillis()));         //时间戳         test.put("timestamp",String.valueOf(System.currentTimeMillis() / 1000));         //这个没有什么说的,和原来的一样调用createSign方法         test.put("sign",createSign(test));         //以json的形式返回客户端         response.getWriter().append(new JSONObject(test).toString());         android或ios得到如下结果:         {                   timestamp: "1494993676",                   sign: "38FB898BC67368BB489F78A07BAC7633",                   partnerid: "136692222",                   noncestr: "1494993676646",                   prepayid: "wx20170517120117dda20d35ab0540951436",                   package: "Sign=WXPay",                   appid: " wx3333"         }

----------------服务器端完----------------------

3 下面要做的是Android的处理:

下载微信提供的demo  SDK与DEMO下载找到android  下载的是这个“【微信支付】APP 支付示例”

         https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1

         当你导入到eclipse的时候,wo kao 那么多的报错(把报错的导入全部删除,重新导入  看一下有什么区别)

         //demo里面的

         importcom.tencent.mm.sdk.constants.ConstantsAPI;

         //更改后的,原来是包名都不一样啊。。。。。。鄙视微信,连一个demo都做的这么的。。。

         importcom.tencent.mm.opensdk.constants.ConstantsAPI;

         没有办法,只能一个一个的改吧。。。

         下一步改AndroidManifest.xml里的包名,改成你的包名

         在改AndroidManifest.xml和Constants文件下为自己的appid如下:

         <data android:scheme=" wx3333"/>

         public static final String APP_ID =" wx3333";

         还的就是把lib下的wechat-sdk-android-with-mta-1.0.2.jar删除的

         注意:还要把项目里的包改为你的包名的“net.sourceforge.simcpux”改为你的包名,同         时AndroidManifest.xml的Activity路径也要改的。       

         因为支付的签名只能为正式的签名,把以我把项目转成AndroidStudio在的项目,在         AndroidStudio里面测试 方法如下:File--Export  一路Next就可以了。


下一步用AndroidStudio打开项目的(该修复的修复一下的,别让项目报错),注意:

         这里也要改的,我的是gradle-3.3-all


#Sat Apr 22 13:17:19 CST 2017distributionBase=GRADLE_USER_HOMEdistributionPath=wrapper/distszipStoreBase=GRADLE_USER_HOMEzipStorePath=wrapper/distsdistributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

配置好正试的签名Gradle文件如下

  buildscript {                repositories{                 mavenCentral()             }             dependencies{                 classpath'com.android.tools.build:gradle:2.3.2'             }         }         apply plugin: 'com.android.application'         dependencies {             compilefileTree(dir: 'libs', include: '*.jar')         }         android {             compileSdkVersion22             buildToolsVersion"25.0.2"             aaptOptions{                 cruncherEnabled= false             }             signingConfigs{                            //配置签名信息,改为自己的                 debug{                     storeFile file("key.jks")                     storePassword "123456"                     keyAlias "lee"                     keyPassword "123456"                 }                 release{                     storeFile file("key.jks")                     storePassword "123456"                     keyAlias "lee"                     keyPassword "123456"                 }             }             buildTypes{                 release{                     minifyEnabled false                     proguardFiles getDefaultProguardFile('proguard-android.txt'),                               'proguard-rules.pro'                     signingConfig signingConfigs.release                 }                 debug{                     signingConfig signingConfigs.debug                 }             }             sourceSets{                 main{                     manifest.srcFile 'AndroidManifest.xml'                     java.srcDirs = ['src']                     resources.srcDirs = ['src']                     aidl.srcDirs = ['src']                     renderscript.srcDirs = ['src']                     res.srcDirs = ['res']                     assets.srcDirs = ['assets']                 }                 instrumentTest.setRoot('tests')                 debug.setRoot('build-types/debug')                 release.setRoot('build-types/release')             }         }

         注意:在支付之前,如果应用没有注册到微信,应该先调用         IWXMsg.registerApp  将应用注册到微信。

         然后调用刚才写的支付接口就可以了

try{    String url = "http://192.168.0.112:8080/weipay/prepayid";    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 ){                 PayReq 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                 Toast.makeText(PayActivity.this, "正常调起支付",Toast.LENGTH_SHORT).show();                 // 在支付之前,如果应用没有注册到微信,应该先调用  //IWXMsg.registerApp将应用注册到微信                 api.sendReq(req);               }else{                     Log.d("PAY_GET", "返回错误"+json.getString("retmsg"));                     Toast.makeText(PayActivity.this, "返回错误"+json.getString("retmsg"),Toast.LENGTH_SHORT).show();               }        }else{             Log.d("PAY_GET", "服务器请求错误");             Toast.makeText(PayActivity.this, "服务器请求错误",Toast.LENGTH_SHORT).show();        }    }catch(Exception e){       Log.e("PAY_GET","异常:"+e.getMessage());       Toast.makeText(PayActivity.this,"异常:"+e.getMessage(),Toast.LENGTH_SHORT).show(); }

         至于如何写服务器回调就不说了的。(就是微信服务器调后台的接口,然后处理订单状  态),如果App支付过程中返回-1  可能的原因:签名错误、未注册APPID、项目设置  APPID不正确、注册的APPID与设置的不匹配、其他异常等。

         哈哈》》》还有一种情况是如果以上配置都是对,还是一直-1,那么你可以把微信卸了重 装,我的就是这样的,用别人的支付没有问题,我的就不行的,可能是缓存吧。
       /**          * 微信支付签名算法sign          */         publicstatic String createSign(SortedMap<String, String> parameters) {                   StringBuffersb = new StringBuffer();                   //所有参与传参的参数按照accsii排序(升序)                   Setset = parameters.entrySet();                   Iteratorit = set.iterator();                   while(it.hasNext()) {                            Map.Entryentry = (Map.Entry) it.next();                            Stringk = (String) entry.getKey();                            Objectv = entry.getValue();                            if(null != v && !"".equals(v) &&!"sign".equals(k) && !"key".equals(k)) {                                     sb.append(k+ "=" + v + "&");                            }                   }                   //重要:这个key是在下面页面配置的--API安全                   //https://pay.weixin.qq.com/index.php/core/cert/api_cert                   sb.append("key="+ KEY);                   Stringsign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();                   System.out.println("sign:" +sign);                   returnsign;         }
项目下载地址http://download.csdn.net/detail/dongliang0108/9844771

原创粉丝点击