5

我正在开发一个PHP链接到Protx VSP Direct payment gateway. 为了处理来自信用卡处理公司的“3D Secure”请求,我需要将用户转发到另一个网站,模仿已发布的表格。我正在尝试使用这些cURL库,但似乎遇到了问题。我的代码如下:

<?php  
$ch = curl_init();  
// Set the URL  
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/');  
// Perform a POST  
curl_setopt($ch, CURLOPT_POST, 1);  
// If not set, curl prints output to the browser  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);   
// Set the "form fields"  
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);  
$output = curl_exec($ch);  
curl_close($ch);  
?>  

所有这一切都是抓取通过的 URL 的内容,并且不会将用户转发到任何地方。我已经尽可能多地尝试谷歌搜索和阅读,但无法弄清楚我错过了什么。有任何想法吗?如果可以避免的话,我不想创建一个自动提交的 HTML 表单。

谢谢你的帮助 :-)

4

10 回答 10

2

3D Secure API 不允许您在后台执行请求。您需要将用户转发到 3D 安全站点。使用 javascript 自动提交您的表单。以下是我们的供应商的建议:

<html> 
    <head> 
        <title>Processing your request...</title> 
    </head> 
    <body OnLoad="OnLoadEvent();"> 
        <form name="downloadForm" action="<%=RedirURL%>" method="POST"> 
            <noscript> 
                <br> 
                <br> 
                <div align="center"> 
                    <h1>Processing your 3-D Secure Transaction</h1> 
                    <h2>JavaScript is currently disabled or is not supported by your browser.</h2><BR> 
                    <h3>Please click Submit to continue the processing of your 3-D Secure transaction.</h3><BR> 
                    <input type="submit" value="Submit"> 
                </div> 
            </noscript> 
            <input type="hidden" name="PaReq" value="<%=PAREQ%>"> 
            <input type="hidden" name="MD" value="<%=TransactionID%>"> 
            <input type="hidden" name="TermUrl" value="<%=TermUrl%>"> 
        </form> 
        <SCRIPT LANGUAGE="Javascript"> 
            <!-- 
            function OnLoadEvent() { 
                document.downloadForm.submit(); 
            } 
            //--> 
        </SCRIPT> 
    </body> 
</html>
于 2008-09-19T19:40:25.140 回答
0

我认为您对 curl 的作用有些困惑。它完全按照您的解释执行,它的行为有点像浏览器,并调用该站点并返回该帖子的内容。我不知道您可以通过任何方式实际重定向浏览器服务器端并表示帖子。我实际上会创建一个 Javascript 解决方案来做这样的事情。

于 2008-09-19T19:42:32.360 回答
0

要将用户重定向到 PHP 中的另一个页面,您可以发送一个header("Location: http://example.com/newpage");. 但是,不幸的是,您的程序重定向会导致所有 POST 变量被删除(出于安全原因)。如果您想让用户的浏览器向不同的 URL 发送 POST 请求,则必须创建一个提交自身的表单。:(

于 2008-09-19T19:42:33.030 回答
0

我宁愿在幕后使用 cURL 之类的东西,因为我不能保证我的用户会启用 JS,并且显示表单会导致一些我宁愿避免的其他问题。这是我的 B 计划 ;-)

于 2008-09-19T19:43:42.043 回答
0

您可以使用 fsockopen() 重定向到新网站,同时保留您的 POST 变量。有一个很好的教程来说明如何做到这一点here

万一该网站被互联网怪物吃掉了,我已经复制并粘贴了该功能,但我建议查看原始网站的上下文。

function sendToHost($host,$method,$path,$data,$useragent=0)
{
    // Supply a default method of GET if the one passed was empty
    if (empty($method)) {
        $method = 'GET';
    }
    $method = strtoupper($method);
    $fp = fsockopen($host, 80);
    if ($method == 'GET') {
        $path .= '?' . $data;
    }
    fputs($fp, "$method $path HTTP/1.1\r\n");
    fputs($fp, "Host: $host\r\n");
    fputs($fp,"Content-type: application/x-www-form- urlencoded\r\n");
    fputs($fp, "Content-length: " . strlen($data) . "\r\n");
    if ($useragent) {
        fputs($fp, "User-Agent: MSIE\r\n");
    }
    fputs($fp, "Connection: close\r\n\r\n");
    if ($method == 'POST') {
        fputs($fp, $data);
    }

    while (!feof($fp)) {
        $buf .= fgets($fp,128);
    }
    fclose($fp);
    return $buf;
}
于 2008-09-19T19:45:38.920 回答
0

啊,如果我误解了 cURL 的作用,我想我会接受带有 JS 自动提交的 HTML 表单。为我创造了更多的工作,但如果这是唯一的方法,我将不得不这样做。

感谢大家的帮助。

于 2008-09-19T19:45:49.700 回答
0

我认为在这种情况下,您需要使用表格。信用卡支付公司的网站需要通过用户的浏览器访问,而不是您的服务器端代码。

是的,3dsecure 等集成起来很烦人,但它们确实提供了真正的安全性提升——按预期使用它。

于 2008-09-19T20:07:20.740 回答
0

也许我错过了一些东西;看起来您正在尝试接收用户的数据,通过 cURL 将其转发到支付处理器,然后将用户重定向到某个地方。对?

如果是这样,您只需将其放在代码的末尾即可:

header("位置:http ://www.yoursite.com/yoururl ");

但是,要使其正常工作,脚本在处理时不能向客户端发送任何内容;这意味着脚本不应在模板中间执行,另一个问题是文件开头开始标记之前的空白。

如果您需要保存原始 POST 事务中的数据,请使用会话来保存它。

这应该适用于无 JS 的解决方案。

于 2008-09-19T21:50:49.243 回答
0

我可能完全错了,但听起来你正在尝试做一些类似于代理模式的事情。

我已经为我合作过的其他网站实现了类似的模式,它确实需要一些修补才能正确。

我将 RETURN_TRANSFER 设置为 TRUE,以便您可以分析检索到的响应并根据它进行应用程序级别的操作。

http://en.wikipedia.org/wiki/Proxy_pattern

祝你好运。

于 2008-09-19T23:06:11.013 回答
0

我发现上面的 sendToHost() 函数非常有用,但是源代码中有一个错字需要一些时间来调试:Content-type 标头值在 'form-' 和 'urlencoded' 之间包含一个空格 - 应该是 'application/ x-www-form-urlencoded'

于 2009-05-28T18:02:47.310 回答