Stripe signs webhook deliveries with an endpoint-specific secret. Rotating the value in Stripe and the application at different times can create a gap where valid payment events fail verification. Accepting both secrets forever creates a different risk. Teams also confuse live and test mode, duplicate endpoints, API versions, and Connect account paths. A safe rotation inventories every endpoint, creates a time-bounded overlap, proves both signatures, watches retries, and retires the old value only after the delivery backlog is clear.
Use this for WooCommerce, subscriptions, custom Stripe integrations, serverless handlers, Connect platforms, or any deployment that needs to rotate a webhook signing secret without losing order updates.
Quick answer
Map endpoint URL, mode, account, API version, enabled events, handler, current secret reference, and idempotency store. Deploy support for old and new secrets from a secure secret manager, rotate or create the endpoint value, and send controlled events signed through the real Stripe delivery path. Confirm both planned signatures verify during the overlap, one event creates one business action, and failures remain retryable. After the backlog and watch window are clear, remove the old secret from code and the secret manager.
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 |
| Old secret | Delivery during overlap | Accepted and deduplicated |
| New secret | Delivery during overlap | Accepted and deduplicated |
| Wrong endpoint | Valid secret for another URL | Rejected |
| After retirement | Old-signed test | Rejected with clear log |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Inventory endpoints and secret references | Inventory every live, test, Connect, regional, legacy, shadow, and disabled endpoint with its URL, API version, event set, handler, and owner. | Every intended endpoint verifies with the new secret in its correct mode and account. |
| Deploy a bounded dual-secret verifier | Record secret references and deployment order without printing secret values in logs, screenshots, tickets, shell history, or article evidence. | Old and new signatures during overlap do not duplicate order or subscription changes. |
| Rotate through the real delivery path | Deploy a bounded dual-secret verification window and test valid old, valid new, tampered, stale, wrong-endpoint, test-mode, and duplicate deliveries. | Delivery failures, retries, and backlog return to normal before retirement. |
| Prove event-level idempotency and retries | Reconcile Stripe event ID with order, payment, refund, subscription, stock, email, analytics, and idempotency records. | The old secret is removed from runtime configuration, secret storage, and documentation without exposing either value. |
What to check first
- Inventory every live, test, Connect, regional, legacy, shadow, and disabled endpoint with its URL, API version, event set, handler, and owner.
- Record secret references and deployment order without printing secret values in logs, screenshots, tickets, shell history, or article evidence.
- Deploy a bounded dual-secret verification window and test valid old, valid new, tampered, stale, wrong-endpoint, test-mode, and duplicate deliveries.
- Reconcile Stripe event ID with order, payment, refund, subscription, stock, email, analytics, and idempotency records.
- Watch delivery failures and retries, then remove the old verifier and secret only after every intended endpoint uses the new value.
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 cache purges, retries, scheduled actions, and deployments can change the evidence between tests.
- Test the public browser path and the server-side result, not only an admin preview or isolated API response.
- Close the task only after the visible workflow, stored record, logs, 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.
rotation_id=whsec-2026-08
endpoint=/stripe/webhook
mode=live
overlap_start=2026-08-28T14:00Z
old_secret=reference-only
new_secret=reference-only
event_id=evt_8841
mutations=1
old_retired=after-backlog-clear
Why this usually happens
- The Stripe dashboard and application deployment are changed in the wrong order.
- One secret is reused or mislabeled across live, test, Connect, or duplicate endpoints.
- Signature verification succeeds twice and idempotency does not protect the business mutation.
- The old secret is removed while Stripe still has failed deliveries queued for retry.
Decision rule
Keep overlap only for the documented deployment and retry window. Both secrets may authenticate deliveries during that window, but one Stripe event ID must still create one business mutation.
Production verification checklist
- Every intended endpoint verifies with the new secret in its correct mode and account.
- Old and new signatures during overlap do not duplicate order or subscription changes.
- Delivery failures, retries, and backlog return to normal before retirement.
- The old secret is removed from runtime configuration, secret storage, and documentation without exposing either value.
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.
- Inventory endpoints and secret references
- Deploy a bounded dual-secret verifier
- Rotate through the real delivery path
- Prove event-level idempotency and retries
- Retire the old secret after the backlog clears
Mistakes to avoid
- Changing production code, cache settings, form fields, webhook endpoints, or firewall rules before preserving the exact failure, current versions, and rollback point.
- Treating one successful page load or dashboard status as proof while browser behavior, PHP logs, scheduled jobs, delivery records, and downstream data remain unchecked.
- Testing a different role, device, locale, form, URL, order state, cache state, or plugin combination than the workflow that users actually reach.
- Leaving helper plugins, debug logging, copied secrets, broad exclusions, temporary endpoints, or test notifications active after the verification window.
Questions teams ask during testing
Can I run this directly on production?
Begin with read-only checks and preserve evidence. Use staging for changes that affect PHP, cache generation, form submission, payment, email, or customer state. When production is necessary, use one named canary, a short monitored window, and a tested rollback.
How do I avoid a false positive?
Match the exact plugin and WordPress versions, URL, role, device, locale, cache state, and integration path. Repeat the same fixture before and after the change, then compare stored evidence rather than relying on memory.
What evidence should I keep?
Keep UTC time, versions, affected URL or record ID, expected result, actual result, relevant log lines, configuration snapshot, change made, rollback point, and final verification. Remove credentials, payment details, and personal data.
When should I bring in a specialist?
Escalate when the site is unavailable, checkout or lead capture is affected, a security boundary is unclear, several systems disagree, or the next step could destroy evidence. A concise incident packet makes outside help much faster.
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, key logs, the change made, 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 rotate and verify the Stripe webhook secret.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references