# Missing or unattributed payments

Why a payment didn't show up in Revenue, and how to read the webhook's answer.

Every provider keeps a delivery log for its webhooks (Stripe: Developers → Webhooks → your endpoint; Paddle: Notifications → Logs; and so on). Open the failed or suspicious delivery and read VisitTrack's response body. It always says what happened.

| Status | Response | What it means | Fix |
| --- | --- | --- | --- |
| `200` | `attributed: true` | Recorded. | Nothing to do. If a retry repeats it, it's deduplicated. |
| `200` | `reason: "no visitor id"` | The payment arrived without a visitor id. | Pass `_ana_vid` at checkout. See your provider's page. |
| `200` | `reason: "unknown visitor"` | The id doesn't match any visitor on this site. | Make sure the tracker runs on the page that starts checkout, on the same site as the webhook URL. |
| `200` | `ignored: "…"` | An event VisitTrack doesn't use. | Nothing, or unsubscribe from it. |
| `400` | `signature verification failed` | The secret in VisitTrack doesn't match the provider's. | Copy the signing secret again into Settings → Revenue. |
| `400` | `timestamp outside tolerance` | The delivery is older than 5 minutes (Polar, Paddle). | Resend it from the provider's dashboard. |
| `404` | `no … connection for this site` | The provider isn't connected for this site id. | Connect it in Settings → Revenue, or check the site id in the URL. |

## Common causes

- **Testing on localhost.** The tracker ignores localhost, so the visitor id never reaches our database. Add `data-allow-local` to the script tag while testing.
- **Checkout on another domain.** The visitor id lives in `localStorage` on your site. Read it there, before redirecting to the provider, not on the provider's hosted page.
- **Ad blockers.** A visitor whose blocker stops the tracker has no id, so their payment can't be attributed. [Serve the script from your own domain](https://visitrack.app/docs/install) to reduce this.
- **Wrong site.** Each site has its own webhook URL. A payment for site A sent to site B's URL finds no visitor.

## Duplicate payments

Payments are keyed on the provider's own payment id, so retried deliveries never double-count. If you also send a `payment_completed` event yourself through `/api/track`, you'll see it twice in funnels. Attributed payments already write that event for you, so stop sending your own.
