You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Stripe结账会话传递Metadata到Webhook时元数据undefined问题

Stripe Checkout Session元数据无法传递到Subscription Webhook的解决办法

问题根源

你给Checkout Session设置的metadata仅属于该会话本身,Stripe不会自动将其同步到后续生成的Subscription对象中,所以在customer.subscription.created事件里读取subscription.metadata.userUid会得到undefined。

方案一:创建会话时直接给Subscription绑定元数据

修改/create-checkout-session接口,在创建Checkout Session时通过subscription_data.metadata字段,将userUid直接附加到即将创建的Subscription上:

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;
  
  const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'auto',
    line_items: [
      {
        price: 'price_1Oi4pfKIP1dcMwGFpd8tLgP2',
        quantity: 1,
      },
    ],
    mode: 'subscription',
    success_url: `${YOUR_DOMAIN}/admin/create`,
    cancel_url: `${YOUR_DOMAIN}?canceled=true`,
    // 可选:保留会话自身的元数据
    metadata: {
      userUid: userUid,
    },
    // 核心配置:给Subscription设置元数据
    subscription_data: {
      metadata: {
        userUid: userUid,
      },
    },
  });

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

修改后,customer.subscription.created事件中的subscription.metadata.userUid就能正常读取到值。

方案二:Webhook中通过关联的Checkout Session获取元数据

若不想修改会话创建逻辑,可在Webhook里通过Subscription关联的Checkout Session读取元数据。需要额外调用Stripe API获取关联的会话信息:

case 'customer.subscription.created':
  subscription = event.data.object;
  // 获取订阅关联的最新发票,并展开关联的支付意图和Checkout会话
  const invoice = await stripe.invoices.retrieve(subscription.latest_invoice, {
    expand: ['payment_intent.checkout_session'],
  });
  const checkoutSession = invoice.payment_intent.checkout_session;
  const userUid = checkoutSession.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;

此方法需要额外API调用,效率不如方案一,优先推荐方案一。

排查提示

  • 测试时需创建全新的Checkout会话和订阅,旧订阅不会自动同步新的元数据。
  • 可在Stripe后台查看订阅详情,确认metadata是否正确配置,快速定位问题。

内容的提问来源于stack exchange,提问作者Identicon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:35:37