# Introducing IPN (/api/nvp-soap/ipn/IPNIntro)

Introduction to Instant Payment Notification (IPN), a message service that notifies you of events related to PayPal transactions



> **Note:** **Important:** NVP/SOAP is a legacy integration method. We
> accept new integrations and support existing integrations, but there are
> newer solutions. If you're starting an integration,
> [we recommend our latest solutions](/).

Instant Payment Notification (IPN) is a message service that notifies you of
events related to PayPal transactions. You can use IPN messages to automate
back-office and administrative functions, such as fulfilling orders, tracking
customers, or providing status and other transaction-related information.

* [IPN Overview](#ipn-overview)

* [IPN Protocol and Architecture](#ipn-protocol-and-architecture)

* [A Sample IPN Message and Response](#a-sample-ipn-message-and-response)

* [Non-IPN Notification Mechanisms](#non-ipn-notification-mechanisms)

## IPN Overview [#ipn-overview]

The IPN service triggers a notification when an event occurs that pertains to
a transaction. Typically, these events represent various kinds of payments;
however, the events may also represent authorizations, Fraud Management Filter
actions and other actions, such as refunds, disputes, and chargebacks. The
notifications are sent to a listener page on your server which receives the
messages and performs backend processing based on the message content.

IPN is a message service that PayPal uses to send notifications about specific
events, such as:

* Instant payments, including Express Checkout, direct credit card payments
  and authorizations (transaction payments that are authorized but have not
  yet been collected)

* eCheck payments and associated status, such as *pending*,
  *completed*, or *denied*, and payments pending for other
  reasons, such as those being reviewed for potential fraud

* Recurring payment and subscription actions

* Chargebacks, disputes, reversals, and refunds associated with a transaction

In many cases, the action that triggers an IPN event is a user-action on your
website. However, other actions can trigger IPNs. For example, your site's
back-office process might invoke a PayPal API that refunds a payment, or a
customer might notify PayPal of a disputed charge.

You receive and process IPN messages with a *listener* (sometimes
called a handler). This listener is basically a web page or web
application that you create on your server that is always active and had code
that allows it to accept and verify IPN messages sent from PayPal, and then
invoke backend services on your server, based on the information from the IPN
message. The web application waits for IPNs and (typically) passes them to an
administrative process that responds appropriately. PayPal provides sample
code that can be modified to implement a listener that handles the IPN sent
from messages PayPal. For details, see
[Implementing an IPN listener](/api/nvp-soap/ipn/IPNImplementation/).

The action to take when your listener is notified of an event is
application-specific. Here are some common actions applications take in
response to IPN messages:

* Trigger order fulfillment

* Enable an online service or media download that was purchased

* Update a list of customers

* Update accounting records

* Create specialized "to do" lists

In addition to IPN messages, you are notified of events by email. However,
unlike email, IPN messages allow you to *automate* responses to events.
The diagram below shows various events that can occur and how PayPal responds
by sending IPN messages to your listener.

![IPN,Overview](https://www.paypalobjects.com/webstatic/en_US/developer/docs/ipn/IPN_overview.gif)

The diagram shows requests and responses, which are the result of processing
button clicks or API operations at PayPal. PayPal sends an IPN message when it
sends a response to a request. However, the IPN message is not actually part
of the response sent to your website. Rather, the IPN message is sent to the
your listener. This feature lets you take actions that are not directly tied
to the operation of your website.

> **Note:** **Note:** The diagram does not show the IPN authentication
> protocol that a listener must implement to validate an IPN message. This
> protocol is discussed in detail below.

IPN is an asynchronous message service, meaning that IPNs are not synchronized
with actions on your website. Thus, listening for an IPN message does not
increase the time required to complete a transaction on your website.

The IPN message service does not assume that your listener will receive all
IPN messages. Because the Internet is not 100% reliable, IPNs can get lost or
be delayed. To address these issues, the IPN message service includes a retry
mechanism that re-sends a message at various intervals until your listener
acknowledges receipt. An IPN message may be present up to four days after the
original was sent. The maximum number of retries is 15.

> **Note:** **Note:** Although the Internet may be at fault, the most
> likely cause of lost, delayed, or duplicate IPN messages is faulty logic in
> the listener itself.

Because IPN messages can arrive at any time, your listener should always be
available; however, the IPN retry mechanism handles the case in which your
listener is down temporarily.

The IPN message service is *not* a real-time service. As a result, your
listener may not receive an IPN message for many seconds after an event
occurs. As a result, your checkout flow should not depend upon receiving an
IPN message to complete. If it does, your checkout flow will be slow during
periods of heavy system load and complicated, since it must handle retries.

## IPN Protocol and Architecture [#ipn-protocol-and-architecture]

The IPN message service is designed to be secure, reliable, and asynchronous.
To meet these requirements, the protocol requires that you acknowledge receipt
of IPN messages. The IPN service provides a retry mechanism to handle cases in
which a message is not acknowledged, e.g., when a transmit or receive failure
occurs.

If you enable the IPN service, PayPal sends messages to the IPN listener at
the URL you specify in your account profile. If you want, you can override
this URL in order to associate a different IPN listener with a specific
transaction. To do this, you can either:

* Specify the URL of a different listener in your definition of a PayPal
  Payment Standard button
  *or*

* Pass the URL of a different listener to a call of a PayPal API operation

The IPN message authentication protocol consists of four steps:

1. PayPal HTTPS POSTs an
   IPN message to your listener that notifies it of an event.

2. Your listener returns an empty HTTP 200
   response to PayPal.

3. Your listener HTTPS
   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.

4. 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.

> **Note:** **Important:**
>
> * Every IPN message you receive from PayPal includes a User-Agent HTTPS
>   request header whose value is
>   `PayPal IPN ( https://www.paypal.com/ipn )&#x60;. Do
>   &#x2A;**not**&#x2A; use this header to verify that an IPN really
>   came from PayPal and has not been tampered with. Rather, to verify these
>   things, you &#x2A;**must*** use the IPN authentication
>   protocol outlined above.
>
> * PayPal expects to receive a response to an IPN message within 30 seconds.
>   Consequently, your listener must not perform time-consuming operations
>   (such as updating a database) before responding to an IPN.

After PayPal verifies an IPN, your listener or administrative software should
make these additional checks:

* Verify that you are the intended recipient of the IPN message. To do this,
  check the email address in the message. This check prevents another
  merchant from accidentally or intentionally using your listener.

* Verify that the IPN is not a duplicate. To do this, save the transaction
  ID and last payment status in each IPN message in a database and verify
  that the current IPN's values for these fields are not already in this
  database.

  > **Note:** **Note:** You can't rely on transaction ID alone to screen
  > out duplicates, as this scenario shows: 1) PayPal sends you an IPN
  > notifying you of a pending payment. 2) PayPal later sends you a
  > *second* IPN telling you that the payment has completed. However,
  > *both IPNs contain the same transaction ID*; therefore, if you
  > were using just transaction ID to identify IPNs, you would to treat the
  > "completed payment" IPN as a duplicate.

* Ensure that you receive an IPN whose payment status is "completed" before
  shipping merchandise or enabling download of digital goods. Because IPN
  messages can be sent at various stages in a transaction's progress, you
  must wait for the IPN whose status is "completed' before handing over
  merchandise to a customer.

* Verify that the payment amount in an IPN matches the price you intend to
  charge. If you do not encrypt your button code, it's possible for someone
  to capture a button-click message and change the price it contains. If you
  don't check the price in an IPN against the real price, you could accept a
  lower payment than you want.

### IPN Message Generation and Flow [#ipn-message-generation-and-flow]

PayPal sends your listener an IPN message when any the following events
happen:

* A user on your website clicks a PayPal Payments Standard payment button
  (e.g., a **Buy Now** button) and completes payment on PayPal's
  site.

* A user on your website clicks a PayPal payment button, causing your web
  application to invoke either an Express Checkout API (such as
  `DoExpressCheckoutPayment`) or an Adaptive Payments API (such as
  `Pay`, `Preapproval`, or `ExecutePayment`)
  that completes the payment on your site.

* A user on your website clicks your own payment button, causing your web
  application to call a Direct Payment API operation (such as
  `DoDirectPayment`) that completes the payment on your site.

* Your back-office application invokes a PayPal API operation, such as
  `RefundTransaction`.

* PayPal observes an external event, such as a dispute, chargeback, an eCheck
  clearing, or various recurring payment and subscription events.

In the first two cases, your customer is redirected from your web app to
PayPal for some or all steps of the transaction. When the user completes
payment, PayPal sends an asynchronous IPN message to your listener.

In the third case, your customer is *not* redirected to PayPal;
instead, the user enters all payment information on your site. Again, when the
user completes payment, PayPal sends an asynchronous IPN message to your
listener.

In the last two cases, IPN messaging is initiated by either your back-office
process or by PayPal itself (as opposed to an end-user). The IPN message is
still sent asynchronously, but there is no web flow involved.

No matter what causes PayPal to send an IPN message, your site can use such
messages to kick-off order fulfillment, enable digital media downloads, store
information in a customer relationship management (CRM) or accounting system,
and so on. However, before you do any of these things, you must be
*certain* that the IPN has not been tampered with. To do this, your
listener must implement the IPN authentication protocol. Steps 2, 3, 4, and 5
in the diagram below show this protocol.

![](https://www.paypalobjects.com/webstatic/en_US/developer/docs/ipn/IPN_auth_flow.gif)

The numbers in the diagram correspond to the following actions:

1. A user clicks a PayPal button to kick off a checkout flow; your web
   application makes an API call; your back-office system makes an API call;
   or PayPal observes an event.

2. PayPal HTTPS POSTs your listener an IPN message that notifies you of this
   event.

3. Your listener returns an empty HTTP 200 response.

4. Your listener HTTPS POSTs the complete, unaltered message back to PayPal.

   > **Note:** **Note:** This message must contain the same fields, in the
   > same order, as the original IPN from PayPal, all preceded by
   > `cmd=_notify-validate`. Further, this message must use the
   > same encoding as the original.

5. PayPal sends a single word back - either `VERIFIED` (if the
   message matches the original) or `INVALID` (if the message does
   not match the original).

> **Note:** **Important:** To prevent fraud, your IPN listener must
> implement the IPN authentication protocol (steps 2, 3, 4, and 5 in the
> diagram above). Upon receipt of a `VERIFIED` response, your
> back-office process can parse the contents of the IPN message and respond
> appropriately - print a packing list, enable a digital download, etc.

### IPN Simulator [#ipn-simulator]

Because the most complex part of implementing and IPN solution is creating
your listener, PayPal provides templates and examples of listener code to help
you. And to help you in testing your listener code, PayPal provides an IPN
Simulator tool that you can use to send test IPN messages to the URL at which
your listener is running. The IPN Simulator tool lets you verify that your
listener is receiving IPN messages and handling them correctly. IPN Simulator
notifications include a `test_ipn` variable, which is not found in
live IPN messages, so the IPN test messages can be distinguished from the real
IPN messages.

See
[IPN Simulator](/api/nvp-soap/ipn/IPNSimulator/)
for details on using the IPN Simulator.

### A Sample IPN Message and Response [#a-sample-ipn-message-and-response]

A PayPal IPN message consists of variables that describe the transaction.
These variables contain information about you, your customer, and the details
of the transaction itself. The following example shows a sample IPN message
PayPal would send for a $19.95 purchase made by Express Checkout:

```javascript lineNumbers
mc_gross=19.95&protection_eligibility=Eligible&address_status=confirmed&payer_id=LPLWNMTBWMFAY&tax=0.00&address_street=1+Main+St&payment_date=20%3A12%3A59+Jan+13%2C+2009+PST&payment_status=Completed&charset=windows-1252&address_zip=95131&first_name=Test&mc_fee=0.88&address_country_code=US&address_name=Test+User¬ify_version=2.6&custom=&payer_status=verified&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AtkOfCXbDm2hu0ZELryHFjY-Vb7PAUvS6nMXgysbElEn9v-1XcmSoGtf&payer_email=gpmac_1231902590_per%40paypal.com&txn_id=61E67681CH3238416&payment_type=instant&last_name=User&address_state=CA&receiver_email=gpmac_1231902686_biz%40paypal.com&payment_fee=0.88&receiver_id=S8XGHLYDW9T3S&txn_type=express_checkout&item_name=&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=&payment_gross=19.95&shipping=0.00
```

The following section details variables and values sent by the sample IPN
message listed above.

**Information about you:**

* `receiver_email = gm_1231902686_biz@paypal.com`: Check email
  address to make sure that this is not a spoof

* `receiver_id = S8XGHLYDW9T3S`

* `residence_country = US`

**Information about the transaction:**

* `test_ipn = 1`: Testing with the sandbox

* `transaction_subject =`

* `txn_id = 61E67681CH3238416`: Keep this ID to avoid processing
  the transaction twice

* `txn_type = express_checkout`: Type of transaction

**Information about your buyer:**

* `payer_email = gm_1231902590_per@paypal.com`

* `payer_id = LPLWNMTBWMFAY`

* `payer_status = verified`

* `first_name = Test`

* `last_name = User`

* `address_city = San Jose`

* `address_country = United States`

* `address_state = CA`

* `address_status = confirmed`

* `address_country_code = US`

* `address_name = Test User`

* `address_street = 1 Main St`

* `address_zip = 95131`

**Information about the payment:**

* `custom =`: Your custom field

* `handling_amount = 0.00`

* `item_name =`

* `item_number =`

* `mc_currency = USD`

* `mc_fee = 0.88`

* `mc_gross = 19.95`

* `payment_date = 20:12:59 Jan 13, 2009 PST`

* `payment_fee = 0.88`

* `payment_gross = 19.95`

* `payment_status = Completed`: Status, which determines whether
  the transaction is complete

* `payment_type = instant`: Kind of payment

* `protection_eligibility = Eligible`

* `quantity = 1`

* `shipping = 0.00`

* `tax = 0.00`

**Other information about the transaction:**

* `notify_version = 2.6`: IPN version; can be ignored

* `charset = windows-1252`

* ```text lineNumbers
    verify_sign =
          AtkOfCXbDm2hu0ZELryHFjY-Vb7PAUvS6nMXgysbElEn9v-1XcmSoGtf
  ```

Before you can trust the contents of the message, you must first verify that
the message came from PayPal. To verify the message, you must send back the
contents in the exact order they were received and precede it with the command
`_notify-validate`, as follows:

```text lineNumbers
https://ipnpb.paypal.com/cgi-bin/webscr?cmd=_notify-validate&mc_gross=19.95&protection_eligibility=Eligible&address_status=confirmed&payer_id=LPLWNMTBWMFAY&tax=0.00&address_street=1+Main+St&payment_date=20%3A12%3A59+Jan+13%2C+2009+PST&payment_status=Completed&charset=windows-1252&address_zip=95131&first_name=Test&mc_fee=0.88&address_country_code=US&address_name=Test+User¬ify_version=2.6&custom=&payer_status=verified&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AtkOfCXbDm2hu0ZELryHFjY-Vb7PAUvS6nMXgysbElEn9v-1XcmSoGtf&payer_email=gpmac_1231902590_per%40paypal.com&txn_id=61E67681CH3238416&payment_type=instant&last_name=User&address_state=CA&receiver_email=gpmac_1231902686_biz%40paypal.com&payment_fee=0.88&receiver_id=S8XGHLYDW9T3S&txn_type=express_checkout&item_name=&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=&payment_gross=19.95&shipping=0.00

```

PayPal will then send one single-word message, either `VERIFIED`,
if the message is valid, or `INVALID` if the messages is not valid.

> **Note:** **Important:** After you have authenticated an IPN message
> (received a `VERIFIED&#x60; response from PayPal),
> &#x2A;**you must perform these important checks*** before you
> can assume that the IPN is both legitimate and has not already been
> processed:

1. Check that the `payment_status` is `Completed`.

2. If the `payment_status` is `Completed`, check the
   `txn_id` against the previous PayPal transaction that you
   processed to ensure the IPN message is not a duplicate.

3. Check that the `receiver_email` is an email address registered in
   your PayPal account.

4. Check that the price (carried in `mc_gross`) and the currency
   (carried in `mc_currency`) are correct for the item (carried in
   `item_name` or `item_number`).

Once you have completed these checks, IPN authentication is complete. Now, you
can update your database with the information provided and initiate any
back-end processing that's appropriate.

### Passing Custom Data [#passing-custom-data]

The `custom` variable is a pass-through variable that allows you to
pass your own custom data to PayPal, and pass it back to your listener. For
example, you may want to pass a user ID and/or part number with your payment
call or PayPal button. This variable allows you to pass that data to PayPal
with the payment API call or button click when your customer leaves your
website and goes to PayPal to make a payment. Then when the payment is
processed, the IPN sends that data back to the listener page, so that on a
successful payment, the listener page has the payment status from the IPN
values, along with the user ID for the customer that made the purchase, and
the part number of the item that was paid for.

The `custom` variable is ignored by PayPal and is never presented
to your customer, it's simply passed to PayPal and then back to your listener.
There is only one `custom` variable accepted by the IPN, however,
if you need to have multiple variables passed through, as in the case of a
user ID and a part number, you can use a delimiter, such as a comma, to split
the `custom` variable into multiple values. Then, on the listener
page, you can parse the value of the `custom` variable based on the
delimiter, to retrieve each of the separate individual values that you need.

> **Note:** **Note:** The length of the `custom` variable is
> limited to 256 characters.

For example, if you are using PayPal buttons, in the button form code, you
just need to add an extra hidden input form variable to set a value for the
`custom` variable.

```text lineNumbers
<input type="hidden" name="custom" value="[UserID],[PartNumber]"/>
```

## Non-IPN Notification Mechanisms [#non-ipn-notification-mechanisms]

You can use IPN with other notification mechanisms. For example, you can use
[Payment Data Transfer (PDT)](/api/nvp-soap/ipn/IPNPDTAnAlternativetoIPN/)
or the API to obtain real-time information about a transaction and let IPN
notify you of any changes after the transaction occurs.

If you use PayPal Payments Standard, you can use PDT to obtain information
about the transaction. If you use Express Checkout or Direct Payment, the
PayPal API notifies you of the status and details of the transaction
immediately and automatically. In either case, you can
*immediately&#x2A; show your customer the payment information returned by
PayPal . &#x2A;**You should not use IPN for this purpose***.
