通过" GET"发送PayPal表单不是" POST"通过重定向客户端

时间:2017-10-27 12:38:07

标签: php paypal

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

  

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

     

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

然而,在this tutorial中,作者正在服务器端构建按钮变量,然后将客户端重定向到PayPal,这将通过&#34; GET&#34;将请求转到PayPal。不是&#34; POST&#34;。 喜欢这个

这是发送给客户的表单(它没有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更舒服,让我有机会在客户端进入Pay​​Pal之前做一些工作,比如根据用户选择更新我的后端系统或隐藏HTML <form>中的一些敏感变量(如notify_url)( 客户端仍然可以看到他被引导到哪里)。

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

3 个答案:

答案 0 :(得分:2)

不是说这是最佳选择,但要创建帖子表单,您可以按如下方式编辑 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();

答案 1 :(得分:1)

建议使用POST,因为使用GET方法有可能超过最大URL长度限制,从而在PayPal上导致以下错误:

  

HTTP 414 URI太长

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

答案 2 :(得分:0)

在我看来,您使用自动提交的JavaScript还是标题并获取Paypal字段都没有关系。重要的是,您发送给Paypal的内容不应位于带有“立即单击付款”形式的隐藏字段中,即不要自动提交,否则用户可以在浏览器调试模式下读取这些隐藏字段。我将这些编码后的变量作为页面(A)中的会话变量传递到单独的发送页面(B),对(B)中的代码进行解密,生成一个传递令牌到paypal并在(B)上进行很多冗余检查,例如页面如果不是来自(A),则中止所有SESSION变量,并匹配它们的未编码对应项。返回传递给Paypal的传递生成的令牌字段,因此可以与它的编码会话对等物进行比较以验证paypal,尽管您可以卷曲到paypal来检查其合法性。您必须闪电般地停止浏览器,仅在(B)上停止浏览,理论上您可以阅读并到达该页面,但是不等待用户输入是一个巨大的威慑性安全明智之举,并且您必须重复很多冗余操作检查变量。