最近準備上網頁的微信支付,大家可以參考後續教程:
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>();
-
-
String notify_url = "http://127.0.0.1:8180/tenpay_api_b2c/payNotifyUrl.jsp";
-
-
-
-
String currTime = TenpayUtil.getCurrTime();
-
-
String strTime = currTime.substring(8, currTime.length());
-
-
String strRandom = TenpayUtil.buildRandom(4) + "";
-
-
String strReq = strTime + strRandom;
-
-
String out_trade_no = strReq;
-
-
-
PackageRequestHandler packageReqHandler = new PackageRequestHandler(request, response);
-
PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);
-
ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);
-
packageReqHandler.setKey(ConstantUtil.PARTNER_KEY);
-
-
int retcode ;
-
String retmsg = "";
-
String xml_body = "";
-
-
-
String token = AccessTokenRequestHandler.getAccessToken();
-
-
log.info("獲取token------值 " + token);
-
-
if (!"".equals(token)) {
-
-
packageReqHandler.setParameter("bank_type", "WX");
-
packageReqHandler.setParameter("body", "測試");
-
packageReqHandler.setParameter("notify_url", notify_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());
-
packageReqHandler.setParameter("fee_type", "1");
-
packageReqHandler.setParameter("input_charset", "GBK");
-
-
-
String packageValue = packageReqHandler.getRequestURL();
-
resInfo.put("package", packageValue);
-
-
log.info("獲取package------值 " + packageValue);
-
-
String noncestr = WXUtil.getNonceStr();
-
String timestamp = WXUtil.getTimeStamp();
-
String traceid = "";
-
-
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);
-
-
-
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=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來處理,處理過程和上面第二步差不多。