Integrations

Payments

Connect your payment provider and every transaction shows up in the Revenue dashboard, attributed to the session, referrer, and user that produced it.

TL;DR: Generate a webhook URL in the dashboard, add it to Stripe or Paddle, and pass Databuddy IDs in your payment metadata.


1. Generate your webhook URL

  1. Open your Databuddy dashboard and go to Website → Revenue.
  2. Click Generate webhook URLs. You get one URL per provider, each with a unique secret path.
  3. Keep this page open, you'll paste the URL into your provider next.

2. Add the webhook to your provider

In the Stripe dashboard, add an endpoint with your generated URL and subscribe to these events:

EventPurpose
payment_intent.succeededRecords successful one-time payments and payment context (required)
invoice.paidRecords invoice and subscription context (required)
invoice_payment.paidRecords exact invoice allocations on modern Stripe versions (required on API 2025-05-28.basil or later)
payment_intent.payment_failedTracks failed payment attempts (required)
payment_intent.canceledTracks canceled payment attempts (required)
invoice.payment_failedTracks failed invoice attempts and retries (required)
charge.refundedRecords each refund (required)

Stripe introduced invoice_payment.paid in 2025-05-28.basil. Subscribe to it on that version or later for exact allocation details. Databuddy also keeps the total from invoice.paid as a safe fallback, so adding the newer event after an API upgrade does not drop or double-count revenue. Earlier versions, including the 2025-03-31.basil transition, use embedded invoice allocations when the full list is available.

Paste the endpoint's signing secret into the Revenue settings so Databuddy can verify each delivery.

In the Paddle dashboard, create a notification destination with your generated URL and subscribe to transaction.completed.

Paste the webhook secret key into the Revenue settings so Databuddy can verify each delivery.

3. Pass Databuddy IDs with each payment

Metadata connects a payment to the visitor who made it. Include what you have: every field is optional, and more fields mean stronger attribution.

ts
import { getProfileId, getTrackingIds } from "@databuddy/sdk";

// In the browser, collect the visitor's IDs...
const { anonId, sessionId } = getTrackingIds();
const profileId = getProfileId();

// ...send them to your server and reuse the same metadata:
const databuddyMetadata = {
databuddy_client_id: websiteId,
databuddy_session_id: sessionId,
databuddy_anonymous_id: anonId,
databuddy_profile_id: profileId,
};

await stripe.paymentIntents.create({
amount,
currency,
metadata: databuddyMetadata,
});

// For recurring billing, attach it to the Subscription too.
await stripe.subscriptions.create({
customer,
items: [{ price: priceId }],
metadata: databuddyMetadata,
});

Stripe does not automatically copy PaymentIntent metadata to future subscription invoices. Put the IDs on the Subscription (or subscription_data.metadata when using Checkout) so recurring revenue stays attributable.

ts
import { getProfileId, getTrackingIds } from "@databuddy/sdk";

const { anonId, sessionId } = getTrackingIds();

Paddle.Checkout.open({
items,
customData: {
  website_id: websiteId,
  session_id: sessionId,
  anonymous_id: anonId,
  profile_id: getProfileId(),
},
});
FieldWhat it unlocks
Session IDTies revenue to the exact visit, referrer, and campaign
Anonymous IDTies revenue to the device even without a session
Profile IDTies revenue to the identified user, see Identify Users

Anonymous IDs are hashed on arrival, the same way the tracker hashes them; raw device IDs are never stored. Profile IDs are your own user IDs and are stored as sent.

Verify it works

Send a test payment (Stripe test mode works), then check Website → Revenue. The transaction appears within seconds of the webhook delivery. If you passed a profile ID, the revenue also shows on that user in Website → Users.

Troubleshooting

  • Nothing appears: confirm the webhook URL matches the generated one exactly and the signing secret is saved in Revenue settings; deliveries with bad signatures are rejected.
  • Revenue appears but isn't attributed: the payment had no Databuddy metadata. Attribution only works for payments created after you started passing IDs.
  • Stripe shows failed deliveries: regenerating webhook URLs invalidates the old path, so update Stripe after regenerating.

How is this guide?