首页 > 代码库 > 如何在微信中接入支付宝支付
如何在微信中接入支付宝支付
前提:需要一台nginx服务器做反向代理
前言:支付宝支付手机支付一共分4个页面分别为1、输入手机号页面,2、输入验证码页面,3、输入支付密码页面,4、支付结果页面
1、配置nginx服务器为 https://mclient.alipay.com做反向代理,对app和支付宝做反向代理如下,要求支付宝的反向代理后的域名与app的域名为同域。
server { listen 80; server_name app.domin.com; access_log /var/website/app/logs/access.log; error_log /var/website/app/logs/error.log; location /app { proxy_pass http://xxx.xx.xxx.xxx:8080/app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 100m; } location / { proxy_pass https://mclient.alipay.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; client_max_body_size 100m; } }
2、前端需要嵌套一个iframe链接支付宝的反向代理地址,看js部分,对第1、2个页面做前端域名替换因为不涉及到js问题,所以没有做处理,第3、4个页面涉及到js的调用,因为支付宝js的写法导致原本绑定的事件不能执行,第3个页面包含了【确认付款】这几个字,所以以此为判断条件,如果是第三个页面就把一个表单插入到iframe的body中,用js把页面的html提交到本文第5节的地址中去,又这个方法处理后增加一个chuliguo的标志重新返回html,使输入密码的js可以正常执行,第4步同理。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="ctx" value="${ pageContext.request.contextPath }" /> <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>支付</title> <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script> <style> .scroll-wrapper{ position: fixed; right: 0; bottom: 0; left: 0; top: 0; -webkit-overflow-scrolling: touch; overflow-y: scroll; } .scroll-wrapper { height: 100%; width: 100%; border: none; } </style> </head> <body> <iframe class="scroll-wrapper" src="${ ctx }/alipay/pay?id=${ id }&type=${ type }"> </iframe> <script> var form = "<form id=‘sbform‘ action=‘${ ctx }/alipay/rerender‘ method=‘post‘><input type=‘hidden‘ id=‘submit_html‘ value=http://www.mamicode.com/‘‘ name=‘html‘>"; function buildRegex() { var op = "g"; return new RegExp("https://mclient.alipay.com", op); } $(".scroll-wrapper").get(0).onload = function(){ var docuemnt = $("iframe").get(0).contentWindow.document; var html = $(docuemnt).find("html").html(); if(html.indexOf("确认付款") > 0 ){ if(html.indexOf("chuliguo") < 0){ $(docuemnt).find("html").find(‘body‘).append($(form)); $(docuemnt).find("html").find(‘body‘).find(‘#sbform‘).find(‘#submit_html‘).val($(docuemnt).find("html").html()); $(docuemnt).find("html").find(‘body‘).find(‘#sbform‘).submit(); } }else if(html.indexOf("付款结果") > 0 ){ if(html.indexOf("chuliguo") < 0){ $(docuemnt).find("html").find(‘body‘).append($(form)); $(docuemnt).find("html").find(‘body‘).find(‘#sbform‘).find(‘#submit_html‘).val($(docuemnt).find("html").html()); $(docuemnt).find("html").find(‘body‘).find(‘#sbform‘).submit(); }else{ location.href = $(docuemnt).find("html").find(‘body‘).find(".J-return-link").find("a").attr("href"); } }else{ html = html.replace(buildRegex(), "http://app.domin.com") $(docuemnt).find("html").html(html); } $("iframe").show(); } </script> </body> </html>
3、生成支付宝订单的时候把openapi的地址替换成项目中的一个action,其中urlService.getUrl返回的是http://app.domin.com/alipay/middle/
form = form.replace("https://openapi.alipay.com", urlService.getUrl("alipay", "middle", request))
4、表单提交到的本地方法如下,因为上一步中支付宝生成的表单中的地址是https://openapi.alipay.com/gateway.do,上一步替换完了就是app.domin.com/alipay/middle/gateway.do。或者上一步连gateway.do一起替换。不清楚可以此处打断点调试。此方法就是对原本的openapi.alipay的请求做一个中转,返回支付宝给的表单html。这一步不能直接对openapi域名反向代理,因为提交以后支付宝端直接跳转到mclient地址,没有替换域名的机会。此处把mclient.alipay.com替换成项目域名也就是app.domin.com,项目域名根目录第一节中反向代理了mclient.alipay.com
@RequestMapping(value = "http://www.mamicode.com/middle/gateway.do") public void middle(HttpServletRequest request,HttpServletResponse response) throws IOException{ String queryString = request.getQueryString(); String biz_content = request.getParameter("biz_content"); Map<String, String> param = new HashMap<>(); param.put("biz_content", biz_content); String res = HttpUtil.http("https://openapi.alipay.com/gateway.do?" + queryString, param,null); res = res.replaceAll("https://mclient.alipay.com", urlService.serverPath(request, "")); response.getWriter().write(res); }
5、后台需要一个重新渲染支付宝html的方法,把支付宝的地址换成我们反向代理支付宝的地址 ,此代码在输完手机号验证码输入支付密码的页面调用见第2节的说明,因为有的步骤是前台做html中域名替换,导致这一步输入不了密码。处理完成后拼接一个chuliguo的input作为前台判断的标志,防止循环重载此页面。可结合前台代码一起理解这一步的作用。
@RequestMapping(value = "http://www.mamicode.com/rerender") public void rerender(HttpServletRequest request,HttpServletResponse response) throws IOException{ String html = request.getParameter("html"); html = html.replaceAll("https://mclient.alipay.com", "http://app.domin.com"); html += "<input type=‘hidden‘ value=http://www.mamicode.com/‘chuliguo‘>"; response.setHeader("X-XSS-Protection", "0"); response.getWriter().write(html); }
如何在微信中接入支付宝支付