Revenue Connectors

Connect every revenue provider you bill on — one webhook each.

Admaxxer is a DTC analytics platform with built-in Meta + Google ad ops. This hub walks through how Admaxxer stitches checkout webhooks from Stripe, Paddle, Lemon Squeezy, Polar, Dodo, WooCommerce, and Shopify into the same first-party pixel data, so you can see revenue attribution, blended MER, cohort LTV (7/30/90 day), and ad-level LTV across every payment provider in one view.

Start free trial Open Revenue settings

1. How revenue attribution works (3 steps)

Every supported revenue provider follows the same three-step pattern. The differences between Stripe and Shopify are which field carries the visitor ID and which header carries the signature — the architecture is identical.

  1. Step 1 — Pixel stamps the visitor.

    The Admaxxer pixel writes a stable first-party visitor ID (UUID) into localStorage + a 1p cookie on first page view. The same ID persists across sessions, devices reachable via login, and the entire customer journey.

  2. Step 2 — Checkout carries the visitor ID forward.

    When a checkout is created (via Stripe Checkout, Paddle, Polar, Lemon Squeezy, etc.), the pixel injects the visitor ID into the provider's structured metadata field (e.g. metadata.admaxxer_visitor_id on Stripe, custom_data.admx_visitor_id on Paddle, note_attributes.admaxxer_visitor_id on Shopify). The visitor ID is now embedded in the order itself — not in the URL, not in a cookie, but in the canonical order record.

  3. Step 3 — Provider fires webhook, Admaxxer ingests + attributes.

    When the order completes, the provider fires its standard webhook (e.g. checkout.session.completed, orders/paid) to https://admaxxer.com/api/pixel/webhooks/<provider>/<YOUR_WEBSITE_ID>. We validate the signature, extract the visitor ID, look up the visitor's full session graph in Tinybird, and write a revenue event joined to acquisition source, campaign, ad creative, and cohort. The order shows up in the attribution dashboard within ~3 seconds.

Because the visitor ID lives in the canonical order record (not a cookie, not a URL parameter), this flow survives every browser privacy mode, every consent change after checkout, every device handoff, and every chargeback or refund. No PII is required — the only field Admaxxer reads is the opaque visitor ID we wrote ourselves.

2. All seven connectors

Pick the connector that matches your payment stack — each guide is a 5-minute, copy-paste setup with screenshots and verification steps.

Stripe →

Restricted-key + webhook setup. Captures checkout.session.completed, payment_intent.succeeded, and charge.succeeded. Visitor ID stitched via metadata.admaxxer_visitor_id.

Events
checkout.session.completed, payment_intent.succeeded, charge.succeeded
Signing
Stripe-Signature header (HMAC-SHA256 + timestamp)

Paddle →

Paddle Billing webhook setup. Captures transaction.completed for one-time and subscription revenue. Visitor ID stitched via custom_data.admx_visitor_id.

Events
transaction.completed
Signing
Paddle-Signature header (HMAC-SHA256)

Lemon Squeezy →

Lemon Squeezy webhook setup for digital goods, subscriptions, and license keys. Visitor ID stitched via meta.custom_data.admx_visitor_id.

Events
order_created
Signing
X-Signature header (HMAC-SHA256)

Polar →

Polar.sh checkout + subscription webhook setup. Captures order.created and subscription.created. Visitor ID stitched via metadata.admx_visitor_id.

Events
order.created, subscription.created
Signing
Polar-Webhook-Signature or X-Polar-Signature header

Dodo →

Dodo Payments webhook setup. Captures payment.succeeded for completed transactions. Visitor ID stitched via data.metadata.admx_visitor_id.

Events
payment.succeeded
Signing
X-Dodo-Signature or Dodo-Signature header

WooCommerce →

WordPress + WooCommerce stack. Use the official Admaxxer WP plugin to forward order_status_completed and order_status_processing webhooks with the visitor ID stamped at checkout.

Events
order_status_completed, order_status_processing
Signing
X-Admaxxer-Signature header (HMAC-SHA256, plugin-signed)

Shopify →

Native Shopify webhook setup. Captures orders/create and orders/paid. Visitor ID stitched via note_attributes.admaxxer_visitor_id (set by the Admaxxer pixel snippet).

Events
orders/create, orders/paid
Signing
X-Shopify-Hmac-Sha256 header (base64-encoded HMAC)

3. Shared architecture (every connector)

All seven connectors share the same back-end pipeline. Knowing it once means you understand all seven:

This is the same architecture used by every existing analytics connector in Admaxxer — see the Analytics docs for how downstream pipes consume revenue_events.

4. Connecting more than one provider

You can connect any number of revenue providers per workspace. Common combinations we see in the wild:

Deduplication is on (provider, external_id), not on amount or visitor — so even if two providers happen to fire identical-looking events, they are recorded independently. Refunds attribute to the provider they originated from.

5. Refunds, disputes, and currency

Every connector handles refunds and disputes through its native webhook event (charge.refunded, order_refunded, refund.created, etc.). Admaxxer:

6. Troubleshooting

The most common issues across every connector, ranked by frequency:

Webhook returns 401
Signing secret mismatch. Re-copy the signing secret from the provider's dashboard into Admaxxer Revenue Settings. Make sure you are not pasting the publishable key by mistake — only the webhook signing secret validates inbound payloads.
Order shows up as unattributed
The visitor ID was missing from the order metadata. Confirm the pixel loaded on the page before the checkout was created (a consent banner that blocks the pixel will cause this). The per-connector pages document how to verify the visitor ID is present on a sample checkout.
Webhook fires but no event appears in Tinybird
Check the X-Admaxxer-Webhook-Status response header — we set it to ok, invalid_signature, missing_visitor_id, or parse_error. The Revenue Settings dashboard also shows the last 50 inbound webhook deliveries with their status.
Same order recorded twice
Should not happen — we dedupe on (provider, external_id). If it does, you likely have two connector entries pointed at the same provider; remove the duplicate from Revenue Settings.

Frequently asked

How does revenue attribution actually work?
The Admaxxer pixel stamps every visitor with a stable first-party ID and writes it into a structured field on the checkout you create with your payment provider — for example metadata.admaxxer_visitor_id on Stripe, custom_data.admx_visitor_id on Paddle, note_attributes.admaxxer_visitor_id on Shopify. When the provider fires its webhook to Admaxxer, we read the visitor ID, validate the signature, and write a revenue event in Tinybird that's joined to the visitor's full session and acquisition source. No PII leaves the provider.
Can I connect more than one revenue provider at once?
Yes. Admaxxer supports an unlimited number of revenue connectors per workspace — common stacks combine Stripe (subscriptions) plus Shopify (physical goods), or Lemon Squeezy plus Paddle for tax-of-record split between regions. Each provider has its own webhook endpoint and signing secret. We deduplicate on (provider, external_id) so the same order isn't double-counted if multiple webhooks fire.
What if I miss a visitor ID on an order?
We still record the revenue event — it's never dropped — but it's marked as unattributed and shows up in the Unattributed bucket on the attribution dashboard. Common causes are: the pixel didn't load before checkout (consent banner blocked it), the order was created from an admin tool not the website, or an old checkout link bypassed the visitor-id injection. Each connector page has a Troubleshooting section that walks through every fallback.
Are webhook signatures actually validated?
Yes. Every connector validates the signature header before processing — Stripe-Signature, Paddle-Signature, X-Signature (Lemon Squeezy), Polar-Webhook-Signature, X-Dodo-Signature, X-Admaxxer-Signature (WooCommerce), or X-Shopify-Hmac-Sha256. Requests with missing or mismatched signatures return 401 and are logged. Replay-window enforcement uses the timestamp embedded in the header (5-minute window) for providers that support it.
How are refunds and disputes reflected in MER and LTV?
Refunds and disputes that fire as separate webhook events (charge.refunded, refund.created, order_refunded, etc.) are recorded as negative revenue events in Tinybird and join back to the original order via external_id. Blended MER, cohort LTV, and ad-level LTV all subtract refunded amounts on a 30-day rolling basis. Disputes are treated identically to refunds for revenue accounting once the dispute is lost; pending disputes are flagged but not subtracted until resolved.

Next steps

Pick the connector for your stack and follow the 5-minute setup:

Already have the pixel installed? See the install index if you haven't, then come back here. The pixel is what stamps the visitor ID — without it, attribution falls back to unattributed.