++ed by:

1 PAUSE user

Andre Walker


Business::CPI::Gateway::PayPal::IPN - Instant Payment Notifications


version 0.902


    my $ipn = Business::CPI::Gateway::PayPal::IPN->new(
        # this could be $ctx->req if in Catalyst, for example
        query => $req,

        # defaults to the main server, but could be changed to sandbox or
        # something else
        gateway_url => 'https://www.sandbox.paypal.com/cgi-bin/webscr',

    if ($ipn->is_valid) {
        my %vars = %{ $ipn->vars };

        if ($vars{payment_status} eq 'Canceled_Reversal') {
            # ...


This is a rewrite of Business::PayPal::IPN. It works somewhat similar to it, and shares almost none of the same code.

But why? Software rewriting is bad!

Well, yes, it is usually a bad idea to rewrite software. But the old module had no updates for about 10 years, and, while it worked fine and was well written, Perl has grown a lot in the last 10 years. As I improved my PayPal interface for CPI, I decided I might want to add new features to the IPN module in a near future. As the code was reasonably small, I rewrote it using Moo. This means it's still pretty fast, and much more readable and extensible. Also, the original module had no tests. (Even though it was proven to work due to being used in production.)

How is it different from the original module?

It has only attributes, no methods. This gives free caching, and lazy loading. It has less than one third the size (counting blank lines, but not pod). It uses Moo, and has a much more readable code. It has real tests, and the small code makes it easier to find mistakes. I removed some methods like completed, so now you have to check: $ipn->vars->{payment_status} eq 'Completed'. There are many more possible payment status in PayPal than what the old module expected (it implemented version 1.5, while at the time of this writing, PayPal's IPN is in version 3.7; so a lot has changed). So I think those auxiliary methods like completed, pending, etc, are not too useful.

It's also lazy. Instantiating the object won't try to parse the request. Instead, it waits for you to ask for the variables, or ask if the request is valid. See the "SYNOPSIS" for more information.



Set this attribute in the constructor in case you want a different server than PayPal's default, such as a test server, or even PayPal's sandbox.


A CGI-compatible object (e.g. Catalyst::Request).


The variables provided by PayPal. Contrary to Business::PayPal::IPN, this returns a HashRef.


Checks with PayPal that the request was really generated by them. Returns true if PayPal validates, otherwise false.


The name of the user agent to post to PayPal.


Defaults to a LWP::UserAgent object, but can be a custom object provided for testing purposes, or by the users preference. Could be Mojo::UserAgent, for example.


The response from PayPal when validating.




Sherzod B. Ruzmetov <sherzodr@cpan.org> for creating Business::PayPal::IPN.


André Walker <andre@andrewalker.net>


Renato CRON <rentocron@cpan.org>


This software is copyright (c) 2013 by André Walker.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.