Everything here failed on me once. Number 1 is the common one: live price IDs are different objects than test ones, so the checkout session throws on a price that exists in the dashboard you are looking at.
Workflow
Copied 16 times
1. Swap all four at once: secret key, publishable key, webhook signing secret, price IDs. Live price IDs are not the test ones.
2. Create the webhook endpoint again in live mode. The test signing secret does not verify live events.
3. Finish account activation, otherwise live charges fail where test charges passed.
4. Set the statement descriptor before the first charge, not after the first dispute.
5. Buy your own product with a real card, then refund it.
6. Open the webhook delivery log for that purchase. You want one 200, not four retries.