Some flows have nowhere to put custom_data: a Paddle payment link you share
by e-mail, a checkout opened by a third-party tool, an in-app purchase, a
reseller. The payment still reaches your dashboard — it simply arrives with no
visitor attached.
There is a second route. Tell us the e-mail address the customer paid with, and we match it against the payment Paddle reports.
window.truestat("payment", { email: "customer@example.com" });Fire this on your own success page, with the address used at checkout.
Why this is weaker, and when it is enough
The match needs the address to be identical. A customer who pays with a work address and signed up with a personal one stays unattributed, and there is no way for us to know the two are the same person.
It also cannot tell one visit from another. custom_data carries a session id
as well as a visitor id, so it can say which visit produced the sale;
e-mail matching can only say which person did.
Use custom_data wherever the checkout allows it — the
Checkout API and
overlay pages both do — and keep this
for the flows where it genuinely cannot be set.
Firing it twice is safe. A duplicate is recognised and ignored, so a success page the customer reloads does not count the payment again.
What it cannot do
It cannot attribute a renewal. The success page fires once, when the customer first buys; the renewals that follow arrive from Paddle with no e-mail event beside them. Subscriptions attributed this way show their first payment against a channel and their renewals as unattributed.
That is the strongest argument for custom_data where you have the choice:
it carries forward on its own, for the life of the subscription.