How to use PayPal IPN on Multiple WooCommerce sites

So you’ve just set up your business and it’s time to get paid via PayPal. You’ve likely already discovered that you can only set up 1 IPN (instant payment notification) URL on you PayPal Business account, so you are unable to correctly set up payment notifications for your new WooCommerce store. This is a common issue that everyone has been facing for a long time, but luckily there are a few workarounds.

What is an IPN Forwarder?

An IPN forwarder is based on the idea of creating a ‘middle man‘ that knows about your multiple WooCommerce stores. The ‘middle man‘ is in charge of forwarding the PayPal IPN to the right WooCommerce where the payment has been made.

This works by setting your PayPal IPN URL to the ‘middle man‘ which is script on one of your servers. The script will then process the IPN and send it to the dedicated store.

IPN Forwarder Script Example

Below is a popular PHP script to broadcast/forward the IPN to multiple urls. It’s made by SoulSeekah on

PHP and cURL are required on the sever.

   * This is a PayPal IPN (Instant Payment Notification) broadcaster
   * Since PayPal does not provide any straightforward way to add
   * multiple IPN listeners we'll have to create a central IPN
   * listener that will broadcast (or filter and dispatch) Instant
   * Payment Notifications to different destinations (IPN listeners)
   * Destination IPN listeners must not panic and recognize IPNs sent
   * by this central broadcast as valid ones in terms of source IP
   * and any other fingerprints. Any IP filtering must add this host,
   * other adjustments made as necessary.
   * IPNs are logged into files for debugging and maintenance purposes
   * this code comes with absolutely no warranty
  ini_set( 'max_execution_time', 0 ); /* Do not abort with timeouts */
  ini_set( 'display_errors', 'Off' ); /* Do not display any errors to anyone */
  $urls = array(); /* The broadcast session queue */
  /* List of IPN listener points */
  $ipns = array(
      'mystore' => '',
      'myotherstore' => '',
      'myotherandbetterstore' => ''
  /* Fingerprints */
  if ( /* My Store IPN Fingerprint */
    preg_match( '#^\d+\|[a-f0-9]{32}$#', $_POST['custom'] ) /* Custom hash */
    and $_POST['num_cart_items'] == 2 /* alwayst 1 item in cart */
    and strpos( $_POST['item_name1'], ' Product' ) == 0 /* First item name */
  ) $urls []= $ipns['mystore']; /* Choose this IPN URL if all conditions have been met */
  if ( /* My Other Store IPN Fingerprint */
    sizeof( explode('_', $_POST['custom']) ) == 7 /* has 7 custom pieces */
  ) $urls []= $ipns['myotherstore']; /* Choose this IPN URL if all conditions have been met */
  /* My Other And Better Store IPN Fingerprint */
  $custom = explode('|', $_POST['custom']);
  if (
    isset($custom[2]) and $custom[2] == 'FROM_OB_STORE' /* custom prefixes */
  ) $urls []= $ipns['myotherandbetterstore']; /* Choose this IPN URL if all conditions have been met */
  /* ... */
  /* Broadcast */
  if ( !sizeof($urls) ) $urls = $ipns; /* No URLs have been matched */
  $urls = array_unique( $urls ); /* Unique, just in case */
  /* Broadcast (excluding IPNs from the list according to filter is possible */
  foreach ( $urls as $url ) broadcast( $url );
  header( 'HTTP/1.1 200 OK', true, 200 );
  exit(); /* Thank you, bye */
  /* Perform a simple cURL-powered proxy request to broadcast */
  function broadcast( $url ) {
    /* Format POST data accordingly */
    $data = array();
    foreach ($_POST as $key => $value) $data []= urlencode($key).'='.urlencode($value);
    $data = implode('&', $data);
    /* Log the broadcast */
    file_put_contents('_logs/'.time().'.'.reverse_lookup( $url ).'-'.rand(1,100), $data);
    $ch = curl_init(); /* Initialize */
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, count($data));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch); /* Execute HTTP request */
    curl_close($ch); /* Close */
  function reverse_lookup( $url ) {
    global $ipns;
    foreach ( $ipns as $tag => $_url ) {
      if ( $url == $_url ) return $tag;
    return 'unknown';
?>Code language: HTML, XML (xml)

You’ll need to configure the the script with your own details and then save it to the server that will be responsible for handling the the IPN forwarding.

Using the IPN Forwarder

Let’s say your domain name is You’ll need to name the script something like ipn-forwarder.php and upload it to your server. Now you’ll have to make sure you can access the file from

Instant Payment Notification URL in PayPal
Instant Payment Notification URL in PayPal

Log into your PayPal account, go to business setup and find the Instant Payment Notification Settings. Set your new IPN URL to be

Make sure to thoroughly test that all your payment notifications are received by the script and correctly being forwarded to the right WooCommerce store.

Testing the IPN Forwarder

This is the most important setup. TEST EVERYTHING again and again. You need to make sure that your IPN is working correctly on all your sites. Otherwise payments from PayPal will not be correctly marked as paid inside WooCommerce.

There are a few way to help if the IPN forwarder is working, so we don’t need to make any real orders.

  1. PayPal IPN Simulator
  2. Resending Instant Payment Notifications

The PayPal IPN Simulator is available to all sandbox accounts, you’ll be able to send test payment notifications to your IPN forwarder. A PayPal sandbox account is a free developer account that mimics all the real features of PayPal plus it lets you keep everything in a test environment without having to deal with real money.

Here are details about using the IPN Simulator.

It’s also possible to resend a real Instant Payment Notification. You can find your IPN history under your IPN settings in your PayPal Business account.

You can resend the same notification as many times as you’d like but your IPN history will disappear when you change your IPN URL.

Wrapping up

PayPal can be pain when handling multiple business. We hope that they will work on a better way to help businesses who are running multiple stores.

The IPN forwarder example is to point you in the right direction. It requires technical knowledge and time to create a bulletproof solution.

Avatar photo

I help eCommerce store owners to run their stores smoothly and get more sales. Let's discuss optimizing your store! Hit me up via the support page or on Twitter @morganhvidt

One comment

  1. Hi Eirik, Principles are still very much the same, We use a modified version for our stores. You’ll just have to make sure you test your version a lot with the PayPal IPN Simulator.

Leave a Reply

Your email address will not be published. Required fields are marked *