PayPal IPN Validation Bypass: Classic Payment Logic Bugs
Instant Payment Notification is old. Plenty of carts still listen for it. The failure pattern has barely changed: the shop trusts a POST that claims payment_status=Completed without asking PayPal whether that POST was real.
If you find an IPN or PDT endpoint on an in-scope store, treat it like any unauthenticated callback with financial impact.
How handlers are supposed to work
A correct IPN receiver takes the raw form body, appends cmd=_notify-validate, and posts it back to PayPal. Only VERIFIED responses should drive fulfillment. PDT has its own token handshake. Shortcuts include trusting the source IP (fragile), checking only that receiver_email looks familiar, or verifying nothing in sandbox mode that accidentally shipped to production.
Endpoints named ipn.php, paypal_callback, or plugin routes under WooCommerce-style paths are still common. Some stacks migrated to REST webhooks but left IPN enabled "for compatibility." Dual receivers mean two code paths to audit—and the abandoned one is usually weaker.
Bypass and logic tests
With your own merchant sandbox or a local mock the program allows:
- Send an IPN-shaped POST to the store with
customorinvoiceset to your unpaid order id andpayment_status=Completedwithout a preceding PayPal flow. If the order flips to paid, verification is missing. - Change
mc_grossandmc_currencyon a captured legitimate notification and replay. Partial payment acceptance is a favorite real-world bug. - Swap
payer_emailwhile keeping a valid verification path—some apps grant accounts based on email matching rather than merchant transaction ids. - Replay the same
txn_idand watch for double fulfillment. - Toggle
payment_statusvalues likePendingorReversedand see whether the shop downgrades entitlements or ignores them.
Do I still see IPN-only shops in 2026? Yes—especially WordPress plugins, older subscription scripts, and "temporary" endpoints never deleted after a migration to Checkout APIs. Sandbox versus live host mixups (www.sandbox.paypal.com vs live) also appear when developers hardcode the validate URL incorrectly and "fix" failures by skipping validation.
Currency and chargeback handling deserve a sentence in solid reports. If a completed IPN can be followed by a forged Refunded notice that deletes another user's order—or fails to revoke access after a real refund—spell out the business logic gap with owned orders only.
Subscription plugins add silent renewals. A forged IPN with txn_type=subscr_payment may extend access months ahead of a real billing event. Prove that on a plan you purchased in sandbox, then stop—do not invent fake subscriber lists.
Proof that finance teams accept
Use the smallest unpaid SKU, a canary order number, and screenshots of before/after order state. Never mark someone else's order paid. If only sandbox is in scope, say so. Include whether the handler returned 200 quickly (PayPal retries on failure—slow handlers create duplicate risk even when validation exists).
Remediation is straightforward: full message validation, enforce receiver account identity, compare amount and currency to the order record, store txn_id uniquely, and prefer modern PayPal webhooks with signature verification when the stack allows. Mention whether the bug is unauthenticated forgery or authenticated replay; those are different severities. Payment bugs get noisy triage—precision beats drama.