douyun8674 2013-03-17 23:36
浏览 36

Paypal IPN订阅(php)

I am trying to set up a subscription using Paypal and their IPN system for days now. I could not understand most tutorials and finally found one that made sense to me.

With help of Sean on here I have changed the code slightly but still no luck.

To create the subscription button, I use the following code:

<form action="https://sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick-subscriptions">
<input type="hidden" name="business" value="info@mydomain.com">
<input type="hidden" name="lc" value="NL">
<input type="hidden" name="item_name" value="Mydomain.com Abonnement">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="no_shipping" value="2">
<input type="hidden" name="notify_url" value="http://www.mydomain.com/pp-ipn-handler.php">
<input type="hidden" name="return" value="http://www.mydomain.com/ppsuccess.php">
<input type="hidden" name="src" value="1">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="bn" value="PP-SubscriptionsBF:btn_subscribeCC_LG.gif:NonHosted">
<input type="hidden" name="custom" value="'. $username .'">
<table>
<tr><td><input type="hidden" name="on0" value="Betaalperiode"><strong>Kies uw betaalperiode:</strong></td></tr><tr><td><select name="os0">
    <option value="Per maand">Per maand : &euro;25.00 EUR</option>
    <option value="Per jaar">Per jaar : &euro;240.00 EUR</option>
</select> </td></tr>
</table>
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="option_select0" value="Per maand">
<input type="hidden" name="option_amount0" value="25.00">
<input type="hidden" name="option_period0" value="M">
<input type="hidden" name="option_frequency0" value="1">
<input type="hidden" name="option_select1" value="Per jaar">
<input type="hidden" name="option_amount1" value="240.00">
<input type="hidden" name="option_period1" value="Y">
<input type="hidden" name="option_frequency1" value="1">
<input type="hidden" name="option_index" value="0">
<input type="image" src="https://www.paypalobjects.com/nl_NL/NL/i/btn/btn_subscribe_LG.gif" border="0" name="submit" alt="PayPal, de veilige en complete manier van online betalen.">
</form>

To handle the ipn response I have a file named pp-ipn-handler.php with the following code:

<?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
";
$header .= "Content-Type: application/x-www-form-urlencoded
";
$header .= "Content-Length: " . strlen($req) . "

";
// assign posted variables to local variables
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
// $payment_currency = $_POST['mc_currency'];
$payment_currency = 'EUR';
$ppusername = $_POST['custom'];
$fp = fsockopen ('sandbox.paypal.com', 80, $errno, $errstr, 30);
if (!$fp)
{
}
else
{
fputs ($fp, $header . $req);
while (!feof($fp))
{
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0)
{
// When a payment has gone trough
    //When payment is 25EUR make it a month validity
    if ($ppusername&&($payment_currency=='EUR')&&($payment_amount=='25'))
    {
        $period = '+1 month';       
    }
    //When payment is 240EUR make it a year validity
    else if ($ppusername&&($payment_currency=='EUR')&&($payment_amount=='25'))
    {
        $period = '+1 year';        
    }
    //There is incorrect information in this payment
    else
    {

    }


    //Lets first get the date in mysql format
    $date = date('m/d/Y h:i:s', time());
    $date = date('m/d/Y h:i:s', strtotime("$date -7 hours"));
    //Now lets update the subscription records
    require_once('core/dbconnect.php');
    $subscriptionrecordexists = mysql_query("SELECT * FROM subscriptions WHERE username='$ppusername'");
    if (mysql_num_rows($subscriptionrecordexists))
    {
        //User has purchase before. Adjust his subscription record and ad an invoice.
        require_once('core/dbconnect.php');
        $subscriptionrecord = mysql_query("SELECT * FROM subscriptions WHERE username='$ppusername'");
        $row = mysql_fetch_array($subscriptionrecord);
        //Update subscription record
        $currentvalidity = $row['validity'];
        if ($currentvalidity >= $date)
        {
            //Add period if subscription is still valid
            $newvalidity = date('m/d/Y h:i:s', strtotime("$currentvalidity $period"));
            require_once('core/dbconnect.php');
            mysql_query("UPDATE subscriptions SET validity='$newvalidity' WHERE username='$ppusername'");
            //Add invoice to user
            if ($period == '+1 month')
            {$product = 'NLTVMee.com voor 1 maand';}
            if ($period == '+1 year')
            {$product = 'NLTVMee.com voor 1 jaar';}
            $paymentmethode = 'Paypal';
            $oldvalid = $currentvalidity;
            $newvalid = $newvalidity;
            require_once('core/dbconnect.php');
            mysql_query("INSERT INTO invoices VALUES ('','$date','$ppusername','$product','$paymentmethode','$payment_currency','$payment_amount','$oldvalid','$newvalid')");
        }
        else
        {
            //Add period from current date if validity is not valid anymore
            $newvalidity = date('m/d/Y h:i:s', strtotime("$date $period"));
            require_once('core/dbconnect.php');
            mysql_query("UPDATE subscriptions SET validity='$newvalidity' WHERE username='$ppusername'");
            //Ad invoice to user
            if ($period == '+1 month')
            {$product = 'NLTVMee.com voor 1 maand';}
            if ($period == '+1 year')
            {$product = 'NLTVMee.com voor 1 jaar';}
            $paymentmethode = 'Paypal';
            $newvalid = $newvalidity;
            require_once('core/dbconnect.php');
            mysql_query("INSERT INTO invoices VALUES ('','$date','$ppusername','$product','$paymentmethode','$payment_currency','$payment_amount','','$newvalid')");
        }
    }
    else
    {
        //User has never purchased before. Make new subscription record and add invoice.
        //Add period from current date if validity is not valid anymore
        $newvalidity = date('m/d/Y h:i:s', strtotime("$date $period"));
        require_once('core/dbconnect.php');
        mysql_query("INSERT INTO subscriptions VALUES ('','$ppusername','$newvalidity')");
        //Ad invoice to user
        if ($period == '+1 month')
        {$product = 'NLTVMee.com voor 1 maand';}
        if ($period == '+1 year')
        {$product = 'NLTVMee.com voor 1 jaar';}
        $paymentmethode = 'Paypal';
        $newvalid = $newvalidity;
        require_once('core/dbconnect.php');
        mysql_query("INSERT INTO invoices VALUES ('','$date','$ppusername','$product','$paymentmethode','$payment_currency','$payment_amount','','$newvalid')");
    }

}
//End
else if (strcmp ($res, "INVALID") == 0)
{

}
}
fclose ($fp);
}
?>

As you can see it is now configured with the Paypal sandbox urls to try it out, but when I do and make the payment nothing is changed in the db and as you can see the IPN handler page should change things.

  • 写回答

1条回答 默认 最新

  • douhoujun9304 2013-03-17 23:55
    关注

    It is a blank page because you have your ipn listener as your return value, which is where you are sent after completion, but no info is sent. The postback to Paypal will have no values and your code will fail.
    (from the docs - The URL to which PayPal redirects buyers' browser after they complete their payments. For example, specify a URL on your site that displays a "Thank you for your payment" page.)

    <input type="hidden" name="return" value="http://www.mydomain.com/pp-ipn-handler.php">
    

    You need to use notify_url
    (from the docs - The URL to which PayPal posts information about the payment, in the form of Instant Payment Notification messages.)

    <input type="hidden" name="notify_url" value="http://www.mydomain.com/pp-ipn-handler.php">
    <input type="hidden" name="return" value="http://www.mydomain.com/payment_complete_thank_message.php">
    

    Edit
    I see 3 additional errors in the code

    Your query on line #65 is $subscriptionrecord, but on line #66 you are using $userinfo

        $subscriptionrecord = mysql_query("SELECT * FROM subscriptions WHERE username='$ppusername'");
        $row = mysql_fetch_array($userinfo);
    

    Correction
    these below are not true as enclosing them in quotes "$currentvalidity $period" is the same as $currentvalidity.$period

    On line #72 you need to concat $currentvalidity & $period inside strtotime() - $currentvalidity.$period

    $newvalidity = date('m/d/Y h:i:s', strtotime("$currentvalidity $period"));
    

    On line #91 & #111 you need to concat $date & $period inside strtotime() - $date.$period

    $newvalidity = date('m/d/Y h:i:s', strtotime("$date $period"));
    
    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100