Turnstile CAPTCHA For WooCommerceTurnstile CAPTCHA For WooCommerce
Buy Now
View Demo
  • Getting Started

    • Introduction
    • Quick Start
    • Features
    • Installation
    • First-Time Setup
    • Get Turnstile Keys
    • Onboarding Wizard
  • Settings

    • Settings Overview
    • API Settings
    • General
    • Design Studio
    • Conditional Rules
    • Per-Form Config
    • Notifications
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks
    • Shortcode
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting
    • Recovery URL
    • Email Digest
    • Webhooks
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health
  • Compare

    • vs reCAPTCHA
    • vs hCaptcha
  • Help

    • Troubleshooting
    • FAQ
    • Glossary
Support
Buy Now
View Demo
  • Getting Started

    • Introduction
    • Quick Start
    • Features
    • Installation
    • First-Time Setup
    • Get Turnstile Keys
    • Onboarding Wizard
  • Settings

    • Settings Overview
    • API Settings
    • General
    • Design Studio
    • Conditional Rules
    • Per-Form Config
    • Notifications
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks
    • Shortcode
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting
    • Recovery URL
    • Email Digest
    • Webhooks
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health
  • Compare

    • vs reCAPTCHA
    • vs hCaptcha
  • Help

    • Troubleshooting
    • FAQ
    • Glossary
Support
  • Getting Started

    • Introduction
    • Quick Start — Turnstile Live in 5 Minutes
    • Features — Everything the Plugin Can Do
    • Installation — Full Setup Guide
    • First-Time Setup
    • Get Turnstile Keys from Cloudflare
    • Onboarding Wizard
  • Settings

    • Settings Overview — All 9 Tabs
    • API Settings Tab
    • General Settings Tab
    • Design Studio Tab
    • Conditional Rules Tab
    • Per-Form Config Tab
    • Notifications Tab
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks Integration
    • Shortcode — Drop the Widget Anywhere
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting — Auto-Lockout for Abusive IPs
    • Recovery URL — Unlock a Stuck IP
    • Email Digest
    • Webhooks — Real-Time Alerts on Bot Spikes
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health Integration
  • Compare

    • Turnstile vs Google reCAPTCHA
    • Turnstile vs hCaptcha
  • Help

    • Troubleshooting
    • Frequently Asked Questions
    • Glossary

Troubleshooting

Most issues fall into one of a few buckets: keys wrong, caching plugin in the way, WP-Cron not firing, or a theme conflict. Start with the symptom that matches yours.

Widget Does Not Appear

Symptom: Form loads but no Turnstile widget

Checklist:

  1. Is the Site Key set on the API Settings tab? Empty = no widget
  2. Is the form ticked on its respective tab (WooCommerce / WordPress / WC Forms)?
  3. Do you have a caching plugin active? Flush cache + hard refresh
  4. Is your hostname in the Cloudflare widget's hostname list?
  5. Open browser DevTools → Console — any JS errors?
  6. Open DevTools → Network — does challenges.cloudflare.com/turnstile/v0/api.js load (200 OK)?

Caching Plugin Conflicts

PluginFix
WP RocketSettings → File Optimization → Exclude these URLs from JS concatenation: challenges.cloudflare.com. Also Settings → Cache → Exclude /my-account/, /checkout/
LiteSpeed CachePage Optimization → JS Settings → Exclude from JS Combine: cloudflare, turnstile. Purge all
AutoptimizeSettings → JS Options → Exclude scripts: turnstile, cloudflare
W3 Total CachePerformance → Minify → JS → Never minify URLs: challenges.cloudflare.com

After changing any cache setting, hard-refresh (Ctrl+Shift+R).

Theme Hook Conflicts

If your theme is aggressively overriding login_form, woocommerce_login_form, or comment_form hooks, the widget may render at the wrong position or not at all.

Fix: edit the theme's form template to include:

<?php echo do_shortcode('[wkcft-turnstile]'); ?>

At the position you want.

Validation Always Fails

Symptom: "Please complete the security check" on every submit

Check:

  1. Secret Key correct on the API Settings tab? Use the show/hide toggle to re-verify
  2. Click Test Connection on the API Settings tab — any error there is your real problem
  3. Does your server have outbound HTTPS to challenges.cloudflare.com? Test via SSH:
curl -X POST https://challenges.cloudflare.com/turnstile/v0/siteverify \
  -d "secret=YOUR_SECRET&response=test"

If this times out or returns an error, your firewall is blocking the API — contact hosting.

Cloudflare Error Codes

The error code in the log tells you exactly what failed:

CodeMeaningFix
missing-input-secretSecret Key field emptyPaste Secret Key, save
invalid-input-secretSecret Key is wrongRe-copy from Cloudflare dashboard
missing-input-responseToken not sent with formWidget did not render — check Site Key + caching
invalid-input-responseToken invalid / expiredTokens expire in 5 min. Usually caching. Flush cache
timeout-or-duplicateToken reused or aged outFull-page cache served the same token twice. Exclude form pages from cache
prohibited-replaySame token used twiceSame — caching issue
bad-requestMalformed request to CloudflareRare. Check curl works from your server

WP-Cron Not Running

Symptom: Email digest / webhook never fire

WP-Cron only runs when someone visits your site. Low-traffic = missed crons.

Fix 1 — Add Real Server Cron

Crontab entry that hits WP-Cron every 5 min:

*/5 * * * * wget -q -O - https://yoursite.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Add to wp-config.php to stop WordPress from running WP-Cron on every page load:

define('DISABLE_WP_CRON', true);

Fix 2 — Manually Trigger a Cron

Via WP-CLI:

wp cron event run wkcft_send_digest
wp cron event run wkcft_check_notifications

Or via a plugin like WP Crontrol (for non-CLI environments).

Verify Scheduled Hooks Exist

wp cron event list | grep wkcft

Should show:

wkcft_send_digest
wkcft_check_notifications
wkcft_logger_purge

Locked Out of wp-admin

Symptom: CAPTCHA is on wp-login, Cloudflare is down or widget won't load

Option 1 — Recovery URL:

https://yoursite.com/?wkcft_recovery=YOUR_TOKEN

Then log in normally.

Option 2 — Disable via database:

UPDATE wp_options SET option_value='no' WHERE option_name='wkcft_wp_login';

Or via WP-CLI:

wp option update wkcft_wp_login no

Option 3 — Deactivate plugin:

wp plugin deactivate turnstile-captcha-for-woocommerce

Widget in Wrong Position

Symptom: Widget shows above the form title or below the page footer

Theme-level hook interference.

Quick fix — use the shortcode at the right position:

  1. Turn OFF the auto-inject for that form (untick on settings tab)
  2. Edit the theme template that renders the form
  3. Insert <?php echo do_shortcode('[wkcft-turnstile]'); ?> at the correct position
  4. Save template

Logged-In User Still Sees CAPTCHA

Symptom: You turned on "Skip logged-in users" but widget still appears

Check:

  1. Conditions tab — is skip_logged_in really ticked? Save Changes?
  2. is_user_logged_in() returns false in your context? Some login issues show user as guest until refresh
  3. IP blacklist — is your current IP on the blacklist? Blacklist overrides skip rules
  4. Clear any page cache

Multiple Widgets on Same Page

Symptom: Two widgets render on a page with shortcode + auto-inject

Fix: If you added a manual shortcode, remove either the shortcode OR the auto-inject toggle for that form. Pick one.

For legitimate multi-widget pages (shortcode used twice), pass different IDs:

[wkcft-turnstile id="widget-newsletter"]
[wkcft-turnstile id="widget-contact"]

Analytics Page Empty

Symptom: "No data available" even though you have run form submits

Check:

  1. Is logging enabled? Check filter wkcft_log_enabled (default true)
  2. Is the table created? Run:
SHOW TABLES LIKE 'wp_wkcft_log';

If missing, deactivate + reactivate the plugin (activation creates the table).

  1. Date range — is it too narrow? Switch to "All time"
  2. Object cache — some caching plugins serve stale analytics data. Wait 5 min or disable object cache for wkcft_stats group

Rate-Limited By Mistake

Symptom: A real customer or your own IP got blocked

Fixes:

  1. Send them the Recovery URL
  2. Add their IP to the IP whitelist
  3. Wait out the lockout (default 5 min)
  4. SQL cleanup:
DELETE FROM wp_options WHERE option_name LIKE '_transient_wkcft_rl_%';

HTTPS Required

Symptom: Widget will not render on HTTP pages

Cloudflare Turnstile requires HTTPS. HTTP-only sites are not supported.

Fix: install an SSL certificate. Free option: Let's Encrypt via your host or Cloudflare's free SSL.

Order Placed Without CAPTCHA

Symptom: Orders are getting through without triggering CAPTCHA

Check:

  1. Is checkout enabled? wkcft_block_checkout should be yes
  2. Is the user on IP whitelist or country whitelist?
  3. Is warn-only mode on? Turn off on General tab
  4. Is the user logged in + skip_logged_in on? Expected behavior

Check the analytics dashboard — if checkout submissions are NOT in the log, the validator is not being called. Compatibility issue with another plugin that overrides the checkout process.

Performance Issues

Symptom: Admin analytics page slow

Fix:

  • Reduce log retention: filter wkcft_log_retention_days to 30
  • Manually purge old rows:
DELETE FROM wp_wkcft_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
  • Add covering indexes (already added by default — only needed if you wrote a custom query)

Symptom: Frontend pages slow

Fix:

  • Switch Load Mode to lazy with a 2-3s delay
  • Switch Appearance to execute for silent verification
  • Exclude form pages from full-page cache (cached pages with stale tokens cause issues)

Translation Not Appearing

Symptom: Plugin text shows in English despite locale set to French/Spanish/German/Portuguese

Check:

  1. Site locale: Settings → General → Site Language set correctly
  2. /wp-content/plugins/turnstile-captcha-for-woocommerce/languages/ folder contains the right .mo file for your locale
  3. WordPress locale: get_locale() returns the expected code
  4. Refresh object cache

Missing a language? Only de_DE, es_ES, fr_FR, pt_BR ship. For others, generate from the .pot template using Poedit or Loco Translate.

Still Stuck?

  • FAQ — Quick answers
  • Glossary — Plain-English definitions
  • Webkul Support: webkul.uvdesk.com
  • GitHub Issues (if public): the plugin's repo
Next
Frequently Asked Questions