【问题标题】:Sending the PayPal form via "GET" not "POST" by redirecting the client通过重定向客户端通过“GET”而不是“POST”发送 PayPal 表单
【发布时间】:2017-10-27 12:38:07
【问题描述】:

POST 是通过 PayPal documentations 发送 PayPal 按钮的推荐方法。他们明确表示:

<FORM action="https://www.paypal.com/cgi-bin/webscr" method="post">

重要提示:请勿更改这些值。这些属性是必需的 对于所有支付按钮和购物车上传命令

但是在this tutorial 中,作者在服务器端构建按钮变量,然后将客户端重定向到 PayPal,这将使请求通过“GET”而不是“POST”发送到 PayPal。 类似的东西

这是发送给客户的表单(它没有 PayPal 变量,只有按钮和一些与我的业务相关的可选变量)

<form class="paypal" action="/payments.php" method="post">
    <select name="product">
        <option value="A">A</option>
        <option value="B">B</option>
    </select>
    <input name="discountCode" type="text">
    <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online!">
</form>

然后他在服务器上构建了 PayPal 变量并将客户端重定向到 PayPal 以继续进行

payments.php

$paypal_email = 'user@example.com';
$return_url = 'http://example.com/payment-successful.html';
$cancel_url = 'http://example.com/payment-cancelled.html';
$notify_url = 'http://example.com/payments.php';//same file
$item_name = 'Test Item'; //build the item and amount depend on what is selected in the form
$item_amount = 5.00;

$querystring = '';
$querystring .= "?business=".urlencode($paypal_email)."&";
$querystring .= "cmd=_xclick&";
$querystring .= "item_name=".urlencode($item_name)."&";
$querystring .= "amount=".urlencode($item_amount)."&";
$querystring .= "return=".urlencode(stripslashes($return_url))."&";
$querystring .= "cancel_return=".urlencode(stripslashes($cancel_url))."&";
$querystring .= "notify_url=".urlencode($notify_url);

// Redirect to paypal (will cause GET request to PayPal)
header('location:https://www.sandbox.paypal.com/cgi-bin/webscr'.$querystring);
exit();

这种方法对我有用,但是 POST 方法是 PayPal 推荐的方法。我发现 PHP 更舒服,让我有机会在客户端转到 PayPal 之前做一些工作,例如根据用户选择更新我的后端系统或从 HTML &lt;form&gt; 隐藏一些敏感变量(如 notify_url)(客户仍然可以看到他被引导到的位置)。

在服务器端构建 PayPal 变量然后通过 GET 请求将客户端重定向到 PayPal 是否可靠且受支持?

【问题讨论】:

  • 您可以通过创建隐藏表单并使用 javascript 提交来轻松地使用发布表单数据进行重定向。
  • 您的意思是隐藏&lt;input&gt; 的常规形式,没有涉及&lt;input type="hidden" name="cmd" value="_xclick"&gt; &lt;input type="hidden" name="business" value="user@example.com"&gt; 之类的java 脚本?
  • 并在&lt;/form&gt; 之后添加&lt;script type="text/javascript"&gt;document.getElementById('myFormId').submit();&lt;/script&gt;,而不是header("Location: ...");。所以你基本上回显了一个包含所有隐藏字段的普通表单并自动提交。
  • 我需要更新 &lt;form&gt; 产品价格取决于使用的折扣代码,并在用户访问 PayPal 网站之前更新我的后端数据库中使用的折扣代码状态。我的第二个选项将是您所说的使用 java 脚本,就像这里 https://www.paypal-knowledge.com/infocenter/index?page=content&id=FAQ1512&expand=true&locale=en_US 一样。但是如果这个 PHP 工作不被推荐并且不可靠,我将使用这个 java 脚本选项。
  • @DainisAbols 哦,是的,我刚刚知道了! .是的,这是一个切割器解决方案,非常感谢您

标签: php paypal


【解决方案1】:

并不是说这是最好的选择,但是要创建一个帖子表单,您可以编辑您的 payments.php,如下所示:

<?php

$paypal_email = 'user@example.com';
$return_url   = 'http://example.com/payment-successful.html';
$cancel_url   = 'http://example.com/payment-cancelled.html';
$notify_url   = 'http://example.com/payments.php';//same file
$item_name    = 'Test Item'; //build the item and amount depend on what is selected in the form
$item_amount  = 5.00;

$querystring = [
    'business'      => urlencode($paypal_email),
    'cmd'           => '_xclick',
    'item_name'     => urlencode($item_name),
    'amount'        => urlencode($item_amount),
    'return'        => urlencode(stripslashes($return_url)),
    'cancel_return' => urlencode(stripslashes($cancel_url)),
    'notify_url'    => urlencode($notify_url),
];

?>

<html>
<head>
</head>
<body>
    <form id="myForm" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="POST">
        <?php
        foreach ($querystring as $a => $b) {
            echo "<input type='hidden' name='".htmlentities($a)."' value='".htmlentities($b)."' />";
        }
        ?>
    </form>
    <script type="text/javascript">
        document.getElementById('myForm').submit();
    </script>
</body>
</html>
<?php
exit();

【讨论】:

    【解决方案2】:

    建议使用 POST,因为使用 GET 方法可能会超过最大 URL 长度限制,导致 PayPal 出现以下错误:

    HTTP 414 URI 太长

    当您开始包含多个产品、名称、价格、服务器令牌、地址等时,这个大小很快就会加起来。就我个人而言,我已经看到在单个产品和最少数据的情况下超过了这个限制,因此跨浏览器更安全使用 POST 的兼容性目的。

    【讨论】:

    • 感谢您的注意,是的,GET 有最大长度。我在询问是否将变量作为 PayPal 记录的 GET 变量发送或是否支持。我按照@Peon 的建议做了 2 年,他的方法对我很有效,感谢您抽出宝贵时间回答这个问题。
    • @Accountantم 是的,我想我只是在帖子中澄清一下为什么不推荐 GET(尽管被接受)。就像 Peon 在他的回答中建议并由您自己证明的那样,切换到 POST 更安全。
    【解决方案3】:

    在我看来,使用自动提交 javascript 或标头并将字段发送到贝宝并不重要。重要的是,您发送到贝宝的内容不应位于带有“点击立即付款”的表单的隐藏字段中,即不自动提交,否则用户可以在浏览器调试模式下读取这些隐藏字段。我将这些编码变量作为来自页面 (A) 的会话变量传递到单独的发送页面 (B),对 in (B) 进行解码,生成通过令牌到 paypal 并在 (B) 上进行大量冗余检查,例如页面如果不是来自 (A),则中止所有 SESSION 变量,并匹配它们未编码的对应项。发送到 paypal 的 pass through 生成的 token 字段被返回,因此可以与它的编码会话对应项进行比较以验证 paypal,尽管您可以 curl 到 paypal 以检查其合法性。您必须以闪电般的速度单独在 (B) 上停止浏览器,理论上您可以阅读两个帖子并到达那里,但不等待用户输入是一个巨大的威慑安全明智的做法,并且您必须复制大量冗余检查变量。

    【讨论】:

    • 如果我理解的没错,你的意思是不是不想在提交给PayPal的表单中设置隐藏字段数据,而是想把它们放在提交给你页面的表单中(B ) ?并取决于用户在重定向和查看那些隐藏字段之前速度不够快以停止浏览器的事实?如果是这种情况,那么用户不需要停止浏览器,他可以记录网络流量并在数小时后查看它们,或者使用读取这些值的自定义机器人。您能否提供一个简单的代码示例来展示您的想法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2021-06-05
    • 2012-01-18
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多