Dodo Payments revenue analytics for Next.js
This guide adds ProductLense to a Next.js site and connects Dodo Payments, so every Dodo Payments payment is attributed to the channel, campaign and landing page that first brought the customer. It takes four steps and about ten minutes.
1. Add ProductLense to Next.js
The script goes in app/layout.tsx with next/script. Replace SITE_ID with the id from Settings → Sites.
import Script from 'next/script';
import type { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://api.productlense.app/a.js"
data-site="SITE_ID"
strategy="afterInteractive"
/>
</body>
</html>
);
}2. Identify signed-in users
'use client';
import { useEffect } from 'react';
declare global {
interface Window {
productlense?: (...args: unknown[]) => void;
}
}
export function ProductLenseIdentify({ userId, email }: { userId?: string; email?: string }) {
useEffect(() => {
if (userId) window.productlense?.('identify', userId, email ? { email } : undefined);
}, [userId, email]);
return null;
}3. Connect Dodo Payments
Setup steps
- In Dodo Payments, open Developer → API Keys and create a live key.
- In ProductLense, open Settings → Billing connections → Dodo Payments and paste the key.
- In Dodo Payments → Developer → Webhooks, add a webhook endpoint with the URL ProductLense shows after you save the connection (pattern https://api.productlense.app/api/webhooks/{provider}/{connection_id}).
- Subscribe to the payment, refund, subscription and dispute events and paste the secret into ProductLense.
- ProductLense backfills 12 months of payments and refunds.
Credentials and permissions
| Field | Secret | Where to find it |
|---|---|---|
| API key | Yes, encrypted at rest | A live API key from Dodo Payments → Developer → API Keys. |
| Webhook secret | Yes, encrypted at rest | The whsec_... secret shown on the webhook endpoint you point at ProductLense. |
Webhook
URL pattern, shown with your connection id after you save:
https://api.productlense.app/api/webhooks/dodo/{connection_id}Events: payment.succeeded, payment.failed, refund.succeeded, subscription.active, subscription.cancelled, dispute.opened
Verification: Standard Webhooks signature headers.
What ProductLense reads
- Customers
- Customers with email and metadata.
- Subscriptions
- Subscriptions with status.
- Payments
- Payments.
- Refunds
- Refunds, plus disputes recorded as chargebacks.
- Fees
- Total amount minus settlement amount when both are in the same currency; otherwise tax only.
What ProductLense never touches
- Never creates, changes, refunds or cancels anything: read-only API calls and incoming webhooks only.
- Never moves money, issues payouts, or reads bank account details.
- Never sees full card numbers; providers do not expose them.
- Never sends your customer data to the AI model: Ask and the daily insight see aggregates only.
Match payments to your users
ProductLense bills its own customers through Dodo Payments, so this connector is the one we use ourselves.
// Add to the body of your subscription or payment create call:
const body = {
customer: { email: user.email, name: user.name },
metadata: { pl_user_id: user.id },
// product_id, billing, ...
};Dodo Payments on Next.js: questions
- Where does the ProductLense script go in Next.js?
- In app/layout.tsx with next/script. Add the Script component to app/layout.tsx with strategy="afterInteractive" and data-site. The script is about 2.3 KB, loads with defer, sets no cookies, and records route changes in single-page apps through the history API, so no extra router code is needed.
- How do I identify users in Next.js?
- Call window.productlense('identify', userId) once the signed-in user is known, as in the app/productlense-identify.tsx example on this page. Use the same id you store on Dodo Payments as pl_user_id, so Dodo Payments payments match by id rather than by email.
- Does ProductLense work with Dodo Payments?
- Yes. ProductLense connects to Dodo Payments with aPI key, webhook secret, backfills 12 months of history, and stays current through signed webhooks plus a nightly reconcile. One connection is included on Starter; Growth and Scale allow every provider at once on the same site.
- What data does ProductLense read from Dodo Payments?
- Customers, subscriptions, payments, refunds and fees, read-only. Payments: payments. Refunds: refunds, plus disputes recorded as chargebacks. Fees: total amount minus settlement amount when both are in the same currency; otherwise tax only.
- Can ProductLense change anything in my Dodo Payments account?
- No. ProductLense only makes read calls and receives webhooks. It never creates, changes, refunds or cancels anything, never moves money, and never sees card numbers. Credentials are encrypted at rest, and the AI features only ever see aggregated numbers, never your customers’ data.
Free up to 10k events a month. No card.
Add the script, connect Stripe or any of 14 other billing providers, and see revenue by channel the same day.