Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Stripe passing Metadata from Create-Checkout-Session to Webhook

Im trying to pass metadata (userUid) to the Webhook so it saves it correctly in my Firebase.
the Checkout Session receives the userUid correctl (seen in the console.log) but somehow the metadata is undefined in the Webhook.

Here is the cretae-Checkout-Session code:

    app.post('/create-checkout-session', async (req, res) => {
  const prices = await stripe.prices.list({
    lookup_keys: [req.body.lookup_key],
    expand: ['data.product'],
  });
  const userUid = req.body.user_uid;
  console.log("Received form data:", req.body);
  console.log("Received user_uid:", req.body.user_uid); //received Correctly
  console.log("Useruid :", userUid); //Logged correctly
  const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'auto',
    line_items: [
      {
         price: 'price_1Oi4pfKIP1dcMwGFpd8tLgP2',
        // For metered billing, do not pass quantity
        quantity: 1,

      },
    ],
    mode: 'subscription',
    
    success_url: `${YOUR_DOMAIN}/admin/create`,
    cancel_url: `${YOUR_DOMAIN}?canceled=true`,
    metadata: {
      userUid: userUid, // Passing userUid as metadata
    },
  });

  res.redirect(303, session.url);
});

And here is my webhook:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    app.post(
  '/webhook',
  express.raw({ type: 'application/json' }), // Ensure the body is received as a raw Buffer
  async (request, response) => {
    const signature = request.headers['stripe-signature'];
    let event;
    let subscription;
   
    console.log(typeof request.body); // This should log 'object', indicating it's a Buffer

    if (endpointSecret) {
      try {
        // Construct the event using the raw body and signature
        event = stripe.webhooks.constructEvent(
          request.body,
          signature,
          endpointSecret
        );
      } catch (err) {
        console.log(`⚠️  Webhook signature verification failed.`, err.message);
        return response.status(400).send(`Webhook Error: ${err.message}`);
      }
    } else {
      // If there's no endpoint secret, you could parse the body to work with it as a JSON object
      // Note: This is not recommended for production as it bypasses signature verification
      event = JSON.parse(request.body.toString());
    }
      response.json({received: true});
 
    switch (event.type) {
      case 'customer.subscription.trial_will_end':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription trial ending.
        // handleSubscriptionTrialEnding(subscription);
        break;
      case 'customer.subscription.deleted':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription deleted.
        // handleSubscriptionDeleted(subscriptionDeleted);
        break;
        case 'customer.subscription.created':
          subscription = event.data.object; // Define subscription here
          userUid = subscription.metadata.userUid; 
          
          try {
            await db.doc(`restaurant/${userUid}/branch/payment`).set({
              model: "pioneer",
              paid: true,
            }, { merge: true });
        
            console.log(`Firestore updated for ${userUid}  with subscription `);
          } catch (error) {
            console.error("Error updating Firestore:", error);
            response.status(500).send(`Error updating Firestore: ${error.message}`);
            return;
          }
        
          console.log(`Handled customer.subscription.created for subscription ${subscription.id}`);
  break;

in the log it says : Firestore updated for undefined with subscription

>Solution :

Currently you are saving metadata on the Checkout Session object not on the Subscription. Since the webhook event you are listening to is customer.subscription.created, you’ll need to set metadata here instead to have it set on the Subscription object and receive it in the customer.subscription.created event.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading