The content of this article is about Java calling the Alipay payment interface. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
1. Scenario: The company needs to make Alipay payment on the website.
2. API: Use the payment capability of Alipay’s open platform-instant payment interface. Alipay Open Platform Link
3. Analysis:
#1. Alipay’s documents are relatively easy to read, mainly because there are corresponding DEMOs. The DEMO I am looking at here It is the JAVA-UTF-8 version.
2. Import DEMO and fill in the corresponding partner and key in com.alipay.config (obtained from the corresponding merchant backend). Run it directly to understand the payment process.
3. Rewrite: I am using springmvc mybatis here. The product initiates purchase (payment via Alipay), jumps to Alipay, and Alipay calls back the payment status.
1. Initiate a purchase request for the product (use the page in the DEMO directly).
<body> <div class="header"> <div class="container black"> <div class="qrcode"> <div class="littlecode"> <img style="max-width:90%" src="img/little_qrcode.jpg" id="licode" alt="Implementation method of calling Alipay payment interface in Java (code)" > <div class="showqrs" id="showqrs"> <div class="shtoparrow"></div> <div class="guanzhuqr"> <img src="img/guanzhu_qrcode.png" style="max-width:90%" alt="Implementation method of calling Alipay payment interface in Java (code)" > <div class="shmsg" style="margin-top:5px;"> 请扫码关注 </div> <div class="shmsg" style="margin-bottom:5px;"> 接收重要信息 </div> </div> </div> </div> </div> </div> <div class="container"> <div class="nav"> <a href="https://www.alipay.com/" class="logo"><img src="img/alipay_logo.png" height="30px" alt="Implementation method of calling Alipay payment interface in Java (code)" ></a> <span class="divier"></span> <a href="http://open.alipay.com/platform/home.htm" class="open" target="_blank">开放平台</a> <ul class="navbar"> <li><a href="https://doc.open.alipay.com/doc2/detail?treeId=62&articleId=103566&docType=1" target="_blank">在线文档</a></li> <li><a href="https://cschannel.alipay.com/portal.htm?sourceId=213" target="_blank">技术支持</a></li> </ul> </div> </div> <div class="container blue"> <div class="title">支付宝即时到账(create_direct_pay_by_user)</div> </div> </div> <div class="content"> <%-- <form action="${ctx}/aliPay/open" class="alipayform" method="POST" target="_blank"> --%> <div class="element" style="margin-top:60px;"> <div class="legend">支付宝即时到账交易接口快速通道 </div> </div> <div class="element"> <div class="etitle">商户订单号:</div> <div class="einput"><input type="text" name="WIDout_trade_no" id="out_trade_no"></div> <br> <div class="mark">注意:商户订单号(out_trade_no).必填(建议是英文字母和数字,不能含有特殊字符)</div> </div> <div class="element"> <div class="etitle">商品名称:</div> <div class="einput"><input type="text" name="WIDsubject" id="WIDsubject" value="test商品123"></div> <br> <div class="mark">注意:产品名称(subject),必填(建议中文,英文,数字,不能含有特殊字符)</div> </div> <div class="element"> <div class="etitle">付款金额:</div> <div class="einput"><input type="text" name="WIDtotal_fee" id="WIDtotal_fee" value="0.01"></div> <br> <div class="mark">注意:付款金额(total_fee),必填(格式如:1.00,请精确到分)</div> </div> <div class="element"> <div class="etitle">商品描述:</div> <div class="einput"><input type="text" name="WIDbody" id="WIDbody" value="即时到账测试"></div> <br> <div class="mark">注意:商品描述(body),选填(建议中文,英文,数字,不能含有特殊字符)</div> </div> <div class="element"> <input type="button" class="alisubmit" id="sbumitBtn" value ="确认支付"> </div> </div> <div id="returnAli"></div> <div class="footer"> <p class="footer-sub"> <a href="http://ab.alipay.com/i/index.htm" target="_blank">关于支付宝</a><span>|</span> <a href="https://e.alipay.com/index.htm" target="_blank">商家中心</a><span>|</span> <a href="https://job.alibaba.com/zhaopin/index.htm" target="_blank">诚征英才</a><span>|</span> <a href="http://ab.alipay.com/i/lianxi.htm" target="_blank">联系我们</a><span>|</span> <a href="#" id="international" target="_blank">International Business</a><span>|</span> <a href="http://ab.alipay.com/i/jieshao.htm#en" target="_blank">About Alipay</a> <br> <span>支付宝版权所有</span> <span class="footer-date">2004-2016</span> <span><a href="http://fun.alipay.com/certificate/jyxkz.htm" target="_blank">ICP证:沪B2-20150087</a></span> </p> </div> </body>
2. After clicking to confirm the payment, request the background through ajax and put the returned html code directly into the
$(function (){ $("#sbumitBtn").on('click', function(){ $.ajax({ type : "post", data : { WIDout_trade_no : $('#out_trade_no').val(), WIDsubject : $('#WIDsubject').val(), WIDtotal_fee : $('#WIDtotal_fee').val(), WIDbody : $('#WIDbody').val() }, url : "${ctx}/aliPay/open", success : function(data) { $('#returnAli').append(data.sHtmlText); }, error : function(da){ } }); }) });
3. In the background controller, the alipayapi.jsp in the demo is basically used directly. It is different. What's more, the parameter transfer is defined by yourself, the return method complies with apringmvc requirements, and the order information with status of unpaid is saved according to business needs.
@RequestMapping("open") public ResponseEntity<HttpEntity> open(Model model, String WIDout_trade_no, String WIDsubject, String WIDtotal_fee, String WIDbody) { //////////////////////////////////// 请求参数////////////////////////////////////// // 商户订单号,商户网站订单系统中唯一订单号,必填 String out_trade_no = WIDout_trade_no; // 订单名称,必填 String subject = WIDsubject; // 付款金额,必填 String total_fee = WIDtotal_fee; // 商品描述,可空 String body = WIDbody; // 把请求参数打包成数组 Map<String, String> sParaTemp = new HashMap<String, String>(); sParaTemp.put("service", AlipayConfig.service); sParaTemp.put("partner", AlipayConfig.partner); sParaTemp.put("seller_id", AlipayConfig.seller_id); sParaTemp.put("_input_charset", AlipayConfig.input_charset); sParaTemp.put("payment_type", AlipayConfig.payment_type); sParaTemp.put("notify_url", AlipayConfig.notify_url); sParaTemp.put("return_url", AlipayConfig.return_url); sParaTemp.put("anti_phishing_key", AlipayConfig.anti_phishing_key); sParaTemp.put("exter_invoke_ip", AlipayConfig.exter_invoke_ip); sParaTemp.put("out_trade_no", out_trade_no); sParaTemp.put("subject", subject); sParaTemp.put("total_fee", total_fee); sParaTemp.put("body", body); // 其他业务参数根据在线开发文档,添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.O9yorI&treeId=62&articleId=103740&docType=1 // 如sParaTemp.put("参数名","参数值"); // 建立请求 String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "确认"); model.addAttribute("sHtmlText", sHtmlText); // 保存支付记录 hysWebMeetingAliService.insertSelective(sParaTemp); return new ResponseEntity(model, HttpStatus.OK); }
4. Callback: The java code in notify_url.jsp in DEMO is also directly used and slightly modified and business code (modified status, etc.) is added;
@RequestMapping("notify") @ResponseBody public String notify(HttpServletRequest request){ //获取支付宝POST过来反馈信息 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); } //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)// //商户订单号 String out_trade_no = request.getParameter("out_trade_no"); //支付宝交易号 String trade_no = request.getParameter("trade_no"); //交易状态 String trade_status = request.getParameter("trade_status"); //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)// if(AlipayNotify.verify(params)){//验证成功 ////////////////////////////////////////////////////////////////////////////////////////// //请在这里加上商户的业务逻辑程序代码 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— boolean flg = false; if(trade_status.equals("TRADE_FINISHED")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 } else if (trade_status.equals("TRADE_SUCCESS")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //付款完成后,支付宝系统发送该交易状态通知 //根据订单号将订单状态和支付宝记录表中状态都改为已支付 flg = hysWebMeetingAliService.changeOrderAndAliStatusSuccess(out_trade_no); } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— //out.print("success"); //请不要修改或删除 if(flg){ return "success"; }else{ return "fail"; } ////////////////////////////////////////////////////////////////////////////////////////// }else{//验证失败 //out.print("fail"); return "fail"; } }
5. return_url: page jump synchronization notification page path, which is the page where Alipay will jump back after the payment is successful. "The complete path in http:// format is required, and custom parameters such as ?id=123 cannot be added. The external network must be accessible normally." Alipay clearly stipulates that no custom parameters can be added after the page that bounces back, so some of us are It is a bit troublesome to judge the jump based on some types. I did a trick here: first move the java code in return_url.jsp directly and modify it slightly (change to springmvc method). My bounce address is IP/aliPay/returnUrl, and then new ModelAndView ("redirect:/meeting/info") to redirect to the URL we are thinking of (see point 4 of the summary below for parameter issues).
@RequestMapping("returnUrl") public ModelAndView returnUrl(HttpServletRequest request){ ModelAndView mv = new ModelAndView("redirect:/meeting/info"); //获取支付宝GET过来反馈信息 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"), "utf-8"); 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"); <span style="color:#ff0000;">String meetingId = request.getParameter("extra_common_param"); mv.addObject("meetingId", meetingId);</span> //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)// //计算得出通知验证结果 boolean verify_result = AlipayNotify.verify(params); if(verify_result){//验证成功 ////////////////////////////////////////////////////////////////////////////////////////// //请在这里加上商户的业务逻辑程序代码 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //如果有做过处理,不执行商户的业务程序 } //该页面可做页面美工编辑 // out.println("验证成功<br />"); //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— ////////////////////////////////////////////////////////////////////////////////////////// }else{ //该页面可做页面美工编辑 // out.println("验证失败"); } return mv; }
1、支付宝集成比较简答,稍微看下DEMO,跑一下了解了流程就比较容易了。
2、调试的时候,特别是回调,要把项目部署到能够外网访问的服务器上。
3、我没有遇到上面莫名其妙的问题,如果遇到了的话,可以联系我,或者看下Eclipse远程debug这篇文章,进行问题的跟踪。
4、做页面跳转同步通知页面路径时,需要传递参数怎么办,我一开始是自定义了一个参数,可是没有取到,然后我看到DEMO中有一句注释是这么写的:
// 其他业务参数根据在线开发文档,添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.O9yorI&treeId=62&articleId=103740&docType=1
所以我打开看了之后,选择了公用回传参数extra_common_param,我自己知道这个字段对于我来说是什么含义。不过也要注意,人家说明了:
参数body(商品描述)、subject(商品名称)、extra_common_param(公用回传参数)不能包含特殊字符(如:#、%、&、+)、敏感词汇,也不能使用外国文字(旺旺不支持的外文,如:韩文、泰语、藏文、蒙古文、阿拉伯语);
open方法中设值:
sParaTemp.put("extra_common_param", meetingId);
returnUrl方法中取值,并作为重定向参数:
String meetingId = request.getParameter("extra_common_param"); mv.addObject("meetingId", meetingId);
相关推荐:
The above is the detailed content of Implementation method of calling Alipay payment interface in Java (code). For more information, please follow other related articles on the PHP Chinese website!