TL;DR: one Cloudflare Worker + one index.js. Stripe and Creem both live inside. The frontend just adds ?provider=creem or ?provider=stripe on /api/checkout to flip the target. Webhooks split by URL. D1 gets one extra provider column and a webhook_events audit table. Total ~500 lines of code.
Why dual? So one MoR's KYC delay never blocks a launch. PLANS map stays single-source so pricing is consistent across both. WebCrypto handles HMAC-SHA256 for Creem webhooks without pulling in a Node SDK.
Full walkthrough with the D1 migrations, WebCrypto snippet and the checkout branch: https://blog.yeluoxiaoxiao.top/posts/cloudflare-worker-stripe-creem-parallel
Happy to discuss trade-offs — especially the ON CONFLICT(email) pitfall on D1.
Top comments (2)
You can't tease the ON CONFLICT(email) pitfall and then not tell the story. My guess is the upsert clobbering the provider column when the same email checks out through the other provider. Close?
Interesting to see both providers in one Worker! How did you handle secrets for both Stripe and Creem within