This guide is for anyone deciding whether to add reCAPTCHA, Turnstile or hCaptcha to a WordPress donation form. Every figure below links to its source.
What does a CAPTCHA actually stop on a donation form?
A CAPTCHA stops the request it guards, and on most donation forms that request is the one that starts a gift, not the one that charges a card. Getting that distinction right decides most of this question.
Here is how a typical Stripe Payment Element form works, Donor Merchant included. The donor fills in their name, email and amount. The site makes one call to the server, which creates a Stripe PaymentIntent and hands back a client secret. The card is then confirmed against that PaymentIntent directly with Stripe. If the card is declined, Stripe's own documentation says that "the PaymentIntent's status returns to requires_payment_method so that the payment can be retried." That retry is a good thing for a real donor who mistyped a digit. It also means one solved CAPTCHA at the start can cover several card attempts afterwards.
That is not unlimited. Stripe also notes that PaymentIntents "might also automatically transition to canceled if they're confirmed too many times," so the attacker eventually has to start over. But starting over is exactly where the CAPTCHA sits, and passing it is cheap. One solving service, 2Captcha, lists reCAPTCHA v2 at $1–$2.99 per 1,000 solves and Cloudflare Turnstile at $1.45 per 1,000 (checked October 1, 2026). Software has also caught up. The USENIX Security 2023 study of modern CAPTCHAs compared its human results against bots reported in the literature and concluded that "these results suggest that bots can outperform humans, both in terms of solving time and accuracy, across all these CAPTCHA types."
| Threat | Does a CAPTCHA on the donate step help? |
|---|---|
| Crude bots that submit the form blindly | Yes, though a honeypot and a timing check catch most of these for free |
| A single source flooding the endpoint | Somewhat; per-IP rate limiting does the same job with no donor friction |
| Card testers paying a solving service | Raises their cost slightly; each solve can still cover several attempts |
| Fraud decisions on the card itself | No. That is the processor's job (Stripe Radar) |
Doesn't Stripe already put a CAPTCHA on my donation form?
Yes, if your form uses Stripe.js. Stripe's advanced fraud detection documentation says that "on each page where you load Stripe.js, it can load hCaptcha. hCaptcha is a type of CAPTCHA that helps stop fraud and provides additional risk factors to Stripe while being low friction for legitimate customers."
That challenge is adaptive, not always on. Stripe's card-testing guide explains that with the Payment Element or Checkout, "we have many automated and manual controls in place to mitigate card testing, including rate limiters, AI models, CAPTCHA triggers, ongoing reviews, and so on. When we detect that you're under a card testing attack, we dynamically choose interventions to suppress the attack as much as possible, while still allowing legitimate users to transact on your account with minimal impact."
Stripe adds a caveat worth taking seriously: "the success of the Stripe controls depends on your integration and what risk factors you send to us." Stripe ranks advanced fraud detection (loading Stripe.js) as the highest-impact signal, followed by IP address, customer email, customer name and billing address. Donor Merchant loads Stripe.js from js.stripe.com and passes the donor's name and email to Stripe when the payment is confirmed, so those signals reach Radar. Adding your own always-on CAPTCHA in front of that means every donor faces a second challenge on top of the one Stripe already shows to the traffic it thinks is risky.
This section is about Stripe. Stripe's hCaptcha does not cover gifts made through PayPal's checkout.
How much does a CAPTCHA cost you in real donations?
Nobody has published a controlled test of a CAPTCHA on a donation form that we could find, so the honest answer is "some, and probably more than you'd guess." The best evidence is the USENIX Security 2023 paper An Empirical Study & Evaluation of Modern CAPTCHAs by Searles and colleagues, in which 1,400 participants collectively solved 14,000 CAPTCHAs.
Two of its findings matter for donation forms:
- Depending on the condition, "between 18% and 45% of participants abandoned the study after the presentation of the first CAPTCHA." These were paid study participants, not volunteers with nothing at stake.
- In a follow-up study built to measure abandonment (574 people started it; 174, or 30%, quit), people who met CAPTCHAs inside a realistic task such as creating an account were "120% more likely to abandon than those in the direct setting," where solving CAPTCHAs was the whole job.
Read those numbers carefully. The 120% compares two ways of presenting CAPTCHAs, not a CAPTCHA against no CAPTCHA, and the realistic task was account creation, not a gift. The direction is still the useful part: people who came to do something else are much less patient with a puzzle than people who came to solve one. A donor came to give. The authors make the business point themselves: "every abandoned task (e.g., purchase, account creation) represents a potential loss for the website."
Accessibility is the other cost. The W3C's note Inaccessibility of CAPTCHA states that "the very nature of the interactive task inherently excludes many people with disabilities, resulting in a denial of service to these users." Invisible and score-based challenges reduce this, but a donor who fails the score still gets a puzzle.
How many free reCAPTCHA checks do you get now?
Ten thousand a month, shared across your whole Google Cloud organization. Google's billing page says the free tier is "Up to 10,000 assessments per calendar month per organization. The limit aggregates use across all accounts and all sites." Without billing enabled, once the organization passes 10,000, further assessments return a "Resource Exhausted (429)" quota error until the first of the next month.
For one small charity that may be plenty. For an agency running thirty client sites under one Google Cloud organization, it is one shared allowance, and a busy month on one site can exhaust it for all of them. Plan for billing or a different provider before you roll it out widely.
| Option | Free allowance | Notes |
|---|---|---|
| Google reCAPTCHA (Essentials) | 10,000 assessments per month per Google Cloud organization | Quota errors past the limit unless billing is on |
| Cloudflare Turnstile (Free) | Unlimited challenges, up to 20 widgets | Needs a Cloudflare account; works without routing your traffic through Cloudflare |
| Stripe's built-in hCaptcha | Included when you load Stripe.js | Adaptive; Stripe decides when to show it |
Is reCAPTCHA allowed under GDPR without consent?
European regulators and courts have said no, at least for reCAPTCHA as Google ships it. Three decisions, each verified against the published text:
- CNIL, SAN-2023-003 (March 16, 2023). The French regulator fined the scooter-rental company Cityscoot €125,000. Most of the case was about collecting scooter location data every 30 seconds; €25,000 was for using reCAPTCHA on account creation, login and password reset without informing users or obtaining consent. The CNIL reasoned that "the purpose of the Google reCaptcha mechanism is not for the sole purpose of securing the authentication mechanism for the benefit of users but also allows analysis operations by Google."
- CNIL, SAN-2023-023 (December 29, 2023). The payment company NS Cards France (Neosurf) was fined €105,000: €90,000 for GDPR breaches including plain-text passwords, and €15,000 for cookie and tracker breaches, which included reCAPTCHA on its registration and login pages without consent. The CNIL repeated the same reasoning about Google's analysis operations.
- Austria's Federal Administrative Court (BVwG), W298 2274626-1 (September 13, 2024). A visitor complained after a political party's membership sign-up page set a reCAPTCHA cookie without consent. The court dismissed the site operators' appeal, holding that reCAPTCHA is not technically necessary to run the website, that there was no legitimate interest, and that consent should have been obtained.
Google's own developer documentation does not help the "strictly necessary" argument. For reCAPTCHA v3 it recommends "including reCAPTCHA verification on forms or actions as well as in the background of pages for analytics." A US-only charity is not bound by the CNIL, but anyone with European donors should treat reCAPTCHA as something that needs a consent banner, which is one more step in front of a gift. These decisions concern reCAPTCHA; they do not settle the question for other providers either way. This is not legal advice.
What should you use instead of a CAPTCHA?
Several quiet layers that real donors never see. Stripe is clear that no single trick is enough: "simple firewall rules or filters based on a single heuristic such as IP addresses are usually not sufficient to prevent card testing on their own." These are the layers Donor Merchant ships, all free, plus the two you set up outside WordPress:
| Layer | What it catches | In Donor Merchant |
|---|---|---|
| Honeypot field | Bots that fill in every input | Hidden dm_website field, checked server-side |
| Signed submit-timing check | Scripts that post the form instantly | Rejects submissions under 3 seconds; adjustable with donor_merchant_min_fill_seconds |
| Per-IP rate limit | Single-source floods | 15 donation starts per IP per hour; donor_merchant_rate_limit |
| Server-side minimum amount | The 50-cent test charge that card testers prefer | Defaults to $5 on new installs, enforced in the REST handler |
| Stale-record sweep | Abandoned pending rows piling up after an attack | Daily cleanup after 90 days; donor_merchant_stale_donation_days |
| Stripe Radar rules | Repeat IPs, emails and card fingerprints | Set in your Stripe Dashboard; custom velocity rules depend on your Radar plan |
| CDN or host rate limiting | Traffic before it reaches WordPress | Set at Cloudflare or your host |
If you are under attack right now, our step-by-step guide to stopping a card-testing attack on your donation form covers the first hour, Radar velocity rules, edge blocking and the safe way to clean up junk donations. This page does not repeat it.
When is a CAPTCHA the right call?
When the quiet layers have not stopped an attack, or when your processor tells you to add one. Stripe recommends CAPTCHA as a mitigation in its own card-testing guide, noting that "card testers often use automated scripts that CAPTCHA can block," and it suggests a sensible middle path: combine CAPTCHAs and rate limits "so the first payment attempt from an IP address succeeds without restriction, but subsequent requests made by that same IP address for the next several hours require a captcha verification to succeed."
If you do add one:
- Verify the token on the server, on every request that can start a payment. A widget that is only checked in the browser stops nobody.
- Prefer an invisible or managed challenge over an image puzzle, and test it with a screen reader and on a phone.
- Put it on a timer. Write down the date you added it and take it off once the attack has been quiet for a couple of weeks.
How do I add a CAPTCHA to Donor Merchant if I need one?
Through the donor_merchant_pre_donation filter. It runs on the public donation endpoint after the honeypot and timing checks and before the rate limiter, any database write or any call to Stripe or PayPal. Your callback receives the incoming REST request; return a WP_Error and the donation is refused with that message. It deliberately does not run for recurring renewals arriving by webhook, gifts you enter by hand in the admin, or the CSV importer, so a CAPTCHA can never block those.
One honest limitation: the form sends a fixed set of fields to the server, so getting a CAPTCHA widget's token into that request takes a little front-end code of your own. It is a short developer task, not a settings checkbox, and it keeps the default form free of third-party scripts beyond the payment gateways.
Other plugins treat CAPTCHA as optional too. GiveWP offers it as a separate free add-on, Give – Cloudflare Turnstile; on October 1, 2026 its WordPress.org listing showed version 1.1.0, last updated April 16, 2025, tested up to WordPress 6.7.9, with 700+ active installations.
Why doesn't Donor Merchant ship a CAPTCHA by default?
Because on the donate step the cost lands on every donor and the benefit is narrow. It bounds donation starts, not card attempts. Stripe.js already brings an adaptive challenge to the Stripe side. The best published research points to real abandonment when a CAPTCHA interrupts a task people came to finish, and reCAPTCHA adds a shared quota and, in Europe, a consent requirement. So the plugin ships the invisible layers, and a filter for the day you need more.