http://blog.csdn.net/seven_cm/article/details/50019927
2015-09-12 更新:
因微信支付已经升级到V3版本,请大家参考官网的帮助文档。
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=1_2
之前一篇提到微信支付的开发过程,写得有点乱,现在重新整理一下。
好了,说说到底该怎样一步一步分享处理。
解压从官网下载下来的开发说明文档(下载地址:https://mp.weixin.qq.com/htmledition/res/bussiness-faq/wx_app_pay.zip):
先把服务端demo的代码整理到我们的服务端中(注意,此代码的编码格式是GBK,直接复制过去注释都会变乱码。可用文本文件打开后再复制过去)。处理完成后启动;且访问:http://localhost:8080/WeiXinpay/
会得到以下视图:
-------------------------------------------------------------------------------------------------------------
页面跳转调用:
获取支付prepayId
后台调用:
点击链接:
0OK wxd930ea5d5a258f4f 454cecc4829279e64d624cd8a8c9ddf1 Sign=WXPay 1900000109 120100001014112819a3561c0c02c882 eb139e44b8df8ce01b386f7c016defe5b95517791417104896
-------------------------------------------------------------------------------------------------------------
返回控制台可以得到以下视图:
好了,到这里,算是成功了一小步了(哈哈哈哈哈哈 yy一下)。
你也许会问,这些参数到底是作什么用的?更可悲的是,居然没有服务端的接口文档。
唯有先看手头上有的资料了。打开《【微信APP支付】接口文档V1.2_For_Android.pdf》
里面有提到微信支付的调用步骤:
1、获取 access_token
2、生成预支付订单
3、调起微信支付
下面说说这几个步骤:
1、access_token的获取
因为access_token的获取有请求频的限制,只能固化到数据库中了。这个不是难题。
2、生成预支付订单
在微信支付android的接口文档开头有提到:
注意:appsecret、appkey、partnerkey 不应硬编码到客户端程序中,建议需要用到这三个字段的过程都在服务器端完成
故此过程所有的信息全部在服务端生成。那么问题来了?挖掘机.... kao, 应该是,如何生成?
在翻看服务端的demo中,有jsp文件夹。打开一看,都几乎可以直接搬运使用了。
实现该过程的文件:payRequest.jsp
如何在JAVA中实现上面jsp的请求?项目中用到了Spring MVC,代码如下:
- @Controller
- @RequestMapping("/weixin/")
- public class WeiXinPayController extends ResponsePage {
- private Logger log = Logger.getLogger(WeiXinPayController.class);
- @RequestMapping("weixin.do")
- public String doWeinXinRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
- Map<Object,Object> resInfo = new HashMap<Object, Object>();
- //接收财付通通知的URL
- String notify_url = "http://127.0.0.1:8180/tenpay_api_b2c/payNotifyUrl.jsp";
- //---------------生成订单号 开始------------------------
- //当前时间 yyyyMMddHHmmss
- String currTime = TenpayUtil.getCurrTime();
- //8位日期
- String strTime = currTime.substring(8, currTime.length());
- //四位随机数
- String strRandom = TenpayUtil.buildRandom(4) + "";
- //10位序列号,可以自行调整。
- String strReq = strTime + strRandom;
- //订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行
- String out_trade_no = strReq;
- //---------------生成订单号 结束------------------------
- PackageRequestHandler packageReqHandler = new PackageRequestHandler(request, response);//生成package的请求类
- PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类
- ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客户端支付参数的请求类
- packageReqHandler.setKey(ConstantUtil.PARTNER_KEY);
- int retcode ;
- String retmsg = "";
- String xml_body = "";
- //获取token值
- String token = AccessTokenRequestHandler.getAccessToken();
- log.info("获取token------值 " + token);
- if (!"".equals(token)) {
- //设置package订单参数
- packageReqHandler.setParameter("bank_type", "WX");//银行渠道
- packageReqHandler.setParameter("body", "测试"); //商品描述
- packageReqHandler.setParameter("notify_url", notify_url); //接收财付通通知的URL
- packageReqHandler.setParameter("partner", ConstantUtil.PARTNER); //商户号
- packageReqHandler.setParameter("out_trade_no", out_trade_no); //商家订单号
- packageReqHandler.setParameter("total_fee", "1"); //商品金额,以分为单位
- packageReqHandler.setParameter("spbill_create_ip",request.getRemoteAddr()); //订单生成的机器IP,指用户浏览器端IP
- packageReqHandler.setParameter("fee_type", "1"); //币种,1人民币 66
- packageReqHandler.setParameter("input_charset", "GBK"); //字符编码
- //获取package包
- String packageValue = packageReqHandler.getRequestURL();
- resInfo.put("package", packageValue);
- log.info("获取package------值 " + packageValue);
- String noncestr = WXUtil.getNonceStr();
- String timestamp = WXUtil.getTimeStamp();
- String traceid = "";
- ////设置获取prepayid支付参数
- prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);
- prepayReqHandler.setParameter("appkey", ConstantUtil.APP_KEY);
- prepayReqHandler.setParameter("noncestr", noncestr);
- prepayReqHandler.setParameter("package", packageValue);
- prepayReqHandler.setParameter("timestamp", timestamp);
- prepayReqHandler.setParameter("traceid", traceid);
- //生成获取预支付签名
- String sign = prepayReqHandler.createSHA1Sign();
- //增加非参与签名的额外参数
- prepayReqHandler.setParameter("app_signature", sign);
- prepayReqHandler.setParameter("sign_method",
- ConstantUtil.SIGN_METHOD);
- String gateUrl = ConstantUtil.GATEURL + token;
- prepayReqHandler.setGateUrl(gateUrl);
- //获取prepayId
- String prepayid = prepayReqHandler.sendPrepay();
- log.info("获取prepayid------值 " + prepayid);
- //吐回给客户端的参数
- if (null != prepayid && !"".equals(prepayid)) {
- //输出参数列表
- clientHandler.setParameter("appid", ConstantUtil.APP_ID);
- clientHandler.setParameter("appkey", ConstantUtil.APP_KEY);
- clientHandler.setParameter("noncestr", noncestr);
- //clientHandler.setParameter("package", "Sign=" + packageValue);
- clientHandler.setParameter("package", "Sign=WXPay");
- clientHandler.setParameter("partnerid", ConstantUtil.PARTNER);
- clientHandler.setParameter("prepayid", prepayid);
- clientHandler.setParameter("timestamp", timestamp);
- //生成签名
- sign = clientHandler.createSHA1Sign();
- clientHandler.setParameter("sign", sign);
- xml_body = clientHandler.getXmlBody();
- resInfo.put("entity", xml_body);
- retcode = 0;
- retmsg = "OK";
- } else {
- retcode = -2;
- retmsg = "错误:获取prepayId失败";
- }
- } else {
- retcode = -1;
- retmsg = "错误:获取不到Token";
- }
- resInfo.put("retcode", retcode);
- resInfo.put("retmsg", retmsg);
- String strJson = JSON.toJSONString(resInfo);
- return responseAjax(request, strJson);
- }
- }
@Controller @RequestMapping("/weixin/") public class WeiXinPayController extends ResponsePage { private Logger log = Logger.getLogger(WeiXinPayController.class); @RequestMapping("weixin.do") public String doWeinXinRequest(HttpServletRequest request,HttpServletResponse response) throws Exception { Map<Object,Object> resInfo = new HashMap<Object, Object>(); //接收财付通通知的URL String notify_url = "http://127.0.0.1:8180/tenpay_api_b2c/payNotifyUrl.jsp"; //---------------生成订单号 开始------------------------ //当前时间 yyyyMMddHHmmss String currTime = TenpayUtil.getCurrTime(); //8位日期 String strTime = currTime.substring(8, currTime.length()); //四位随机数 String strRandom = TenpayUtil.buildRandom(4) + ""; //10位序列号,可以自行调整。 String strReq = strTime + strRandom; //订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行 String out_trade_no = strReq; //---------------生成订单号 结束------------------------ PackageRequestHandler packageReqHandler = new PackageRequestHandler(request, response);//生成package的请求类 PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类 ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客户端支付参数的请求类 packageReqHandler.setKey(ConstantUtil.PARTNER_KEY); int retcode ; String retmsg = ""; String xml_body = ""; //获取token值 String token = AccessTokenRequestHandler.getAccessToken(); log.info("获取token------值 " + token); if (!"".equals(token)) { //设置package订单参数 packageReqHandler.setParameter("bank_type", "WX");//银行渠道 packageReqHandler.setParameter("body", "测试"); //商品描述 packageReqHandler.setParameter("notify_url", notify_url); //接收财付通通知的URL packageReqHandler.setParameter("partner", ConstantUtil.PARTNER); //商户号 packageReqHandler.setParameter("out_trade_no", out_trade_no); //商家订单号 packageReqHandler.setParameter("total_fee", "1"); //商品金额,以分为单位 packageReqHandler.setParameter("spbill_create_ip",request.getRemoteAddr()); //订单生成的机器IP,指用户浏览器端IP packageReqHandler.setParameter("fee_type", "1"); //币种,1人民币 66 packageReqHandler.setParameter("input_charset", "GBK"); //字符编码 //获取package包 String packageValue = packageReqHandler.getRequestURL(); resInfo.put("package", packageValue); log.info("获取package------值 " + packageValue); String noncestr = WXUtil.getNonceStr(); String timestamp = WXUtil.getTimeStamp(); String traceid = ""; ////设置获取prepayid支付参数 prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID); prepayReqHandler.setParameter("appkey", ConstantUtil.APP_KEY); prepayReqHandler.setParameter("noncestr", noncestr); prepayReqHandler.setParameter("package", packageValue); prepayReqHandler.setParameter("timestamp", timestamp); prepayReqHandler.setParameter("traceid", traceid); //生成获取预支付签名 String sign = prepayReqHandler.createSHA1Sign(); //增加非参与签名的额外参数 prepayReqHandler.setParameter("app_signature", sign); prepayReqHandler.setParameter("sign_method", ConstantUtil.SIGN_METHOD); String gateUrl = ConstantUtil.GATEURL + token; prepayReqHandler.setGateUrl(gateUrl); //获取prepayId String prepayid = prepayReqHandler.sendPrepay(); log.info("获取prepayid------值 " + prepayid); //吐回给客户端的参数 if (null != prepayid && !"".equals(prepayid)) { //输出参数列表 clientHandler.setParameter("appid", ConstantUtil.APP_ID); clientHandler.setParameter("appkey", ConstantUtil.APP_KEY); clientHandler.setParameter("noncestr", noncestr); //clientHandler.setParameter("package", "Sign=" + packageValue); clientHandler.setParameter("package", "Sign=WXPay"); clientHandler.setParameter("partnerid", ConstantUtil.PARTNER); clientHandler.setParameter("prepayid", prepayid); clientHandler.setParameter("timestamp", timestamp); //生成签名 sign = clientHandler.createSHA1Sign(); clientHandler.setParameter("sign", sign); xml_body = clientHandler.getXmlBody(); resInfo.put("entity", xml_body); retcode = 0; retmsg = "OK"; } else { retcode = -2; retmsg = "错误:获取prepayId失败"; } } else { retcode = -1; retmsg = "错误:获取不到Token"; } resInfo.put("retcode", retcode); resInfo.put("retmsg", retmsg); String strJson = JSON.toJSONString(resInfo); return responseAjax(request, strJson); } }
好了此时,客户端需要的参数都已经可以通过请求:http://localhost:8080/WeiXinpay/weixin/weixin.do 来获取
3、调起微信支付
这步就不需要我们服务端处理了。客户端的兄弟,来接力。
示例的完整代码可以在此链接下载:https://github.com/seven-cm/weixinpay
最后,微信回调:可以参考jsp文件夹中的payNotifyUrl.jsp来处理,处理过程和上面第二步差不多。
原文:http://www.cnblogs.com/itclw/p/5732338.html