【问题标题】:ModPay Payment Gateway HowToMolPay 支付网关 如何
【发布时间】:2014-07-13 03:02:42
【问题描述】:

更新:我已将其范围缩小到 Ajax 调用。我可以使用普通的表单提交,仍然使用相同的 PHP 代码并且它可以工作。阿贾克斯没有。因此,如果任何熟悉 Ajax 的人有一个想法......或者如果您对如何在没有用户交互的情况下从代码执行 POST 有更好的想法......

更新 2: 如果我用下面的代码替换 GetPaymentSetup() 函数,它也可以使用 PostTo。这似乎是重定向的东西......

    public function GetPaymentSetup() {
        $script1 = "<script type=\"text/javascript\">
            function post_to_url() {
                var form = document.createElement('form');
                form.action = '" . self::PROXY_URL . "';
                form.method = 'POST';

                var input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'clientId';
                input.value = '" . self::CLIENTID . "';
                document.body.appendChild(input);
                form.appendChild(input);

                var input1 = document.createElement('input');
                input1.type = 'hidden';
                input1.name = 'clientCode';
                input1.value = '" . self::CLIENTCODE . "';
                document.body.appendChild(input1);
                form.appendChild(input1);

                var input2 = document.createElement('input');
                input2.type = 'hidden';
                input2.name = 'postTo';
                input2.value = '" . self::POSTTO_URL . "';
                document.body.appendChild(input2);
                form.appendChild(input2);

                var input3 = document.createElement('input');
                input3.type = 'hidden';
                input3.name = 'target';
                input3.value = 'GetPaymentSetup';
                document.body.appendChild(input3);
                form.appendChild(input3);

                form.submit();
            }
        </script>";
        $html2 = "<br><button id='hidformbtn' onclick=\"post_to_url()\">Click 3</button><br>";

        echo $script1;
        echo $html2;
}

我想这会奏效。在某些情况下,我需要将其自动化,但这不是问题。我只是想知道为什么 jQuery/Ajax 会失败。


我到处搜索,但找不到与此系统相关的任何问题。所以我需要一些指导,也许可以作为将来使用它的任何人的参考。我的任务是与 ModPay.com 的支付系统集成。它也称为 TotalTransact。出于测试目的,他们有一个足够简单的页面,您可以在没有任何实际数据交换的情况下进行 POST 并获取响应。我已经编写了适用于此的代码,但是当我向“PostTo a different url”添加一个选项时,我没有得到回复。首先,这是他们的 API 文档中描述该选项的方式:

如果您提供 PostTo=URL 参数,则调用 xxxxx 页面会将其结果发布到提供的 url,而不是 返回带有结果的网页。

我想将结果发布到不同的 url,以便更轻松地拆分解析。如果我不使用此参数,我会从发出请求的页面中返回 ok 的结果。如果我使用该参数,我仍然会获得成功的 POST,但没有返回。他们的开发人员摸不着头脑,所以我更倾向于认为这与我的代码有关。

我已验证他们可以直接发布到我的 PostTo 网址。所以我知道这不是问题。我还添加了“Access-Control-Allow-Origin”标头,以确保它们可以正常回发以避免跨域问题。

这是PHP中的相关代码:

function post($url, $data) {
    $header = array("Content-Type: application/x-www-form-urlencoded");
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

    //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
    //curl_setopt($curl, CURLOPT_SSLVERSION,3);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($curl, CURLOPT_HEADER, true);  //This option returns some data to the screen
    curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
    //curl_setopt($curl, CURLOPT_COOKIEFILE, ''); //write cookies.  empty string to ignore.
    //curl_setopt($curl, CURLOPT_COOKIEJAR, ''); //read cookies
    //curl_setopt($curl, CURLOPT_VERBOSE, '1');
    //curl_setopt($curl, CURLOPT_NOPROXY, 1); // causes POST to fail
    //curl_setopt($curl, CURLOPT_HTTPHEADER,array("Expect:"));
    //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

在哪里

$data = http_build_query($_POST, '', '&');

并且 $_POST 来自另一个页面上的 AJAX 调用(避免浏览器 CORS 问题的代理):

public function GetPaymentSetup($useButton) {
    $script = "<script type=\"text/javascript\">";
    if($useButton == true) {
        $script .= "
        $(document).ready(function() {
        $(\"button\").click(function() {
        ";
    }
    $script .= "
        var request = jQuery.ajax ({
            type:   'POST',
            url:    '" . self::PROXY_URL . "',
            crossDomain: true,
            data:       { \"clientId\"      : \"" . self::CLIENTID . "\",
                          \"clientCode\"    : \"" . self::CLIENTCODE . "\",
                          \"postTo\"        : \"" . self::POSTTO_URL . "\" 
                        }
            success: function(responseData, textStatus, jqXHR) {
                        $('#dresponse').html(responseData);
                     },
            error:   function(responseData, textStatus, errorThrown) {
                        $('#dresponse').html('Error. POST failed.');
                     }
        });";
    if($useButton == true) {
        $script .= "
        });});";
    }
    $script .= " </script>";
    if($useButton == true)
        $html = "<button>click</button><div id='dresponse'></div>";
    else
        $html = "<div id='dresponse'></div>";
    echo $script;
    echo $html;
}

谁能解释一下为什么我使用这条线:

                      \"postTo\"        : \"" . self::POSTTO_URL . "\" 

POSTTO_URL 页面永远不会得到任何返回。但是,如果我删除该行,我会得到回复吗?再一次,使用 POSTTO_URL,我在原始 AJAX 调用中也没有收到错误,因此它作为一个成功的 POST。我可以通过将 CLIENTID 更改为其他内容来验证这一点,然后我会失败。

这是我正在做的事情,还是他们不正确的事情?有没有人有与他们集成的经验?

提前致谢!

【问题讨论】:

  • 我还应该提到,无论我是否使用 PostTo,所有注释掉的 curl 选项都没有区别。
  • 如果你把postTo url直接放在那里会发生什么?
  • 没有任何变化。我假设您的意思是 \"postTo\" : \"xxxx\",对吗?
  • 类似postTo: 'xxxx'
  • 不。我确实在上面添加了一个更新,UPDATE 2,展示了如果我不使用 jQuery/Ajax,它是如何成功工作的。

标签: php jquery ajax payment


【解决方案1】:

没有人知道为什么最初的 Ajax/jQuery 会失败。但我确实有一个可行的解决方案,所以下面为任何希望未来进行 TotalTransact/ModPay 集成的人:

创建文件:modPayProcessing.php:

<?php
class modPayProcessing {
    const CLIENTCODE = "xxxxxxx";
    const CLIENTID = "xxxxxx";
    const PROXY_URL = "https://....modPayProxy.php";
    const POSTTO_URL = "https://....modPayReceive.php";

    public function GetPaymentSetup($useButton=false, $usePostTo=false) {
        $script = "<script type=\"text/javascript\">
            function post_to_url() {
                var form = document.createElement('form');
                form.action = '" . self::PROXY_URL . "';
                form.method = 'POST';

                var input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'clientId';
                input.value = '" . self::CLIENTID . "';
                document.body.appendChild(input);
                form.appendChild(input);

                var input1 = document.createElement('input');
                input1.type = 'hidden';
                input1.name = 'clientCode';
                input1.value = '" . self::CLIENTCODE . "';
                document.body.appendChild(input1);
                form.appendChild(input1);
        ";
        if($usePostTo === true) {
            $script .= "
                var input2 = document.createElement('input');
                input2.type = 'hidden';
                input2.name = 'postTo';
                input2.value = '" . self::POSTTO_URL . "';
                document.body.appendChild(input2);
                form.appendChild(input2);
            ";
        }
        $script .= "
                var input3 = document.createElement('input');
                input3.type = 'hidden';
                input3.name = 'target';
                input3.value = 'GetPaymentSetup';
                document.body.appendChild(input3);
                form.appendChild(input3);

                form.submit();
            }
        ";
        if($useButton == true) {
            $html = "<button id='hidformbtn' onclick=\"post_to_url()\">Submit</button>";
            $script .= "</script>";
        }
        else {
            $html = "";
            $script .= "
            if(window.onload) {
                var currOnload = window.onload;
                var newOnload = function() {
                    currOnload();
                    post_to_url();
                };
                window.lonload = newOnload;
            }
            else {
                window.onload = post_to_url();
            }
        </script>";
        }

        echo $script;
        echo $html;
    }

    public function PostPayment($useButton, $usePostTo=false) {
    // Same as the above function, but change the input.name/value to be for whatever you want to submit
    // Implementations of how to retrieve the data vary, so I am not listing it exactly here, but the basic format is the same.
    }

创建一个文件:modPayProxy.php:

//You can use Curl, or you can use php Streams.  Below is a function for each:
<?php
    function postCurl($url, $data) {
        $header = array("Content-Type: application/x-www-form-urlencoded");
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 3);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_HEADER, false);  //This option returns some data to the screen
        curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);

        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }

    function postStreams($url, $data) {
        $params = array(
            'http' => array(
                'method'=>'POST',
                'content'=>$data,
                'header'=>array("Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n"),
                'user_agent'=>"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
            )
        );
        $ctx = stream_context_create($params);
        $fp = @fopen($url, 'rb', false, $ctx);
        if(!$fp) {
            throw new Exception("Problem with $url, $php_errormsg");
        }
        $response = @stream_get_contents($fp);
        fclose($fp);
        if($response === false) {
            throw new Exception("Problem reading data from $url, $php_errormsg");
        }
        return $response;
    }

    if(array_key_exists('target', $_POST)) {
        if($_POST['target'] == 'GetPaymentSetup')
            $url = GETSETUP_URL;
        elseif($_POST['target'] == 'PostPayment')
            $url = POST_URL;
        else
            $url = "";

        unset($_POST['target']);
        $data = http_build_query($_POST, '', '&');

        echo(postStreams($url, $data)); //change to postCurl if you prefer
    }
    else {  // if POSTTO_URL is not used in the calling function.
        $postdata = file_get_contents("php://input");
        parse_str($postdata, $output);
        // Do whatever you want with $output now.
    }

创建一个文件,modPayReceive.php:

<?php
    $postdata = file_get_contents("php://input");
    parse_str($postdata, $output);
    // Now do whatever you want with $output now.

要发起呼叫,请确保您需要 modPayProcessing.php,然后:

$cc = new modPayProcessing();
$cc->GetPaymentSetup(true, false);

如果第二个参数为 false,则不会使用 POSTTO_URL / modPayReceive.php 文件。 第一个参数可以设置为 true 以将其作为表单上的按钮。或者 false 直接处理(一个更好的主意,这样你就不会暴露你的 clientID 等)

【讨论】:

    猜你喜欢
    • 2018-04-11
    • 2017-01-01
    • 2016-02-25
    • 2016-06-16
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多