Stripe signs each webhook delivery using the raw request body, endpoint secret, and a timestamp in the Stripe-Signature header. Official libraries normally apply a five-minute recency tolerance to reduce replay risk. A WooCommerce endpoint can fail when the server clock drifts, a proxy delays the request, the wrong endpoint secret is loaded, middleware changes the body, or an old payload is replayed with a stale header. Increasing tolerance can hide the symptom while weakening replay protection. The diagnosis should measure Stripe timestamp, receive time, application time, NTP offset, queue delay, body hash, secret identity, and verification result for the same delivery.
Use this when WooCommerce Stripe webhooks intermittently report timestamp outside tolerance, signature verification failed, or old events fail during manual replay.
Quick answer
Capture one failed delivery without logging the secret or full sensitive payload. Compare the Stripe header timestamp with the edge, origin, PHP, container, and NTP time sources. Confirm the request reaches the exact endpoint whose secret is configured and that verification uses the untouched raw body. Keep the default tolerance unless measured network conditions justify a documented value. Never set tolerance to zero because that disables the recency check.
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 |
| Valid current | Correct secret and raw body | Verification passes |
| Clock drift | Server offset over limit | NTP issue identified |
| Old replay | Stale timestamp | Rejected for recency |
| Wrong secret | Other endpoint secret | Rejected consistently |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Capture one delivery timeline | Record Stripe event and delivery IDs, endpoint ID, livemode, secret identifier, header timestamp, edge receive time, origin receive time, application verify time, and server NTP offset. | Current valid events pass with the documented finite tolerance and accurate server time. |
| Verify NTP and route identity | Hash the raw request body before any JSON parsing, whitespace changes, form conversion, logging middleware, proxy transformation, or framework reconstruction. | Stale payloads, wrong secrets, and changed raw bodies fail for the expected reason. |
| Preserve the raw body | Confirm test and live secrets, old and new endpoint secrets, environment variables, secret rotation, container rollout, and route selection are not mixed. | Retries produce a fresh signature and remain idempotent in WooCommerce. |
| Correct secret or middleware ownership | Measure proxy, WAF, load balancer, queue, cold-start, and application delay separately from actual operating-system clock drift. | NTP offset, proxy delay, endpoint identity, and alert thresholds are monitored. |
What to check first
- Record Stripe event and delivery IDs, endpoint ID, livemode, secret identifier, header timestamp, edge receive time, origin receive time, application verify time, and server NTP offset.
- Hash the raw request body before any JSON parsing, whitespace changes, form conversion, logging middleware, proxy transformation, or framework reconstruction.
- Confirm test and live secrets, old and new endpoint secrets, environment variables, secret rotation, container rollout, and route selection are not mixed.
- Measure proxy, WAF, load balancer, queue, cold-start, and application delay separately from actual operating-system clock drift.
- Fix time synchronization, route, secret, or raw-body handling first, then retest valid delivery, retry, stale replay, duplicate event, and intentional bad signature.
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 a cache purge, scheduled action, retry, or deployment can change the evidence between tests.
- Test the real browser and downstream record, not only an admin preview or isolated API call.
- Close the task only after the public workflow, server-side record, and relevant delivery or analytics system agree.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
stripe_timestamp=1787846400
edge_received=1787846401
origin_received=1787846402
app_verified=1787846402
ntp_offset_ms=34
tolerance_seconds=300
raw_body_hash=sha256:redacted
result=valid
Why this usually happens
- A virtual machine or container host loses reliable time synchronization.
- A proxy or queue holds the request long enough to exceed the intended window.
- The application parses and reserializes JSON before signature verification.
- A deployment uses the signing secret from a different Stripe endpoint or mode.
Decision rule
Do not widen signature tolerance until clock and delivery measurements prove it is necessary. Keep a finite recency check and fix server time, proxy delay, raw-body handling, or secret selection at the source.
Production verification checklist
- Current valid events pass with the documented finite tolerance and accurate server time.
- Stale payloads, wrong secrets, and changed raw bodies fail for the expected reason.
- Retries produce a fresh signature and remain idempotent in WooCommerce.
- NTP offset, proxy delay, endpoint identity, and alert thresholds are monitored.
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.
- Capture one delivery timeline
- Verify NTP and route identity
- Preserve the raw body
- Correct secret or middleware ownership
- Retest valid, retry, and stale cases
Mistakes to avoid
- Changing production code, form fields, webhook endpoints, cache settings, or security limits before preserving the failing fixture and current configuration.
- Treating one clean dashboard status as proof even though the browser, PHP process, database, delivery provider, and downstream record have not been reconciled.
- Testing with a different form, role, locale, order state, entry shape, plugin version, or cache state than the workflow users actually reach.
- Leaving debug logs, temporary endpoints, broad permissions, copied secrets, or test notifications active after the verification window closes.
Questions teams ask during testing
Can I test this directly on production?
Read-only checks can be appropriate when access is controlled and output is redacted. Make a backup first, use a named canary record, test state-changing work on staging, define rollback, and schedule any production change for a monitored window.
How do I avoid a false positive?
Match the exact version, request path, form or order ID, role, locale, cache state, and integration path. Repeat the same fixture before and after the change, then compare the saved evidence rather than relying on memory.
What evidence should I keep?
Keep the UTC time, site and plugin versions, fixture ID, expected result, actual result, relevant logs, configuration snapshot, change made, rollback point, and final verification. Remove passwords, tokens, payment details, and personal data.
When should I bring in a specialist?
Escalate when checkout, payments, lead capture, security, customer email, accessibility, or several integrations are affected, or when the safest next step is unclear. A concise evidence packet reduces diagnosis time.
What to tell the client or owner
Give the owner a short evidence packet with the affected workflow, exact versions, UTC test time, fixture ID, expected and actual result, logs, change, rollback point, final result, owner, and next review date. Redact 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 trace the Stripe signature failure.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references