Integrations

Dodo Payments revenue attribution and setup guide

Dodo Payments supports checkout metadata and signed payment/refund delivery. Connect both so a sale can retain its source even after the buyer leaves your website to pay.

Before you connect

Install the tracker on your verified website and confirm the first event. Open that site’s Settings → Revenue as a workspace owner or admin, choose Dodo Payments, and copy the webhook URL shown there. Your deployment’s settings are the authority for its origin.

Configure the webhook

  1. In Dodo Developer → Webhooks, choose Add endpoint and paste the URL for your analytics site. Start in Dodo test mode with a separate AnalyticFast test site.
  2. For hosted tracking, the endpoint has this form:
    https://t.analyticfast.com/api/webhooks/dodo/YOUR_SITE_ID
    Replace YOUR_SITE_ID with this site’s ID; use the exact URL from Settings if its origin differs.
  3. Subscribe to these events:
    • payment.succeeded
    • refund.succeeded
  4. Copy the endpoint signing secret as provided and save it in AnalyticFast. The receiver checks Standard Webhooks signatures with the decoded whsec_ key and a five-minute signed-timestamp window. An account API key is not a webhook signing secret.
  5. Save. Optionally enter product IDs to filter transactions. A matching product includes the entire transaction, so a filter is not product-level revenue allocation.
Screenshot placeholder: Dodo Payments webhook destination with the site URL and required events selected; hide all signing secrets.

Carry the visitor into checkout

For server-created checkout, put ml_visitor_id and ml_session_id in the checkout’s metadata. Static /buy/ links support metadata_ml_visitor_id and metadata_ml_session_id URL fields. See Dodo’s payment-link integration guide.

// Browser: read IDs immediately before asking your server to create checkout.
const attribution = window.analyticfast?.attribution?.() ?? {};
// Send these optional IDs with your existing checkout request.
// Server: validate them and copy only the present values into provider metadata.
// Keep prices, products and all payment credentials under server control.
// Browser helper, for your own trusted Dodo /buy/ checkout URL.
function checkoutUrlWithAttribution(checkoutUrl) {
  try {
    const url = new URL(checkoutUrl);
    if (url.protocol !== 'https:' || url.username || url.password || url.port) return checkoutUrl;
    const ids = window.analyticfast?.attribution?.() ?? {};
    if (ids.ml_visitor_id && ids.ml_session_id &&
        !url.searchParams.has('metadata_ml_visitor_id') &&
        !url.searchParams.has('metadata_ml_session_id')) {
      url.searchParams.set('metadata_ml_visitor_id', ids.ml_visitor_id);
      url.searchParams.set('metadata_ml_session_id', ids.ml_session_id);
    }
    return url.href;
  } catch { return checkoutUrl; } // Checkout must work if analytics is unavailable.
}
// Use the returned URL in your existing checkout navigation.

Preserve an existing analytics identity pair rather than partially replacing it. Automatic decoration is limited to configured, allowed checkout URLs. Send buyers back to a tracked thank-you page for journey continuity; a page visit alone is not proof of payment.

What creates revenue and refunds

Payments use payment_id; refunds use their own refund_id linked to the payment_id. A successful payment with charge_type=renewal is recurring revenue. Duplicate deliveries do not create duplicate money, and partial/full refunds reconcile against the original transaction and currency. Webhook customer names and emails do not automatically identify analytics visitors.

Verify with a real signed test delivery

  1. On your separate test site, arrive with a unique UTM campaign and complete a sandbox payment through your actual checkout flow.
  2. Inspect the provider’s delivery log, then check the payment, its currency and its attributed visit in AnalyticFast. Test mode data should stay out of your production analytics site.
  3. Retry the same delivery and confirm no duplicate revenue. Issue a successful partial or full refund and confirm the net amount falls once. For subscriptions, test a later renewal.

The settings test button is a local parser preview. It does not contact Dodo Payments, verify signatures over the network or persist revenue.

Limits to check before going live

Keep customer identity separate from analytics metadata. Explicit metadata provides the strongest handoff. Existing return-page and customer matching can help when available, but timing-based matching is a fallback and cannot guarantee that every payment has an attributable source.

No universal historical import runs when you save a webhook. Validate new deliveries first. Keep currencies separate and compare like date ranges; an analytics revenue total is not a bank payout statement.

Official references

Setup reviewed against the current adapter and official documentation on October 31, 2026. This is an implementation guide, not a claim that a live checkout was exercised.

Add your website to AnalyticFast, then open Settings → Revenue to copy its webhook URL.

Questions, answered.

Does a thank-you page count as payment revenue?

No. The signed successful-payment webhook records revenue. A tracked return page can provide attribution context, but refreshing it must not create a new payment.

Does the test button send a real payment?

No. It is a local parser preview: it contacts no provider, verifies no signed delivery, and records no revenue. Use a separate AnalyticFast test site and your provider sandbox to check payment, renewal, retry and refund delivery.

Do I need to expose payment credentials in my website?

No. The Site ID is public. Webhook signing secrets belong in the Revenue settings, and payment API keys belong on your server. Only optional visitor and session IDs travel from the browser to your checkout code.