Checkout Blocks may create a checkout-draft record before the shopper submits payment. Generic order-created hooks, broad queries, and webhook relays can send that record to a CRM, ERP, email platform, fulfillment system, or analytics destination. The result is a fake lead, empty order, premature stock action, duplicate contact, or purchase event. The solution is a centralized status and transition gate plus event-level idempotency, not a different exclusion in every destination.
Use this when WooCommerce drafts appear in CRM, ERP, email automation, webhooks, fulfillment, finance exports, support tools, or analytics before checkout completes.
Quick answer
Trace one checkout-draft ID from Store API creation through every hook, webhook, queue, and destination. Define which statuses may create, update, fulfill, email, or measure a real order. Suppress checkout-draft at the first owned integration boundary, then emit a single downstream event when the order reaches the approved transition. Use order ID plus event type and transition time for idempotency, and test abandonment, failed payment, retry, duplicate callback, and successful payment.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| checkout-draft | Initial Store API record | No business sync |
| pending payment | Submitted order | Owned actions only |
| processing | Payment confirmed | One CRM and analytics event |
| duplicate callback | Same event ID | No duplicate mutation |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Map every downstream path | Inventory every order-created, order-updated, status-change, webhook, queue, export, CRM, ERP, email, fulfillment, and analytics path with its owner. | Abandoned drafts create no unintended CRM, ERP, email, fulfillment, or purchase records. |
| Trace one draft fixture end to end | Create one draft fixture and correlate order ID, order key, status, created_via, checkout request, webhook delivery, queue message, and destination record. | A valid paid transition creates exactly one intended downstream mutation per destination. |
| Define status and transition contracts | Write an explicit allowed-status and allowed-transition matrix for each business action instead of relying on a broad not-failed condition. | Retries, duplicate webhooks, cleanup, refunds, and rollbacks remain idempotent. |
| Centralize suppression and idempotency | Place suppression at the earliest shared boundary and add event-level idempotency so retries or later transitions cannot duplicate the destination mutation. | The status contract and owner are shared across every integration. |
What to check first
- Inventory every order-created, order-updated, status-change, webhook, queue, export, CRM, ERP, email, fulfillment, and analytics path with its owner.
- Create one draft fixture and correlate order ID, order key, status, created_via, checkout request, webhook delivery, queue message, and destination record.
- Write an explicit allowed-status and allowed-transition matrix for each business action instead of relying on a broad not-failed condition.
- Place suppression at the earliest shared boundary and add event-level idempotency so retries or later transitions cannot duplicate the destination mutation.
- Test abandoned draft, cleanup, failed payment, retry, paid order, refund, duplicate webhook, and status rollback, then reconcile every destination.
Field notes
- Write the expected result before changing anything and keep one repeatable canary fixture for the full test window.
- Record exact versions and UTC timestamps because caches, retries, scheduled actions, and deployments can change the evidence between checks.
- Test the public browser path and the stored server-side result, not only an admin preview or isolated API response.
- Close the task only after the visible workflow, logs, stored record, and relevant downstream system agree.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
order_id=1486
created_via=store-api
status=checkout-draft
crm_sync=suppressed
webhook_mutation=suppressed
purchase_event=suppressed
allowed_transition=processing
idempotency_key=1486:processing:v1
Why this usually happens
- An integration treats database creation as the business event placed order.
- The status filter is duplicated across several destinations and drifts over time.
- A retry reaches the allowed state twice and there is no idempotency key.
- Analytics, CRM, and fulfillment use different definitions of a valid order.
Decision rule
A checkout-draft record must never become a sale, fulfillment, customer email, or purchase conversion merely because it has an order ID. Use an approved business-state transition.
Production verification checklist
- Abandoned drafts create no unintended CRM, ERP, email, fulfillment, or purchase records.
- A valid paid transition creates exactly one intended downstream mutation per destination.
- Retries, duplicate webhooks, cleanup, refunds, and rollbacks remain idempotent.
- The status contract and owner are shared across every integration.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Map every downstream path
- Trace one draft fixture end to end
- Define status and transition contracts
- Centralize suppression and idempotency
- Reconcile all order scenarios
Mistakes to avoid
- Changing production configuration before recording the exact version, failing request, timestamp, and rollback point.
- Treating a clean dashboard or one successful request as proof while the public page, background job, log, stored record, and downstream system remain unchecked.
- Testing a different role, device, locale, order state, form, cache state, or integration path from the one that users actually reach.
- Leaving debug logging, temporary exclusions, duplicate hooks, helper code, test endpoints, or broad permissions active after the verification window.
Questions teams ask during testing
Can I make this change directly in production?
Start with read-only evidence and use staging for code, update, security, checkout, form, or queue changes. If production is required, use one named canary, a short monitored window, and a tested rollback.
How do I avoid a false positive?
Repeat the same fixture with the same versions, role, URL, device, locale, cache state, and downstream integration. Compare stored evidence rather than relying on a visual impression.
What evidence should I retain?
Keep UTC time, exact versions, URL or record ID, expected and actual result, relevant log lines, change made, rollback point, owner, and final verification. Redact credentials and personal data.
When should I escalate?
Escalate when the site is unavailable, security scope is unclear, checkout or lead capture is affected, several systems disagree, or the next action could destroy evidence.
What to tell the client or owner
Give the owner a concise evidence packet with the affected workflow, exact versions, UTC test time, fixture ID, expected result, actual result, key logs, change made, rollback point, final result, owner, and next review date. Remove credentials and personal data before sharing it.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, have HandL WP repair WooCommerce draft-order tracking and sync.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references