2
votes

I know this question has been asked heaps, but I've been through all the answers that I can find and none have helped; many are years old, so I'm not sure if that's part of the problem.

I've been testing a paypal IPN listener by sending an IPN through Sandbox. It states that the IPN has been sent and the handshake verified, but the status that is returned to the listener is always invalid. I've tried several different examples, but none work. I've stripped my code right back, just logging the input text, the output text, the verification status from paypal and the http status code:

<?php

define("LOG_FILE", "./ipn.log");
define("DEBUG", 0);
define("USE_SANDBOX", 1); //for testing

//get raw input
$stream_input = file_get_contents('php://input');
error_log(date('[Y-m-d H:i e] '). $stream_input. PHP_EOL, 3, LOG_FILE); //log result for comparison to return string

//choose correct URL
if(USE_SANDBOX == 1) {
    $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
    $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}

// add cmd for return request
$return_string = 'cmd=_notify-validate&' . $stream_input;
error_log(date('[Y-m-d H:i e] '). $return_string. PHP_EOL, 3, LOG_FILE); //log result for comparison

//cURL setup
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
    return FALSE;
}
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, $return_string);
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'));
$verification_status = curl_exec($ch);
$http_status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);

//log result
error_log(date('[Y-m-d H:i e] '). $verification_status . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). $http_status . PHP_EOL, 3, LOG_FILE);

//log cURL errors
if (curl_errno($ch) != 0) // cURL error
    {
    if(DEBUG == true) { 
        error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
    }
    curl_close($ch);
    exit;
} else {
        // Log the entire HTTP response if debug is switched on.
        if(DEBUG == true) {
            error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $return_array" . PHP_EOL, 3, LOG_FILE);
            error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $verification_status" . PHP_EOL, 3, LOG_FILE);
        }
        curl_close($ch);
}
?>

And this is the output I get in the log:

[2016-06-20 03:52 America/New_York] payment_type=instant&payment_date=Mon%20Jun%2020%202016%2017%3A50%3A12%20GMT+1000%20%28AUS%20Eastern%20Standard%20Time%29&payment_status=Canceled_Reversal&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&[email protected]&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&[email protected]&[email protected]&[email protected]&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=146655022&notify_version=2.1&parent_txn_id=SOMEPRIORTXNID003&reason_code=other&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AXwY9QNq9ZSeZMzEi6Nyk68hdvbc
[2016-06-20 03:52 America/New_York] cmd=_notify-validate&payment_type=instant&payment_date=Mon%20Jun%2020%202016%2017%3A50%3A12%20GMT+1000%20%28AUS%20Eastern%20Standard%20Time%29&payment_status=Canceled_Reversal&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&[email protected]&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&[email protected]&[email protected]&[email protected]&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=146655022&notify_version=2.1&parent_txn_id=SOMEPRIORTXNID003&reason_code=other&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AXwY9QNq9ZSeZMzEi6Nyk68hdvbc
[2016-06-20 03:52 America/New_York] INVALID
[2016-06-20 03:52 America/New_York] 200

I've tested the input and output strings against each other, and they are identical except for the 'cmd=_notify-validate&' at the start of the output string. I have tried sending the output back as an array using urlencode as most of the examples do, but no luck there either.

Please, what am I missing?

1
Its not you. Its them. The code is fine.Rodrigo M
Ah, cool. Was driving me crazy yesterday. Thanks mate.Elenchus

1 Answers

1
votes

I've had the exact same problem. It seems to be an error in the IPN simulator and any date fields. The encoding seems to be all messed up which means when you try and post the data back to verify it, PayPal thinks the message isn't the same.

Clear all the date fields and it should then work.