douji4223 2018-06-10 09:27
浏览 123

Paypal IPN总是返回INVALID - php

I've tried multiple different examples of IPN classes and every time paypal returns with INVALID in the IPN simulator.

End point: https://ipnpb.sandbox.paypal.com/cgi-bin/webscr

I've done some testing, and the data I'm returning to paypal looks the same. e.g.

What paypal is sending:

payment_type=echeck&payment_date=Sun%20Jun%2010%202018%2010%3A17%3A15%20GMT%2B0100%20%28GMT%20Summer%20Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer@paypalsandbox.com&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&business=seller@paypalsandbox.com&receiver_email=seller@paypalsandbox.com&receiver_id=seller@paypalsandbox.com&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=300182286&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=undefined

What I'm sending Paypal

cmd=_notify-validate&payment_type=echeck&payment_date=Sun%20Jun%2010%202018%2010%3A17%3A15%20GMT%2B0100%20%28GMT%20Summer%20Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer@paypalsandbox.com&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&business=seller@paypalsandbox.com&receiver_email=seller@paypalsandbox.com&receiver_id=seller@paypalsandbox.com&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=300182286&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=undefined

Paypal returned: 'INVALID'

The code I'm currently using is this:

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';

    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 = rawurlencode(stripslashes($value));
        } else {
            $value = rawurlencode($value);
        }
        // Added this line to see if it helps
        $value = str_replace('%40', '@', $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__ . "/cert/cacert.pem");
    }

    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'User-Agent: PHP-IPN-Verification-Script',
        'Connection: Close',
    ));

    $res = curl_exec($ch);

    if (!($res)) {
        file_put_contents("paypal-errors.txt", "error no: ".$errno($ch)." errorstr: ".curl_error($ch));
        $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) {
        file_put_contents("paypal-errors.txt", "error http status response = ".$http_code);
        throw new Exception("PayPal responded with http code $http_code");
    }

    curl_close($ch);
    file_put_contents("paypal-sent.txt", "response: ".file_get_contents('php://input'));
    file_put_contents("paypal-result.txt", "response: ".$res);

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

So at this point, I'm assuming there is something wrong with my environment. My server has TLS 1.2 and 1.3. I've ran out of ideas for troubleshooting. Any help would be greatly appreciated!

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 如何实验stm32主通道和互补通道独立输出
    • ¥30 这是哪个作者做的宝宝起名网站
    • ¥60 版本过低apk如何修改可以兼容新的安卓系统
    • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
    • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
    • ¥50 有数据,怎么用matlab求全要素生产率
    • ¥15 TI的insta-spin例程
    • ¥15 完成下列问题完成下列问题
    • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
    • ¥15 YoloV5 第三方库的版本对照问题