zoukankan      html  css  js  c++  java
  • 微信支付——调用微信客户端支付之【服务端】开发详解

    原文:http://blog.csdn.net/seven_cm/article/details/41559301

    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,代码如下:

    1. @Controller  
    2. @RequestMapping("/weixin/")  
    3. public class WeiXinPayController extends ResponsePage  {  
    4.   
    5.     private Logger log = Logger.getLogger(WeiXinPayController.class);  
    6.       
    7.     @RequestMapping("weixin.do")  
    8.     public String doWeinXinRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {  
    9.         Map<Object,Object> resInfo = new HashMap<Object, Object>();  
    10.         //接收财付通通知的URL  
    11.         String notify_url = "http://127.0.0.1:8180/tenpay_api_b2c/payNotifyUrl.jsp";  
    12.   
    13.         //---------------生成订单号 开始------------------------  
    14.         //当前时间 yyyyMMddHHmmss  
    15.         String currTime = TenpayUtil.getCurrTime();  
    16.         //8位日期  
    17.         String strTime = currTime.substring(8, currTime.length());  
    18.         //四位随机数  
    19.         String strRandom = TenpayUtil.buildRandom(4) + "";  
    20.         //10位序列号,可以自行调整。  
    21.         String strReq = strTime + strRandom;  
    22.         //订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行  
    23.         String out_trade_no = strReq;  
    24.         //---------------生成订单号 结束------------------------  
    25.   
    26.         PackageRequestHandler packageReqHandler = new PackageRequestHandler(request, response);//生成package的请求类   
    27.         PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类  
    28.         ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客户端支付参数的请求类  
    29.         packageReqHandler.setKey(ConstantUtil.PARTNER_KEY);  
    30.   
    31.         int retcode ;  
    32.         String retmsg = "";  
    33.         String xml_body = "";  
    34.         //获取token值   
    35.           
    36.         String token = AccessTokenRequestHandler.getAccessToken();  
    37.           
    38.         log.info("获取token------值 " + token);  
    39.           
    40.         if (!"".equals(token)) {  
    41.             //设置package订单参数  
    42.             packageReqHandler.setParameter("bank_type", "WX");//银行渠道  
    43.             packageReqHandler.setParameter("body", "测试"); //商品描述     
    44.             packageReqHandler.setParameter("notify_url", notify_url); //接收财付通通知的URL    
    45.             packageReqHandler.setParameter("partner", ConstantUtil.PARTNER); //商户号      
    46.             packageReqHandler.setParameter("out_trade_no", out_trade_no); //商家订单号     
    47.             packageReqHandler.setParameter("total_fee", "1"); //商品金额,以分为单位    
    48.             packageReqHandler.setParameter("spbill_create_ip",request.getRemoteAddr()); //订单生成的机器IP,指用户浏览器端IP    
    49.             packageReqHandler.setParameter("fee_type", "1"); //币种,1人民币   66  
    50.             packageReqHandler.setParameter("input_charset", "GBK"); //字符编码  
    51.   
    52.             //获取package包  
    53.             String packageValue = packageReqHandler.getRequestURL();  
    54.             resInfo.put("package", packageValue);  
    55.               
    56.             log.info("获取package------值 " + packageValue);  
    57.   
    58.             String noncestr = WXUtil.getNonceStr();  
    59.             String timestamp = WXUtil.getTimeStamp();  
    60.             String traceid = "";  
    61.             ////设置获取prepayid支付参数  
    62.             prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);  
    63.             prepayReqHandler.setParameter("appkey", ConstantUtil.APP_KEY);  
    64.             prepayReqHandler.setParameter("noncestr", noncestr);  
    65.             prepayReqHandler.setParameter("package", packageValue);  
    66.             prepayReqHandler.setParameter("timestamp", timestamp);  
    67.             prepayReqHandler.setParameter("traceid", traceid);  
    68.   
    69.             //生成获取预支付签名  
    70.             String sign = prepayReqHandler.createSHA1Sign();  
    71.             //增加非参与签名的额外参数  
    72.             prepayReqHandler.setParameter("app_signature", sign);  
    73.             prepayReqHandler.setParameter("sign_method",  
    74.                     ConstantUtil.SIGN_METHOD);  
    75.             String gateUrl = ConstantUtil.GATEURL + token;  
    76.             prepayReqHandler.setGateUrl(gateUrl);  
    77.   
    78.             //获取prepayId  
    79.             String prepayid = prepayReqHandler.sendPrepay();  
    80.               
    81.             log.info("获取prepayid------值 " + prepayid);  
    82.               
    83.             //吐回给客户端的参数  
    84.             if (null != prepayid && !"".equals(prepayid)) {  
    85.                 //输出参数列表  
    86.                 clientHandler.setParameter("appid", ConstantUtil.APP_ID);  
    87.                 clientHandler.setParameter("appkey", ConstantUtil.APP_KEY);  
    88.                 clientHandler.setParameter("noncestr", noncestr);  
    89.                 //clientHandler.setParameter("package", "Sign=" + packageValue);  
    90.                 clientHandler.setParameter("package", "Sign=WXPay");  
    91.                 clientHandler.setParameter("partnerid", ConstantUtil.PARTNER);  
    92.                 clientHandler.setParameter("prepayid", prepayid);  
    93.                 clientHandler.setParameter("timestamp", timestamp);  
    94.                 //生成签名  
    95.                 sign = clientHandler.createSHA1Sign();  
    96.                 clientHandler.setParameter("sign", sign);  
    97.   
    98.                 xml_body = clientHandler.getXmlBody();  
    99.                 resInfo.put("entity", xml_body);  
    100.                 retcode = 0;  
    101.                 retmsg = "OK";  
    102.             } else {  
    103.                 retcode = -2;  
    104.                 retmsg = "错误:获取prepayId失败";  
    105.             }  
    106.         } else {  
    107.             retcode = -1;  
    108.             retmsg = "错误:获取不到Token";  
    109.         }  
    110.           
    111.         resInfo.put("retcode", retcode);  
    112.         resInfo.put("retmsg", retmsg);  
    113.         String strJson = JSON.toJSONString(resInfo);  
    114.         return responseAjax(request, strJson);  
    115.     }  
    116.       
    117. }  
    @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来处理,处理过程和上面第二步差不多。

  • 相关阅读:
    智能指针
    C++学习之对类中的成员函数的定义和声明最后添加一个const作用
    动态链接,静态链接库
    Java 位运算
    Java 工具类
    Java 枚举
    Java 内部类
    Java 异常机制
    Java hashCode 和 equals
    Java 字节流和字符流
  • 原文地址:https://www.cnblogs.com/itclw/p/5732338.html
Copyright © 2011-2022 走看看