閒來無事,寫點博客javascript
支付寶的掃碼支付,實際就是PC支付稍微作了改造.html
這裏推薦支付寶掃碼支付使用支付寶的SDK jar包. 官網有下載.這裏我就不給出下載地址了.java
支付寶有幾個坑.我大體描述一下 : jquery
1.私鑰使用pkcs8格式.且不要頭尾,不能有空格ajax
2.在官網給出的java demo中,使用了公鑰. 但我實際使用的時候.發現不須要公鑰.加上公鑰反而會報錯.千萬不能使用公鑰.express
3.seller_id 不須要使用.json
下面給出具體代碼api
1.獲取支付寶二維碼地址服務器
/* 掃碼須要使用的參數. app_id,私鑰 . 記住這個和 商戶號 密鑰不同. 這裏面用不到商戶號和密鑰. */ public static String alipayEwmApi(HttpServletRequest request, HttpServletResponse response) { SmartDao smartdao = (SmartDao) request.getAttribute("smartdao"); String sHtmlText =""; 支付寶SDK的類,掃碼api類 AlipayTradePrecreateResponse responseInfo = null; try { //判斷是不是及時訂單 System.out.println("===================begin======================"); String orderId = (String) request.getAttribute("orderId"); if (UtilValidate.isEmpty(orderId)) { orderId = request.getParameter("orderId"); } //付款金額 String totalFee = ""; //訂單標題 String subject = ""; //訂單名稱 SmartValue orderHeader = smartdao.findOne("OrderHeader", SmartMisc.toMap("orderId", orderId),false); totalFee = orderHeader.getBigDecimal("grandTotal").toPlainString(); List<SmartValue> itemList = smartdao.findByAnd("OrderItemAndProduct", SmartMisc.toMap("orderId", orderId)); if(itemList.size()==1){ subject = itemList.get(0).getString("productName"); }else{ subject = new String(orderId); } AlipayConfig alipayConfig = new AlipayConfig(orderHeader.getString("productStoreId")); //服務器異步通知頁面路徑 String notify_url = alipayConfig.notify_url; //付款金額 String total_fee = new String(totalFee); String app_id = alipayConfig.app_id; //私鑰 String private_key =alipayConfig.private_key; String public_key = ""; AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",app_id,private_key,"json","utf-8",public_key); AlipayTradePrecreateRequest requestInfo = new AlipayTradePrecreateRequest(); //異步回調地址 notify_url = "http://www.xxx.com/control/alipay_notify_Sign"; Debug.log("notify_url================="+notify_url); requestInfo.setNotifyUrl(notify_url); //版本號 requestInfo.setApiVersion("1.0"); String goodDetail = ""; int i = 0 ; //組裝訂單明細 for(SmartValue item : itemList){ goodDetail += "{" + " \"goods_id\":\""+item.getString("productId")+"\"," + " \"goods_name\":\""+item.getString("productName")+"\"," + " \"quantity\":"+item.getBigDecimal("quantity").longValue()+"," + " \"price\":"+String.valueOf(item.getBigDecimal("unitPrice").setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()) + " }" ; i = i + 1; if(i<itemList.size()){ goodDetail+=","; } } //訂單編號,總金額,訂單標題,內容,明細,超時時間.m表明分鐘. String bizContent = "{" + " \"out_trade_no\":\""+orderId+"\"," + " \"total_amount\":"+total_fee+"," + " \"subject\":\""+subject+"\"," + " \"body\":\""+subject+"\"," + " \"goods_detail\":[" + goodDetail + "]," + " \"timeout_express\":\"90m\"" + " }"; requestInfo.setBizContent(bizContent); responseInfo = alipayClient.execute(requestInfo); if(UtilValidate.isNotEmpty(responseInfo)){ if(responseInfo.isSuccess()){ //獲取返回的二維碼地址,就是個http地址,若是調用失敗,記得看返回的錯誤碼. sHtmlText = responseInfo.getQrCode(); request.setAttribute("sHtmlText", sHtmlText); System.out.println("調用成功"); } else { System.out.println("調用失敗"); } } } catch (SmartEntityException e) { e.printStackTrace(); } catch (AlipayApiException e) { e.printStackTrace(); } return "success"; }
2.前臺使用app
<script type="text/javascript" src="/ofcupload/images/js/code/jquery.qrcode.js"></script> <script type="text/javascript" src="/ofcupload/images/js/code/qrcode.js"></script> <!--這兩個js在百度中能夠找到--> <!--二維碼顯示--> <div id="Canvas" style="width:300px;height:300px;"></div> <script> submitEwmForm("${(parameters.orderId)!})"); //請求AlipayEwmApi ,獲取二維碼地址.放入到上面的div中. function submitEwmForm(orderId){ $.ajax({ type: "POST", dataType: "json", data: {"orderId":orderId}, url: "findAlipayEwmApi", success: function(data3){ var code_url = data3.sHtmlText; $('#Canvas').html(""); $('#Canvas').qrcode({text: code_url}); var reqNumber=1; setTimeout("possucc('"+orderId+"',"+reqNumber+")",2000); //getServerMsg("success","請掃描圖中的二維碼進行支付!"); } }); } //訂單是否支付了,是由異步回調的地方觸發的.若是已經支付了,這裏的查詢就會查到. //每兩秒循環檢查訂單是否已經支付了,循環60次,若是已經支付,則刷新整個頁面. function possucc(orderId,reqNumber){ $.ajax({ url: 'findOrderHeaderJson', data: {orderId:orderId}, type: "POST", async:false, success: function(data) { var statusId = data.statusId; //console.log("data========="+data); if("ORDER_COMPLETED"==statusId){ $('#Checkout').modal('hide'); //getServerMsg("success","下單成功,謝謝您的光臨!"); //作打印操做. var orderId = data.orderId; //作打印操做. printOrderContent(orderId); location.href="main"; }else{ if(reqNumber<60){ reqNumber++; setTimeout("possucc('"+orderId+"',"+reqNumber+")",2000); } } } }); } </script>
3.支付寶後臺異步處理訂單
(注 : 這裏有一個坑必定要注意,支付寶的非掃碼支付方式, 回調觸發的時候,要判斷verify_result 這個參數,但在 掃碼支付 回調觸發的時候, 是沒有verify_result 這個參數的. 不要去獲取verify_result 這個參數,這是由於 掃碼支付和非掃碼支付,他們使用的方式不同. 前者用的app_ID和 私鑰, 後者用的商戶號和密鑰 ,verify_result是簽名驗證,只有在非掃碼支付的時候纔有這個參數.)
/** * 異步返回數據 * @param dctx * @param context */ @SuppressWarnings({ "rawtypes"}) public static String alipay_notify_Sign(HttpServletRequest request,HttpServletResponse response) { SmartDao smartdao = (SmartDao) request.getAttribute("smartdao"); LocalSmartService smartService =(LocalSmartService) request.getAttribute("smartService"); String returnIsInfo =""; //交易狀態 String trade_status; try { SmartValue smartUser =smartdao.findOne("SmartUser", SmartMisc.toMap("smartUserId","admin"),false); Map<String,String> params = new HashMap<String,String>(); Map requestParams = request.getParameterMap(); for (Iterator 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); } Debug.log("request.getParameterMap()=========="+request.getParameterMap()); //訂單號 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //支付寶訂單號 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); //支付寶的支付狀態 trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); SmartValue orderHeader = smartdao.findOne("OrderHeader", SmartMisc.toMap("orderId", out_trade_no), false); String statusId = orderHeader.getString("statusId"); String orderName=orderHeader.getString("orderName"); Debug.log("trade_status============="+trade_status); if((trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS"))){//驗證成功 if(UtilValidate.isNotEmpty(orderHeader) && "ORDER_CREATED".equals(statusId)){ //處理訂單 } }else{ returnIsInfo = "error"; } request.setAttribute("orderId", out_trade_no); } catch (SmartEntityException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } catch (UnsupportedEncodingException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } catch (ServiceAuthException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } catch (ServiceValidationException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } catch (SmartServiceException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } catch (CartItemModifyException e) { Debug.logError(e.getMessage(), module); returnIsInfo = "error"; } return returnIsInfo; }
結束,over!