{"id":183,"date":"2026-03-12T12:16:42","date_gmt":"2026-03-12T12:16:42","guid":{"rendered":"https:\/\/igfirst.com.ng\/resources\/docs\/cloudflare-setup-for-woocommerce-igfirsterp-sync\/"},"modified":"2026-03-12T14:43:29","modified_gmt":"2026-03-12T14:43:29","password":"","slug":"cloudflare-setup-for-woocommerce-igfirsterp-sync","status":"publish","type":"docs","link":"https:\/\/igfirst.com.ng\/resources\/docs\/cloudflare-setup-for-woocommerce-igfirsterp-sync\/","title":{"rendered":"Cloudflare Setup for WooCommerce + IGFirstERP Sync (No 403 Errors)"},"content":{"rendered":"<h2>Problem<\/h2>\n<p>Many WooCommerce businesses turn on too many Cloudflare protections at once. The site looks secure, but IGFirstERP stock and order sync starts failing with blocked responses.<\/p>\n<p>A common failure pattern is:<\/p>\n<ul>\n<li>Woo API call returns HTTP <code>403<\/code><\/li>\n<li>Response is not valid JSON<\/li>\n<li>ERP logs show <code>JSON ERROR: Syntax error<\/code><\/li>\n<li>Stock sync jobs retry and queue pressure increases<\/li>\n<\/ul>\n<h2>Who this is for<\/h2>\n<ul>\n<li>Founders running WooCommerce with IGFirstERP<\/li>\n<li>Operations teams managing stock sync reliability<\/li>\n<li>Technical support teams configuring Cloudflare rules<\/li>\n<\/ul>\n<h2>Prerequisites<\/h2>\n<ul>\n<li>WooCommerce store is live behind Cloudflare<\/li>\n<li>IGFirstERP Woo integration is active<\/li>\n<li>You can edit Cloudflare WAF, Rate Limiting, and Cache Rules<\/li>\n<li>You can test Woo API health from ERP after rule changes<\/li>\n<\/ul>\n<h2>Steps<\/h2>\n<h3>In simple terms<\/h3>\n<p>Cloudflare should filter abuse, not block business traffic. If Cloudflare challenges real API calls, IGFirstERP gets HTML challenge pages instead of JSON, and sync breaks.<\/p>\n<h3>1. Why this 403 + JSON syntax error happens<\/h3>\n<p>IGFirstERP Woo sync jobs expect JSON responses from Woo endpoints. When Cloudflare blocks or challenges these calls, the response body can become HTML. ERP then logs JSON parse failures like <code>JSON ERROR: Syntax error<\/code> with HTTP 4xx\/5xx.<\/p>\n<h3>2. Keep these controls ON (Do This)<\/h3>\n<div class=\"igf-checklist-box igf-checklist-do\">\n<h4>Enable this baseline first<\/h4>\n<ul>\n<li>Targeted custom WAF rules, not blanket global blocking<\/li>\n<li>Targeted rate limits on abuse-heavy catalog requests<\/li>\n<li>Cache bypass for Woo dynamic routes and query flags<\/li>\n<li>Aggressive static asset caching only for safe file types<\/li>\n<li>API and callback-safe exceptions where needed<\/li>\n<\/ul>\n<\/div>\n<h3>3. Keep these controls OFF (Avoid This)<\/h3>\n<div class=\"igf-checklist-box igf-checklist-avoid\">\n<h4>Avoid these misconfigurations<\/h4>\n<ul>\n<li>Blanket challenge or block on all <code>POST<\/code> requests<\/li>\n<li>Aggressive challenge on all <code>\/wp-json\/*<\/code> routes<\/li>\n<li>Cache on checkout, cart, my-account, or wp-admin paths<\/li>\n<li>Global over-hardening toggles without endpoint exceptions<\/li>\n<li>Large security changes during promo windows without staged validation<\/li>\n<\/ul>\n<\/div>\n<h3>4. Free-plan-safe Cloudflare expressions (step cards)<\/h3>\n<p>These expressions avoid the <code>matches<\/code> operator and work on free plans.<\/p>\n<div class=\"igf-step-grid\">\n<section class=\"igf-step-card\">\n<h4>Step 4.1: Sensitive probes block<\/h4>\n<div class=\"igf-step-meta\">\n<p><strong>Cloudflare path:<\/strong> Security -> WAF -> Custom Rules -> Create rule<\/p>\n<p><strong>Rule name:<\/strong> <code>Block sensitive path probes<\/code><\/p>\n<p><strong>Action:<\/strong> <code>Block<\/code><\/p>\n<\/p><\/div>\n<pre><code>(http.host eq \"example.com\" or http.host eq \"www.example.com\")\nand not cf.client.bot\nand (\n  starts_with(lower(http.request.uri.path), \"\/.env\")\n  or starts_with(lower(http.request.uri.path), \"\/.git\")\n  or starts_with(lower(http.request.uri.path), \"\/.svn\")\n  or lower(http.request.uri.path) eq \"\/wp-config.php\"\n  or lower(http.request.uri.path) eq \"\/phpinfo.php\"\n  or lower(http.request.uri.path) eq \"\/composer.json\"\n  or lower(http.request.uri.path) eq \"\/composer.lock\"\n  or lower(http.request.uri.path) contains \"\/vendor\/\"\n)<\/code><\/pre>\n<p class=\"igf-step-verify\"><strong>Quick verification:<\/strong> probe requests such as <code>\/.env<\/code> should be blocked at edge.<\/p>\n<\/section>\n<section class=\"igf-step-card\">\n<h4>Step 4.2: User enumeration challenge<\/h4>\n<div class=\"igf-step-meta\">\n<p><strong>Cloudflare path:<\/strong> Security -> WAF -> Custom Rules -> Create rule<\/p>\n<p><strong>Rule name:<\/strong> <code>Challenge user enumeration<\/code><\/p>\n<p><strong>Action:<\/strong> <code>Managed Challenge<\/code><\/p>\n<\/p><\/div>\n<pre><code>(http.host eq \"example.com\" or http.host eq \"www.example.com\")\nand not cf.client.bot\nand (\n  lower(http.request.uri.path) eq \"\/wp-json\/wp\/v2\/users\"\n  or starts_with(lower(http.request.uri.query), \"author=\")\n  or lower(http.request.uri.query) contains \"&amp;author=\"\n  or lower(http.request.uri.query) contains \"rest_route=\/wp\/v2\/users\"\n)<\/code><\/pre>\n<p class=\"igf-step-verify\"><strong>Quick verification:<\/strong> normal storefront traffic works, while user-enumeration patterns are challenged.<\/p>\n<\/section>\n<section class=\"igf-step-card\">\n<h4>Step 4.3: Filtered catalog challenge<\/h4>\n<div class=\"igf-step-meta\">\n<p><strong>Cloudflare path:<\/strong> Security -> WAF -> Custom Rules -> Create rule<\/p>\n<p><strong>Rule name:<\/strong> <code>Challenge filtered catalog abuse<\/code><\/p>\n<p><strong>Action:<\/strong> <code>Managed Challenge<\/code><\/p>\n<\/p><\/div>\n<pre><code>(http.host eq \"example.com\" or http.host eq \"www.example.com\")\nand (http.request.method in {\"GET\" \"HEAD\"})\nand (\n  starts_with(lower(http.request.uri.path), \"\/shop\")\n  or starts_with(lower(http.request.uri.path), \"\/product-category\/\")\n)\nand (\n  lower(http.request.uri.query) contains \"min_price=\"\n  or lower(http.request.uri.query) contains \"max_price=\"\n  or lower(http.request.uri.query) contains \"orderby=\"\n  or lower(http.request.uri.query) contains \"filter_\"\n  or lower(http.request.uri.query) contains \"s=\"\n)\nand not cf.client.bot\nand not (lower(http.request.uri.query) contains \"wc-ajax=\")\nand not (http.cookie contains \"wordpress_logged_in_\")\nand not (http.cookie contains \"woocommerce_items_in_cart\")\nand not (http.cookie contains \"woocommerce_cart_hash\")<\/code><\/pre>\n<p class=\"igf-step-verify\"><strong>Quick verification:<\/strong> high-cost filter scraping gets challenged while normal customer browsing still loads.<\/p>\n<\/section>\n<section class=\"igf-step-card\">\n<h4>Step 4.4: Dynamic Woo cache bypass<\/h4>\n<div class=\"igf-step-meta\">\n<p><strong>Cloudflare path:<\/strong> Caching -> Cache Rules -> Create rule<\/p>\n<p><strong>Rule name:<\/strong> <code>Bypass Woo dynamic routes<\/code><\/p>\n<p><strong>Action:<\/strong> <code>Bypass cache<\/code><\/p>\n<\/p><\/div>\n<pre><code>(http.host eq \"example.com\" or http.host eq \"www.example.com\")\nand (\n  starts_with(lower(http.request.uri.path), \"\/wp-admin\/\")\n  or lower(http.request.uri.path) eq \"\/wp-login.php\"\n  or starts_with(lower(http.request.uri.path), \"\/cart\")\n  or starts_with(lower(http.request.uri.path), \"\/checkout\")\n  or starts_with(lower(http.request.uri.path), \"\/my-account\")\n  or lower(http.request.uri.query) contains \"wc-ajax=\"\n  or lower(http.request.uri.query) contains \"add-to-cart=\"\n)<\/code><\/pre>\n<p class=\"igf-step-verify\"><strong>Quick verification:<\/strong> cart, checkout, and account should remain dynamic with no cached user state.<\/p>\n<\/section>\n<section class=\"igf-step-card\">\n<h4>Step 4.5 (Optional): Allow WooCommerce mobile app traffic<\/h4>\n<div class=\"igf-step-meta\">\n<p><strong>Use only if:<\/strong> your team actively uses the WooCommerce mobile app and app requests are being challenged.<\/p>\n<p><strong>Cloudflare path:<\/strong> Security -> WAF -> Custom Rules -> Create rule<\/p>\n<p><strong>Rule name:<\/strong> <code>allow the WooCommerce mobile app<\/code><\/p>\n<p><strong>Action:<\/strong> <code>Skip<\/code><\/p>\n<p><strong>WAF components to skip:<\/strong> <code>All remaining custom rules<\/code> (keep rate limiting active by default).<\/p>\n<\/p><\/div>\n<pre><code>(http.user_agent contains \"WooCommerce\")\nor (http.user_agent contains \"wc-ios\")\nor (http.user_agent contains \"wc-android\")<\/code><\/pre>\n<p class=\"igf-step-verify\"><strong>Quick verification:<\/strong> app requests work while checkout, sync, and storefront protections remain stable.<\/p>\n<\/section>\n<\/div>\n<p><strong>Security note:<\/strong> user-agent exceptions are convenience controls. Keep them narrow, monitor logs, and do not broaden skip scope unless a tested business flow requires it.<\/p>\n<h3>5. Optional Pro\/Business upgrades<\/h3>\n<ul>\n<li>Bot score-driven traffic handling<\/li>\n<li>Finer endpoint-level WAF tuning with advanced expressions<\/li>\n<li>More granular catalog abuse controls for very large stores<\/li>\n<\/ul>\n<p>Apply these only after the free-plan-safe baseline is stable.<\/p>\n<h3>6. If sync breaks, recover in 5 minutes<\/h3>\n<ol>\n<li>Pause new security experiments immediately.<\/li>\n<li>Disable the newest WAF or rate-limit rule first.<\/li>\n<li>Confirm Woo API endpoints return JSON, not challenge HTML.<\/li>\n<li>Run a small IGFirstERP stock sync test.<\/li>\n<li>Check logs for repeated HTTP 403 and JSON syntax errors.<\/li>\n<li>Re-enable protection gradually with tested exceptions.<\/li>\n<\/ol>\n<h3>7. ERP sync allowlist note<\/h3>\n<p>For strict allowlist designs, do not hardcode public docs with a fixed production IP. Use this placeholder and confirm current values with support:<\/p>\n<p><code>&lt;IGFIRST_SYNC_EGRESS_IP&gt;<\/code><\/p>\n<h2>Common mistakes<\/h2>\n<ul>\n<li>Turning on many Cloudflare controls at once without staged testing<\/li>\n<li>Protecting API and checkout routes with generic challenge policies<\/li>\n<li>Caching dynamic Woo pages to improve speed<\/li>\n<li>Not validating response body type after WAF changes<\/li>\n<li>Assuming storefront page loads means sync traffic is healthy<\/li>\n<\/ul>\n<h2>Verification checklist<\/h2>\n<ul>\n<li>Woo dynamic routes bypass cache<\/li>\n<li>WAF and rate-limit rules are targeted, not blanket<\/li>\n<li>IGFirstERP sync test updates stock successfully<\/li>\n<li>No fresh <code>403 + JSON ERROR: Syntax error<\/code> entries after rollout<\/li>\n<li>Checkout, cart, login, and account flows remain normal<\/li>\n<\/ul>\n<h2>Escalation<\/h2>\n<p>Escalate to IGFirstERP Support if:<\/p>\n<ul>\n<li>Blocked non-JSON sync failures continue after rollback<\/li>\n<li>Queue failures continue after disabling recent Cloudflare rules<\/li>\n<li>You need strict IP allowlist enforcement with current confirmed egress values<\/li>\n<\/ul>\n<h2>Related workflow links<\/h2>\n<ul>\n<li><a href=\"\/resources\/docs\/fixing-stock-mismatches-daily-reconciliation\/\">Fixing Stock Mismatches (Daily Reconciliation)<\/a><\/li>\n<li><a href=\"\/resources\/docs\/preventing-website-stock-issues-from-transfers\/\">Preventing Website Stock Issues from Transfers<\/a><\/li>\n<li><a href=\"\/resources\/docs\/founder-weekly-control-reports\/\">Founder Weekly Control Reports<\/a><\/li>\n<\/ul>\n<h2>CTA<\/h2>\n<p><a href=\"\/book\">Book an Operations Fit Call<\/a><\/p>\n<p><a href=\"\/pricing\">View Pricing<\/a><\/p>\n<h2>Last reviewed<\/h2>\n<p>2026-03-12<\/p>\n<p>Review cadence: every 45 days or immediately after a Cloudflare-related sync incident.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem Many WooCommerce businesses turn on too many Cloudflare protections at once. The site looks secure, but IGFirstERP stock and order sync starts failing with blocked responses. A common failure pattern is: Woo API call returns HTTP 403 Response is not valid JSON ERP logs show JSON ERROR: Syntax error Stock sync jobs retry and &#8230; <a title=\"Cloudflare Setup for WooCommerce + IGFirstERP Sync (No 403 Errors)\" class=\"read-more\" href=\"https:\/\/igfirst.com.ng\/resources\/docs\/cloudflare-setup-for-woocommerce-igfirsterp-sync\/\" aria-label=\"Read more about Cloudflare Setup for WooCommerce + IGFirstERP Sync (No 403 Errors)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"doc_category":[10],"doc_tag":[],"class_list":["post-183","docs","type-docs","status-publish","hentry","doc_category-website-online-store-sync"],"year_month":"2026-05","word_count":1160,"total_views":"78","reactions":{"happy":"0","normal":"0","sad":"0"},"author_info":{"name":"IGFirstERP","author_nicename":"igfirsterp","author_url":"https:\/\/igfirst.com.ng\/resources\/author\/igfirsterp\/"},"doc_category_info":[{"term_name":"Website and Online Store Sync","term_url":"https:\/\/igfirst.com.ng\/resources\/docs-category\/website-online-store-sync\/"}],"doc_tag_info":[],"knowledge_base_info":[],"knowledge_base_slug":[],"_links":{"self":[{"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/docs\/183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/comments?post=183"}],"version-history":[{"count":2,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/docs\/183\/revisions"}],"predecessor-version":[{"id":185,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/docs\/183\/revisions\/185"}],"wp:attachment":[{"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/media?parent=183"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/doc_category?post=183"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/igfirst.com.ng\/resources\/wp-json\/wp\/v2\/doc_tag?post=183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}