mike182uk / paypal-ipn-listener

A PayPal IPN (Instant Payment Notification) listener for PHP
MIT License
89 stars 31 forks source link

ipn listener not verifying #18

Closed Bulmer closed 9 years ago

Bulmer commented 9 years ago

I am using the current version, but had used the older version for some time without issues. Its probably just that I have been trying to track this problem (and am tired) and have come up against a brick wall. The ipns are being sent, returning a http200 and the code is being logged into $listener->onVerified but Paypal isn't getting a response that its gone through. Any idea how to proceed with debugging this further would be greatly appeciated as this is on a live site. Cheers.

mike182uk commented 9 years ago

If onVerified is being called, then this means that the IPN listener is getting back a verified response from PayPal.

Im not sure what you mean by Paypal isn't getting a response that its gone through?

Can you give a little more detail?

Bulmer commented 9 years ago

Thanks for responding Mike. What I mean is that I do get a verification coming through but Paypal just keeps sending them again and again. This is the basic layout. I can't pick any faults in it. Also I realised that i'm actually using version 3 instead of the current version 4.

<?php
use Mdb\PayPal\Ipn\Event\MessageInvalidEvent;
use Mdb\PayPal\Ipn\Event\MessageVerificationFailureEvent;
use Mdb\PayPal\Ipn\Event\MessageVerifiedEvent;
use Mdb\PayPal\Ipn\ListenerBuilder\Guzzle\InputStreamListenerBuilder as ListenerBuilder;

class PaypalController extends Controller
{
    public function postIpnListener()
    {
        $listenerBuilder = new ListenerBuilder();
        $listener = $listenerBuilder->build();

        $listener->onInvalid(function (MessageInvalidEvent $event) {
            $ipnMessage = $event->getMessage();
        //do stuff
        });
        $listener->onVerified(function (MessageVerifiedEvent $event) {
            $ipnMessage = $event->getMessage();
                //do stuff
        });
        $listener->onVerificationFailure(function (MessageVerificationFailureEvent $event) {
        $error = $event->getError();
        //do stuff
        });
        $listener->listen();
    }
}
mike182uk commented 9 years ago

It is normal for PayPal to resend the IPN message multiple times. From the docs:

The IPN message authentication protocol consists of four steps:

  • PayPal HTTP POSTs an IPN message to your listener that notifies it of an event.
  • Your listener returns an empty HTTP 200 response to PayPal.
  • Your listener HTTP POSTs the complete, unaltered message back to PayPal; the message must contain the same fields (in the same order) as the original message and be encoded in the same way as the original message.
  • PayPal sends a single word back - either VERIFIED (if the message matches the original) or INVALID (if the message does not match the original).

Your listener must respond to every IPN message it gets, whether you take action on it or not. If you do not respond, PayPal assumes the IPN was not received and re-sends it. Further, PayPal continues to re-send the message periodically until your listener responds, although the interval between retries increases with each attempt. An IPN will be resent for up to four days, with a maximum of 15 retries.

This resend algorithm can lead to situations in which PayPal re-sends an IPN message at the same time you are sending back the original message. In this case, you should send your response again, to address the possibility that PayPal did not receive your first response. You must also ensure that you do not process the transaction associated with an IPN message twice.

If the logic in your onVerified method is being executed that means everything is ok. My library will take care of steps 3, 4 but its up to you to make sure the URL PayPal sends the IPN message too should return a http 200 status.

Bulmer commented 9 years ago

Its seems to be returning a 200 status from apaches ssl_access log, over and over: 173.0.81.1 - - [29/Jul/2015:22:03:22 +1000] "POST /paypal/ipn-listener HTTP/1.0" 200 4030 "-" "PayPal IPN ( https://www.paypal.com/ipn )" 173.0.81.1 - - [29/Jul/2015:22:04:25 +1000] "POST /paypal/ipn-listener HTTP/1.0" 200 4077 "-" "PayPal IPN ( https://www.paypal.com/ipn )" ............ i'll have a fresh look at it in the morning...

Bulmer commented 9 years ago

Ok, i'm getting somewhere now.... I tried using http instead of https and it has worked. It had something to do with Paypals negotiation of my sites SSL certificates. Not an uncommon problem with Paypal....