php - 如果我使用沙箱,IPN 无效

标签 php paypal

我已经把那个 url http://pvpcoach.com/notification.php在我的个人资料中的即时付款通知设置中,我使用该 notification.php 脚本代码获取即时付款通知数据。

通知.php

    <?php
    // Revision Notes
    // 11/04/11 - changed post back url from https://www.paypal.com/cgi-bin/webscr to https://ipnpb.paypal.com/cgi-bin/webscr
    // For more info see below:
    // https://www.x.com/content/bulletin-ip-address-expansion-paypal-services
    // "ACTION REQUIRED: if you are using IPN (Instant Payment Notification) for Order Management and your IPN listener script is behind a firewall that uses ACL (Access Control List) rules which restrict outbound traffic to a limited number of IP addresses, then you may need to do one of the following: 
    // To continue posting back to https://www.paypal.com  to perform IPN validation you will need to update your firewall ACL to allow outbound access to *any* IP address for the servers that host your IPN script
    // OR Alternatively, you will need to modify  your IPN script to post back IPNs to the newly created URL https://ipnpb.paypal.com using HTTPS (port 443) and update firewall ACL rules to allow outbound access to the ipnpb.paypal.com IP ranges (see end of message)."


    /////////////////////////////////////////////////
    /////////////Begin Script below./////////////////
    /////////////////////////////////////////////////

    // 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";

    // If testing on Sandbox use:
    $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

    //$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);


    // assign posted variables to local variables
    $item_name = $_POST['item_name'];
    $business = $_POST['business'];
    $item_number = $_POST['item_number'];
    $payment_status = $_POST['payment_status'];
    $mc_gross = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $receiver_email = $_POST['receiver_email'];
    $receiver_id = $_POST['receiver_id'];
    $quantity = $_POST['quantity'];
    $num_cart_items = $_POST['num_cart_items'];
    $payment_date = $_POST['payment_date'];
    $first_name = $_POST['first_name'];
    $last_name = $_POST['last_name'];
    $payment_type = $_POST['payment_type'];
    $payment_status = $_POST['payment_status'];
    $payment_gross = $_POST['payment_gross'];
    $payment_fee = $_POST['payment_fee'];
    $settle_amount = $_POST['settle_amount'];
    $memo = $_POST['memo'];
    $payer_email = $_POST['payer_email'];
    $txn_type = $_POST['txn_type'];
    $payer_status = $_POST['payer_status'];
    $address_street = $_POST['address_street'];
    $address_city = $_POST['address_city'];
    $address_state = $_POST['address_state'];
    $address_zip = $_POST['address_zip'];
    $address_country = $_POST['address_country'];
    $address_status = $_POST['address_status'];
    $item_number = $_POST['item_number'];
    $tax = $_POST['tax'];
    $option_name1 = $_POST['option_name1'];
    $option_selection1 = $_POST['option_selection1'];
    $option_name2 = $_POST['option_name2'];
    $option_selection2 = $_POST['option_selection2'];
    $for_auction = $_POST['for_auction'];
    $invoice = $_POST['invoice'];
    $custom = $_POST['custom'];
    $notify_version = $_POST['notify_version'];
    $verify_sign = $_POST['verify_sign'];
    $payer_business_name = $_POST['payer_business_name'];
    $payer_id =$_POST['payer_id'];
    $mc_currency = $_POST['mc_currency'];
    $mc_fee = $_POST['mc_fee'];
    $exchange_rate = $_POST['exchange_rate'];
    $settle_currency  = $_POST['settle_currency'];
    $parent_txn_id  = $_POST['parent_txn_id'];
    $pending_reason = $_POST['pending_reason'];
    $reason_code = $_POST['reason_code'];


    // subscription specific vars

    $subscr_id = $_POST['subscr_id'];
    $subscr_date = $_POST['subscr_date'];
    $subscr_effective  = $_POST['subscr_effective'];
    $period1 = $_POST['period1'];
    $period2 = $_POST['period2'];
    $period3 = $_POST['period3'];
    $amount1 = $_POST['amount1'];
    $amount2 = $_POST['amount2'];
    $amount3 = $_POST['amount3'];
    $mc_amount1 = $_POST['mc_amount1'];
    $mc_amount2 = $_POST['mc_amount2'];
    $mc_amount3 = $_POST['mcamount3'];
    $recurring = $_POST['recurring'];
    $reattempt = $_POST['reattempt'];
    $retry_at = $_POST['retry_at'];
    $recur_times = $_POST['recur_times'];
    $username = $_POST['username'];
    $password = $_POST['password'];

    //auction specific vars

    $for_auction = $_POST['for_auction'];
    $auction_closing_date  = $_POST['auction_closing_date'];
    $auction_multi_item  = $_POST['auction_multi_item'];
    $auction_buyer_id  = $_POST['auction_buyer_id'];



    //DB connect creds and email 
    $notify_email =  "vikastyagi87@gmail.com";         //email address to which debug emails are sent to
    $DB_Server = "localhost"; //your MySQL Server
    $DB_Username = "username"; //your MySQL User Name
    $DB_Password = "password"; //your MySQL Password
    $DB_DBName = "databasename"; //your MySQL Database Name


    if (!$fp) {
    // HTTP ERROR
    } else {
    fputs ($fp, $header . $req);
    while (!feof($fp)) {
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0) {



    //create MySQL connection
    $Connect = @mysql_connect($DB_Server, $DB_Username, $DB_Password)
    or die("Couldn't connect to MySQL:<br>" . mysql_error() . "<br>" . mysql_errno());


    //select database
    $Db = @mysql_select_db($DB_DBName, $Connect)
    or die("Couldn't select database:<br>" . mysql_error(). "<br>" . mysql_errno());


    $fecha = date("m")."/".date("d")."/".date("Y");
    $fecha = date("Y").date("m").date("d");

    //check if transaction ID has been processed before
    $checkquery = "select txnid from paypal_payment_info where txnid='".$txn_id."'";
    $sihay = mysql_query($checkquery) or die("Duplicate txn id check query failed:<br>" . mysql_error() . "<br>" . mysql_errno());
    $nm = mysql_num_rows($sihay);
    if ($nm == 0){

    //execute query



        if ($txn_type == "cart"){
        $strQuery = "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";

         $result = mysql_query($strQuery) or die("Cart - paypal_payment_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());
         for ($i = 1; $i <= $num_cart_items; $i++) {
             $itemname = "item_name".$i;
             $itemnumber = "item_number".$i;
             $on0 = "option_name1_".$i;
             $os0 = "option_selection1_".$i;
             $on1 = "option_name2_".$i;
             $os1 = "option_selection2_".$i;
             $quantity = "quantity".$i;

             $struery = "insert into paypal_cart_info(txnid,itemnumber,itemname,os0,on0,os1,on1,quantity,invoice,custom) values ('".$txn_id."','".$_POST[$itemnumber]."','".$_POST[$itemname]."','".$_POST[$on0]."','".$_POST[$os0]."','".$_POST[$on1]."','".$_POST[$os1]."','".$_POST[$quantity]."','".$invoice."','".$custom."')";
             $result = mysql_query($struery) or die("Cart - paypal_cart_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());

         }
        }



        else{
         $strQuery = "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,itemnumber,itemname,os0,on0,os1,on1,quantity,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$item_number."','".$item_name."','".$option_name1."','".$option_selection1."','".$option_name2."','".$option_selection2."','".$quantity."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";
         $result = mysql_query("insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,itemnumber,itemname,os0,on0,os1,on1,quantity,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$item_number."','".$item_name."','".$option_name1."','".$option_selection1."','".$option_name2."','".$option_selection2."','".$quantity."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')") or die("Default - paypal_payment_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());
        }


        // send an email in any case
     echo "Verified";
         mail($notify_email, "VERIFIED IPN", "$res\n $req\n $strQuery\n $struery\n  $strQuery2");
    }
    else {
    // send an email
    mail($notify_email, "VERIFIED DUPLICATED TRANSACTION", "$res\n $req \n $strQuery\n $struery\n  $strQuery2");
    }

        //subscription handling branch
        if ( $txn_type == "subscr_signup"  ||  $txn_type == "subscr_payment"  ) {

          // insert subscriber payment info into paypal_payment_info table
          $strQuery = "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";
          $result = mysql_query($strQuery) or die("Subscription - paypal_payment_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());


             // insert subscriber info into paypal_subscription_info table
            $strQuery2 = "insert into paypal_subscription_info(subscr_id , sub_event, subscr_date ,subscr_effective,period1,period2, period3, amount1 ,amount2 ,amount3,  mc_amount1,  mc_amount2,  mc_amount3, recurring, reattempt,retry_at, recur_times, username ,password, payment_txn_id, subscriber_emailaddress, datecreation) values ('".$subscr_id."', '".$txn_type."','".$subscr_date."','".$subscr_effective."','".$period1."','".$period2."','".$period3."','".$amount1."','".$amount2."','".$amount3."','".$mc_amount1."','".$mc_amount2."','".$mc_amount3."','".$recurring."','".$reattempt."','".$retry_at."','".$recur_times."','".$username."','".$password."', '".$txn_id."','".$payer_email."','".$fecha."')";
            $result = mysql_query($strQuery2) or die("Subscription - paypal_subscription_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());


                 mail($notify_email, "VERIFIED IPN", "$res\n $req\n $strQuery\n $struery\n  $strQuery2");

        }
    }

    // if the IPN POST was 'INVALID'...do this


    else if (strcmp ($res, "INVALID") == 0) {
    // log for manual investigation

    mail($notify_email, "INVALID IPN", "$res\n $req");
    }
    }
    fclose ($fp);
    }
    ?>

如果我在 paypal 上进行真正的 paypal 支付,那时候 notification.php 脚本代码工作,如果我使用沙箱,那时候代码不起作用,我在电子邮件中得到了输出

INVALID
cmd=_notify-validate&amount3=12.00&address_status=confirmed&subscr_date=02%3A15%3A39+Feb+22%2C+2012+PST&payer_id=A5DUBM9B67SU8&address_street=1+Main+St&mc_amount3=12.00&charset=windows-1252&address_zip=95131&first_name=Test&reattempt=1&address_country_code=US&address_name=Test+User&notify_version=3.4&subscr_id=I-0817P6BX3P66&custom=c25a9064af5fe1e082f4d4dccf9ef8f1&payer_status=verified&business=vikast_1312898140_biz%40gmail.com&address_country=United+States&address_city=San+Jose&verify_sign=ADSm5I2w3q7evTcsSPu0fdxbnxnTAsg9iSN23V8wbqKs9Jyf0Yeapofa&payer_email=vikast_1316757002_per%40gmail.com&btn_id=2401055&last_name=User&address_state=CA&receiver_email=vikast_1312898140_biz%40gmail.com&recurring=1&txn_type=subscr_signup&item_name=test&mc_currency=USD&residence_country=US&test_ipn=1&period3=1+M&ipn_track_id=d9bef80986ce7

如果有任何问题理解问题请告诉我

提前致谢,vikas tyagi

最佳答案

我认为沙盒 url 应该是

https://www.sandbox.paypal.com/cgi-bin/webscr

(然后是通过 GET 附加的所有值(加上额外的 cmd=_notify-validate)。 此外,我认为包含的 curl 函数更易于使用来验证这样的请求:

$responseURL = "https://www.sandbox.paypal.com/cgi-bin/webscr?";
$params = "cmd=_notify-validate&" .http_build_query($_POST);

// verify IPN with paypal
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $responseURL. $params);
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

if($response == "VERIFIED"){ 
    // VALID ...
} else {
    // INVALID ...
}

关于php - 如果我使用沙箱,IPN 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9393616/

相关文章:

javascript - onclick方法在javascript中动态创建按钮

php - 从收件箱中的特定号码获取所有短信 - Esendex

php - IPN - 教程有错误

Paypal 通知网址无法显示 1985 年的最晚交货日期?

paypal - 通过 PayPal API 从任何帐户向任何其他帐户付款

php - 从一个表中获取信息并将返回的信息保存在新表中 - Laravel 5.2

php - 如何知道 h1 标签是否在 SEO 中起作用

php - 如何在 CI 中使用 OR 和 AND 运算符进行查询?

现场忽略 Paypal 返回字段

Paypal 网站支付标准集成