微信支付——調用微信客戶端支付之【服務端】開發詳解

最近準備上網頁的微信支付,大家可以參考後續教程:

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


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  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. }  

好了此時,客戶端需要的參數都已經可以通過請求:http://localhost:8080/WeiXinpay/weixin/weixin.do 來獲取


3、調起微信支付

這步就不需要我們服務端處理了。客戶端的兄弟,來接力。


示例的完整代碼可以在此鏈接下載:https://github.com/seven-cm/weixinpay


最後,微信回調:可以參考jsp文件夾中的payNotifyUrl.jsp來處理,處理過程和上面第二步差不多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章