Paypal IPN,在更改帐户中的ipn url后没有收到所有交易响应

RAU*_*MAR 18 php mysql paypal paypal-ipn laravel-5

我正在我的项目中实现ipnlistner.我在我的paypal帐户中设置了ipn url.但我没有得到该网址的所有交易ipn响应.但是,当我在我的帐户中检查ipn历史记录时,它会显示已发送所有ipn.例如,昨天它显示了所有已发送的112个ipn.但我的数据库中只有7个.这是我的ipn listner代码.我只在第一行插入数据库中的所有数据.

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Response;

class PaypalIPN extends Controller {

private $use_sandbox = null;

const VALID = 'VERIFIED';

const INVALID = 'INVALID';

public function useSandbox() {
    $this->use_sandbox = env( 'USE_SANDBOX' );
}

public function getPaypalUri() {
    if ( $this->use_sandbox ) {
        return env( 'SANDBOX_VERIFY_URI' );
    } else {
        return env( 'VERIFY_URI' );
    }
}

public function verifyIPN() {
    try {
        DB::table( 'ipn_response' )->insert( [ 'data' => json_encode( $_POST, true ) ] );
        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";
        }

        // Use the sandbox endpoint during testing.
        $this->useSandbox();

        // 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 );
        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 ) {
            DB::table( 'ipn_response' )->insert( [ 'data' => json_encode( $res, true ) ] );
        } else {
            DB::table( 'ipn_response' )->insert( [ 'data' => json_encode( $res, true ) ] );
        }

        // Reply with an empty 200 response to indicate to paypal the IPN was received correctly.
        header( "HTTP/1.1 200 OK" );
    }catch (\Exception $e){
        DB::table( 'ipn_response' )->insert( [ 'data' => json_encode( ["Exception"=>$e->getMessage()]) ] );
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我在这个网址上非常关注IPN

https://ipnpb.paypal.com/cgi-bin/webscr

我的ipn网址是

https://www.myproject.com/api/verify-ipn

注意:之前我在这个帐户上创建了一些paypal按钮,我没有得到该按钮付款的ipn响应

请帮助或指导如何做到这一点..

smc*_*nes 3

听起来您的代码中可能有错误。需要进一步调试。当我遇到类似的事情时,我通常会检查错误日志以了解发生了什么。

PayPal 将继续尝试发送请求,直到收到200 OK正文中没有内容的 HTTP 状态响应。如果 PayPal 显示端点已成功接收,则数据库无法输入数据的位置可能就在header调用您的函数之前。

我的下一步调试步骤是尝试找出我的数据库插入是否由于某种数据完整性错误/警告而失败。

捕获数据库错误并触发某种未通过的响应可能会有所帮助,以便 PayPal 重新发送,直到您解决脚本问题。

还:

  • 尝试使用类似的方法添加额外的日志记录Monolog,甚至只是error_log为了了解脚本终止的位置或未按预期工作的情况。

我应该指出,我现在也在实现 PayPal IPN,但这个库很难使用。我用订阅者模式衍生出了自己的模式。它尚未准备好公开,但主要是为了将逻辑与验证分开,以实现更好的测试和可读性。