PayPal/IPN

Overview
Instant Payment Notification (IPN) is one of two methods by which a web site may retrieve payment information, in real time (i.e. immediately after the payment is completed), resulting from a transaction conducted on PayPal's web site. The other method is Payment Data Transfer (PDT).

IPN is somewhat more reliable than PDT in that PayPal's server contacts the merchant's server directly to transmit transaction data as soon as the transaction has occurred, rather than depending on the customer's browser to convey the data.

Pages

 * /example

Links

 * Order Integration: IPN
 * sample code
 * how it works (login required)

Authentication
In order to prevent spoofing of an IPN, i.e. determine that it definitely comes from PayPal rather than from a third party trying to fool your system into believing a payment has been made, each IPN should be authenticated before being trusted. The process works like this:
 * PayPal generates a verify_sign code, and includes it with the IPN data
 * Your server sends return post back to PayPal which includes the verify_sign data
 * PayPal checks that this is the verify_sign it sent, and returns a code to let you know the result of the check

According to the Order Management Integration Guide (OMIG), "The value of verify_sign is an encrypted string used to validate the authenticity of the transaction." The idea appears to be that this is a random string whose value is stored by PayPal at the time of generation; only PayPal knows what value is associated with each transaction, making it essentially impossible for a spoofer to generate a "valid" verify_sign value.

Your server's return post back to PayPal ensures that PayPal is actually in the loop during this process.

Some sample values of verify_sign: AiPC9BjkCyDFQXbSkoZcgqH3hpacAM9KNT3jv0YPjZMPbrIcmvcIcLHa A7dSYdSlxg1gCvXiSPGpzFCXqlPvAIpupa..c7qIy0mlpCpNahyX5eL7 A1.T9PIMhr2k3PSwkHkiKBR19G59AqQHhQC02ybe8q549oTKvY0Bbhlh

Tentatively, it looks like a modulo-64 (upper & lowercase alpha, numerics, period = 26+26+10+1=63; presumably there's another punctuation character to make it a nice, round 64) encoded integer; with 56 digits, that means 6456 (over 10101) possible values.