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
This webhook will have to be listening for the following events:
customer.subscription.created
customer.subscription.deleted
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
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