WP Manifestindependent plugin directory
manifest / ecommerce / checkout-guard-rules

Checkout Guard Rules

Refuses WooCommerce orders that match rules you set on email, phone, address, country or network, with automatic rules built from order history, a separate rule for cash on delivery, an allow list that always wins, and a log of every decision.

by George Vasiliades · github.com/poseidonas/checkout-guard-rules · website

0stars
1release downloads
0forks

Install

The author publishes release zips, so WP-CLI can install straight from GitHub:

wp plugin install https://github.com/poseidonas/checkout-guard-rules/releases/download/v1.0.0/checkout-guard-rules.zip

Declares an update source (https://github.com/Poseidonas/checkout-guard-rules), so updates arrive through the plugin's own updater.

Readme

Checkout Guard Rules

Latest release WordPress 6.7+ WooCommerce 9.0+ PHP 8.0+ License GPL-2.0-or-later

Refuses WooCommerce orders that match rules you set on email address, phone, postcode, wording, country or network. Automatic rules build themselves from your order history, one payment method can be refused on its own while the rest stay open, an allow list always wins, and every decision is written to a log you can undo.

  • Author: George Vasiliades - https://github.com/Poseidonas
  • License: GPL-2.0-or-later
  • Requires WordPress 6.7 or newer
  • Requires PHP 8.0 or newer
  • Requires WooCommerce 9.0 or newer, tested up to 11.0
  • Compatible with High-Performance Order Storage and with the cart and checkout blocks
  • Settings live in WooCommerce > Checkout Guard

Nothing is refused until you say so. On a fresh install the plugin runs in log-only mode, so you can watch what your rules would have done before a single sale is at risk.

What was measured before writing this

Measured on WooCommerce 11.0.1 with a stock store:

Question Result
What does the core offer against fraudulent orders? Nothing. Only a restriction on which countries you sell and ship to. No option exists holding a blocked email, address or network
Where does the classic checkout validate? woocommerce_after_checkout_validation, with the posted data and a WP_Error
Where does the block checkout validate? woocommerce_checkout_validate_order_before_payment, which despite its name fires only from the Store API (OrderController.php:209) and turns a WP_Error into a 400
Is there order history to build rules from? Yes. The wc_orders table of HPOS carries an ip_address column, and wc_get_orders() accepts customer_ip_address and billing_email directly
How does WooCommerce decide a customer's address? WC_Geolocation::get_ip_address() returns HTTP_X_REAL_IP without checking that the request came through a proxy at all

The last row is why this plugin resolves the address itself. On a site with no proxy in front of it, anybody can send X-Real-IP: 1.2.3.4 by hand and walk straight past a network rule, or put an innocent customer's address in that header and have them refused. Verified in the lab: with a forged header, this plugin kept using the real connection address while WooCommerce recorded the forged one on the order.

So the plugin ships with proxy headers off, and the settings page shows the connection address, whatever the headers claim, which one the rules use and which one WooCommerce writes on orders, side by side.

Modes

Log only is the default. Rules are evaluated, matches are written to the log, and nothing is refused. This is how you find out that a rule you were about to switch on would have cost you eleven real sales.

Refuse the order turns the same rules into refusals.

The message the customer sees is yours to write and never names the rule that matched, because that would tell a determined buyer exactly what to change.

Block lists

One entry per line. An empty list does nothing.

List How it is compared
Email addresses Exact, ignoring letter case. An asterisk stands for anything, so *@spam.test covers the domain
Email domains Written without the at sign. throwaway.io also covers mail.throwaway.io
Phone numbers On the last nine digits, so +30 690 123 4567, 0030-690-123-4567 and 6901234567 are the same number
Addresses and networks A single address, or a range in CIDR form. IPv4 and IPv6 both work, so 2001:db8:1234::/48 is a valid entry
Postcodes Ignoring spaces and letter case, so SW1A 1AA matches sw1a1aa
Wording in the name or address Found anywhere inside the name, street and city
Countries Picked from the WooCommerce country list

The billing address is always checked. When the shipping address differs, its country, postcode, street, city and name are checked as well.

The allow list

Checked before anything else. An email address or a network here is never refused, whatever the block lists and the automatic rules say. This exists so that one broad rule cannot cost you a good customer, and it is the reason automatic rules are safe to switch on.

Automatic rules from order history

Written as a sentence you can read: refuse a buyer with 3 orders within 30 days that ended as Cancelled or Failed, counted by email address or by network address.

The count comes from real orders through wc_get_orders(), so it works on High-Performance Order Storage and on the older storage alike. Only the statuses you tick count, and only orders inside the window.

Counting by network catches the buyer who returns with a fresh email address. Counting by email catches the buyer who returns from a different connection. Neither is right for every shop, which is why you choose.

Rules for one payment method

The same kinds of rule, applied to payment methods you pick rather than to the order. Cash on delivery is the usual case: a buyer who keeps refusing deliveries loses cash on delivery while card and bank transfer stay open, so you keep the sale instead of losing it.

Where the rule can be decided before the customer types anything, that is, by network or by country, the payment method is simply not offered. Where it depends on the email address, the order is refused with your message once the address is known.

The log

Every match, in both modes: when, the buyer, the address, which checkout and which payment method, the rule that matched, and whether the order was refused or only logged.

Each row with an email address carries Not right, allow this buyer, which adds that address to the allow list and removes the row in one step. That is the undo, and it is the reason log-only mode is worth running first.

The log keeps a number of entries you set, oldest dropping off the end. Since it holds customer email addresses and network addresses, it answers to the WordPress personal data eraser: erasing a person's data removes their rows.

Honest limits

  • The plugin refuses orders. It does not detect fraud. A rule is only as good as what you put in it.
  • A network rule is worth as much as the address behind it. Read the section on proxy headers above, and check the table on the settings page before writing one.
  • Automatic rules read order history, so a shop with no history yet has nothing to go on.
  • Blocking a country here refuses the order at checkout. If you never want to sell there at all, the WooCommerce setting for selling countries is the better tool, because it also stops the customer earlier.
  • Wording rules match plain substrings. A short word matches a great deal, so keep them specific.
  • Orders created in the admin or through the REST API are not checked. This guards the checkout a customer uses.

Filters

add_filter( 'icxcnika_guard_reasons', function ( array $reasons, array $order, string $gateway ): array {
    return $reasons;
}, 10, 3 );

add_filter( 'icxcnika_guard_settings', function ( array $settings ): array {
    return $settings;
} );

icxcnika_guard_reasons receives every reason a checkout matched, and is the last word before the plugin acts. Return an empty array to let the order through, or add your own reason to refuse it. icxcnika_guard_registry_payload receives the data sent to the installation registry.

Data stored

  • Option icxcnika_guard_settings (the rules).
  • Option icxcnika_guard_log (the log).
  • Option icxcnika_guard_registry_key (random installation key of 48 characters, created only if installation reporting is active).
  • Transient icxcnika_guard_release (cached GitHub release lookup, 12 hours).
  • Cron event icxcnika_guard_registry_ping (weekly, only if installation reporting is active).

Nothing is written to the orders table and nothing of WooCommerce is changed.

Installation reporting

On activation, on deactivation and once a week the plugin sends a small JSON message to the author's installation registry: plugin slug, plugin version, home URL, site URL, WordPress version, WooCommerce version, PHP version, locale and whether the site is a multisite. Each report carries a random installation key generated locally on first use. No customer data, order data or log data is ever sent.

The reporting address is empty by default, which means nothing is sent at all. Add define( 'ICXCNIKA_REGISTRY_DISABLE', true ); to wp-config.php to turn the reporting off, or define( 'ICXCNIKA_REGISTRY_URL', '...' ); to point it elsewhere.

Updates

Updates are delivered from GitHub Releases through the Update URI header of WordPress. The Plugins screen shows View details and allows automatic updates to be enabled, exactly as for a plugin from the directory.

Uninstall

Deleting the plugin removes both options, the installation key, the cached release check and the scheduled report. Orders, customers and WooCommerce settings are left exactly as they were.


Checkout Guard Rules (Ελληνικά)

Απορρίπτει παραγγελίες WooCommerce που ταιριάζουν σε κανόνες τους οποίους ορίζετε σε διεύθυνση email, τηλέφωνο, ταχυδρομικό κώδικα, διατύπωση, χώρα ή δίκτυο. Οι αυτόματοι κανόνες χτίζονται μόνοι τους από το ιστορικό παραγγελιών, μία μέθοδος πληρωμής μπορεί να απορριφθεί μόνη της ενώ οι υπόλοιπες μένουν ανοιχτές, η λίστα επιτρεπτών υπερισχύει πάντα, και κάθε απόφαση γράφεται σε ημερολόγιο που μπορείτε να αναιρέσετε.

  • Δημιουργός: George Vasiliades - https://github.com/Poseidonas
  • Άδεια: GPL-2.0-or-later
  • Απαιτεί WordPress 6.7 ή νεότερο
  • Απαιτεί PHP 8.0 ή νεότερη
  • Απαιτεί WooCommerce 9.0 ή νεότερο, δοκιμασμένο έως 11.0
  • Συμβατό με το High-Performance Order Storage και με τα μπλοκ καλαθιού και ταμείου
  • Οι ρυθμίσεις βρίσκονται στο WooCommerce > Checkout Guard

Τίποτα δεν απορρίπτεται μέχρι να το πείτε εσείς. Σε νέα εγκατάσταση το πρόσθετο τρέχει σε λειτουργία μόνο καταγραφής, ώστε να δείτε τι θα έκαναν οι κανόνες σας πριν κινδυνέψει έστω μία πώληση.

Τι μετρήθηκε πριν γραφτεί

Μετρήθηκε σε WooCommerce 11.0.1 με κατάστημα χωρίς παρεμβάσεις:

Ερώτημα Αποτέλεσμα
Τι προσφέρει ο πυρήνας απέναντι σε δόλιες παραγγελίες; Τίποτα. Μόνο περιορισμό στις χώρες πώλησης και αποστολής. Δεν υπάρχει καμία option με μπλοκαρισμένο email, διεύθυνση ή δίκτυο
Πού επικυρώνει το κλασικό ταμείο; woocommerce_after_checkout_validation, με τα υποβληθέντα δεδομένα και ένα WP_Error
Πού επικυρώνει το ταμείο με μπλοκ; woocommerce_checkout_validate_order_before_payment, που παρά το όνομά του εκπέμπεται μόνο από το Store API (OrderController.php:209) και μετατρέπει ένα WP_Error σε 400
Υπάρχει ιστορικό παραγγελιών για κανόνες; Ναι. Ο πίνακας wc_orders του HPOS έχει στήλη ip_address, και το wc_get_orders() δέχεται απευθείας customer_ip_address και billing_email
Πώς αποφασίζει το WooCommerce τη διεύθυνση του πελάτη; Το WC_Geolocation::get_ip_address() επιστρέφει το HTTP_X_REAL_IP χωρίς να ελέγξει καν αν το αίτημα πέρασε από proxy

Η τελευταία γραμμή είναι ο λόγος που αυτό το πρόσθετο βρίσκει μόνο του τη διεύθυνση. Σε ιστότοπο χωρίς proxy μπροστά του, οποιοσδήποτε στέλνει X-Real-IP: 1.2.3.4 με το χέρι και προσπερνά κατευθείαν έναν κανόνα δικτύου, ή βάζει τη διεύθυνση ενός αθώου πελάτη σε εκείνη την κεφαλίδα και τον κάνει να απορριφθεί. Επαληθεύτηκε στο εργαστήριο: με πλαστή κεφαλίδα, το πρόσθετο συνέχισε να χρησιμοποιεί την πραγματική διεύθυνση σύνδεσης ενώ το WooCommerce κατέγραψε την πλαστή στην παραγγελία.

Γι' αυτό το πρόσθετο έρχεται με τις κεφαλίδες proxy απενεργοποιημένες, και η σελίδα ρυθμίσεων δείχνει δίπλα δίπλα τη διεύθυνση σύνδεσης, ό,τι ισχυρίζονται οι κεφαλίδες, ποια χρησιμοποιούν οι κανόνες και ποια γράφει το WooCommerce στις παραγγελίες.

Λειτουργίες

Μόνο καταγραφή είναι η προεπιλογή. Οι κανόνες αξιολογούνται, τα ταιριάσματα γράφονται στο ημερολόγιο, και τίποτα δεν απορρίπτεται. Έτσι ανακαλύπτετε ότι ένας κανόνας που ετοιμαζόσασταν να ενεργοποιήσετε θα σας είχε κοστίσει έντεκα πραγματικές πωλήσεις.

Απόρριψη της παραγγελίας μετατρέπει τους ίδιους κανόνες σε απορρίψεις.

Το μήνυμα που βλέπει ο πελάτης το γράφετε εσείς και δεν αναφέρει ποτέ τον κανόνα που ταίριαξε, γιατί έτσι θα λέγατε σε έναν αποφασισμένο αγοραστή ακριβώς τι να αλλάξει.

Read the full README on GitHub →

Releases

TagPublishedAssetDownloads
v1.0.0 Aug 19, 2026 checkout-guard-rules.zip 1