> For the complete documentation index, see [llms.txt](https://docs.billingjs.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.billingjs.com/getting-started/configure-webhooks-and-triggers/subscription-webhook.md).

# Subscription webhook

You will need to configure a webhook on Stripe to receive events when subscriptions are created, updated or deleted. You can add a webhook from the Stripe Dashboard [here](https://dashboard.stripe.com/webhooks/)

This webhook will have to be listening for the following events:

`customer.subscription.created`

`customer.subscription.deleted`&#x20;

`customer.subscription.updated`

#### `updatedSubscriptionWebhook.ts`

This code example updates the user's subscription in firestore

It will delete the subscription if the user was delete from Stripe or add the subscription if it's a new one or simply update it if there was an existing one already in the database

```typescript
import { firestore, admin } from "../utils/firebase"
import stripe, { Stripe } from "../utils/stripe"
import * as express from "express"

const router = express.Router()

router.post("/", (req: any, res) => {
    let event
    try {
        // check stripe event signature
        event = stripe.webhooks.constructEvent(
            req.rawBody,
            req.headers["stripe-signature"],
            process.env.YOUR_WEBHOOK_SIGNING_SECRET // visible on the Stripe Dashboard (https:
        )
    } catch (error) {
        reportError(error, { request: req, details: "stripe-signature check error" }, req)
        return res.status(400).send({ error })
    }

    if (!event || !event.type || !event.data?.object) return res.status(400).send({ event, error: "Missing data" })

    const {
        status,
        customer: stripeCustomerId,
        id: subscriptionId,
        trial_end: trialEnd,
        current_period_end: periodEnd,
        cancel_at_period_end: cancelAtPeriodEnd
    } = event.data.object

    const { id: plan } = event.data.object?.plan

    return stripe.customers
        .retrieve(stripeCustomerId)
        .then((customer): any => {
            if (customer.deleted) {
                // if customer is deleted, delete subscription
                return firestore
                    .collection("users")
                    .where("subscription.stripeCustomerId", "==", stripeCustomerId)
                    .get()
                    .then((querySnapshot) => {
                        if (querySnapshot.empty) {
                            throw Error("user not found")
                        }

                        // get first matching user
                        const matchingUser = querySnapshot.docs[0]

                        const userId = matchingUser.id

                        return firestore.collection("users").doc(userId).set(
                            {
                                subscription: admin.firestore.FieldValue.delete() // delete subscription if customer is deleted
                            },
                            { merge: true }
                        )
                    })
                    .then(
                        () => `The subscription's owner was deleted so the subscription has been removed from the user.`
                    )
            }

            // if customer is not deleted, update or add subscription
            return firestore
                .collection("users")
                .where("email", "==", (customer as Stripe.Customer).email)
                .get()
                .then((querySnapshot) => {
                    if (querySnapshot.empty) {
                        throw Error("user not found")
                    }

                    // get first matching user
                    const matchingUser = querySnapshot.docs[0]

                    const userId = matchingUser.id

                    const subscription = {
                        stripeCustomerId,
                        id: subscriptionId,
                        status,
                        plan,
                        trialEnd,
                        periodEnd,
                        cancelAtPeriodEnd
                    }

                    return firestore.collection("users").doc(userId).set(
                        {
                            subscription
                        },
                        { merge: true }
                    )
                })
                .then(() => `The subscription was updated in firebase.`)
        })
        .then((status) => res.status(200).send({ status }))
        .catch((error) => {
            console.error(`>> WEBHOOK ERROR: ${error}`)
            res.status(400).send({ event, error })
        })
})

export default router

```
