Stopping Spam PayPal Orders in WooCommerce (Real Fix for reCAPTCHA Bypass)

If you run a WooCommerce store and suddenly notice dozens of failed PayPal payments appearing in your orders list, you’re not alone. I ran into the same issue on one of our client sites recently, and at first, I thought PayPal was glitching or customers were backing out before completing their payments. But after checking the logs, it became clear these weren’t real customers at all — they were bots.

The spam orders were flooding in at strange hours, all marked as failed or cancelled payments, and most of them originated from random countries that we don’t even sell to. After digging deeper, I realized the issue wasn’t actually with PayPal. The real problem was that Google reCAPTCHA was never triggered when someone clicked on the yellow PayPal Smart Button at checkout.

The Root Cause

If you’re using the official WooCommerce PayPal Payments plugin, you might have noticed it loads the PayPal button inside an iframe. That iframe belongs to PayPal’s domain, and because of that, your site’s JavaScript — including reCAPTCHA validation — can’t detect or block what happens inside it. In short, when a user (or a bot) clicks the PayPal Smart Button, it completely skips reCAPTCHA and opens the PayPal popup directly.

So even though reCAPTCHA protects your checkout form, it doesn’t protect PayPal’s iframe. Bots can hit that button directly, trigger a fake transaction attempt, and WooCommerce still logs it as a failed payment. Over time, this can flood your order list, trigger unnecessary webhooks, and even cause performance issues.

Finding the Fix

I didn’t want to disable PayPal Smart Buttons altogether because they genuinely improve conversions for real users. I just needed a way to make sure the button stays inactive until reCAPTCHA has been successfully verified. Since the PayPal iframe itself can’t be modified or intercepted, I decided to disable the PayPal button container until reCAPTCHA passes. That way, bots can’t even click it.

The idea was simple: when the checkout page loads, the PayPal button appears slightly greyed out and unclickable. Once a user ticks “I’m not a robot,” the script detects the verified token from reCAPTCHA and instantly re-enables the button. Real customers don’t even notice the delay, but bots are completely blocked.

Here’s the code snippet I used — you can drop it into your theme’s functions.php file or a small custom plugin:

add_action('wp_footer', function() {
if (is_checkout()) : ?>
<script>
(function() {
console.log('[PayPal Spam Fix] Script running...');

const paypalContainerId = '#ppc-button-ppcp-gateway';
let paypalContainer;

function disablePaypal() {
if (!paypalContainer) return;
paypalContainer.style.opacity = '0.4';
paypalContainer.style.pointerEvents = 'none';
}

function enablePaypal() {
if (!paypalContainer) return;
paypalContainer.style.opacity = '1';
paypalContainer.style.pointerEvents = 'auto';
}

function checkRecaptcha() {
if (typeof grecaptcha === 'undefined') {
disablePaypal();
return;
}

try {
let verified = false;
if (typeof grecaptcha.getResponse === 'function') {
for (let i = 0; i < 10; i++) {
const resp = grecaptcha.getResponse(i);
if (resp && resp.length > 0) {
verified = true;
break;
}
}
}
verified ? enablePaypal() : disablePaypal();
} catch (e) {
console.warn('[PayPal Spam Fix] Error checking reCAPTCHA:', e);
disablePaypal();
}
}

function init() {
paypalContainer = document.querySelector(paypalContainerId);
if (!paypalContainer) return;
disablePaypal();
setInterval(checkRecaptcha, 1000);
}

let tries = 0;
const wait = setInterval(() => {
tries++;
if (document.querySelector(paypalContainerId)) {
clearInterval(wait);
init();
} else if (tries > 20) {
clearInterval(wait);
}
}, 1000);
})();
</script>
<?php endif;
});

This script checks the reCAPTCHA status every second. When it detects a valid token, it makes the PayPal button clickable again. If the token expires or the user reloads the page, the button automatically becomes inactive until reCAPTCHA is solved again. It’s lightweight, safe, and doesn’t depend on modifying your reCAPTCHA plugin.

Improving User Experience

To avoid confusing customers, I added a small line of text above the PayPal button that says:

if (paypalContainer) {
const msg = document.createElement('div');
msg.textContent = 'Please verify "I am not a robot" to enable PayPal checkout.';
msg.style.fontSize = '13px';
msg.style.color = '#b00';
msg.style.marginBottom = '8px';
paypalContainer.parentNode.insertBefore(msg, paypalContainer);
}

This message only appears when the button is disabled. Once the reCAPTCHA is verified, the message stays visible for a moment and the PayPal button fades in naturally. It’s simple, clear, and prevents confusion for customers who might otherwise think the button is broken.

After implementing this, spam PayPal attempts stopped entirely. Bots couldn’t click the button anymore without passing reCAPTCHA, and since reCAPTCHA can’t be solved automatically by scripts, the fake checkout attempts vanished. Real customers continued using PayPal normally without noticing anything different.

No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *