---
title: "Stripe Webhook"
method: POST
path: "/api/stripe/webhook"
tags: ["stripe"]
---

# Stripe Webhook

`POST /api/stripe/webhook`

## Request

- Base URL: `https://api.equity-rank.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.equity-rank.com/api/stripe/webhook`
- Auth: none declared

Receive and process Stripe webhook events.

Security:
- Verifies Stripe-Signature header using stripe.Webhook.construct_event.
- Returns 400 on invalid signature (must use raw bytes — request.body()).

Idempotency:
- Checks processed_webhook_events table before processing.
- Inserts event_id after success.
- Returns 200 even if event already processed (Stripe retries on non-2xx).

Handled events:
- customer.subscription.created  → upsert subscriptions row
- customer.subscription.updated  → upsert subscriptions row
- customer.subscription.deleted  → set status='cancelled', owner alert
- invoice.paid                   → owner payment-received alert
- invoice.payment_failed         → set status='past_due'
- payment_method.attached        → set has_payment_method=true

## Response `200`

Successful Response

- unknown

---

[API](https://skmtc.dev/equity-rank/apis/equity-rank-api.md) · [All operations](https://skmtc.dev/equity-rank/apis/equity-rank-api/llms.txt) · [OpenAPI document](https://skmtc.dev/equity-rank/apis/equity-rank-api/revisions/c2f2463fee33?raw)
