Calendar

2008年六月
« 五   七 »
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Translator

PayPal IPN 处理程序

PAYPAL即时付款通知 (IPN) 是PayPal用于处理实时购买确认和服务器到服务器通信的界面。IPN 发送您收到的PayPal付款的即时通知和确认,并提供有关待付款、已取消或失败的交易状态及其他数据。

IPN可用于管理和自定义各种启用PayPal的API和通信,包括:

  • 自定义网站对客户购物进行实时回复
  • 通过 IPN“转递”变量跟踪客户
  • 为软件下载和其他数码产品分配访问键
  • 自动履行操作
  • 跟踪合作伙伴的销售和佣金
  • 在您自己的数据库中存储交易信息

立即注册PayPal并开始接受信用卡付款。

检索变量

进行了支付之后,PayPal 会向通过 POST 发送给 PayPal 服务器的 notify_url 变量中指定的 URL 发送通知。上面指定的脚本是 paypal_ipn_handler.php,所以请创建这个文件,并像下面这样定义它:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
include('includes/user_functions.php');
include('includes/shared_functions.php');
 
// assign posted variables to local variables
$payment_status = $_POST['payment_status'];
$amountDue = $_POST['mc_gross'];
$txn_id = $_POST['txn_id'];
$payment_currency = $_POST['mc_currency'];
$cartid = $_POST['custom'];
$my_email = $_POST['business'];
$email = $_POST['payer_email'];
...

首先,把 PayPal 通过 POST 发送过来的重要变量保存在本地变量中。

验证支付

对支付进行验证的方式是:搜集从 PayPal 发送过来的变量,并通过 POST 重新发送它们。继续定义 paypal_ipn_handler.php,添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
$my_email = $_POST['business'];
$email = $_POST['payer_email'];
 
$req="";
foreach ($_POST as $key => $value) {
    $req .= $key."=".urlencode($value) . "&";
}
$req .= 'cmd=_notify-validate';
 
$fp = fsockopen (PAYPAL_URL, 80, $errno, $errstr, 30);
if (!$fp) 
    die();
fputs($fp, "POST /cgi-bin/webscr HTTP/1.1\r\n"); 
fputs($fp, "Host: ".PAYPAL_URL."\r\n"); 
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
fputs($fp, "Content-length: ".strlen($req)."\r\n"); 
fputs($fp, "Connection: close\r\n\r\n"); 
fputs($fp, $req . "\r\n\r\n"); 
$info = "";
while(!feof($fp)) { 
    $info .= @fgets($fp, 1024); 
}
...

foreach 语句接受 POST 数组中的所有变量,并把它们保存在另一个变量 $req 中,并添加命令 _notify-validate。这个命令请求 PayPal 对支付进行验证。这么做的话,其他人就不能随便向这个 URL POST 数据,因为要把所有变量重新 POST 回来,从而使整个过程非常安全。PayPal 还发送另外一个通知,可以在 while 循环中用 $info 和 @fgets 搜集到这个通知。

处理第二个通知

现在,已经接收了从 PayPal POST 过来的变量,而且也通过 POST 把它们又发送回 PayPal。PayPal 现在要发送第二个通知。请继续定义 paypal_ipn_handler.php,添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
while(!feof($fp)) { 
    $info .= @fgets($fp, 1024); 
}
if(strstr($info, "VERIFIED") != ''){
    if($payment_currency == "USD" &&
       $payment_status == "Completed" &&
       $my_email == MY_EMAIL) {
 
        $pdo = db_connect();
        $sql = "select amount_due from orders
                                  where cartid=$cartid";
        $row = $pdo->query($sql)->fetch();
        $balance = $row['AMOUNT_DUE']-$total;
 
        $sql = "update orders set
                              status='Processing',
                              amount_due=$balance
                              where cartid=$cartid";
        $pdo->exec($sql);
    }
}
else{
    // log for manual investigation
}
fclose ($fp);
?>

如果 $info 变量返回的数据中包含单词 VERIFIED,那么支付成功!请验证正确的货币类型是美元、返回的支付状态是 “Completed”、付款的电子邮件保存在刚才定义的常量 MY_EMAIL 中。

参考
IPN PHP CLASS 本人改写的PAYPAL IPN PHP通用类
PayPal IPN handler IPN简单处理程序


Leave a reply

  1. You will post the following soon.
    Go ahead and start typing.