Webhook
A URL you hand another service so it calls your app as soon as something happens, instead of you asking over and over.
See it
What it is
A webhook flips who makes the call. Normally your app asks a service for news. With a webhook you publish a URL, register it in the other service's dashboard, and that service POSTs a JSON payload to you when an event fires: 'payment succeeded', 'issue closed', 'form submitted'. Stripe, GitHub, Shopify, and Slack all work this way.
Reach for one when waiting is wasteful. Polling every 10 seconds burns rate limit and still lags; a webhook usually lands within seconds of the event and costs nothing while nothing is happening. The rule of thumb: your handler should do almost nothing except verify the signature, drop the event on a queue, and return 200 fast. Senders time out in seconds and will retry if you are slow.
Two gotchas bite everyone. Delivery is best effort, not a guarantee: the same event will show up twice sooner or later, some land minutes late, and one can be lost for good if your endpoint is down through every retry the sender is willing to make. Key your processing off the event ID so a duplicate is a no-op, and run a periodic reconciliation that refetches state from the API so a missed event does not leave you permanently wrong. And anyone on the internet can POST to your URL, so verify the signature header against your signing secret before you trust a byte of it. Also: localhost is not reachable from Stripe's servers, which is why tunnels like ngrok and the Stripe CLI exist.
Ask AI for it
Add a webhook receiver at POST /api/webhooks/stripe. Preserve the exact raw request body (do not let the framework parse it first, the signature is computed over raw bytes), read the 'Stripe-Signature' header, and verify it with Stripe's official webhook-construction helper plus the endpoint secret from an env var. Reject verification failures with 400 before any JSON parsing happens. Durably enqueue the event types I list, deduplicate by Stripe event ID so retries and replays are no-ops, and return 2xx only after the enqueue succeeds. Do the slow work in a background job and log every rejected or unhandled event.