fix(website): use Stripe fetch client on Cloudflare Workers (#20966)

## Summary

Every `/api/enterprise/*` route on `twenty-website-prod` is currently
timing out at exactly 80s with `Request aborted due to timeout being
reached (80000ms)` — that's `Stripe.DEFAULT_TIMEOUT` aborting itself,
not Cloudflare.

The Stripe SDK's default transport uses Node's `http`/`https` module.
Under workerd, even with `nodejs_compat`, the outbound TLS connection to
`api.stripe.com` hangs and the SDK eventually times out at its built-in
80s ceiling. Worked on EKS (real Node), breaks on Cloudflare Workers.

Fix is one line: pass `httpClient: Stripe.createFetchHttpClient()` so
the SDK uses workerd's native `fetch` instead of the polyfilled Node
transport.

## Blast radius

`getStripeClient()` is shared across every enterprise route. All of
these are silently broken on prod right now:

- `POST /api/enterprise/checkout` (confirmed in logs)
- `POST /api/enterprise/portal`
- `POST /api/enterprise/seats`
- `GET  /api/enterprise/status`
- `POST /api/enterprise/activate`
- `POST /api/enterprise/validate`

Single change in `stripe-client.ts` unblocks all of them.

## Test plan

- [ ] After merge + deploy to prod: `wrangler tail twenty-website-prod`
while hitting the enterprise checkout flow; same call should complete in
<2s instead of 80s
- [ ] Verify a real Stripe checkout session is created (Stripe dashboard
→ Payments → Checkout sessions)
- [ ] Spot-check `/api/enterprise/status` and `/api/enterprise/portal`
are no longer timing out
This commit is contained in:
Félix Malfait
2026-05-27 16:03:48 +02:00
committed by GitHub
parent 73ab5de46c
commit e79f43813b
@@ -10,7 +10,12 @@ export const getStripeClient = (): Stripe => {
throw new Error('STRIPE_SECRET_KEY is not configured');
}
stripeInstance = new Stripe(secretKey, {});
// On Cloudflare Workers the Stripe SDK's default Node http transport hangs
// on outbound TLS — even with nodejs_compat — and aborts at the SDK's own
// 80s timeout. Forcing the fetch-based client uses workerd's native fetch.
stripeInstance = new Stripe(secretKey, {
httpClient: Stripe.createFetchHttpClient(),
});
}
return stripeInstance;