Hesychia.ai Stripe webhook returns 405 from static nginx #41

Closed
opened 2026-10-10 04:26:40 -07:00 by westfarn · 0 comments
Owner

Stripe live webhook we_1TzDNHDV0RPXOyxGCOftavHV (Hesychia.ai) posts to https://hesychia.ai/api/finance/webhooks/stripe/. Delivery stays pending (pending_webhooks: 1).

What failed

On 2026-10-09 (America/Chicago), Grafana Loki (web-static / chat_web_app prod) recorded 15 POST /api/finance/webhooks/stripe/ responses with HTTP 405 and request_time 0.000. User-Agent Stripe/1.0 (+https://stripe.com/docs/webhooks). Same 405s continued from 2026-10-08 invoice events that never delivered.

The request hits the static SPA nginx (roles/web-static). try_files falls through to index.html. Nginx's static handler rejects POST, so Stripe never reaches chat_backend StripeWebhookView (/api/finance/webhooks/stripe/ on port 8003 prod / 8013 beta).

Fix

Proxy /api/finance/webhooks/ from the chat_web_app static vhost to the same-env chat_backend port via host.docker.internal. Send Host: chatbackend.aimloperations.com (beta: beta.chatbackend.aimloperations.com) so Django ALLOWED_HOSTS accepts the request. Stripe signature verification uses the raw body, not Host.

Stripe live webhook `we_1TzDNHDV0RPXOyxGCOftavHV` (Hesychia.ai) posts to `https://hesychia.ai/api/finance/webhooks/stripe/`. Delivery stays pending (`pending_webhooks: 1`). ## What failed On 2026-10-09 (America/Chicago), Grafana Loki (`web-static` / `chat_web_app` prod) recorded **15** `POST /api/finance/webhooks/stripe/` responses with **HTTP 405** and `request_time` 0.000. User-Agent `Stripe/1.0 (+https://stripe.com/docs/webhooks)`. Same 405s continued from 2026-10-08 invoice events that never delivered. The request hits the static SPA nginx (`roles/web-static`). `try_files` falls through to `index.html`. Nginx's static handler rejects POST, so Stripe never reaches `chat_backend` `StripeWebhookView` (`/api/finance/webhooks/stripe/` on port 8003 prod / 8013 beta). ## Fix Proxy `/api/finance/webhooks/` from the `chat_web_app` static vhost to the same-env `chat_backend` port via `host.docker.internal`. Send `Host: chatbackend.aimloperations.com` (beta: `beta.chatbackend.aimloperations.com`) so Django `ALLOWED_HOSTS` accepts the request. Stripe signature verification uses the raw body, not Host.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ai_ml_operations/server-infra#41