Alex Navarro
Alex Navarro

Reputation: 153

Node.js - Handling a webhook and updating an express-session

I'm using Stripe to let my customers change their plans, and we send them to an external Stripe-hosted page to complete the checkout. After they checkout, Stripe sends them back to a thank-you page and initiates a webhook.

The webhooks are great, because it doesn't update any database information or changes their plan until after the payment has succeeded and their card has been charged.

I also use webhooks to "reset" their plan limits on a successful card charge. So each month, on each successful charge webhook, the limits update. But if the user is in an active session when they update, I should update that session.

BUT what I'm struggling with is, in a webhook event how do I update an active express session?

There's no req.session object, because the "event" is coming from Stripe's webhoook.

app.post('/webhook', async (req, res) => {

    /* <-- Update the database, which is good --> */
    database.updateUser()

    /* <-- Update their session if it's active --> */

    // This won't work, because there is no req.session and no cookie being sent!
    req.session.user.plan = parseWebhookData()

    // I can't access the store, because I don't know the user's session id
    // Plus, all my store is encrypted so I can't do a MongoDb query search for their session.
    store.get(sid, callback)

    // How do I update their session??
})

The only solution I have so far is to have the database re-update their information on every page they visit. But that slows down my response time by 1s per page!

Upvotes: 1

Views: 485

Answers (1)

Alex Navarro
Alex Navarro

Reputation: 153

I solved this myself.

Solution #1: Recommended by Stripe: Update user on login, not with the webhook

Stripe recommends checking a user's subscription on login, and resetting their "plan usage" on login INSTEAD of resetting their plan usage on a webhook.

I thought this was very interesting and after implementing I've found this is a much better solution than trying to deal with Webhooks and session objects!

Solution #2: Get the session ID and update the express-session database!

Express-session gives you the sessionID in "req.sessionID" so you can search your database for the sessionID and update what you need to.

app.get('/getID', (req, res) => {
    console.log("sessionID: " + req.sessionID);
    res.send(req.sessionID);
});

It also helps to do MongoDB's atomic updates if you turn off the stringify feature in your express-session.

const store = MongoStore.create({
    stringify:false
});

Upvotes: 2

Related Questions