# Dodo Payments

> Connect Dodo Payments to atrby so payments and subscription renewals are matched to the visit that brought them, with payment metadata.

Canonical: https://atrby.site/docs/integrations/dodo
Last updated: 2026-10-21

Attribute every Dodo Payments payment to the visit that brought it.

## Connect

1. In the Dodo Payments dashboard, open Developer → Webhooks → Add endpoint and copy the **signing secret**; it starts with `whsec_`.
2. In atrby, open Revenue → Payment processors → Connect, choose Dodo Payments and paste the secret.
3. atrby shows your webhook URL. It looks like `https://app.atrby.site/api/webhooks/dodo/…`. Add it in Dodo Payments and send these events: `payment.succeeded`, `refund.succeeded`, `subscription.active`, `subscription.renewed`.

The connection shows as active once the first webhook arrives. Webhooks with a wrong signature are rejected.

## Pass the visit ids

Where they go: Payment or subscription `metadata`. Read them in the browser with `atrby.ids()` and send them to your server with the checkout request.

*Browser*

```js
const ids = window.atrby?.ids(); // { atrby_sid, atrby_site }
```

*Server · Dodo Payments checkout*

```js
await fetch("https://live.dodopayments.com/checkouts", {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.DODO_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({
    product_cart: [{ product_id: productId, quantity: 1 }],
    return_url: "https://acme.io/welcome",
    metadata: { ...ids, atrby_uid: user.id },
  }),
});
```

`atrby_uid` is your user id, from [identify](https://atrby.site/docs/identify). It's optional, but it credits payments made long after the first visit.

## What gets recorded

- Each payment once, however often Dodo Payments retries the webhook.
- Each refund is subtracted from the source of the original payment.

## Related
- [Stripe](https://atrby.site/docs/integrations/stripe)
- [Polar](https://atrby.site/docs/integrations/polar)
- [Payment API](https://atrby.site/docs/payment-api)
