48-hour launch: 40% off with code LAUNCH40, Guide $5.40 / Kit $11.40

PayPal IPN not received or IPN listener not working: troubleshooting checklist

PayPal's IPN flow has four steps. PayPal POSTs the message to your listener. Your listener returns an empty HTTP 200. Your listener POSTs the complete message back, prefixed with cmd=_notify-validate. PayPal replies with one word, VERIFIED or INVALID. Most "IPN not working" problems break one of these steps.

1. Start with IPN History

In your PayPal account, open IPN History. It shows each message, the URL it was sent to, its status and your server's HTTP response code. Sent means your listener answered with 200. Failed or Retrying means it didn't. You can also resend messages from this page. By default a resend goes to the message's original URL, so tick the option to send it to your current profile URL if you've changed it.

2. Nothing arrives, or the status is Failed/Retrying

3. You get INVALID

Minimal listener (Node, Express)

app.post('/ipn', express.raw({ type: '*/*' }), async (req, res) => {
  res.status(200).end();                               // empty 200 first
  const raw = req.body.toString('utf8');               // original order and encoding
  const sandbox = /(^|&)test_ipn=1(&|$)/.test(raw);
  const url = sandbox ? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' : 'https://ipnpb.paypal.com/cgi-bin/webscr';
  const r = await fetch(url, { method: 'POST', body: 'cmd=_notify-validate&' + raw,
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'MyShop-IPN-Listener' } });
  if ((await r.text()) !== 'VERIFIED') return;          // log INVALID and stop
  // then check payment_status, receiver_email, amount/currency and that txn_id is new
});

The guide is Stripe-only. The kit is a self-hosted Cloudflare Worker relay that adds retries, replay and a dead-letter list in front of your endpoint. Its built-in schemes cover Stripe, Lemon Squeezy, Shopify, Paddle Billing, Square, Twilio (status callbacks) and GitHub. PayPal IPN isn't supported, because it uses postback verification, not a signature header.

Fix Your Stripe Webhooks guide · Self-Hosted Webhook Relay Kit. Code LAUNCH40 = 40% off until Sun Oct 11, 6:40 AM MT.

Once you get VERIFIED, PayPal's docs still tell you to check the payment status, the receiver, the amount and currency, and that you haven't already processed that txn_id.

Free download: Webhook debugging cheat sheet.

Fighting webhooks on more than one platform? The Fix Your Stripe Webhooks guide ($9) covers raw-body and signature problems in depth, and the Self-Hosted Webhook Relay Kit ($19) adds retries, replay and a dead-letter list in front of any endpoint.