如何在微信中接入支付寶支付


前提:需要一台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='' name='html'></form>";

    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 = "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 = "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='chuliguo'>";
        response.setHeader("X-XSS-Protection", "0");
        
        response.getWriter().write(html);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM