0

我最近研究了一个 PayPal IPN 脚本,并且可以正常工作。但是,我最近将文件转移到另一台服务器上,它似乎不再正常运行。我在下面包含了 PayPal IPN 代码和 HTML 表单。

发生的事情是脚本根本没有运行。我添加了一些调试来测试并查看遗漏了哪些步骤,我得出的结论是 PayPal 根本没有提醒 ipn.php。在 PayPal 上的 IPN 历史记录中,它只是说它正在“重试”。我的代码如下。

HTML:

<form action="https://<?php echo $url; ?>/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_xclick-subscriptions"/>
    <input type="hidden" name="business" value="<?php echo $email; ?>"/>
    <input type="hidden" name="item_name" value="<?php echo $pname; ?>"/>
    <input type="hidden" name="item_number" value="<?php echo $id; ?>"/>
    <input type="hidden" name="amount" value="<?php echo $prices[$id - 1] . ".00"; ?>"/>
    <input type="hidden" name="quantity" value="1"/>
    <input type="hidden" name="no_note" value="1"/>
    <input type="hidden" name="currency_code" value="USD"/>
    <input type="hidden" name="lc" value="US"/>
    <input type="hidden" name="bn" value="PP-BuyNowBF"/>
    <input type="hidden" name="a3" value="<?php echo $prices[$id - 1] . ".00"; ?>"/>
    <input type="hidden" name="p3" value="1"/>
    <input type="hidden" name="t3" value="M"/>
    <input type="hidden" name="src" value="1"/>
    <input type="hidden" name="sra" value="1"/>
    <input type="hidden" name="return"
           value="https://bvpn.biz/success.php?id=<?php echo $id; ?>&met=<?php echo $met; ?>"/>
    <input type="hidden" name="cancel_return"
           value="https://bvpn.biz/success.php?id=<?php echo $id; ?>&met=<?php echo $met; ?>&do=2"/>
    <input type="hidden" name="rm" value="2"/>
    <input type="hidden" name="notify_url" value="https://bvpn.biz/ipn.php"/>
    <input type="hidden" name="custom" value="<?php echo $_SESSION['username'].'|'.getUserId($_SESSION["username"]).'|'.getUserEmail($_SESSION["username"]); ?>"/>
    <div style="padding-top:100px; padding-right: 40%; padding-left: 40%;">
        <center><input type="submit" name="submit" class="btn" value="Checkout with PayPal"></center>
    </div>
</form>

ipn.php:

<?php
include("inc/er.php");
include("inc/database.php");
include("inc/functions.php");

$debug = true;

require("inc/ipn.config.php");
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
}

if ($debug)
{
    $ourFileName = "debug/debug1_postdata.txt";
    $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
    fwrite($ourFileHandle, $postback);
    fclose($ourFileHandle);
}

// post back to PayPal system to validate //
$header .= "POST cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: " . $url . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$header .= "Connection: close\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

if (!$fp) {

    //email
    $mail_From = "From: IPN@tester.com";
    $mail_To = $email;
    $mail_Subject = "HTTP ERROR";
    $mail_Body = $errstr;

    mail($mail_To, $mail_Subject, $mail_Body, $mail_From);
}
else
{
    if ($debug)
    {
        $ourFileName = "debug/debug2_connected.txt";
        $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
        fclose($ourFileHandle);
    }
    $ids = explode("|", $_POST['custom']);
    $item_username = $ids[0];
    $item_userid = $ids[1];
    $item_email = $ids[2];
    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $payment_status = $_POST['payment_status'];
    $payment_amount = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txnId = $_POST['txn_id'];
    $receiverEmail = $_POST['receiver_email'];
    $payerEmail = $_POST['payer_email'];
    $price = 5;
    $payment_amount = str_replace('.00', '', $payment_amount);

    fputs ($fp, $header . $req);
    while (!feof($fp)) {
        if ($debug)
        {
            $ourFileName = "debug/debug3_fgets.txt";
            $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
            fwrite($ourFileHandle, $response);
            fclose($ourFileHandle);
        }
        $res = fgets ($fp, 1024);
        $res = trim($res);
        if (strcmp ($res, "VERIFIED") == 0) {
            if ($debug)
            {
                $ourFileName = "debug/debug4_verified.txt";
                $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                fclose($ourFileHandle);
            }

            if($payment_status == "Completed") {
                $ourFileName = "debug/debug_completed";
                $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                fclose($ourFileHandle);
            }

            if($payment_amount == $price)
            {
                $ourFileName = "debug/debug_price";
                $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                fclose($ourFileHandle);
            }

            if($payment_currency == "USD")
            {
                $ourFileName = "debug/debug_currency";
                $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                fclose($ourFileHandle);
            }

            if(checkTxnId($txnId) == 0) {
                $ourFileName = "debug/debug_txn";
                $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                fclose($ourFileHandle);
            }

            if(($payment_status == "Completed") && ($receiver_email == $email) && ($payment_amount == $price) && ($payment_currency == "USD") && (checkTxnId($txnId) == 0)) {
                addPaypalPayment($item_name, $item_number, $item_username, $item_userid, $item_email, $payment_status, $payment_amount, $payment_currency, $txnId, $receiver_email, $payer_email, '1');
                serviceAdd($item_userid, $item_number, getNumServices($item_userid));
                setServiceActive($item_userid, $item_packageid);
                sendEmailWithUsername("Carwash", "PayPal IPN", "Success!");
                if ($debug)
                {
                    $ourFileName = "debug/debug5_confirmedok.txt";
                    $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                    fclose($ourFileHandle);
                }
                sendEmailWithUsername($_SESSION["username"], "Your new VPN purchase", "You can gain access to your new VPN account by visiting <a href='https://bvpn.biz/manage.php?do=activate'>this</a> link.");
            }
            else
            {
                if ($debug)
                {
                    $ourFileName = "debug/debug6_confirmedok.txt";
                    $ourFileHandle = fopen($ourFileName, 'w') or die("can't open file");
                    fclose($ourFileHandle);
                }
                $mail_To = $email;
                $mail_Subject = "PayPal IPN status not completed or security check fail";
                $mail_Body = "Something wrong. \n\nThe transaction ID number is: $txn_id \n\n Payment status = $payment_status \n\n Payment amount = $payment_amount";
                mail($mail_To, $mail_Subject, $mail_Body);

            }
        }
        else if (strcmp ($res, "INVALID") == 0) {
            $mail_To = $email;
            $mail_Subject = "PayPal - Invalid IPN ";
            $mail_Body = "We have had an INVALID response. \n\nThe transaction ID number is: $txn_id \n\n username = $username";
            mail($mail_To, $mail_Subject, $mail_Body);
        }
    } //end of while
    fclose ($fp);
}
?>

ipn.config.php:

<?php
$url = "www.sandbox.paypal.com";
$email = "bking-facilitator@inbox.com";
?>

我已经为此苦苦挣扎了一段时间,并且真的需要我能得到的任何帮助。谢谢!

4

1 回答 1

0

我最近在将站点移动到新服务器时遇到了类似的问题,并且两者fopenfsockopen在新主机上不可用,也许您在这里遇到了同样的问题。

这是我现在使用的基于 CURL 的 IPN 类,也许你可以转换你的:https ://gist.github.com/thehelvetian/6098154

完整代码:

<?php
class PayPal_IPN {

    var $paypal_post_vars;
    var $paypal_response;
    var $error_email;
    var $sandbox;

    private $sandboxUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr";
    private $productionUrl = "https://www.paypal.com/cgi-bin/webscr";
    private $serviceUrl = NULL;

    function __construct( $sandbox = false ) {
        $this->sandbox = $sandbox;
        $this->send_response();
    }

    function send_response() {
        // STEP 1: Read POST data
        // reading posted data from directly from $_POST causes serialization 
        // issues with array data in POST
        // reading raw POST data from input stream instead. 
        $raw_post_data = file_get_contents('php://input');
        $raw_post_array = explode('&', $raw_post_data);
        $myPost = array();
        foreach ($raw_post_array as $keyval) {
            $keyval = explode ('=', $keyval);
            if (count($keyval) == 2) {
                $myPost[$keyval[0]] = urldecode($keyval[1]);
            }
        }
        $this->paypal_post_vars = $myPost;

        // read the post from PayPal system and add 'cmd'
        $req = 'cmd=_notify-validate';
        if(function_exists('get_magic_quotes_gpc')) {
            $get_magic_quotes_exists = true;
        }

        foreach ($myPost as $key => $value) {        
            if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 
                $value = urlencode(stripslashes($value)); 
            } else {
                $value = urlencode($value);
            }
            $req .= "&$key=$value";
        }

        // Set the service URL
        $this->serviceUrl = ($this->sandbox) ? $this->sandboxUrl : $this->productionUrl;

        // STEP 2: Post IPN data back to paypal to validate
        $ch = curl_init($this->serviceUrl);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

        // In wamp like environments that do not come bundled with root authority certificates,
        // please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path 
        // of the certificate as shown below.
        // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
        if( !($res = curl_exec($ch)) ) {
            $this->write_log("Got " . curl_error($ch) . " when processing IPN data");
            curl_close($ch);
            exit;
        }
        $this->paypal_response = $res;
        curl_close($ch);
    }

    function is_verified() {
        if (strcmp ($this->paypal_response, "VERIFIED") == 0) {
            return true;
        } else if (strcmp ($this->paypal_response, "INVALID") == 0) {
            return false;
        }
    }

    function get_payment_status() {
        return $this->paypal_post_vars['payment_status'];
    }

    function error_out($message, $em_headers) {
        $date = date("D M j G:i:s T Y", time());
        $message .= "\n\nThe following data was received from PayPal:\n\n";
        @reset($this->paypal_post_vars);
        while( @list($key,$value) = @each($this->paypal_post_vars)) {
            $message .= $key . ':' . " \t$value\n";
        }
        mail($this->error_email, "[$date] PayPal IPN Notification", $message, $em_headers);
    }

    function write_log($text) {
        $filename = "ipn.log";
        $fh = fopen($filename, "a") or die("Could not open log file.");
        fwrite($fh, date("Y-m-d H:i:s").": $text\r\n") or die("Could not write file!");
        fclose($fh);
    }
}
于 2013-07-28T10:29:46.407 回答