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.