闲来无事,写点博客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!