当我收到 PayPal IPN 时,我应该在哪里执行 UPDATE 查询?

Posted

技术标签:

【中文标题】当我收到 PayPal IPN 时,我应该在哪里执行 UPDATE 查询?【英文标题】:Where should I execute an UPDATE query when I receive PayPal IPN? 【发布时间】:2012-03-22 16:40:48 【问题描述】:

跟进my previous newbie question about Paypal,我有一个新的新手问题。

我已经成功地设置了一个 Paypal 沙箱,并在我的服务器上实现了一个 php“侦听器”,当我测试我的 Paypal 支付按钮时,一切似乎都运行良好。所以看来我已经掌握了支付系统的基本骨架。

现在我有点困惑如何将它带到下一步根据我的需要进行定制。

为了设置监听器,我复制了the code offered on Paypal's site。我的希望和假设是,我可以在该代码中找到 Paypal 告诉我付款已到的位置。

但是,我不清楚这一点在哪里。如果我根据付费或未付费设置某种“if”语句,我看不出我会测试什么值。

我想要做的就是如果 Paypal 告诉我此人已付款,那么我的 mysql 数据库中的一个标志将被标记为“已付款”。应该是定期付款,所以如果下次自动付款失败,那么数据库中的标志应该被标记为“未付款”。

他们的代码中是否有一个地方可以用作添加我自己的自定义操作的起点?还是我需要完全使用其他代码库?

作为参考,这里是有问题的 PHP 代码:

<?php

error_reporting(E_ALL ^ E_NOTICE);
$email = $_GET['ipn_email'];
$header = "";
$emailtext = "";
// Read the post from PayPal and add 'cmd'
$req = 'cmd=_notify-validate';
if (function_exists('get_magic_quotes_gpc'))

    $get_magic_quotes_exists = true;

foreach ($_POST as $key => $value)
// Handle escape characters, which depends on setting of magic quotes

    if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1)
    
        $value = urlencode(stripslashes($value));
    
    else
    
        $value = urlencode($value);
    
    $req .= "&$key=$value";

// Post back to PayPal 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://www.paypal.com', 443, $errno, $errstr, 30);


// Process validation from PayPal
// TODO: This sample does not test the HTTP response code. All
// HTTP response codes must be handles or you should use an HTTP
// library, such as cUrl

if (!$fp)
 // HTTP ERROR

else

// NO HTTP ERROR
    fputs($fp, $header . $req);
    while (!feof($fp))
    
        $res = fgets($fp, 1024);
        if (strcmp($res, "VERIFIED") == 0)
        
            // TODO:
            // Check the payment_status is Completed
            // Check that txn_id has not been previously processed
            // Check that receiver_email is your Primary PayPal email
            // Check that payment_amount/payment_currency are correct
            // Process payment
            // If 'VERIFIED', send an email of IPN variables and values to the
            // specified email address
            foreach ($_POST as $key => $value)
            
                $emailtext .= $key . " = " . $value . "\n\n";
            
            mail($email, "Live-VERIFIED IPN", $emailtext . "\n\n" . $req);
        
        else if (strcmp($res, "INVALID") == 0)
        
            // If 'INVALID', send an email. TODO: Log for manual investigation.
            foreach ($_POST as $key => $value)
            
                $emailtext .= $key . " = " . $value . "\n\n";
            
            mail($email, "Live-INVALID IPN", $emailtext . "\n\n" . $req);
        
    
    fclose($fp);

?>

【问题讨论】:

【参考方案1】:

您必须更进一步并实施 TODO 步骤。

现在,PayPal 有一个名为 item_number 的标准传递字段。您可以使用该字段来传递数据库的订单 ID:

<input type="hidden" name="item_number" value="<?php echo $OrderID ?>">

由于它是一个传递变量,因此 PayPal 将在 IPN 中回显此变量的值。因此,在您验证 IPN 并查看 TODO 列表后,请更新您的数据库:

// if ($_POST["payment_status"] == "Completed"
// &&  $_POST["receiver_email"] == the_email_you_use_in_business_field
// &&  etc etc
// )
"UPDATE Orders SET paid = 1 WHERE OrderID = $_POST[item_number]"

在数据库查询中使用 POST 变量之前对其进行验证和清理。

html Variables for Website Payments Standard -- 您通过 HTML 表单发送到 PayPal 的变量 IPN and PDT Variables -- 您在 IPN 中收到的变量

编辑

我现在看到您想要处理定期付款。看起来并不直截了当:

仔细检查变量引用。您可以使用几个字段来识别订阅(custom、invoice、item_number)。 您将在订阅的多个阶段收到多个 IPN,包括订阅本身、首次付款、后续付款以及订阅终止的时间。 随着每种类型的付款更改传递的变量。您必须彻底查阅文档,以确定应针对每种类型的 IPN 检查哪些字段。

【讨论】:

【参考方案2】:

把你的数据库相关代码放在里面:

if (strcmp($res, "VERIFIED") == 0) //your database query here

【讨论】:

【参考方案3】:

你有这个cmets:

> // TODO:
>             // Check the payment_status is Completed
>             // Check that txn_id has not been previously processed
>             // Check that receiver_email is your Primary PayPal email
>             // Check that payment_amount/payment_currency are correct
>             // Process payment
>             // If 'VERIFIED', send an email of IPN variables and values to the
>             // specified email address

把你的代码放在这里:

   if (strcmp($res, "VERIFIED") == 0)
   

    ...

    

【讨论】:

以上是关于当我收到 PayPal IPN 时,我应该在哪里执行 UPDATE 查询?的主要内容,如果未能解决你的问题,请参考以下文章

Paypal IPN - 区分定期付款和初始付款

PayPal 订阅 - 缺少 PDT 发票

Paypal IPN状态 - 排队

PayPal IPN - 排队

IPN 验证在应该失败时不会失败

在哪里使用新的 Paypal UI 为 Paypal 定期付款设置 IPN URL?