This guide is written for the person who did not build the donate button and does not want to become a developer to fix it. You inherited a page. It works. Money arrives. Somebody forwarded you a warning and now you need to know whether it is urgent, what breaks, and what it costs to put right.
What exactly is PayPal retiring?
Two old pieces of PayPal, used together, are going away.
- Website Payments Standard (WPS) is the hosted button system. You logged into PayPal, filled in an amount, and PayPal handed you a snippet of HTML to paste into your page. Donate, Buy Now and Add to Cart buttons all come from this system.
- Instant Payment Notification (IPN) is the old message PayPal sends back to your website after a payment, so your plugin can record the gift, email a receipt, and credit a campaign. It is the reporting half of the pair.
| When | What changed or changes |
|---|---|
| End of 2025 | PayPal stopped issuing new IPN and Website Payments Standard credentials. Existing ones kept working. |
| January 2026 | Website Payments Standard formally deprecated. Support ends; only limited security updates continue. |
| January 2027 | Full end-of-life. WPS integrations cease to function and payments through them fail. |
The replacement is PayPal's current API: Orders v2 for one-off gifts, PayPal Subscriptions for recurring giving, and signed REST webhooks instead of IPN for the reporting.
Verified September 2026 against PayPal's published deprecation notices and third-party add-on end-of-life announcements. PayPal can move dates; confirm the current position in your own PayPal account before you plan around a specific month.
How do I tell if my WordPress donation plugin still uses PayPal IPN?
Three checks, none of which require a developer. Do them in order and stop when you get an answer.
Check 1: look at the donate page itself
Open your donation page in a browser, right-click on an empty part of the page and choose View page source, then press Ctrl+F (Cmd+F on a Mac) and search the source for paypal.com/cgi-bin/webscr.
| What you find | What it means | Urgency |
|---|---|---|
cgi-bin/webscr or a form with hosted_button_id | A classic hosted PayPal button or a Website Payments Standard form post. This is the thing being retired. | Act now |
| A form posting to your own site, plus a plugin setting mentioning IPN | A plugin using WPS behind the scenes with IPN for recording. Same deprecation path. | Act now |
| A PayPal button that renders itself into the page from PayPal's JavaScript SDK | Modern Smart Buttons on Orders v2. Not in the deprecation path. | No action |
Check 2: look at your plugin settings
In WordPress, open your donation plugin's payment or gateway settings. Language matters here. Options named PayPal Standard, PayPal Payments Standard, IPN URL, IPN listener or PayPal Identity Token are all legacy. Settings that ask for a Client ID and Secret, or that mention REST app or webhook ID, are modern.
One more clue: if your plugin sends donors away to paypal.com to complete the gift and then bounces them back, that is usually the old flow. Modern integrations keep the donor on your page in a PayPal popup.
Check 3: look in your PayPal dashboard
Log into PayPal, then go to the account settings gear icon, then Account Settings, then Notifications, then Instant payment notifications. If IPN is listed as enabled with a notification URL pointing at your website, your site is still relying on IPN messages. Under Account Settings then Website payments, you can also see whether any hosted buttons exist on the account.
cgi-bin/webscr, hosted_button_id, notify_url and PDT. Any hit is a site on the clock. Sites still on a legacy WPS gateway also need their recurring donors handled individually, which is the slow part and the reason to start the audit now rather than in November.Why do these failures go unnoticed instead of throwing an error?
This is the part that costs organisations real money, and it is the reason a half-finished migration is more dangerous than no migration.
IPN sends form-encoded data. Webhooks send JSON. When a JSON webhook arrives at code written to read form-encoded IPN, every field comes back undefined. The code checks a condition, the condition is false, nothing is recorded, and the handler still returns HTTP 200 because nothing actually crashed. PayPal reads that 200 as successful delivery and stops retrying. The donor is charged. The receipt never sends. The gift never appears in your reports. Nothing in your system logs an error, because from the software's point of view nothing went wrong.
Beyond the encoding, the field names themselves changed. These are the specific renames that break records:
| Old IPN field | New webhook field | What breaks |
|---|---|---|
mc_gross | resource.amount.value | The new value is a string, not a number. Numeric comparisons and amount-validation checks misbehave, and a gift can be silently rejected as mismatched. |
custom | custom_id | Your campaign, fund or donor reference arrives under a name the old code never looks for, so the gift is orphaned from its campaign. |
payer_email | Absent from the capture resource | No donor email means no receipt, no donor record match, and a duplicate donor created on the next gift. |
payment_status = Completed | resource.status = COMPLETED | Case-sensitive. A check for Completed never matches COMPLETED, so completed payments are skipped entirely. |
| Refunds and chargebacks in the same message | Separate event_type values | If you only subscribe to capture events, your books show a gift as received while PayPal shows it refunded. Reconciliation fails months later. |
Amount-validation logic is a known sore spot on legacy PayPal Standard recurring donations generally. GiveWP's own documentation states plainly that each renewal on a PayPal Standard subscription is recorded only in response to an IPN hitting the site, and that missing renewals are an IPN problem first. If that message stops arriving, or arrives in a shape the plugin rejects, the renewal exists at PayPal and does not exist on your site.
If I replace our PayPal donate button, will our monthly donors have to sign up again?
Yes, if they are on a legacy Website Payments Standard subscription. We would rather tell you that plainly than let you discover it in February.
An active PayPal billing agreement or subscription lives at PayPal, tied to the integration that created it. It cannot be handed to a different integration. No plugin can move it, ours included, and any vendor who tells you otherwise is describing something else. The same is true in reverse for Stripe subscriptions. This is a payment-network constraint, not a software limitation.
The practical sequence that keeps the money coming in:
- Export your active recurring donors from PayPal: name, email, amount, frequency, start date and the subscription or agreement ID.
- Stand up the new donation form first, on the same site, and test it with a real small gift of your own.
- Write to recurring donors personally. Say what is changing and why, in one short paragraph, with a direct link to the new recurring form and the exact amount they were giving pre-filled in the message text. People re-enrol at far higher rates when they are not asked to work out their own amount.
- Watch new sign-ups arrive. Tick each donor off your export as their new schedule confirms.
- Only then cancel that donor's old schedule in PayPal.
What is the difference between Website Payments Standard and PayPal Orders v2?
| Website Payments Standard | Orders v2 + Subscriptions | |
|---|---|---|
| How the button is made | HTML copied from PayPal's dashboard | Rendered by PayPal's JavaScript SDK, controlled by your plugin |
| Where the donor pays | Redirected to paypal.com and back | Popup over your own page |
| Reporting back to your site | IPN, form-encoded, unsigned by default | REST webhooks, JSON, cryptographically signed |
| Recurring giving | Legacy subscriptions button | PayPal Subscriptions API with plan objects |
| Status after January 2027 | Ceases to function | Current and supported |
What Donor Merchant uses
Donor Merchant 2.5.2 has always used PayPal Orders v2, PayPal Subscriptions and signed PayPal webhooks. It has never shipped an IPN listener or a Website Payments Standard integration, so it is not in the deprecation path. That is a statement about our code, not a prediction about PayPal's roadmap.
It is free and GPL, listed on WordPress.org, and requires WordPress 6.2 or newer, PHP 7.4 or newer, and HTTPS. There is no platform fee and no percentage taken by us. You pay PayPal's processing fee and nothing else. PayPal publishes a confirmed-charity donation rate of 1.99% + $0.49 against a 2.89% + $0.49 standard rate, subject to application and pre-approval (verified September 2026; confirm current rates with PayPal).
You can also run Stripe alongside PayPal or instead of it. Stripe covers cards, Apple Pay, Google Pay and ACH bank debit. Stripe publishes no nonprofit rate, only three eligibility criteria. If you are weighing the two, see Stripe vs PayPal for nonprofit donations.
On the giving side you get monthly, quarterly and yearly recurring through both gateways, campaigns with goal thermometers, designations and funds, tributes and memorials, fee recovery, PDF receipts and annual tax statements, and a passwordless donor portal where a monthly donor can update or cancel their own giving without emailing you. Setup steps are in the PayPal setup docs.
How do I bring the old donation history across?
Handle the money and the history as two separate jobs. The money is the gateway switch above. The history is a CSV.
Donor Merchant includes a free CSV importer that takes an export from PayPal, GiveWP, Charitable, Donorbox or a spreadsheet. Three things about it matter for this job:
- Imported gifts are written as completed records directly, so they never fire receipt emails, admin alerts, outgoing webhooks or Mailchimp syncs. Nobody gets a receipt for a gift they made in 2019.
- It dedupes by transaction ID, and where there is no transaction ID, by donor plus amount plus calendar day. Re-running the same file is safe.
- The cap is 5,000 rows per file. Split larger exports by year.
The full switching procedure, including what to do about lifetime totals and year-end statements, is in migrating a donation plugin without losing donor history. Churches doing this alongside a giving-statement season should also read accepting church donations on WordPress.
What to do, and when
| Window | Action |
|---|---|
| This month | Run the three checks above and write down the answer. Export your active recurring donors from PayPal and save the file somewhere that is not one person's laptop. If nothing is legacy, you are done. |
| Next 30 to 60 days | Install a modern donation plugin on the same site, connect PayPal with a REST Client ID and Secret, configure the webhook, and test in test mode then with one small live gift. Import your history from CSV. Do not touch the old button yet. |
| Before December | Run the recurring re-enrolment campaign. Give it eight to ten weeks, because response is slow and you will need two or three reminders. Cancel each old schedule only as its replacement confirms. |
| By late December | Remove the old button from every page, including the ones you forgot: bulletin PDFs, QR codes on printed envelopes, the footer, the thank-you page, and any email signature or social profile linking to a paypal.me or hosted button URL. |
| January 2027 | If you have done nothing, expect one-off gifts through a WPS button to fail and legacy recurring schedules to stop producing usable records. Money that does arrive may not be recorded on your site at all. |
What we are not claiming
- We cannot migrate an active PayPal subscription or billing agreement. Nobody can. Those donors must re-enrol.
- We do not offer a one-click converter that turns a hosted PayPal button into a modern form. The button is replaced, not converted.
- This page is not PayPal's official guidance and is not legal or tax advice. Confirm dates and rates with PayPal, and confirm anything touching donor acknowledgement or substantiation with your accountant.
- Donor Merchant's donation form uses a honeypot field and per-IP rate limiting. It does not use CAPTCHA.
If you would rather have someone read your setup over your shoulder before you touch anything, the plugin is free to download and use forever, and support plans exist for organisations that want a person on the other end during the switch. The software is not the paid part. Help is.