本文介绍了Paypal IPN,更改帐户中的ipn网址后未获得所有交易响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am implementing ipnlistner inside my project. I set the ipn url inside my paypal account. But i am not getting all the transaction ipn responses to that url. But when i am checking ipn history in my account it displays that all the ipn has been sent. For example yesterday it is showing all 112 ipn had sent. but i am getting only 7 in my db. Here is my code for ipn listner. I am inserting all the data i am getting in the db at the first line only.

<?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()]) ] );
    }
}
}

我正在此网址上使用IPN

I am veryfying IPN on this url

我的IPN网址是

注意:以前,我在此帐户上创建了一些Paypal按钮,但没有收到该按钮付款的ipn响应

Note: previously i created some paypal buttons on this account, i am not getting the ipn responses for that button payments

请帮助或指导如何做.

推荐答案

听起来您的代码中可能有错误.进一步的调试将是必要的.当我遇到类似问题时,通常会检查错误日志以查看发生了什么情况.

It sounds like there may be an error in your code. Further debugging would be necessary. When I run into something like this I usually check the error logs to see what's going on.

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

PayPal will keep trying to send requests until it receives a 200 OK HTTP status response with no content in the body. If PayPal is showing successful receipt by the endpoint, then the place where the database is failing to enter data is probably just before your header function is being called.

下一步我要调试的方法是尝试确定数据库插入是否由于某种数据完整性错误/警告而失败.

My next move to debug would be to try to figure out if my database inserts were failing due to some kind of data integrity error/warning.

捕获数据库错误并触发某种非通过响应可能会有所帮助,因此PayPal会重新发送,直到您找出脚本问题为止.

It might be helpful to catch DB errors and trigger some kind of non-passing response so PayPal resends until you've figured out the scripting problem.

也:

  • 尝试使用诸如Monolog或什至只是error_log之类的方式添加其他日志记录,以到达脚本终止或无法正常工作的地方的底部.
  • Try to add additional logging using something like Monolog or even just error_log to get to the bottom of where your script is terminating or what is not working as expected.

我应该注意,我现在也正在实现PayPal IPN,并且该库很难使用.我用订户模式自行创建.它尚未准备好公开发布,但主要是为了从逻辑上将逻辑与验证分离开来,以实现更好的测试和可读性.

I should note that I'm implementing PayPal IPN right now too and this library was difficult to use. I spun out my own with a subscriber pattern. It's not ready to go public yet but it was largely to separate out logic from verification for better testing and readability.

这篇关于Paypal IPN,更改帐户中的ipn网址后未获得所有交易响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 08:00