WooCommerce Credit Card Skimmers: How They Hide and How to Remove Them
By Glenn Lyvers · Updated · 7 min read
If customers are reporting fraudulent charges after buying from your WooCommerce store, assume a card skimmer until you have proven otherwise. A skimmer is a small piece of malicious code — sometimes JavaScript in the checkout page, sometimes PHP buried in the store itself — that copies card numbers as they are typed and sends them to the attacker. The store keeps working, orders keep going through, and nothing looks wrong from the outside. That invisibility is the point, and it is why skimmers routinely run for months before anyone connects the fraud reports back to the store.
I clean these up regularly, and they are a different animal from the redirect hacks and spam injections that make up most of my work. A skimmer compromise touches real cardholder data, which changes both how carefully the cleanup has to be done and what you are obligated to do afterward. Here is how they work, where they hide, and how I get them out.
How a skimmer actually captures cards
There are two families, and they hide in completely different places.
The first is the browser-side skimmer, the kind the security press calls Magecart. It is JavaScript that runs on your checkout page, watches the card number, expiry, and CVV fields, and quietly posts a copy of whatever the customer types to a server the attacker controls. The customer's order completes normally — the skimmer does not interfere with payment, because interfering would get it noticed.
The second is the server-side skimmer, and it is the nastier of the two. This is PHP code hooked into WooCommerce's checkout processing that copies payment fields out of the form submission on the server, after the customer hits Place Order. Nothing malicious ever appears in the page source, so scanning the checkout page in a browser shows a clean site. I have found these appended to gateway plugin files, hiding in theme functions.php, and dressed up as a fake payment-logging plugin with a plausible name.
Whether your gateway setup protects you
It matters enormously how your store collects cards. If checkout redirects the customer away to PayPal or to a hosted payment page, the card number is typed on the processor's site, not yours — a skimmer on your server has much less to steal, though attackers have countered this by injecting a fake card form that appears before the redirect and harvests the number the customer helpfully types into it.
If your store uses embedded card fields inside an iframe from the gateway — the way Stripe Elements works — the card data lives in a frame your page's JavaScript cannot read, which blocks the classic keystroke-reading skimmer. But it does not block a fake-form overlay, and it does nothing against server-side code if your gateway configuration ever posts card data through your server. Hosted and iframe checkouts shrink the target; they do not eliminate it.
The signs I look for
The pattern that should set off alarms is fraud reports that cluster: several customers, all of whom bought from your store recently, all reporting misuse of the same card they used at checkout. One report is a coincidence. Three is a signal. Banks and processors sometimes spot the pattern first — if your payment processor emails you about a possible common point of purchase, take it seriously the same hour.
On the technical side, I open the checkout page with the browser's network tools and watch every request it makes while I fill the form with test data. A skimmer has to send the stolen data somewhere, and that outbound request — often to a domain that looks almost legitimate, a misspelled analytics service or a lookalike of a real CDN — is the smoking gun. I also diff the checkout page's scripts against what the theme and plugins actually ship, and I check whether any script only loads when the URL contains checkout. Skimmers frequently condition themselves to run only on payment pages to stay out of sight everywhere else.
Where the code hides
On WooCommerce sites I have cleaned, skimming code turns up in a short list of places. Theme files, especially functions.php and checkout template overrides in the theme's woocommerce/ folder. Plugin files, most often inside the payment gateway plugin itself, where extra code blends in with legitimate payment logic. The database — injected into rows that render on every page, or stashed in an option the theme prints into the footer. And standalone JavaScript files in wp-content/uploads/, which should never contain executable files at all.
The database hiding spots deserve their own attention, because file scanners never see them — I wrote a separate guide to malware in the WordPress database that covers exactly where to look. And wherever the skimmer itself lives, there is nearly always a backdoor planted separately from it, so the attacker can put the skimmer back after you remove it. Cleaning the skimmer without finding the backdoor is how stores end up re-skimmed three weeks later — the same reinfection loop I see with every other hack type, except here each round of reinfection costs your customers real money.
Cleanup, in the order that works
Take payments offline first. I know no store owner wants to hear it, but every hour checkout stays up with a skimmer on it is another batch of stolen cards, and your liability grows with each one. Put the store in maintenance mode or disable the checkout — a day of lost orders is cheaper than what fraudulent-use chargebacks and a forensic investigation cost.
Then the cleanup itself follows the same discipline as any serious compromise: full backup of the infected state for evidence, then reinstall WordPress core, the theme, and every plugin from fresh official copies rather than trusting file-by-file inspection, then audit everything that cannot be reinstalled — the database, uploads, and configuration. Rotate every secret: admin passwords, database password, the keys and salts in wp-config.php (my wp-config guide has the full rotation list), and critically, your payment gateway API keys, because a skimmer operator with gateway credentials does not need your website at all. Check for admin accounts you did not create while you are in there.
The part nobody wants to hear: disclosure
A skimmer is not just malware, it is a cardholder-data breach, and that carries obligations the average hacked site does not. Contact your payment processor and tell them what you found — they have seen this before, they can tell you the window of exposure from their side, and hiding it from them is the one move that can get your merchant account terminated permanently. Depending on where you and your customers are, notification duties to affected customers may apply, and being straight with people is also simply the right thing to do: a short honest email telling customers who bought during the exposure window to watch their statements does less damage to your reputation than the story getting out any other way.
I am not a lawyer and this is not legal advice — for a breach involving card data it is worth an hour of a real one's time. What I can tell you from the stores I have cleaned is that the ones who notified quickly kept their customers, and the ones who sat on it did not.
Keeping the next one off your checkout
Most of the prevention story is ordinary hardening done consistently: updates applied promptly, no nulled plugins ever, strong unique admin passwords, and file-integrity monitoring so a modified gateway plugin gets flagged the day it changes instead of the month the fraud reports arrive. Wordfence's scanner comparing plugin files against the official repository copies is genuinely useful here.
Checkout-specific measures are worth the extra effort on a store. Keep the checkout page lean — every third-party script that loads there is something that can be compromised upstream and turned into a skimmer without your site ever being touched. Prefer iframe or hosted payment fields over card fields your own page renders. And make a habit of watching the network traffic on your own checkout once in a while; sixty seconds with the network tab open is the cheapest skimmer scan there is.
If you are staring at fraud reports right now and want the whole thing handled — confirmation, cleanup, backdoor hunt, key rotation, and a straight answer on what the exposure window was — that is exactly the kind of job my Bulletproof Cleaning exists for. Card-data cases get treated as the emergencies they are. And if you are not sure yet whether what you are seeing is a skimmer, start with the free scan and go from there.
Common questions
How do I know if my WooCommerce store has a card skimmer?
The strongest signal is fraud reports that cluster: several recent customers all reporting misuse of the card they used at your checkout. To check technically, open your checkout page with the browser's network tools, fill the form with test data, and watch for requests going to domains you don't recognize. A file scan alone can miss it — server-side skimmers never appear in the page source at all.
My store redirects customers to PayPal — can I still have a skimmer?
Redirect and hosted checkouts shrink the risk but don't remove it. A common trick is injecting a fake card form that appears before the redirect, harvesting whatever the customer types into it. If cards are never typed on your domain and no fake form has been added, your exposure is much lower — but the fake-form check still has to be done.
Do I have to tell my customers about a card skimmer?
A skimmer is a cardholder-data breach, not just malware. Contact your payment processor the same day you confirm it — concealing a breach is the one move that can get a merchant account terminated permanently — and get real legal advice about customer notification duties where you operate. In my experience the stores that notified customers quickly kept them; the ones that sat on it did not.
Will reinstalling my plugins remove a skimmer?
Reinstalling replaces infected plugin files, which helps, but skimming code also hides in the database, and there is nearly always a separate backdoor planted so the attacker can put the skimmer back after a cleanup. Without the backdoor hunt and a full rotation of passwords and payment-gateway API keys, it returns.
Should I take my store offline when I find a skimmer?
Take payments offline immediately. Every hour the checkout stays live is another batch of stolen cards and more liability for you. A day or two of lost orders is far cheaper than the chargebacks, forensics, and reputation damage of a longer exposure window.