MEMBLOG

Stripe subscription webhooks

- 2024-12-11

Businesses using Stripe Subscriptions might want to execute a custom workflow upon receiving Stripe webhooks for subscription events.

I wrote a Membrane program, pete/stripe-subscriptions, to query subscriptions and expose webhooks for created, deleted, paused, resumed, and updated events.

I also wrote a companion program, pete/stripe-subscriptions-watcher, as an example of handling subscription webhooks. Follow that link^ to install the program in your own workspace and customize it to your needs.

The code

stripe-subscriptions-watcher uses stripe-subscriptions as a program connection, subscribing to each Stripe event it exposes and attaching a handler function.

For sake of example, we use the same handler for each event to send an email (using membrane/email). In practice you can handle events however you need.

// stripe-subscription-watcher/index.ts

import { root, nodes } from "membrane";

export async function setup() {
  await nodes.stripe.subscriptions.created.$subscribe(root.handle);
  await nodes.stripe.subscriptions.deleted.$subscribe(root.handle);
  await nodes.stripe.subscriptions.paused.$subscribe(root.handle);
  await nodes.stripe.subscriptions.resumed.$subscribe(root.handle);
  await nodes.stripe.subscriptions.updated.$subscribe(root.handle);
}

export async function handle(_, { event }) {
  console.log(`Handling Stripe webhook for: ${event.type}`);

  // Do something with the webhook, e.g. send yourself an email
  await nodes.email.send({
    subject: "Stripe subscription webhook",
    body: `${event.type}: ${event.subscription.status}`,
  });
}

Handling webhooks in Membrane

In many cases, Membrane is a great fit to handle webhooks. In particular, these three features are useful:

  1. Endpoint
  2. State
  3. Replays

1. Endpoint

Each Membrane program comes with an HTTP endpoint that you can configure as a webhook URL. Simply export an endpoint fn to handle requests however you need.

2. State

Membrane programs have durable state, so you get persistence out of the box without having to set up a database.

3. Replays

When endpoint receives a request and executes, not only can you view the request in Logs and the Navigator, but you can invoke the request again to replay it.

This is especially helpful when you want to update your code and test again without triggering another request (e.g. via the Stripe dashboard).

Feedback?

Would this program or a similar one be useful for your team? We'd love to hear from you on Discord, via email, or in a live session.

We're getting ready for an open Beta launch (from Alpha), and we appreciate hearing your feedback.


- Pete Millspaugh (pete@membrane.io)

© 2024 Programmability, Inc.