You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Stripe订阅相关Webhook如何传递订阅Metadata以关联订单?

Got it, let's tackle this issue—this is a common gotcha with Stripe's webhooks because charge.succeeded events don't automatically inherit subscription metadata by default. Here are a few reliable ways to fix this so you can link the charge to your database order seamlessly:

1. Fetch the Subscription/Invoice via API from the Charge Event

When you receive a charge.succeeded event, the charge object will include either a subscription ID (if the charge came from a subscription) or an invoice ID. You can use these IDs to retrieve the full subscription or invoice object directly from Stripe, which will contain your original metadata.

Here's a Node.js example using the Stripe SDK:

const stripe = require('stripe')('your_secret_api_key');

// Handle webhook endpoint
app.post('/stripe-webhook', async (req, res) => {
  const event = req.body;

  if (event.type === 'charge.succeeded') {
    const charge = event.data.object;
    
    // Option 1: Fetch the subscription directly
    if (charge.subscription) {
      const subscription = await stripe.subscriptions.retrieve(charge.subscription);
      const orderId = subscription.metadata.order_id;
      // Use orderId to link to your database order here
    }

    // Option 2: Fetch the invoice (which links to the subscription)
    if (charge.invoice) {
      const invoice = await stripe.invoices.retrieve(charge.invoice);
      // Get metadata from the invoice or linked subscription
      const orderId = invoice.metadata.order_id || invoice.subscription.metadata.order_id;
      // Handle order association
    }
  }

  res.json({ received: true });
});

This approach works without changing your subscription creation logic, but it does add an extra API call per charge event.

2. Propagate Metadata to Invoices (and Charges) on Subscription Creation

Stripe lets you set default metadata for invoices when creating a subscription. Since charges inherit metadata from their parent invoices, this ensures the charge.succeeded event will include your order ID directly in the charge object.

When creating the subscription, add the invoice_settings.default_metadata field alongside the subscription's own metadata:

const subscription = await stripe.subscriptions.create({
  customer: 'cus_yourCustomerId',
  items: [{ price: 'price_yourSubscriptionPrice' }],
  // Subscription-level metadata (for reference)
  metadata: {
    order_id: 'your_database_order_id'
  },
  // Metadata that gets passed to every invoice generated by this subscription
  invoice_settings: {
    default_metadata: {
      order_id: 'your_database_order_id'
    }
  }
});

Now every invoice (and its corresponding charge) will have the order_id metadata, so you can access it directly from charge.metadata.order_id in the charge.succeeded event—no extra API calls needed.

3. Expand the Subscription in the Webhook Payload

You can configure your Stripe webhook endpoint to automatically include the full subscription object in charge.succeeded events, instead of just the subscription ID. This lets you access the metadata directly from the webhook payload.

To set this up:

  • Go to your Stripe Dashboard → Webhooks → Select your endpoint
  • Under "Event settings", find the charge.succeeded event
  • Add an expansion parameter: data.object.subscription
  • Save the changes

Now when you receive a charge.succeeded event, the charge.subscription field will be the full subscription object, so you can pull the metadata directly with charge.subscription.metadata.order_id.

Note: This increases the payload size, so make sure your webhook handler can handle larger requests.

Quick Tips

  • Always test webhook events with the Stripe CLI (stripe trigger charge.succeeded --subscription sub_yourTestSubscriptionId) to verify metadata is being passed correctly.
  • Double-check that you're setting metadata correctly when creating the subscription—typos or missing fields are a common culprit.
  • Use the latest version of the Stripe SDK to ensure you have access to all these features.

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

火山引擎 最新活动