Paddle revenue attribution
Connect Paddle to your Clickport site with an API key and revenue shows up next to your traffic: a Revenue stat in the dashboard header, a revenue line on the main chart, and payments attributed back to the visit that made them. Setup is one paste in Clickport plus one line in your checkout call.
What you see in the dashboard
Once revenue events exist, a Revenue stat appears in the dashboard header, right next to Engagement (the labels compact to REV and ENG when both are showing). Click it to toggle a revenue line onto the main chart, bucketed exactly like the other metrics. The KPI row itself stays untouched: all standard KPIs keep their place.
Revenue lives in the header next to Engagement; the toggled pill draws the revenue line. The KPI row keeps its standard cells.
Because every attributed payment carries its session's dimensions, revenue works with the rest of the dashboard:
- Cross-filtering: filter to a source, campaign, country, or device and the Revenue stat re-computes for that slice.
- Custom events: Purchases and Refunds appear as events in the Goals panel's custom events list, with revenue totals and averages.
- Goals and funnels: add a custom-event goal on
Purchaseand funnels can end at the payment, with real amounts behind the conversion step. - Refunds and chargebacks net out: both land as negative revenue events attributed to the same session as the original purchase, so per-source revenue stays honest.
Add a goal on the Purchase event and it ranks alongside your existing goals, with revenue and average per conversion:
A custom-event goal on Purchase, ranked with the rest of the Goals panel.
How to connect
Clickport asks for an API key you scope yourself, with read access only. Create a dedicated key for the connection instead of reusing one your backend already holds; it keeps the permissions minimal and lets you revoke it independently.
- In Paddle, open Developer tools → Authentication and click New API key.
- Grant it: Transactions — Read, Adjustments — Read. Optionally add Notifications — Write (see the sync modes section below). Everything else stays off.
- Copy the key (new keys start with
pdl_live_apikey_; older keys have no prefix and work too). - In Clickport, open Settings → Integrations → Revenue for your site, click Connect with API key on the Paddle card, and paste it.
The Paddle card in Settings → Integrations → Revenue after connecting.
On connect, Clickport validates the key, imports the last 90 days of payments as a backfill, and starts syncing new ones. Revenue from the backfill appears within a few minutes.
Sync modes
- Real-time (recommended): if the key includes Notifications — Write, Clickport creates a webhook destination on your Paddle account automatically. Payments appear in the dashboard the moment they land. Deliveries are signed and verified; the destination is removed again when you disconnect.
- Periodic: without the notification scope, Clickport pulls new payments every 10 minutes. Same data, small delay.
How attribution works
Clickport's tracker knows its own session ID. Pass it into checkout as custom data and Paddle returns it with the completed transaction. Clickport joins it back to the session, and the payment inherits the visit's source, campaign, channel, country, and device.
If you open checkout with Paddle.js (overlay or inline), it's one added key:
Paddle.Checkout.open({
items: [{ priceId: 'pri_...', quantity: 1 }],
customData: { clickport_ref: window.clickport.checkoutRef() }
});
customData is a plain object, so clickport_ref merges alongside anything you already pass there. Clickport never touches your other keys. In a React or Vue app the call is the same, made inside your buy-button's click handler.
Paddle.Checkout.open with its own priceId. Adding customData: { clickport_ref: window.clickport.checkoutRef() } to the shared checkout helper is the entire integration. From the next deploy on, every purchase carries its visit.
Server-created transactions
If your backend creates transactions via the Paddle API (including hosted checkout links for them), pass the token server-side instead. Read it in the browser with clickport.checkoutRef(), send it with your checkout request, and set it as custom data:
// In the browser: send the token to your backend with the checkout request
const ref = window.clickport.checkoutRef(); // "cp-1234567890"
// On your server: pass it when creating the transaction
const txn = await paddleApi.post('/transactions', {
items: [{ price_id: 'pri_...', quantity: 1 }],
custom_data: { clickport_ref: ref },
});
attributed property so you can see the split in the event's property breakdown.
Refunds correct the record
When you approve a refund (or a chargeback lands), Clickport writes a negative revenue event dated at the refund, carrying the original visit's source and campaign. If one of July's 21 newsletter purchases refunds in August, the newsletter's revenue self-corrects by that €49 without you touching anything.
Manual revenue tracking still works
The Paddle integration and the custom events API compose. If you sell through something else too, or want revenue on non-payment events, keep using:
clickport.track('Order Completed', { plan: 'yearly' }, { amount: 149, currency: 'EUR' });
The Revenue stat and chart line sum every event that carries revenue, whichever way it got there. Selling through Stripe as well? The Stripe integration runs side by side with this one.
Multi-currency
Amounts are recorded in the currency the customer paid, including tax: the checkout total, which is the number that matches what your customer saw. Zero-decimal currencies (yen and won) are handled correctly.
Paddle is a merchant of record, so customers often pay in their local currency and your revenue arrives mixed. Pick a reporting currency on the same Integrations tab and Clickport converts every payment into it at the daily European Central Bank reference rate of its payment date: one currency everywhere, past payments included. The original charged amounts are always kept unchanged, and switching back to "As charged" restores them. Without a reporting currency, totals are displayed in whichever currency carries the largest share.
Disconnecting
Click Disconnect Paddle on the Integrations card. Clickport deletes the encrypted key immediately and removes the webhook destination it created on your Paddle account. Revenue already imported stays in your analytics; reconnecting later won't double-import it, because every processed payment is remembered by its Paddle ID.
Troubleshooting
"Paddle did not accept the key"
The key is wrong, revoked, or from the sandbox environment. Clickport connects to live Paddle accounts; create the key in your production dashboard and paste it again.
"The key needs read access to Transactions and Adjustments"
The key exists but lacks the read permissions. Edit the key in Paddle, grant Transactions — Read and Adjustments — Read, and paste it again.
Payments arrive but show as unattributed
- The one-line
customDatapass-through has to be in your checkout call. Without it there is no token to join, and that's the most common cause. - The buyer must have the Clickport tracker loaded on the page that opened checkout. If checkout starts from a page without the tracker (an email link, a separate landing page), there's no session to join.
- Subscription renewals are unattributed by design; see the note above.
- Ad blockers that block the tracker also block attribution for that visitor. The payment still counts via Paddle, just without a source.
Revenue totals differ from the Paddle dashboard
Clickport records the checkout total: what the customer paid, including tax. Paddle's own reporting often leads with earnings, which subtracts tax and Paddle's fee. Clickport also timestamps at payment time in your dashboard timezone, while Paddle may group by UTC days or settlement dates. Both differences are expected.
Privacy and data handling
- Your API key (and the webhook signing secret, in real-time mode) is AES-256-GCM-encrypted at rest. Disconnecting deletes it immediately.
- The key is read-only by your own scoping; Clickport cannot modify anything in your Paddle account beyond the webhook destination you optionally allow it to create.
- Clickport stores the payment amount, currency, timestamp, and Paddle object IDs. No customer names, emails, or card details are read or stored.
- Attribution uses the session token alone. No cookies, no fingerprinting, no cross-session identity. Connecting or disconnecting the integration is recorded in your site's audit trail.