最近一直在接觸第三方,剛接入完支付寶的API作一下總結,我的能力薄弱有不對的地方望指教. 作的是一個小型電商項目,因此會接入第三方的支付和登入功能, 第一次接入第三方擼了不少官方文檔. java
進入主題, 支付寶支付先要去 螞蟻金服開放平臺註冊帳號:https://open.alipay.com/platform/home.htm
json
而後建立應用選擇須要接入的功能,有些應用是須要簽約的簽約就行了審覈蠻快的.api
以上應用申請,功能申請的一些操做我就很少作解釋了網上不少例子, app
這裏有APP支付和手機網站支付, APP支付是針對Android和IOS的案例, 那麼我作的是手機網站支付針對Java後臺的案例.異步
這裏直達官方文檔:https://docs.open.alipay.com/203/105285/
ide
我直接貼個人代碼:
測試
/** * * 說明:支付寶支付 (我只填了部分參數,若是有更多參數需求的 能夠直接:https://docs.open.alipay.com/203/107090/ ) * @param orderNumber 商戶網站惟一訂單號 * @param orderMoney 訂單金額 * @param orderSubject 商品的標題,關鍵字 * @param notifyUrl 異步回調地址(後臺) 獲取訂單信息 * @param returnUrl 同步回調地址(APP) 處理業務及渲染頁面 * @author ArLen * @time:2018年12月11日 下午2:14:57 */ @Override public void payment(String orderNumber, String orderMoney, String orderSubject, String notifyUrl, String returnUrl) { //填寫本身建立的app的對應參數 private static AlipayClient alipayClient = new DefaultAlipayClient("支付寶網關", "appid", "私鑰", "json", "utf-8", "公鑰","RSA2"); AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); // 封裝請求支付信息 AlipayTradeWapPayModel model=new AlipayTradeWapPayModel(); model.setOutTradeNo(orderNumber); model.setTotalAmount(orderMoney); model.setSubject(orderSubject); model.setProductCode("QUICK_WAP_WAY"); alipayRequest.setBizModel(model); //異步回調地址(後臺) alipayRequest.setNotifyUrl(notifyUrl); // 同步回調地址(APP) alipayRequest.setReturnUrl(returnUrl); try { //調用SDK生成表單 String form = alipayClient.pageExecute(alipayRequest).getBody(); //打印, 能夠直接response到頁面上 System.out.println(form); } catch (AlipayApiException e) { e.printStackTrace(); } }
支付成功後支付寶會自動請求你寫的 notifyUrl (異步通知, 接收支付寶異步通知,從而獲取此訂單的狀態) 和 returnUrl (支付完成後,支付寶會發送同步請求進行數據渲染, 這裏我是用ModelAndView 渲染的數據)網站
異步響應數據官方文檔: https://docs.open.alipay.com/203/105286/ url
公共響應參數 : https://docs.open.alipay.com/api_1/alipay.trade.wap.payspa
/** * * 說明:對於手機網站支付產生的交易,支付寶會根據原始支付API中傳入的異步通知地址notify_url,經過POST請求的形式將支付結果做爲參數通知到商戶系統。 * @param request * @return * @author Arlen * @time:2018年12月3日 下午4:51:35 */ @RequestMapping("notifyUrl") @ResponseBody public String notify(HttpServletRequest request){ int im=0; im++; //測試請求次數 System.out.println("次數:"+im); //獲取支付寶POST過來反饋信息 Map<String,String> params = new HashMap<String,String>(); Map<String, String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也可使用這段代碼轉化 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); params.put(name, valueStr); } //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(如下僅供參考)// //商戶訂單號 String out_trade_no = request.getParameter("out_trade_no"); //支付寶交易號 String trade_no = request.getParameter("trade_no"); //交易狀態 String trade_status = request.getParameter("trade_status"); System.out.println(trade_status); try { boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2"); if(verify_result){ //驗證成功 //請在這裏加上商戶的業務邏輯程序代碼 System.out.println("returnUrl_params:驗證成功"); //——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— boolean flg = false; if(trade_status.equals("TRADE_FINISHED")){ System.out.println("returnUrl_params:交易結束"); //交易結束,不可退款 //注意: //退款日期超過可退款期限後(如三個月可退款),支付寶系統發送該交易狀態通知 } else if (trade_status.equals("TRADE_SUCCESS")){ //交易支付成功 //注意: //付款完成後,支付寶系統發送該交易狀態通知 //根據訂單號將訂單狀態和支付寶記錄表中狀態都改成已支付 System.out.println("returnUrl_params:交易支付成功"); flg = true; } //——請根據您的業務邏輯來編寫程序(以上代碼僅做參考)—— if(flg){ return "success"; }else{ return "fail"; } }else{//驗證失敗 //out.print("fail"); return "fail"; } } catch (AlipayApiException e) { e.printStackTrace(); return "500"; } }
我在這邊處理了業務邏輯,還在測試階段, 我以爲有些欠缺.
@RequestMapping("/returnUrl") public ModelAndView result( HttpServletRequest request) { System.out.println("進來"); //用ModelAndView 進行數據渲染 ModelAndView mv = new ModelAndView("alipay/return_url"); //獲取支付寶GET過來反饋信息 Map<String,String> params = new HashMap<String,String>(); Map<String, String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也可使用這段代碼轉化 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } //交易訂單編號 String out_trade_no = request.getParameter("out_trade_no"); //交易金額 String total_amount = request.getParameter("total_amount"); //支付寶交易帳號 //String trade_no = request.getParameter("trade_no"); //訂單建立時間 String timestamp = request.getParameter("timestamp"); mv.addObject("out_trade_no", out_trade_no); mv.addObject("total_amount", total_amount); mv.addObject("timestamp", timestamp); //打印全部響應數據 System.out.println("returnUrl_params:"+params); try { boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2"); if(verify_result){ //驗證成功 這裏寫的是假代碼 //系統處理根據支付寶回調更改訂單狀態或者其餘關聯表的數據 (走業務流程, 根據訂單編號獲取訂單數據 //Order order =orderService.queryOrderByNumber(out_trade_no); /* if(order !=null){ //order不爲null mv.addObject("verify_result", verify_result); mv.addObject("msg", "商戶訂單號不存在"); } */ return mv; }else{ //驗證失敗 跳失敗頁面 System.out.println("驗證失敗"); return null; } } catch (AlipayApiException e) { e.printStackTrace(); //出現異常 跳失敗頁面 return null; } }
今天就先寫到 支付寶支付,明天再寫支付寶退款及其餘操做.