Problem
I am using Stripe to manage customer subscriptions. While customers can manage their subscriptions through the Customer Portal, there are scenarios where they don’t use it. In such cases, I rely on Stripe Webhook events to handle subscription updates and manage my database accordingly.
The Webhook events I am currently using are:
- invoice.payment_succeeded
- invoice.payment_failed
- customer.subscription.updated
- customer.subscription.deleted
Here’s how I handle these events:
invoice.payment_succeeded: When a payment is successful, I extend the subscription’s end date.
invoice.payment_failed: When a payment fails, the existing end date remains unchanged.
When a customer is created, I store their Stripe customerId in my database to track their subscriptions and payment status.
Issue
In the test environment, I can’t test Webhook events like invoice.payment_succeeded and invoice.payment_failed in real-time or simulate them with proper billing_reason values. Setting up a 1-day subscription in Stripe is time-consuming because I can only receive the Webhook events once the subscription ends or the payment date arrives.
Question
Is there a way to simulate Stripe Webhook events with proper billing_reason values (e.g., subscription_create or subscription_cycle) in a faster and more efficient way? Are there any tools, techniques, or workarounds to speed up testing for these specific scenarios in the Stripe test environment?
What I’ve Tried
1. Stripe CLI Testing:
I used the Stripe CLI to manually trigger the invoice.payment_succeeded event. While this works for basic testing, it doesn’t allow me to fully simulate scenarios that depend on the billing_reason value in the event payload.
For example:
- if billing_reason === subscription_create, it indicates the subscription is being created for the first time. In this case, I calculate and set the initial end date.
- if billing_reason === subscription_cycle, it indicates a recurring payment, and I extend the end date based on the subscription’s duration days.
The CLI does not provide realistic billing data for these cases, making it difficult to test properly.
1. Ngrok for Webhook Testing:
I set up a 1-day test subscription in Stripe and used Ngrok to expose my local endpoint. My goal was to test whether Stripe successfully triggers the Webhook to my endpoint when the subscription ends. However, I didn’t see any Webhook trigger after the 1-day subscription expired, which made it challenging to verify my implementation.
Have you looked in to Test Clocks? They are a way to simulate the advancement of time for Stripe subscriptions. You can use Test Clocks to simulate monthly & annual subscription cycles in seconds ( although you do need to wait while the clock advances before you call the API again).
When the test clock advances through a period of time when the events would be triggered (like a billing cycle) it will trigger the webhook events.
Caveat: Not all the timestamps in the Invoice objects will reflect the simulated time from the test clock. There are more details in the linked docs
1