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

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 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值