# How to Automate Stripe Payment Notifications using the API

- Tool: API Automations
- Difficulty: Beginner
- Fix time: 15-30 minutes
- Compatibility: Stripe account; secret key (sk_*) and webhook signing secret (whsec_*) required; no additional API plan needed
- Last updated: May 2026

## TL;DR

Automate Stripe payment notifications by setting up webhooks for payment_intent.succeeded, charge.failed, and charge.dispute.created events. Stripe POSTs to your endpoint; verify the Stripe-Signature header using stripe.webhooks.constructEvent() with the RAW request body — parsing JSON first breaks verification. Then forward to Slack, email, or SMS. Rate limit: Stripe retries failed webhooks for up to 3 days.

## Best practices

- Always verify webhook signatures before accessing event data — treat unverified webhooks as potential attacks
- Use the raw request body (bytes) for verification — never the parsed JSON object
- Return 200 within seconds and process asynchronously — Stripe considers your endpoint failed after 30 seconds
- Implement idempotency using event.id as a deduplication key — Stripe may deliver the same event multiple times
- Log the full event.id and event.type for every webhook received to enable debugging and audit trails
- Subscribe to charge.dispute.created and monitor it closely — disputes have 7-day response deadlines and evidence must be submitted promptly
- Use the Stripe Dashboard's webhook delivery logs to see which events succeeded or failed and trigger manual retries

## Frequently asked questions

### Why does my webhook signature verification keep failing?

The most common cause: the request body was parsed as JSON before calling constructEvent(). In Express.js, if express.json() middleware runs before your webhook route, it parses the body and the raw bytes are lost. Fix: use express.raw({type: 'application/json'}) specifically for the webhook route, and define it before any global JSON parsing middleware. In Flask, use request.get_data() (returns bytes) not request.json (returns dict).

### What happens if my webhook endpoint is down?

Stripe retries failed webhook deliveries (non-2xx response or timeout) for up to 3 days using exponential backoff. Starting intervals: immediate, +5 minutes, +30 minutes, +2 hours, +5 hours, growing from there. After 3 days, retries stop. Events remain retrievable via GET /v1/events for 30 days — use the backfill pattern in Step 4 to reprocess missed events.

### Can I receive a webhook event more than once?

Yes. Stripe guarantees at-least-once delivery — the same event can be delivered multiple times, especially when your endpoint returns a 5xx or times out. Always implement idempotency using event.id as a deduplication key. Store processed event IDs in Redis (SET with NX flag and TTL) or a database unique constraint.

### What event should I use for one-time Stripe Checkout payments vs subscription renewals?

For one-time Checkout payments, use checkout.session.completed. For subscription renewals, use invoice.paid (payment succeeded) and invoice.payment_failed (payment failed). For custom payment flows using Payment Intents directly, use payment_intent.succeeded. Don't use charge.succeeded — it's a lower-level event that fires for many charge types and is harder to filter correctly.

### How do I test webhooks locally during development?

Use the Stripe CLI: run stripe listen --forward-to localhost:3000/webhooks/stripe. This creates a secure tunnel and forwards all events to your local server, showing you the exact payloads. The CLI also provides a webhook signing secret that you set as STRIPE_WEBHOOK_SECRET for local testing. Alternatively, trigger test events from your Dashboard under Developers > Webhooks > Send test webhook.

### How urgent are chargeback (dispute) notifications?

Very urgent. When charge.dispute.created fires, you have 7 days to respond with evidence via the Stripe Dashboard or API. Missing this deadline results in automatic loss of the dispute and the charged-back amount plus a $15 dispute fee. Set up immediate alerting for dispute events — dedicated Slack channel, PagerDuty, or SMS alert.

### Can RapidDev help build a custom payment notification and monitoring system?

Yes. RapidDev has built 600+ apps including real-time payment dashboards, dispute management workflows, and multi-channel notification systems integrated with Stripe. Get a free consultation at rapidevelopers.com.

---

Source: https://www.rapidevelopers.com/api-automations/how-to-automate-stripe-payment-notifications-using-the-api
© RapidDev — https://www.rapidevelopers.com/api-automations/how-to-automate-stripe-payment-notifications-using-the-api
