2026-11-06 · Q&A guide

Track Daily Product Sales with Stripe Checkout & Webhooks

Learn how to extract product sales data from Stripe Checkout using webhooks, metadata, and Sigma queries.

1. Checkout Session Line Items

When a customer completes a Stripe Checkout, the resulting Checkout Session contains a list of line items. Each line item references the product ID, price ID, and quantity. These objects are not stored in the PaymentIntent itself, which is why the dashboard shows limited aggregation.

2. Persist Product IDs in Metadata

Add the product ID to the Checkout Session’s metadata before redirecting the customer. This makes the data available in webhook events and in the Session object that you can query later.

stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  line_items: [{price: 'price_123', quantity: 1}],
  mode: 'payment',
  metadata: {product_id: 'prod_ABC123'}
});

3. Webhook Handler Example

Listen for the `checkout.session.completed` event, extract the metadata, and write a record to your database. This gives you a reliable source of sales data that survives any dashboard changes.

const express = require('express');
const app = express();
app.use(express.json({ verify: stripe.webhooks.makeRequestHandler({ secret: process.env.STRIPE_WEBHOOK_SECRET }) }));
app.post('/webhook', async (req, res) => {
  const session = req.body.data.object;
  const productId = session.metadata.product_id;
  const quantity = session.line_items?.data[0]?.quantity || 1;
  await db.insert('sales', { product_id: productId, quantity, timestamp: new Date() });
  res.sendStatus(200);
});

4. Generate Reports with Sigma

If you prefer a no‑code solution, use Sigma to query the `line_items` table. A simple query returns daily totals per product:

SELECT
  DATE(created) AS day,
  product_id,
  SUM(quantity) AS sold
FROM
  line_items
GROUP BY
  day, product_id
ORDER BY
  day DESC;

5. Best Practices & Troubleshooting

• Store the product ID in metadata on every Checkout Session. • Validate webhook signatures to avoid spoofed events. • Keep a local copy of sales data; it’s faster for analytics than hitting the API each day. • If you use multiple price IDs for the same product, map them back to the product ID in your database.

Takeaway: Persist product identifiers in Checkout Session metadata and capture them via webhooks; use Sigma or a simple database query to generate daily sales reports.

People also ask

Can I get product sales directly from the Stripe dashboard?

The dashboard shows totals per payment but not per product. Use Sigma or your own database for product‑level reporting.

What if my site uses multiple price tiers for the same product?

Store the product ID in metadata and map each price ID to that product in your database; then aggregate by product ID.

Inspired by a public discussion on Stack Overflow. This article is an original explanation for learners.

← All posts