PayPal金额篡改

时间:2013-11-01 14:42:45

标签: php security paypal tampering

我之前从未进行过paypal集成,但我曾与其他网关合作过。

对于其他网关,还有一个哈希值也会在表单中发送,这会阻止人们篡改数据,即更改数量。

如何通过paypal停止这种篡改,似乎没有任何哈希。

<form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
  <input type="hidden" value="_xclick" name="cmd">
  <input type="hidden" value="online****@theg*****.com" name="business">
  <!-- <input type="hidden" name="undefined_quantity" value="1" /> -->
  <input type="hidden" value="Order" name="item_name">
  <input type="hidden" value="NA" name="item_number">
  <input type="hidden" value="22.16" name="amount">
  <input type="hidden" value="5.17" name="shipping">
  <input type="hidden" value="0" name="discount_amount">        
  <input type="hidden" value="0" name="no_shipping">
  <input type="hidden" value="No comments" name="cn">
  <input type="hidden" value="USD" name="currency_code">
  <input type="hidden" value="http://XXX/XXX/XXX/paypal/return" name="return">
  <input type="hidden" value="2" name="rm">      
  <input type="hidden" value="11255XXX" name="invoice">
  <input type="hidden" value="US" name="lc">
  <input type="hidden" value="PP-BuyNowBF" name="bn">
  <input type="submit" value="Place Order!" name="finalizeOrder" id="finalizeOrder" class="submitButton">
</form>

那么我怎样才能阻止人们在发送到PayPal之前修改金额?即数量应为100但人们将其更改为1。

2 个答案:

答案 0 :(得分:5)

有几种方法可以防止这种情况发生。第一种是使用PayPal的Instant Payment Notification(IPN)。使用此功能,您可以将PayPal发回给您的价格进行比较,以确认它们符合您的预期。如果它们不匹配,则取消订单。

示例工作流程:

  • 用户订购商品并将价格修改为0.01美元
  • 订单发布到PayPal,显示价格为$ 0.01
  • 用户接受价格并支付0.01美元
  • PayPal拨打您的IPN网址并发布交易详情,显示该用户支付0.01美元的费用
  • 您的IPN会检查PayPal收到的价格($ 0.01)以及您所期望的价格(&gt; $ 0.01)。由于它们不匹配,您取消订单

PayPal IPN Flow

另一种选择是使用PayPal的Button API来创建动态加密buttons。它们嵌入到您的页面中,用户单击它以进行订购。由于它是加密的,因此用户无法在事务期间可靠地修改源代码。这个answer提供了一个很好的例子。此外,您可以将其与上面列出的IPN选项结合起来,作为对事务的良好审计

答案 1 :(得分:0)

您需要做的是实施简单的发票系统。在数据库中有一个名为invoices (ID, User_Id, Invoice_Value, Payment_Status)的表(示例)。

当用户到达结帐页面时,到目前为止,您应该在该用户的数据库表中插入一个条目,包括他们必须支付的总金额以及“待处理”的初始付款状态。插入发票表行后,获取最后一个插入ID和一个名为$invoice_id的变量。

现在,您输出html paypal结帐按钮表单,其中一个隐藏的输入字段应该是这样的:

<input type="hidden" value="<?php echo $invoice_id; ?>" name="custom">

现在,当paypal使用IPN回复您的返回网址时,您的IPN处理程序应该按照这种方式行事:

<?php

// read the post from PayPal system and add 'cmd'  
$req = 'cmd=_notify-validate';  
foreach ($_POST as $key => $value) {  
    $value = urlencode(stripslashes($value));  
    $req .= "&$key=$value";  
}

// post back to PayPal system to validate  
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";  
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";  
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";  

$fp = fsockopen ('ssl://sandbox.www.paypal.com', 443, $errno, $errstr, 30);  
if (!$fp) {  
    // HTTP ERROR  
}
else
{
    // Make Request To PayPal
    fputs ($fp, $header . $req);  
    while (!feof($fp))
    { 
        // Read Response 
        $res = fgets ($fp, 1024);

        // Check Response  
        if (strcmp ($res, "VERIFIED") == 0)
        {  
            // PAYMENT VALIDATED & VERIFIED!

            // Load the Invoice_Value from invoices table for $_POST['custom']
            // and compare it with paypal posted amount held in $_POST['mc_gross']
            // if it matches, paypal has authenticated the payment and the value has not been tampered with
            // update the invoice table and set the payment status
        }  
        else if (strcmp ($res, "INVALID") == 0)
        {  
            // PAYMENT INVALID & INVESTIGATE MANUALY!  
        }
    }  
    fclose ($fp);  
}  

?>