How to process Instant Payment Notification (IPN) messages
Last updated: Sept 18th, 6:39pm
IPN is a message service that sends you a notification when any type of transaction occurs in your account. The messages are received and processed by your server(s).
Process overview
To receive and process Instant Payment Notification (IPN) messages:
- Create an IPN listener to receive and process the IPN messages sent by PayPal. For complete details on creating an IPN listener, see Implementing an IPN Listener.
- In your PayPal merchant account settings, enable the IPN Message Service and specify the URL of your listener.
- Continuously run the IPN listener on the website specified by your listener URL.
Do it
To receive and process IPN messages:
-
Create a listener that:
- Receives an IPN message sent from PayPal
- Confirms to PayPal that the message was received
- Verifies that it is a valid IPN message using the request-response handshaking required by PayPal
- Processes the IPN messages according to your needs
To create a basic listener that echoes IPN messages to a browser window:
-
Capture the IPN messages that PayPal sends to your listener
After receiving an IPN message from PayPal, you must respond to PayPal with a
POST
message that is an exact copy of the received message but with "cmd=_notify-validate
" added to the end of the message. Append to your message a duplicate of the notification received (the same IPN fields and values in the exact order you received them):1<?php2// STEP 1: read POST data3// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.4// Instead, read raw POST data from the input stream.5$raw_post_data = file_get_contents('php://input');6$raw_post_array = explode('&', $raw_post_data);7$myPost = array();8foreach ($raw_post_array as $keyval) {9 $keyval = explode ('=', $keyval);10 if (count($keyval) == 2)11 $myPost[$keyval[0]] = urldecode($keyval[1]);12}13// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'14$req = 'cmd=_notify-validate';15if (function_exists('get_magic_quotes_gpc')) {16 $get_magic_quotes_exists = true;17}18foreach ($myPost as $key => $value) {19 if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {20 $value = urlencode(stripslashes($value));21 } else {22 $value = urlencode($value);23 }24 $req .= "&$key=$value";25}2627// Step 2: POST IPN data back to PayPal to validate28$ch = curl_init('https://ipnpb.paypal.com/cgi-bin/webscr');29curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);30curl_setopt($ch, CURLOPT_POST, 1);31curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);32curl_setopt($ch, CURLOPT_POSTFIELDS, $req);33curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);34curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);35curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);36curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));37// In wamp-like environments that do not come bundled with root authority certificates,38// please download 'cacert.pem' from "https://curl.haxx.se/docs/caextract.html" and set39// the directory path of the certificate as shown below:40// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');41if ( !($res = curl_exec($ch)) ) {42 // error_log("Got " . curl_error($ch) . " when processing IPN data");43 curl_close($ch);44 exit;45}46curl_close($ch);When PayPal receives your POST message, it sends a message back to your listener to indicate the validity of the initial notification. PayPal's message has an HTTP status code of
200
and a body that contains eitherVERIFIED
orINVALID
. -
Before processing the IPN message, ensure that the message is valid as follows:
1<?php2// inspect IPN validation result and act accordingly3if (strcmp ($res, "VERIFIED") == 0) {4 // The IPN is verified, process it5} else if (strcmp ($res, "INVALID") == 0) {6 // IPN invalid, log for manual investigation7}8?> -
Parse the message for information on the transaction referenced by the IPN, the type of notification sent, and the associated transaction status. Take the appropriate action(s) based on the notification received:
1<?php2// inspect IPN validation result and act accordingly3if (strcmp ($res, "VERIFIED") == 0) {4 // The IPN is verified, process it:5 // check whether the payment_status is Completed6 // check that txn_id has not been previously processed7 // check that receiver_email is your Primary PayPal email8 // check that payment_amount/payment_currency are correct9 // process the notification10 // assign posted variables to local variables11 $item_name = $_POST['item_name'];12 $item_number = $_POST['item_number'];13 $payment_status = $_POST['payment_status'];14 $payment_amount = $_POST['mc_gross'];15 $payment_currency = $_POST['mc_currency'];16 $txn_id = $_POST['txn_id'];17 $receiver_email = $_POST['receiver_email'];18 $payer_email = $_POST['payer_email'];19 // IPN message values depend upon the type of notification sent.20 // To loop through the &_POST array and print the NV pairs to the screen:21 foreach($_POST as $key => $value) {22 echo $key . " = " . $value . "<br />";23 }24} else if (strcmp ($res, "INVALID") == 0) {25 // IPN invalid, log for manual investigation26 echo "The response from IPN was: <b>" .$res ."</b>";27}28?>
-
Log in to your PayPal business account and specify the Notification URL to your IPN listener. For detailed instructions about how to specify the Notification URL, see Identifying your IPN listener to PayPal. As an example, the web server where you host a PHP listener might resemble the following URL:
1https://example.com/ipnListener/ipn-Listener.phpIn addition to enabling the IPN service and setting the Notification URL location through your PayPal account, you can also set the location using the
NOTIFYURL
parameter in an API call. By dynamically setting the Notification URL, you can set up different listeners for different needs (such as if you are supporting different merchant sites with a single PayPal account). -
Run your listener on a server that hosts the URL you specified as your Notification URL in Step 1.
Your listener must always be accessible at the specified website—PayPal can send notifications at any time of day.
Learn more
PayPal sends IPN messages for every type of transaction or transaction status update (including payment and subscription notifications), and each notification type contains a unique set of fields. You need to configure your listener to handle the fields for every type of IPN message you might receive, depending on the types of PayPal transactions you support. For a complete guide on the different types of IPN messages and the data fields associated with each type, see the IPN Integration Guide.
Consider the following processes in your notification handler to properly direct the notifications and to guard against fraud:
- Use the Transaction ID value to ensure you haven't already processed the notification.
-
Confirm the status of the transaction, and take proper action depending on
value. For example, payment response options include
Completed
,Pending
, andDenied
. Don't send inventory unless the transaction has completed! - Validate the e-mail address of the receiver.
- Verify the item description and transaction costs with those listed on your website and catalog.
-
Use the values of
txn_type
orreason_code
of a VERIFIED notification to determine your processing actions.