PayPal 捐赠的 IPN 监听器未被正确调用 PHP

问题描述 投票:0回答:0

我有一个 PayPal 捐赠 IPN 的监听器。然而,它没有被调用,PayPal 沙箱中也没有日志。代码是:
donations.php:

<?php
     // For test payments we want to enable the sandbox mode. If you want to put live
    // payments through then this setting needs changing to `false`.
    $enableSandbox = true;

    // Database settings. Change these for your database configuration.
    $dbConfig = [
        'host' => 'localhost',
        'username' => 'xxxx',
        'password' => 'xxxx',
        'name' => 'xxxx'
    ];

    // PayPal settings. Change these to your account details and the relevant URLs
    // for your site.
    $paypalConfig = [
        'email' => $enableSandbox ? '[email protected]' : '[email protected]',
        'return_url' => 'https://example.com/index.php?page=/donation-successful.php',
        'cancel_url' => 'https://example.com/index.php?page=/donation-cancelled.php',
        'notify_url' => 'https://example.com/donations.php',
    ];

    $paypalUrl = $enableSandbox ? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' : 'https://ipnpb.paypal.com/cgi-bin/webscr';

    function verifyTransaction($data) {
        global $paypalUrl;
        $req = 'cmd=_notify-validate';
        foreach ($data as $key => $value) {
            $value = urlencode(stripslashes($value));
            //$value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i', '${1}%0D%0A${3}', $value); // IPN fix
            $req .= "&$key=$value";
        }
        $ch = curl_init($paypalUrl);
        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_SSLVERSION, 6);
        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_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
        $res = curl_exec($ch);
        if (!$res) {
            $errno = curl_errno($ch);
            $errstr = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL error: [$errno] $errstr");
        }
        $info = curl_getinfo($ch);
        // Check the http response
        $httpCode = $info['http_code'];
        if ($httpCode != 200) {
            throw new Exception("PayPal responded with http code $httpCode");
        }
        curl_close($ch);
        return $res == 'VERIFIED';
    }
    
    function checkTxnid($txnid) {
        $db = new mysqli($dbConfig['host'], $dbConfig['username'], $dbConfig['password'], $dbConfig['name']);
        $txnid = $db->real_escape_string($txnid);
        $results = $db->query('SELECT * FROM `donations` WHERE txnid = \'' . $txnid . '\'');
        return ! $results->num_rows;
    }
    
    function addPayment($data) {
        $db = new mysqli($dbConfig['host'], $dbConfig['username'], $dbConfig['password'], $dbConfig['name']);
        if (is_array($data)) {
            if ($db->query("INSERT INTO 'donations' (txnid, payment_amount, payment_status, createdtime) VALUES('" . $data["txn_id"] . "', '" . $data["payment_amount"] . "', '" . $data["payment_status"] . "', '" . date("Y-m-d H:i:s") . "')")) {
                return true;
            }
        }
        return false;
    }

    // Check if paypal request or response
    // STEP 1: read POST data
    // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
    // Instead, read raw POST data from the input stream.
    $raw_post_data = file_get_contents('php://input');
    $raw_post_array = explode('&', $raw_post_data);
    $data = array();
    foreach ($raw_post_array as $keyval) {
        $keyval = explode ('=', $keyval);
        if (count($keyval) == 2) {
            $data[$keyval[0]] = urldecode($keyval[1]);
        }
    }
    if (!isset($data["txn_id"]) && !isset($data["txn_type"])) {
        // Set the PayPal account.
        $data['business'] = $paypalConfig['email'];
        // Set the PayPal return addresses.
        $data['return'] = stripslashes($paypalConfig['return_url']);
        $data['cancel_return'] = stripslashes($paypalConfig['cancel_url']);
        $data['notify_url'] = stripslashes($paypalConfig['notify_url']);
        // Set the currency so that these aren't overridden by the form data.
        $data['currency_code'] = 'GBP';
        // Build the query string from the data.
        $queryString = http_build_query($data);
        // Redirect to paypal IPN
        header('location:' . $paypalUrl . '?' . $queryString);
        exit();
    } else {
        // Handle the PayPal response.
        // Create a connection to the database.
        $db = new mysqli($dbConfig['host'], $dbConfig['username'], $dbConfig['password'], $dbConfig['name']);
        // We need to verify the transaction comes from PayPal and check we've not
        // already processed the transaction before adding the payment to our
        // database.
        if (verifyTransaction($data) && checkTxnid($data['txn_id'])) {
            // Assign posted variables to local data array.
            $data = [
                'item_name' => $data['item_name'],
                'item_number' => $data['item_number'],
                'payment_status' => $data['payment_status'],
                'payment_amount' => $data['mc_gross'],
                'payment_currency' => $data['mc_currency'],
                'txn_id' => $data['txn_id'],
                'receiver_email' => $data['receiver_email'],
                'payer_email' => $data['payer_email'],
            ];
            if (addPayment($data) !== false) {
                // Payment successfully added.
            }
        }
    }
?>

替换了一些地方的敏感信息,但你明白了。 PayPal 日志中没有任何内容。我的捐赠数据库中没有添加任何内容。付款在交易列表中显示为已完成。

php paypal paypal-ipn
© www.soinside.com 2019 - 2024. All rights reserved.