If your WooCommerce or PrestaShop store runs on your own server or a basic hosting plan, every request from the internet goes straight to PHP: real shoppers, price scrapers, and the bots that try known exploits against every shop they can find. A web application firewall (WAF) sits in front and drops the obvious attacks before they reach your store.

Cloudflare's free plan includes one. It will not make an unpatched plugin safe, but it blocks a set of widely exploited attacks for no money and very little setup. The part that catches shop owners out is not the firewall itself: it is the payment provider's webhook, the background call that tells your store "this order was paid". Block that, and customers are charged while the order sits on "pending payment". This guide sets up the firewall and keeps those calls working.
What the free plan actually gives you
- The proxy. Your domain's traffic goes through Cloudflare first, and visitors see Cloudflare's addresses instead of your server's.
- The Free Managed Ruleset. Cloudflare describes it as protection against "high-impact and widely exploited vulnerabilities", safe to deploy on most applications. It is a subset of the full Cloudflare Managed Ruleset and, per Cloudflare's getting-started guide, deployed by default on Free plans. The broader Managed Ruleset and the OWASP Core Ruleset need Pro or higher.
- Five custom rules. Enough to add one exception for your payment webhooks and a couple of rules of your own. Regex matching is not available on Free, so rules use plain matches like
containsandeq.
Step 1: move DNS to Cloudflare and switch on the proxy
- Add your domain to a free Cloudflare account. It copies your existing DNS records.
- Check every record against your current DNS provider, especially MX and TXT records for email. A missed record here breaks order emails, not the shop.
- Set the shop's
A/CNAMErecords (the root domain andwww) to Proxied (orange cloud). Leave mail-related records DNS only. - Change the nameservers at your domain registrar to the two Cloudflare gives you.
- Under SSL/TLS, set the mode to Full (strict) if your server already has a valid certificate. "Flexible" leaves the hop to your server unencrypted and often causes redirect loops in WooCommerce.
Step 2: confirm the Free Managed Ruleset is running
Do not assume; check. In the dashboard, open your domain's Security settings and look under web application exploits / managed rules. The Free Managed Ruleset should show as deployed, which appears as a rule with an Execute action. If it is off, turn it on and save.
Leave it running for a day and look at Security → Events. You will usually see blocked probes for paths that do not exist on your shop. That is the firewall doing its job. If you see a real customer action blocked (for example a checkout request), note the rule ID before changing anything.
Step 3: keep payment webhooks out of the firewall's way
Find the exact webhook address your payment plugin uses. For the official WooCommerce Stripe extension it is your site URL with ?wc-api=wc_stripe on the end, for example https://www.example.com/?wc-api=wc_stripe; WooCommerce shows it under WooCommerce → Settings → Payments → Stripe. PayPal, Mollie, PrestaShop payment modules and shipping/courier integrations each have their own; their settings page or the provider's dashboard lists it.

Then add one custom rule with the Skip action (Security rules → Create rule → Custom rules):
Rule name: Payment webhooks skip managed rules
Expression: (http.request.uri.query contains "wc-api=wc_stripe")
or (http.request.uri.path contains "/wc-api/")
Action: Skip -> All managed rules
Adjust the expression to the addresses you found, and keep it as narrow as possible: skip only the webhook URLs, never /wp-admin or the whole site. Skipping is reasonable here because providers like Stripe sign every webhook and your plugin checks that signature; the firewall adds little on that one URL.
One setting cannot be fixed with an exception: Bot Fight Mode. Cloudflare says it "may challenge API or mobile app traffic" and that you "cannot bypass or skip Bot Fight Mode using WAF custom rules". A webhook is exactly that kind of traffic. On a shop that relies on webhooks, leave Bot Fight Mode off (Security settings → Bot traffic). The managed ruleset is the part you want anyway.
Step 4: lock your server so only Cloudflare can reach it
A firewall in front is useless if attackers can go around it. Your old server IP is still in DNS history, and scanners hit IP addresses directly. Cloudflare's own advice is to block all traffic to your web server that does not come from Cloudflare's IP ranges, which it publishes at cloudflare.com/ips.

On your own Ubuntu server with UFW, allow web traffic only from those ranges (keep your SSH rule as it is):
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do sudo ufw allow from "$ip" to any port 443 proto tcp; done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do sudo ufw allow from "$ip" to any port 443 proto tcp; done
sudo ufw status numbered
Then delete any older rule that allows 80 or 443 from anywhere (sudo ufw delete <number>). Cloudflare adds ranges occasionally, so re-run this every few months. If you are technical, a Cloudflare Tunnel goes further: the server makes an outbound connection to Cloudflare and needs no open web port at all.
On shared or managed hosting you cannot touch the firewall. Ask your host instead: "Can you restrict web access to my account to Cloudflare's IP ranges, or do you support Cloudflare Authenticated Origin Pulls?" Many WordPress hosts have a switch for this.
Step 5: test a real order before the sales start
- Put Stripe (or PayPal) in test mode and place an order with a test card.
- Confirm the order moves to Processing by itself within a minute. If it stays on "pending payment", the webhook is being blocked.
- In Stripe's dashboard, open the webhook endpoint and check the latest deliveries returned
200. A403means the firewall or Bot Fight Mode stopped it; Security → Events will show which. - Repeat for every gateway and courier integration you use.
- Switch payments back to live mode.
Stripe can disable a webhook endpoint after it fails repeatedly, so if you find failures, fix them and re-enable the endpoint in Stripe's webhook settings.
What this does not do
- It does not patch your shop. Keep WordPress, WooCommerce or PrestaShop, PHP and every plugin updated. The free ruleset covers widely exploited flaws, not every flaw.
- It does not protect a URL you skipped. That is why the skip rule names only webhook addresses.
- It does not stop logged-in abuse. A stolen admin password still works. Turn on two-factor login for every admin account.
Budget an afternoon: an hour for DNS, ten minutes for the rules, and the rest for test orders. Do it now rather than in the week of Black Friday, when a broken webhook costs real orders.
Sources
- Managed Rules (Cloudflare docs)
- WAF: Get started (Cloudflare docs)
- Custom rules and Skip options (Cloudflare docs)
- Bot Fight Mode (Cloudflare docs)
- Allow Cloudflare IP addresses (Cloudflare docs)
- Cloudflare Tunnel (Cloudflare docs)
- Stripe webhooks for WooCommerce (WooCommerce docs)


