Lately I’ve been implementing Instant Payment Notification - great feature provided by PayPal. To be honest it cost me quite some time and a little bit of my dignity. I mean you can read the official guide and play with Instant Payment Notification (IPN) simulator - but in the end it’s back to trials and errors.

So here we go, here are some tips for you, I hope you will find them useful and it will save you some time.

  1. When you receive an IPN notification you obviously have to send it back to paypal for verification (with additional cmd=_notify-validate option), don’t forget to escape parameters while you do that (it may depend how you send it, but URI.escape may be your friend).

  2. You may receive txn_type you didn’t expect, here a (incomplete) list of possible variables: subscr_signup, subscr_modify, subscr_failed, subscr_cancel, subscr_payment, subscr_eot, recurring_payment_profile_created, recurring_payment_profile_cancel, recurring_payment_failed, recurring_payment_outstanding_payment_failed, recurring_payment, recurring_payment_skipped, recurring_payment_expired, recurring_payment_suspended_due_to_max_failed_payment

  3. What’s more interesting (so to speak) is that you may receive different parameters depending on txn_type - for example if you get subscr_ you can identify your buyer with subscr_id. On the other hand if you get a recurring_payment_ you will have to use recurring_payment_id. There are more differences but you will have to debug it yourself - this is just a heads up.

  4. PayPal tends to return a time in some messed up format (like 01:00:00 Jan 11, 2013 PST) that can’t be parsed using regular Time.parse method, instead you have to write your own parser:

    def paypal_time(time)
    DateTime.strptime(time, "%H:%M:%S %b %e, %Y %Z")
    # you may also want to convert it back to UTC using .utc on in

And thats four simple tips that can save A LOT of time.