MySQL数据库中的IPN和数据输入问题

When I test my IPN handler, if I use the IPN Simulator from: https://developer.paypal.com/developer/ipnSimulator/ everything works fine.

Although, when I try to use the sandbox environment on my website: https://ipnpb.sandbox.paypal.com/cgi-bin/webscr nothing is inserted in the database.

I do see the entry processed successfully with the HTTP response code 200 from: https://www.sandbox.paypal.com/webscr?cmd=_display-ipns-history

I suppose that both must work differently, am I missing something?

When I use the sandbox environment, I never see an INSERT command in the MySQL logs either.

Here is the code for the listener:

<?php

class PaypalIPN
{

/**
 * @var bool $use_sandbox     Indicates if the sandbox endpoint is used.
 */
private $use_sandbox = false;
/**
 * @var bool $use_local_certs Indicates if the local certificates are used.
 */
private $use_local_certs = true;

/** Production Postback URL */
const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr';
/** Sandbox Postback URL */
const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';


/** Response from PayPal indicating validation was successful */
const VALID = 'VERIFIED';
/** Response from PayPal indicating validation failed */
const INVALID = 'INVALID';


/**
 * Sets the IPN verification to sandbox mode (for use when testing,
 * should not be enabled in production).
 * @return void
 */
public function useSandbox()
{
    $this->use_sandbox = true;
}

/**
 * Sets curl to use php curl's built in certs (may be required in some
 * environments).
 * @return void
 */
public function usePHPCerts()
{
    $this->use_local_certs = false;
}


/**
 * Determine endpoint to post the verification data to.
 * @return string
 */
public function getPaypalUri()
{
    if ($this->use_sandbox) {
        return self::SANDBOX_VERIFY_URI;
    } else {
        return self::VERIFY_URI;
    }
}


/**
 * Verification Function
 * Sends the incoming post data back to PayPal using the cURL library.
 *
 * @return bool
 * @throws Exception
 */
public function verifyIPN()
{
    if ( ! count($_POST)) {
        throw new Exception("Missing POST Data");
    }

    $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) {
            // Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it.
            if ($keyval[0] === 'payment_date') {
                if (substr_count($keyval[1], '+') === 1) {
                    $keyval[1] = str_replace('+', '%2B', $keyval[1]);
                }
            }
            $myPost[$keyval[0]] = urldecode($keyval[1]);
        }
    }

    // Build the body of the verification post request, adding the _notify-validate command.
    $req = 'cmd=_notify-validate';
    $get_magic_quotes_exists = false;
    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";
    }

    // Post the data back to PayPal, using curl. Throw exceptions if errors occur.
    $ch = curl_init($this->getPaypalUri());
    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);

    // This is often required if the server is missing a global cert bundle, or is using an outdated one.
    if ($this->use_local_certs) {
        curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "\\assets\\cert\\cacert.pem");
    }
    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);
    $http_code = $info['http_code'];
    if ($http_code != 200) {
        throw new Exception("PayPal responded with http code $http_code");
    }

    curl_close($ch);

    // Check if PayPal verifies the IPN data, and if so, return true.
    if ($res == self::VALID) {
        return true;
    } else {
        return false;
    }
}
}

Here is the code for the handler (I am using more variables than needed for testing purposes right now):

<?php require('PaypalIPN.php');
use PaypalIPN;
ipn = new PaypalIPN();
// Use the sandbox endpoint during testing.
$ipn->useSandbox();
$verified = $ipn->verifyIPN();
if ($verified) {
/*
 * Process IPN
 * A list of variables is available here:
 * https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/
 */

 /*

 ADD DATABASE COMMANDS HERE

 */

$payment_type = "";
$payment_date = "";
$payment_status = "";
$pending_reason = "";
$address_status = "";
$payer_status = "";
$first_name = "";
$last_name = "";
$payer_email = "";
$payer_id = "";
$address_name = "";
$address_country = "";
$address_country_code = "";
$address_zip = "";
$address_state = "";
$address_city = "";
$address_street = "";
$business = "";
$receiver_email = "";
$receiver_id = "";
$residence_country = "";
$item_name = "";
$item_name1 = "";
$item_number = "";
$item_number1 = "";
$quantity = "";
$shipping = "";
$tax = "";
$mc_currency = "";
$mc_fee = "";
$mc_gross = "";
$mc_gross_1 = "";
$mc_handling = "";
$mc_handling1 = "";
$mc_shipping = "";
$mc_shipping1 = "";
$txn_type = "";
$txn_id = "";
$notify_version = "";
$parent_txn_id = "";
$reason_code = "";
$receipt_ID = "";
$auction_buyer_id = "";
$auction_closing_date = "";
$for_auction = "";
$custom = "";
$invoice = "";
$protection_eligibility = "";
$charset = "";
$option_selection1 = "";
$subscr_id = "";
$verify_sign = "";
$option_name1 = "";
$btn_id = "";
$payment_fee = "";
$test_ipn = "";
$transaction_subject = "";
$payment_gross = "";
$ipn_track_id = "";

if (isset($_POST['payment_type']))
{
    $payment_type = $_POST['payment_type'];
}

    if (isset($_POST['payment_date']))
{
    $payment_date = $_POST['payment_date'];
}

    if (isset($_POST['payment_status']))
{
    $payment_status = $_POST['payment_status'];
}

    if (isset($_POST['pending_reason']))
{
    $pending_reason = $_POST['pending_reason'];
}

    if (isset($_POST['address_status']))
{
    $address_status = $_POST['address_status'];
}

    if (isset($_POST['payer_status']))
{
    $payer_status = $_POST['payer_status'];
}

    if (isset($_POST['first_name']))
{
    $first_name = $_POST['first_name'];
}

    if (isset($_POST['last_name']))
{
    $last_name = $_POST['last_name'];
}

    if (isset($_POST['payer_email']))
{
    $payer_email = $_POST['payer_email'];
}

    if (isset($_POST['payer_id']))
{
    $payer_id = $_POST['payer_id'];
}

    if (isset($_POST['address_name']))
{
    $address_name = $_POST['address_name'];
}

    if (isset($_POST['address_country']))
{
    $address_country = $_POST['address_country'];
}

    if (isset($_POST['address_country_code']))
{
    $address_country_code = $_POST['address_country_code'];
}

    if (isset($_POST['address_zip']))
{
    $address_zip = $_POST['address_zip'];
}

    if (isset($_POST['address_state']))
{
    $address_state = $_POST['address_state'];
}

    if (isset($_POST['address_city']))
{
    $address_city = $_POST['address_city'];
}

    if (isset($_POST['address_street']))
{
    $address_street = $_POST['address_street'];
}

    if (isset($_POST['business']))
{
    $business = $_POST['business'];
}

    if (isset($_POST['receiver_email']))
{
    $receiver_email = $_POST['receiver_email'];
}

    if (isset($_POST['receiver_id']))
{
    $receiver_id = $_POST['receiver_id'];
}
    if (isset($_POST['residence_country']))
{
    $residence_country = $_POST['residence_country'];
}
    if (isset($_POST['item_name']))
{
    $item_name = $_POST['item_name'];
}
    if (isset($_POST['item_name1']))
{
    $item_name1 = $_POST['item_name1'];
}
    if (isset($_POST['item_number']))
    {
    $item_number = $_POST['item_number'];
}
    if (isset($_POST['item_number1']))
{
    $item_number1 = $_POST['item_number1'];
}
    if (isset($_POST['quantity']))
{
    $quantity = $_POST['quantity'];
}
    if (isset($_POST['shipping']))
{
    $shipping = $_POST['shipping'];
}
    if (isset($_POST['tax']))
{
    $tax = $_POST['tax'];
}
    if (isset($_POST['mc_currency']))
{
    $mc_currency = $_POST['mc_currency'];
}
    if (isset($_POST['mc_fee']))
{
    $mc_fee = $_POST['mc_fee'];
}
    if (isset($_POST['mc_gross']))
{
    $mc_gross = $_POST['mc_gross'];
}
    if (isset($_POST['mc_gross_1']))
{
    $mc_gross_1 = $_POST['mc_gross_1'];
}
    if (isset($_POST['mc_handling']))
{
    $mc_handling = $_POST['mc_handling'];
}
    if (isset($_POST['mc_handling1']))
{
    $mc_handling1 = $_POST['mc_handling1'];
}
    if (isset($_POST['mc_shipping']))
{
    $mc_shipping = $_POST['mc_shipping'];
}
    if (isset($_POST['mc_shipping1']))
{
    $mc_shipping1 = $_POST['mc_shipping1'];
}
    if (isset($_POST['txn_type']))
{
    $txn_type = $_POST['txn_type'];
}
    if (isset($_POST['txn_id']))
{
    $txn_id = $_POST['txn_id'];
}
    if (isset($_POST['notify_version']))
{
    $notify_version = $_POST['notify_version'];
}
    if (isset($_POST['parent_txn_id']))
{
    $parent_txn_id = $_POST['parent_txn_id'];
}
    if (isset($_POST['reason_code']))
{
    $reason_code = $_POST['reason_code'];
}
    if (isset($_POST['receipt_ID']))
{
    $receipt_ID = $_POST['receipt_ID'];
}
    if (isset($_POST['auction_buyer_id']))
{
    $auction_buyer_id = $_POST['auction_buyer_id'];
}
    if (isset($_POST['auction_closing_date']))
{
    $auction_closing_date = $_POST['auction_closing_date'];
}
    if (isset($_POST['for_auction']))
{
    $for_auction = $_POST['for_auction'];
}
    if (isset($_POST['custom']))
{
    $custom = $_POST['custom'];
}
    if (isset($_POST['invoice']))
{
    $invoice = $_POST['invoice'];
}
    if (isset($_POST['protection_eligibility']))
{
    $protection_eligibility = $_POST['protection_eligibility'];
}
    if (isset($_POST['charset']))
{
    $charset = $_POST['charset'];
}
    if (isset($_POST['option_selection1']))
{
    $option_selection1 = $_POST['option_selection1'];
}
    if (isset($_POST['subscr_id']))
{
    $subscr_id = $_POST['subscr_id'];
}
    if (isset($_POST['verify_sign']))
{
    $verify_sign = $_POST['verify_sign'];
}
    if (isset($_POST['option_name1']))
{
    $option_name1 = $_POST['option_name1'];
}
    if (isset($_POST['btn_id']))
{
    $btn_id = $_POST['btn_id'];
}
    if (isset($_POST['payment_fee']))
{
    $payment_fee = $_POST['payment_fee'];
}
    if (isset($_POST['test_ipn']))
{
    $test_ipn = $_POST['test_ipn'];
}
    if (isset($_POST['transaction_subject']))
{
    $transaction_subject = $_POST['transaction_subject'];
}
    if (isset($_POST['payment_gross']))
{
    $payment_gross = $_POST['payment_gross'];
}
    if (isset($_POST['ipn_track_id']))
{
    $ipn_track_id = $_POST['ipn_track_id'];
}

$servername = "REDACTED";
$username = "REDACTED";
$password = "REDACTED";
$dbname = "REDACTED";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = 
"INSERT INTO paypal (payment_type,payment_date,payment_status,pending_reason,address_status,payer_status,first_name,last_name,payer_email,payer_id,address_name,address_country,address_country_code,address_zip,address_state,address_city,address_street,business,receiver_email,receiver_id,residence_country,item_name,item_name1,item_number,item_number1,quantity,shipping,tax,mc_currency,mc_fee,mc_gross,mc_gross_1,mc_handling,mc_handling1,mc_shipping,mc_shipping1,txn_type,txn_id,notify_version,parent_txn_id,reason_code,receipt_ID,auction_buyer_id,auction_closing_date,for_auction,custom,invoice,protection_eligibility,charset,option_selection1,subscr_id,verify_sign,option_name1,btn_id,payment_fee,test_ipn,transaction_subject,payment_gross,ipn_track_id)
VALUES
(
'" . $payment_type . "',
'" . $payment_date . "',
'" . $payment_status . "',
'" . $pending_reason . "',
'" . $address_status . "',
'" . $payer_status . "',
'" . $first_name . "',
'" . $last_name . "',
'" . $payer_email . "',
'" . $payer_id . "',
'" . $address_name . "',
'" . $address_country . "',
'" . $address_country_code . "',
'" . $address_zip . "',
'" . $address_state . "',
'" . $address_city . "',
'" . $address_street . "',
'" . $business . "',
'" . $receiver_email . "',
'" . $receiver_id . "',
'" . $residence_country . "',
'" . $item_name . "',
'" . $item_name1 . "',
'" . $item_number . "',
'" . $item_number1 . "',
'" . $quantity . "',
'" . $shipping . "',
'" . $tax . "',
'" . $mc_currency . "',
'" . $mc_fee . "',
'" . $mc_gross . "',
'" . $mc_gross_1 . "',
'" . $mc_handling . "',
'" . $mc_handling1 . "',
'" . $mc_shipping . "',
'" . $mc_shipping1 . "',
'" . $txn_type . "',
'" . $txn_id . "',
'" . $notify_version . "',
'" . $parent_txn_id . "',
'" . $reason_code . "',
'" . $receipt_ID . "',
'" . $auction_buyer_id . "',
'" . $auction_closing_date . "',
'" . $for_auction . "',
'" . $custom . "',
'" . $invoice . "',
'" . $protection_eligibility . "',
'" . $charset . "',
'" . $option_selection1 . "',
'" . $subscr_id . "',
'" . $verify_sign . "',
'" . $option_name1 . "',
'" . $btn_id . "',
'" . $payment_fee . "',
'" . $test_ipn . "',
'" . $transaction_subject . "',
'" . $payment_gross . "',
'" . $ipn_track_id . "'
)";

if ($conn->query($sql) === TRUE) {
    echo "New record created successfully";
} else {
    echo "Error: " . $sql . "<br>" . $conn->error;
}

$conn->close();
}
// Reply with an empty 200 response to indicate to paypal the IPN was received correctly.
header("HTTP/1.1 200 OK");?>

Reference: This is the source of the code I used to set up my IPN: https://github.com/paypal/ipn-code-samples

Thank you for your time and help, it is greatly appreciated.