plugin-icon

Checkout Bouncer

제작자: Mahruf Hussain·
Stops card-testing bots and fake orders at the WooCommerce checkout with reCAPTCHA v3 — classic, block checkout and pay-for-order alike.
버전
1.0.0
최근 업데이트일
Aug 15, 2026
Checkout Bouncer

Your checkout is the one page on your store that anyone on the internet can submit to, over and over, for free. That is why card-testing bots live there. They arrive with a list of stolen card numbers, push a cheap product through your checkout a few hundred times an hour, and use your gateway as a free validity checker. You are left with the fallout: a wall of failed orders, a pile of authorisation fees, a plummeting success rate, and eventually an unhappy email from your payment processor.

Most stores reach for a captcha plugin and assume the problem is solved. Then they switch their checkout page to the WooCommerce Checkout block — and any captcha plugin that only hooks the classic form silently stops working. The block checkout does not submit a form. It posts JSON to the WooCommerce Store API, and a plugin that only hooks woocommerce_checkout_process never sees that request at all. Worse, that route stays open even on stores whose visible checkout page still uses the classic shortcode. A bot does not need your checkout page. It only needs the route.

Checkout Bouncer is built around that gap. It follows one simple idea, end to end:

Detect every way an order can enter this store protect the ones that can carry a token block the ones that cannot.

Detect

Checkout Bouncer ships a real checkout scanner, not a settings page with a checkbox. It opens your store, works out how your checkout is actually built, and writes you a plain-English report:

  • Reads the checkout page WooCommerce is configured to use, and tells you if it is missing, unpublished or trashed.
  • Works out which renderer that page uses — the WooCommerce Checkout block, the classic [woocommerce_checkout] shortcode, or a page builder. Elementor, Divi, WPBakery, Beaver Builder, Bricks and Oxygen are detected by name, and Checkout Bouncer looks inside the builder’s own saved layout for the checkout element.
  • Hunts down rogue duplicate checkout pages — the theme-demo import, the staging copy, the “checkout-2” a page builder left behind. Every one of them is a second address where an order can be started, and most store owners have no idea they exist. A page only counts as a duplicate when it really renders a checkout: the WooCommerce Checkout block, the [woocommerce_checkout] shortcode itself, or a page builder layout holding the checkout element. A knowledge-base page that merely writes about the shortcode is not flagged. Duplicate detection needs a checkout page configured in WooCommerce to compare against, so it is paused — and nothing is listed or blocked as a duplicate — while that setting is empty.
  • Checks whether the Store API checkout route is registered, and whether anything is guarding it.
  • Resolves your pay-for-order and add-payment-method endpoints, which are the two surfaces bots love precisely because everyone forgets them.
  • Runs configuration health checks and shouts about the dangerous combinations — no keys saved, master switch off, a block checkout that is neither verified nor blocked, a score threshold of 0 that rejects nothing, a threshold so high it will turn away real customers, or no WooCommerce checkout page configured at all, which is the state that pauses duplicate detection.

Every finding comes with a one-click action, and every action explains what it will break before you switch it on.

Protect

Where a token can be attached, Checkout Bouncer attaches one and scores it with reCAPTCHA v3 — the invisible kind. There is no checkbox, no traffic-light puzzle, and nothing for a genuine customer to do.

  • Classic checkout. A hidden token field is added to the order review, refreshed while the customer types and re-minted every time WooCommerce refreshes the review by AJAX. If the token is missing or older than 90 seconds when Place Order is pressed, the submit is held for a moment, a fresh token is minted and the form goes on its way by itself, so a customer who left the tab open is not rejected for a stale token. The score is checked during checkout validation, which runs before WooCommerce creates the order, so a rejected bot normally leaves no order row behind at all. If a gateway or a checkout replacement skips that validation hook, Checkout Bouncer verifies again the moment the order is created and stops it there — before any gateway is engaged, with the order marked failed and annotated.
  • Block checkout (Store API). The token rides along as registered Store API extension data and is verified on the checkout request itself. Several widely-installed captcha plugins still do not check this route — WooCommerce patched a number of the larger ones in December 2024, but not all of them, and a plugin that only hooks the classic form still sees nothing here.
  • Pay for order. The emailed payment link is verified before the gateway is called. This is the page bots use to retry stolen cards against an order they already created.
  • Add payment method. Optional, off by default. Stops a signed-in bot saving cards against your gateway without buying anything.

Verification happens before any gateway is asked for money, on every surface.

Block

Some surfaces cannot carry a token — an old WooCommerce that cannot register Store API extension data, or a duplicate page nobody maintains. For those, Checkout Bouncer closes the door instead:

  • Block the Store API checkout route with a 404 or 403 of your choosing.
  • Block duplicate checkout pages found by the scanner, with the same status code. Enforcement reads the tiny list the scanner saved, so it keeps working after a settings save, a page edit or a cache clear — and it never blocks your configured checkout page, or anything at all while WooCommerce has no checkout page set.
  • Store staff and allowlisted IP addresses are always let through, so you can still inspect a blocked page yourself.

And a second, different kind of protection

reCAPTCHA answers “is this a browser?”. It cannot answer “is this browser behaving like a card tester?”, because each individual request looks perfectly human. So Checkout Bouncer also ships a gateway-agnostic order-rate throttle with three rules, all keyed on a salted hash of the client IP:

  • too many orders in an hour;
  • too many failed payments in fifteen minutes — the classic card-testing signature;
  • too many distinct billing email addresses in an hour — one card, many identities.

It covers the classic checkout, the block checkout’s Store API and pay-for-order alike, with no gateway-specific code anywhere. Each surface is enforced on the hook WooCommerce actually lets a rejection travel through — woocommerce_checkout_order_processed for the classic form, woocommerce_store_api_checkout_update_order_from_request for the Store API, and woocommerce_before_pay_action for pay-for-order, the page bots use to retry stolen cards. That last one matters: paying for an order that already exists never creates one, so a throttle hung on order creation alone would never see it.

Some deliberate details:

  • Only a real placement is counted. Opening the block checkout creates a draft order behind the scenes; that is a page view, not an order, and it never touches your limits.
  • An attempt that was blocked is not counted either, so a rolling window always drains and a shared office or mobile-carrier address recovers by itself.
  • A throttled block-checkout placement is refused with HTTP 429 and the draft is left alone, and a throttled pay-for-order attempt returns the customer to the payment page with a notice and the order still payable. Only the classic checkout leaves a failed order behind, because WooCommerce has already created the row by the time any hook can stop it.

There is a monitor mode that records every trip without blocking anything, so you can tune the limits against your real traffic before you arm them. The throttle works even before you have finished setting up your reCAPTCHA keys.

Everything else you would expect

  • Events dashboard. Seven-day tiles by verdict, the top block reasons, and a paginated log of every pass, fail, skip and block — filterable by verdict, surface, reason, date range and free text, with a CSV export that downloads exactly the selection on screen.
  • Per-gateway targeting. Verify all payment methods, only a chosen list, or everything except a chosen list. No gateway id is hardcoded anywhere in this plugin.
  • Staff and IP bypass. Roles you choose skip verification, plus an IP allowlist that accepts IPv4, IPv6 and CIDR ranges for your office or warehouse.
  • Fail open or fail closed. Decide for yourself whether an order goes through when Google cannot be reached.
  • HPOS and block compatible. Compatibility with High-Performance Order Storage and with Cart & Checkout Blocks is formally declared, so WooCommerce never flags Checkout Bouncer as incompatible.
  • Keys in wp-config.php. Define CHECKOUT_BOUNCER_SITE_KEY and CHECKOUT_BOUNCER_SECRET_KEY to keep them out of the database entirely; the settings fields then render read-only.
  • Privacy-first logging. IP addresses are anonymised before they are stored, billing addresses are only ever kept as salted digests, and a daily job purges anything older than your retention window.
  • Invisible to real customers. No challenge, no puzzle, no extra click, no layout shift.
  • Built for a store, not a client. No hardcoded IP addresses, no hardcoded gateway, no assumptions about your theme or your checkout type.
  • Translation-ready, multisite-aware, no bundled frameworks, no CDN assets, no build step, no tracking, and no phone-home of any kind.

Scope

Checkout Bouncer protects the WooCommerce checkout, and only the checkout, using reCAPTCHA v3 only. It deliberately does not touch your login form, registration, comments or contact forms, and it does not offer reCAPTCHA v2, hCaptcha or Turnstile. Doing one job completely beats doing six jobs partially.

Third-Party Services and Privacy

Checkout Bouncer relies on one external service: Google reCAPTCHA v3. This is inherent to the plugin’s purpose — reCAPTCHA is the thing doing the scoring — and it cannot be switched off while the plugin is verifying checkouts. Please read this section before installing, and reflect it in your own privacy policy.

What is loaded in your customer’s browser

Checkout Bouncer enqueues Google’s reCAPTCHA v3 API script from https://www.google.com/recaptcha/api.js. Loading that script means Google receives your visitor’s IP address and standard request headers, and reCAPTCHA collects device, browser and interaction signals in order to produce a risk score. Google may set cookies in your visitor’s browser.

By default this happens on every front-end page of your shop, not only the checkout. That is deliberate: reCAPTCHA v3 scores a visitor on how they behaved across the whole site, and Google recommends running it in the background of pages rather than only on the form you are protecting, because a single data point produces unreliable scores. If you would rather limit Google’s reach, set the loading scope to “Checkout screens only” and the script is enqueued on checkout, pay-for-order and add-payment-method views alone — at the cost of less accurate scoring. Please check which setting fits your privacy policy, and, if you serve visitors in the EU or another consent regime, your cookie-consent flow.

What is sent from your server

When an order is submitted, Checkout Bouncer sends a single server-to-server POST request to Google’s verification endpoint:

https://www.google.com/recaptcha/api/siteverify

That request contains your secret key, the reCAPTCHA token minted in the visitor’s browser, and the visitor’s IP address (as remoteip, which is how Google’s API is designed to be called). Google replies with a success flag, a score between 0.00 and 1.00, the hostname and action the token was minted for, and any error codes. No order contents, no customer name, no email address and no payment details are ever sent to Google by Checkout Bouncer.

Your secret key is only ever used server-side. It is never printed into a page, never written to a log, and never returned to the browser — the settings screen shows a fixed mask instead of the stored value, and error messages are scrubbed of it before display.

  • Google Privacy Policy: https://policies.google.com/privacy
  • Google Terms of Service: https://policies.google.com/terms
  • reCAPTCHA overview: https://developers.google.com/recaptcha

Sites in regions where www.google.com is unreachable can point the browser script at Google’s www.recaptcha.net mirror using the checkout_bouncer_api_script_url filter.

What Checkout Bouncer stores on your own site

  • An events table ({prefix}checkout_bouncer_events) holding one row per verification, throttle trip or block: timestamp, surface, verdict, reason, score, an anonymised IP address, the order id where one exists, the payment gateway id and a short note. IPv4 addresses are stored with the final octet zeroed and IPv6 addresses with the last 80 bits zeroed. Rows older than your retention window (30 days by default) are deleted by a daily scheduled job, and you can clear the table at any time.
  • Throttle counters in transients, named using a site-salted, non-reversible hash of the IP address — a raw address is never written into a transient name. Billing email addresses are stored only as salted digests, never in plaintext, because the rule only needs to know whether two addresses differ.
  • Order notes recording what Checkout Bouncer decided about each order, its score and the threshold in force.
  • Optional lines in the standard WooCommerce logger, which never contain the token, the secret key or a full email address.

Uninstalling the plugin removes all of it: the settings, the transients, the scheduled job and the events table.

No other external requests

Google’s api.js and siteverify are the only outbound requests this plugin makes. There is no analytics, no licence check, no usage tracking, no remote font and no CDN asset of any kind.

무료유료 요금제에서
설치하면 WordPress.com 서비스 약관서드파티 플러그인 약관에 동의하게 됩니다.
테스트된 버전
WordPress 7.0.4
이 플러그인은 다운로드할 수 있으며 에서 사용할 수 있습니다.