Stripe Event Types

A complete guide to understanding and handling Stripe webhook events, from payment completion to subscription lifecycle management.

When building payment infrastructure with Stripe, understanding the event type system is fundamental to creating robust, reliable integrations. Stripe generates over 200 different webhook event types that notify your application when meaningful actions occur--from successful payments to subscription cancellations. This guide covers the essential event types you need to handle, their payloads, and best practices for implementation.

Why Event Types Matter

Stripe's event types follow a consistent naming convention that makes it intuitive to understand what each event represents. Event types follow the pattern resource.action, where the resource indicates the affected object and the action describes what happened. This structured approach helps developers quickly identify relevant events for their integration needs, as covered in MagicBell's comprehensive webhook guide.

For teams building payment systems as part of a broader web development initiative, mastering webhook event handling ensures your application responds accurately to payment state changes.

Event Naming Convention

The event type naming convention provides immediate context about each event. For example, payment_intent.succeeded clearly indicates a PaymentIntent resource that has succeeded, while customer.subscription.deleted signals a deleted subscription for a customer.

Event Categories

Payment Events cover the complete payment lifecycle:

  • payment_intent.succeeded - Payment completed successfully
  • payment_intent.payment_failed - Payment attempt failed
  • charge.succeeded - Charge created successfully
  • charge.refunded - Charge has been refunded

Subscription Events manage recurring billing:

  • customer.subscription.created - New subscription begins
  • customer.subscription.updated - Subscription details changed
  • customer.subscription.deleted - Subscription has ended
  • customer.subscription.trial_will_end - Trial ending in 3 days

Checkout Events relate to Stripe Checkout:

  • checkout.session.completed - Customer completed checkout payment

For a complete list of all event types, refer to Stripe's official API reference.

Understanding these event types is essential when implementing Stripe Checkout for your e-commerce platform.

The checkout.session.completed Event

The checkout.session.completed event is one of the most important events for e-commerce integrations using Stripe Checkout. This event fires when a customer successfully completes a payment flow through Stripe's hosted checkout page.

Event Payload

The event includes a comprehensive session object with payment details, customer information, and order data:

  • Payment intent ID and amount
  • Customer email for confirmations
  • Line items and product details
  • Shipping information if applicable
  • Payment method used

Best Practices for Handling

Signature Verification: Always verify the webhook signature using Stripe's constructEvent method with your endpoint secret. This ensures the webhook actually came from Stripe and prevents malicious actors from spoofing events.

Idempotency: Stripe may deliver the same event multiple times due to their retry mechanism. Store processed event IDs in your database and skip duplicate handling to prevent issues like double-charging or duplicate order fulfillment.

Order Fulfillment Workflow: When handling this event, mark orders as paid in your database, update inventory systems, and trigger any necessary fulfillment processes. The session object contains everything you need without additional API calls.

Confirmation Emails: Use the customer email from the session to send order confirmations, shipping notifications, and receipts. This communication builds trust and reduces customer support inquiries.

For secure payment handling, consider implementing 3D Secure for additional fraud protection on high-risk transactions.

Handling checkout.session.completed
1app.post('/webhooks/stripe', express.raw({type: 'application/json'}), (req, res) => {2 const sig = req.headers['stripe-signature'];3 const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;4 5 let event;6 try {7 event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);8 } catch (err) {9 return res.status(400).send(`Webhook Error: ${err.message}`);10 }11 12 if (event.type === 'checkout.session.completed') {13 const session = event.data.object;14 // Handle successful checkout15 fulfillOrder(session);16 }17 18 res.json({received: true});19});

Essential Payment Event Types

Successful Payment Events

The payment_intent.succeeded event indicates that a payment has been successfully processed and the funds are secured. This event contains the PaymentIntent object with complete payment details including amount, currency, payment method, and customer information.

For many integrations, this event triggers:

  • Order fulfillment
  • Access grant to paid features
  • Service delivery
  • Payment confirmation emails

Failed Payment Events

The payment_intent.payment_failed event alerts you when a payment attempt cannot complete. The event payload includes:

  • Failure reason and error code
  • Customer-facing message
  • Next payment attempt timestamp

Refund Events

The charge.refunded event fires when a refund is processed. The event indicates whether the refund was full or partial through the amount_refunded field. This event is essential for maintaining accurate financial records and updating order status accordingly.

According to MagicBell's webhook implementation guide, failed payment handling requires careful consideration of user experience, including providing clear instructions for updating payment methods and implementing retry logic.

When handling payment events, ensure your authentication flow properly validates user identity through Stripe Authentication for secure transactions.

Subscription Lifecycle Events

Creation and Updates

The customer.subscription.created event marks the beginning of a new subscription relationship. The event payload includes subscription details such as the price ID, current period end, and status.

Subscription updates trigger customer.subscription.updated events when:

  • Plan upgrades or downgrades occur
  • Payment method changes
  • Quantity adjustments
  • Trial conversions

Trial Events

The customer.subscription.trial_will_end event provides a critical three-day warning before a trial converts to a paid subscription. This notification window enables proactive customer engagement--send reminders about trial expiration, highlight product value, and offer incentives for conversion.

Cancellation Events

The customer.subscription.deleted event signals the final end of a subscription. Handle this event by:

  • Revoking subscription access
  • Sending confirmation communications
  • Initiating win-back campaigns

The customer.subscription.updated event includes both old and new subscription values, enabling you to calculate proration and adjust customer access accordingly, as documented in MagicBell's webhook guide.

Subscription handling is a core component of backend development for SaaS platforms offering recurring billing.

Security Best Practices

Signature Verification

Always verify webhook signatures using Stripe's constructEvent method before processing any event. This verification ensures the webhook originated from Stripe and hasn't been tampered with. The signature is sent in the stripe-signature header and validated against your webhook endpoint secret, as recommended in Stripe's official webhook documentation.

Idempotency Implementation

Design your webhook handlers to process events idempotently. Stripe may deliver the same event multiple times due to their retry mechanism. Track processed event IDs in your database and skip duplicate processing. This prevents duplicate orders, access grants, or other unintended actions.

HTTPS Requirements

Production webhook endpoints must use HTTPS to encrypt webhook data in transit. This requirement protects sensitive payment information and prevents eavesdropping or tampering. For local development, use the Stripe CLI to forward webhooks securely to your local environment, as covered in Stripe's webhook setup guide.

Implementing secure webhooks is a critical part of building secure payment infrastructure that protects both your business and your customers.

Security and Idempotency Implementation
1// Verify webhook signature2try {3 event = stripe.webhooks.constructEvent(4 req.body,5 req.headers['stripe-signature'],6 endpointSecret7 );8} catch (err) {9 console.log(`Signature verification failed: ${err.message}`);10 return res.status(400).send(`Webhook Error: ${err.message}`);11}12 13// Implement idempotency14async function handlePaymentSucceeded(paymentIntent) {15 const existing = await db.payments.findOne({16 stripe_payment_intent_id: paymentIntent.id17 });18 19 if (existing) {20 console.log(`Payment ${paymentIntent.id} already processed`);21 return;22 }23 24 await db.payments.create({25 stripe_payment_intent_id: paymentIntent.id,26 amount: paymentIntent.amount,27 status: 'completed'28 });29}

Event Object Structure

Every Stripe webhook event follows a consistent structure:

{
 "id": "evt_1234567890",
 "object": "event",
 "api_version": "2024-11-20.acacia",
 "created": 1732800000,
 "type": "payment_intent.succeeded",
 "data": {
 "object": {
 "id": "pi_1234567890",
 "amount": 2000,
 "currency": "usd",
 "status": "succeeded",
 "customer": "cus_1234567890"
 }
 }
}

Key Fields:

  • id - Unique event identifier for idempotency tracking
  • type - The event type string (e.g., payment_intent.succeeded)
  • api_version - Stripe API version for consistent interpretation
  • data.object - The full resource that triggered the event

The api_version field indicates which Stripe API version was used, ensuring consistent event structure interpretation. According to MagicBell's implementation guide, understanding this structure is essential for building reliable webhook handlers.

This consistent structure makes it easier to build robust payment integrations that can handle various event types reliably.

Best Practices Summary

When implementing Stripe event type handling, prioritize the events most critical to your business logic:

  1. Start with essential events: checkout.session.completed, customer.subscription.created, payment_intent.payment_failed

  2. Implement security first: Signature verification and HTTPS are non-negotiable for production

  3. Design for idempotency: Handle Stripe's retry mechanism gracefully

  4. Respond quickly: Return 2xx status codes within 5 seconds, process asynchronously

  5. Test thoroughly: Use Stripe CLI for local testing before deployment

  6. Monitor deliveries: Use the Stripe Dashboard to track webhook success rates

Additional Resources

Explore our other Stripe integration guides:

Frequently Asked Questions

Ready to Implement Secure Payment Processing?

Our team specializes in building robust payment infrastructure with Stripe. Let us help you create a secure, reliable payment system.