微信支付Java后台和Android的接入
2017-05-17 15:40
369 查看
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里面了
//返回正确的结果如下:
先把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
接上面的代码
----------------服务器端完----------------------
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里的包名,改成你的包名
4000
在改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
配置好正试的签名Gradle文件如下
注意:在支付之前,如果应用没有注册到微信,应该先调用 IWXMsg.registerApp 将应用注册到微信。
然后调用刚才写的支付接口就可以了
至于如何写服务器回调就不说了的。(就是微信服务器调后台的接口,然后处理订单状 态),如果App支付过程中返回-1 可能的原因:签名错误、未注册APPID、项目设置 APPID不正确、注册的APPID与设置的不匹配、其他异常等。
哈哈》》》还有一种情况是如果以上配置都是对,还是一直-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里的包名,改成你的包名
4000
在改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
相关文章推荐
- Android 支付宝支付、微信支付、银联支付 整合第三方支付接入方法(后台订单支付API设计)
- Android 支付宝支付、微信支付、银联支付 整合第三方支付接入方法(后台订单支付API设计)
- 关于Des加密(Android与ios 与后台java服务器之间的加密解密
- Android使用webview控件加载本地html,通过Js与后台Java实现数据的传递
- Atitit。Js调用后台语言 java c# php swing android swt的方法大总结
- 用Java后台+Android_写一个简单的HttpConnection
- 关于 Des加密(Android与ios 与后台java服务器之间的加密解密)
- android java开发 第四天 之(后台服务处理完业务数据后,传送给ui Activity并刷新界面)
- Android 支付宝以及微信支付快速接入流程
- Android接入微信支付的坑
- 关于Java后台处理android上传图片的问题
- Android App支付系列(一):微信支付接入详细指南(附官方支付demo)
- java后台接收android客户端通过http方式发送的数据
- android拍照并通过Http发送到Java后台
- 【请求加密】android ios java后台通用DES base64加密
- 支付宝java后台接入简单流程
- android中文参数传到java tomcat后台变成乱码
- java 同时处理android和ios后台时
- 利Android AQuery中ajax访问SSH搭建的后台Java Web服务器
- Android接入微信支付完全解析,太全了~