# Introduction (https://talivia.com/docs)



Talivia is revenue-first analytics for founders and small teams. It tracks visits, sessions, sources, events, product journeys, search keywords, and payments in one workspace so you can see what actually creates revenue.

Talivia is analytics with payment attribution, session-level revenue, native Stripe, Yolfi, and Dodo Payments connections, a Manual Payment API, search integrations, and practical collaboration for sharing a website with another user.

## What Talivia tracks [#what-talivia-tracks]

* Visits, sessions, pages, referrers, campaigns, countries, devices, browsers, and operating systems.
* Custom events from data attributes or `window.talivia.track`.
* Session replay and Web Vitals when enabled for a website.
* Revenue from connected payment providers, checkout return URLs, and the Manual Payment API.
* Search queries from Google Search Console and Bing Webmaster with estimated revenue allocation.

## Recommended path [#recommended-path]

1. Add your website.
2. Install the tracking script.
3. Confirm that visits appear in the dashboard.
4. Connect revenue sources when checkout is ready.
5. Invite teammates or viewers if someone else needs access.




## Use these docs [#use-these-docs]

Start with **Installation** if you only need the script. Use **Tracking** for JavaScript and data-attribute examples. Use **Revenue** and **Attribution** when payments need to connect back to sessions and traffic sources.


---

# Cross-domain tracking (https://talivia.com/docs/cross-domain-tracking)



Browser cookies cannot be shared between unrelated root domains. Talivia uses a short-lived signed linker instead.

1. Open **Settings -> Attribution**.
2. Add every owned root domain used by the journey.
3. Keep **Cross-domain tracking** enabled.
4. Copy the refreshed snippet from **Settings -> Tracking** to each domain.

The generated snippet includes `data-cross-domain-domains`. After the first tracking response, Talivia decorates matching links with `_tlv`. The destination verifies the signature, continues the anonymous visitor/session, and removes `_tlv` from the address before storing the page view.

The linker expires after five minutes and is scoped to one Talivia website ID. A modified token, expired token, or token issued for another website is rejected.

Subdomains do not need the linker. Use [Subdomain tracking](https://talivia.com/docs/subdomain-tracking) for `example.com` and `app.example.com`.


---

# Distinct IDs (https://talivia.com/docs/distinct-ids)



Talivia is anonymous by default. The tracker creates a visitor key and session key in browser storage, then records page views without requiring a user id.

Use `identify` when your app knows who the visitor is.

```js
window.talivia.identify('user_123', {
  email: 'founder@example.com',
  name: 'Founder',
});
```

## Payment customer fields [#payment-customer-fields]

Talivia recognizes common payment/customer fields:

```js
window.talivia.identify('user_123', {
  stripeCustomerId: 'cus_123',
  providerName: 'stripe',
  providerCustomerId: 'cus_123',
  externalCustomerId: 'user_123',
  emailHash: 'sha256-email-hash',
});
```

These fields help connect Stripe or manual payments back to the visitor, especially when checkout happens later.

## What identify does [#what-identify-does]

Identify sends an `identify` collection event, stores session data, and links the current visitor/session to the customer identity.

## When to call it [#when-to-call-it]

Call identify after login, signup, account creation, or whenever a new payment customer is created.


---

# Goals (https://talivia.com/docs/goals)



Goals let you define important outcomes and watch conversion rates over time.

## Goal examples [#goal-examples]

* A visit to `/pricing`.
* A custom event such as `signup-click`.
* A checkout return page.
* A session property or event-data match.

## How to use goals [#how-to-use-goals]

Create goals from the website reports area. Choose the condition that represents success, then review conversion count and rate across the selected date range.

## Revenue goals [#revenue-goals]

For paid conversion analysis, prefer the Revenue and Attribution reports. Goals are best for product milestones that may happen before payment.


---

# Installation (https://talivia.com/docs/install)



Installation has two useful steps: add the tracker to your site, then connect the payment system that creates revenue.

## Step 1. Install the tracker [#step-1-install-the-tracker]

The Talivia tracker works anywhere you can add a script tag. Start with the universal snippet, then use a framework guide only when you need exact placement for your stack.

### Universal snippet [#universal-snippet]

In the app, open the website, go to **Settings -> Tracking**, and copy the snippet generated for that website.

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-domain="example.com"
></script>
```

Always copy the snippet from your website settings. Replace YOUR\_WEBSITE\_ID with the real ID from Talivia Settings -> Tracking. Do not reuse the example value.

Place the snippet before the closing `</body>` tag, or load it through your framework's shared document/layout component.

Talivia Cloud usually includes `data-domain` in the generated snippet. A website running on one hostname also works without it, but keeping the generated value lets the root website and its subdomains share the same visitor and 30-minute rolling session. You do not need to add or remove this attribute manually for a normal installation.

If your flow crosses to a different root domain, add the owned domains under **Settings -> Attribution** and copy the refreshed snippet.

Tracking overview

See what the script records automatically and which runtime functions it exposes.

Tracker configuration

Understand optional script attributes, storage, filtering, and collection settings.

Subdomain tracking

Keep one visitor identity across a root website, app, docs, and checkout.

### Framework and builder guides [#framework-and-builder-guides]

If your site uses a framework, CMS, ecommerce platform, or no-code builder, open the guide below for the exact place to paste the same snippet. Framework examples focus on placement and may omit optional attributes, so use the complete code generated in **Settings -> Tracking**.

Next.js

App Router and shared layouts.

React

Vite, CRA, and static HTML shells.

Vue

Vue apps and shared HTML entry points.

Nuxt

Nuxt app head and plugin setup.

Angular

Workspace index.html or runtime injection.

SvelteKit

Global app template placement.

Astro

Base layouts and content sites.

Remix

Root document and Scripts component.

SolidStart

Root document setup.

Qwik

Root layout and head placement.

Gatsby

SSR document hooks.

Expo

Expo Web and static HTML.

Laravel

Blade layouts and shared app views.

Django

Base templates and inherited pages.

Ruby on Rails

Application layout and ERB templates.

Express

EJS, Pug, or static HTML shells.

NestJS

Server-rendered templates or static clients.

Flask

Jinja base templates.

Phoenix

Root layouts and LiveView pages.

WordPress

Theme footer, child themes, or snippet plugins.

Shopify

Theme layout and storefront pages.

Wix

Dashboard custom code settings.

Webflow

Site custom code and project settings.

Squarespace

Code injection for all pages.

Framer

Custom code before body end.

Tilda

Site-wide HTML before body close.

## Step 2. Connect payments [#step-2-connect-payments]

Traffic only becomes useful revenue analytics after Talivia can see payment events. Choose the payment path that matches your checkout.

Stripe

Connect a restricted API key and let Talivia configure webhooks.




Yolfi

Connect the account and configure the Checkout Session return URL.

LemonSqueezy

Use provider events when LemonSqueezy powers checkout.




Polar

Use Polar payment events when your product sells through Polar.




Dodo Payments

Connect one API key; Talivia creates the payment and refund webhook.




Manual Payment API

Send payments from your backend or custom processor.

For hosted providers that expose a unique checkout return ID, configure that provider's return
placeholder. For custom payment flows, pass `window.talivia.getSessionId()` as supported provider
metadata or as `sessionId` to the Manual Payment API. The Revenue guides document each provider's
preferred signal.

## Verify the install [#verify-the-install]

1. Open your website in a normal browser tab.
2. Visit a page that includes the tracker.
3. Return to Talivia and open the website dashboard.
4. Look for a new session, page view, referrer, browser, and country.
5. After payment setup, make a test payment and confirm revenue appears in the same website.


---

# Angular (https://talivia.com/docs/installation-guides/angular)



For Angular apps, add the tracker to the HTML shell that wraps the app.




## Add the script [#add-the-script]

Open `src/index.html` and place the snippet before the closing `</body>` tag.

```html
<app-root></app-root>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

Replace the website ID. Use the ID from Talivia Settings -> Tracking for this exact Angular domain.

Build or run the app, open a page, and check Talivia for the first session.


---

# Astro (https://talivia.com/docs/installation-guides/astro)



Add Talivia to the shared layout used by your Astro pages.




## Add the script [#add-the-script]

Open your base layout, for example `src/layouts/BaseLayout.astro`, and place the snippet before the closing `</body>` tag.

```astro
---
const { title } = Astro.props;
---

<html lang="en">
  <head>
    <title>{title}</title>
  </head>
  <body>
    <slot />
    <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
  </body>
</html>
```

Replace the website ID. Use the ID from Talivia Settings -> Tracking for this Astro site.

Deploy or run the site, visit a page, and confirm the new session in Talivia.


---

# Django (https://talivia.com/docs/installation-guides/django)



Install Talivia in the base template inherited by your public pages.




## Base template [#base-template]

Open a shared template such as `templates/base.html` and place the snippet before `</body>`.

```html
    <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
</html>
```

If different parts of the site use different base templates, add Talivia to each public base template.

Do not leave the placeholder. Replace YOUR\_WEBSITE\_ID with the value from Talivia Settings -> Tracking.

Deploy the template, visit a page, and confirm the first session in Talivia.


---

# Expo (https://talivia.com/docs/installation-guides/expo)



Talivia's browser tracker is for web pages. Use this guide for Expo Web or web builds of an Expo Router app.




## Expo Router [#expo-router]

Create or update `app/+html.tsx` and place the script in the body.

```tsx
import { ScrollViewStyleReset } from 'expo-router/html';

export default function Root({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <ScrollViewStyleReset />
      </head>
      <body>
        {children}
        <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID" />
      </body>
    </html>
  );
}
```

## Expo web HTML [#expo-web-html]

If your project exposes a web HTML template, add the universal snippet before `</body>`.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Native apps are different. This script tracks browser traffic only. Use it for Expo Web, not iOS or Android native screens.


---

# Express (https://talivia.com/docs/installation-guides/express)



Use the shared HTML template that wraps your Express pages.




## Template apps [#template-apps]

If you use EJS, Pug, Handlebars, or another view engine, place the snippet in the base layout before `</body>`.

```html
<main>
  <!-- page content -->
</main>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

## Static apps [#static-apps]

If Express serves a static frontend, add the snippet to the generated `index.html`.

Replace the website ID. Use the value from Talivia Settings -> Tracking.

Restart the server, open a page, and verify the session in Talivia.


---

# Flask (https://talivia.com/docs/installation-guides/flask)



Add Talivia to the base Jinja template used by your pages.




## Add the script [#add-the-script]

Open your base template, often `templates/base.html`, and place the snippet before `</body>`.

```html
{% block content %}{% endblock %}
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

Replace the website ID. Use the value from Talivia Settings -> Tracking.

Run Flask, open a page, and confirm Talivia receives a session.


---

# Framer (https://talivia.com/docs/installation-guides/framer)



Use Framer custom code to load Talivia across the published site.




## Add custom code [#add-custom-code]

1. Open the Framer project.
2. Go to Site Settings.
3. Open the Custom Code area.
4. Add the Talivia snippet before the closing body tag.
5. Publish the site.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Replace the website ID. Copy the ID from Talivia Settings -> Tracking for this Framer site.

Visit the published site and verify the first Talivia session.


---

# Gatsby (https://talivia.com/docs/installation-guides/gatsby)



Use Gatsby's SSR hooks so Talivia appears on every generated page.




## Add the script [#add-the-script]

Create or open `gatsby-ssr.js` and append the Talivia script to the post-body components.

```jsx
import React from 'react';

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="talivia"
      defer
      src="https://talivia.com/script.js"
      data-website-id="YOUR_WEBSITE_ID"
    />,
  ]);
};
```

Replace the website ID. Use the ID from Talivia Settings -> Tracking.

Build or run Gatsby, open a page, and verify the session in Talivia.


---

# Laravel (https://talivia.com/docs/installation-guides/laravel)



Add Talivia to the Blade layout that wraps every public page.




## Blade layout [#blade-layout]

Open a shared layout such as `resources/views/layouts/app.blade.php` and place the snippet before `</body>`.

```html
    <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
</html>
```

If your marketing site uses another layout, add the snippet there instead.

Use the website ID from Talivia. Each Laravel app or domain should use the ID generated for that website.

## Verify [#verify]

Visit the Laravel site in a browser, then open Talivia and check the website dashboard for a new session.


---

# NestJS (https://talivia.com/docs/installation-guides/nest-js)



NestJS can serve templates or a separate frontend. Add Talivia wherever the browser HTML shell is created.




## Server-rendered templates [#server-rendered-templates]

Place the snippet in the shared layout or template before the closing `</body>` tag.

```html
<main>
  <!-- page content -->
</main>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

## API-only apps [#api-only-apps]

If NestJS only serves an API, install Talivia in the frontend app instead, such as Next.js, React, Angular, or Vue.

Replace the website ID. Copy it from Talivia Settings -> Tracking for the public website.

Open the public app and verify the first session in Talivia.


---

# Next.js (https://talivia.com/docs/installation-guides/next-js)



Use the root layout so the tracker loads on every route.




## App Router [#app-router]

Open `app/layout.tsx` and add `next/script`.

```tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://talivia.com/script.js"
          data-website-id="YOUR_WEBSITE_ID"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}
```

Replace the website ID. Use the ID from Talivia Settings -> Tracking for this exact website.

## Pages Router [#pages-router]

If your app uses `pages/_document.tsx`, place the script before `</body>`.

```tsx
import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID" />
        <NextScript />
      </body>
    </Html>
  );
}
```

## Verify [#verify]

Run the app, open a page, then return to Talivia and check for a new session.


---

# Nuxt (https://talivia.com/docs/installation-guides/nuxt)



Use Nuxt's global app head so the tracker loads on every route.




## Add the script [#add-the-script]

Open `nuxt.config.ts` and add the Talivia script to `app.head.script`.

```ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          src: 'https://talivia.com/script.js',
          defer: true,
          'data-website-id': 'YOUR_WEBSITE_ID',
        },
      ],
    },
  },
});
```

Replace the website ID. Copy it from Talivia Settings -> Tracking for this Nuxt website.

Run the app, open a public route, and verify the new session in Talivia.


---

# Phoenix (https://talivia.com/docs/installation-guides/phoenix)



Add Talivia to the shared root layout so the tracker loads across Phoenix pages.




## Add the script [#add-the-script]

Open the root layout, often `lib/my_app_web/components/layouts/root.html.heex`, and place the snippet before `</body>`.

```html
<%= @inner_content %>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

Replace the website ID. Copy it from Talivia Settings -> Tracking.

Open the Phoenix site and check Talivia for the new visit.


---

# Qwik (https://talivia.com/docs/installation-guides/qwik)



Use the root layout so the tracker is included on every public page.




## Add the script [#add-the-script]

Open the root layout or document file and add the Talivia snippet near the end of the body.

```tsx
export default component$(() => {
  return (
    <>
      <Slot />
      <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID" />
    </>
  );
});
```

Replace the website ID. Copy it from Talivia Settings -> Tracking for the Qwik site.

Open a route and confirm the visit in Talivia.


---

# React (https://talivia.com/docs/installation-guides/react)



For React apps, add the tracker to the HTML shell that wraps the app.




## Vite [#vite]

Open `index.html` and place the snippet before the closing `</body>` tag.

```html
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

## Create React App [#create-react-app]

Open `public/index.html` and place the snippet before the closing `</body>` tag.

```html
<div id="root"></div>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Use your Talivia website ID. The example ID is only a placeholder.

Talivia listens to browser history changes, so route changes in React Router are tracked after the script loads.


---

# Remix (https://talivia.com/docs/installation-guides/remix)



Use the root document so the tracker is included on every route.




## Add the script [#add-the-script]

Open `app/root.tsx` and place the snippet before Remix's `Scripts` component.

```tsx
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';

export default function App() {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID" />
        <Scripts />
      </body>
    </html>
  );
}
```

Replace the website ID. Copy it from Talivia Settings -> Tracking.

Open a route and verify that Talivia receives a session.


---

# Ruby on Rails (https://talivia.com/docs/installation-guides/ruby-on-rails)



Add Talivia to the application layout so every rendered page includes the tracker.




## Add the script [#add-the-script]

Open `app/views/layouts/application.html.erb` and place the snippet before the closing `</body>` tag.

```html
<%= yield %>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

Replace the website ID. Copy the ID from Talivia Settings -> Tracking for this Rails domain.

Open the Rails app in a browser and check Talivia for the new session.


---

# Shopify (https://talivia.com/docs/installation-guides/shopify)



Install Talivia in the Shopify theme layout so storefront pages are tracked.




## Theme layout [#theme-layout]

Open the Shopify theme code editor and edit `layout/theme.liquid`. Place the snippet before the closing `</body>` tag.

```html
    <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
</html>
```

Storefront first. This tracks the online store pages where the theme is rendered. Checkout pages may be controlled separately depending on your Shopify plan and setup.

## Verify [#verify]

Preview or publish the theme, visit a product or landing page, and confirm the visit appears in Talivia.


---

# SolidStart (https://talivia.com/docs/installation-guides/solid-start)



Add Talivia to the root document so it loads across the app.




## Add the script [#add-the-script]

Open the root entry file where `StartServer`, `Scripts`, or the document body is defined, then place the snippet before closing the body.

```tsx
import { Scripts } from '@solidjs/start';

export default function Root() {
  return (
    <html lang="en">
      <body>
        <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID" />
        <Scripts />
      </body>
    </html>
  );
}
```

Replace the website ID. Use the value from Talivia Settings -> Tracking.

Run the app and open a page to verify the first session.


---

# Squarespace (https://talivia.com/docs/installation-guides/squarespace)



Use Squarespace code injection so Talivia loads on every public page.




## Add code injection [#add-code-injection]

1. Open the Squarespace site dashboard.
2. Go to Settings and open Code Injection.
3. Paste the Talivia snippet in the footer or body-end injection area.
4. Save and publish.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Replace the website ID. Use the ID from Talivia Settings -> Tracking.

Open the published Squarespace site and check Talivia for a new session.


---

# SvelteKit (https://talivia.com/docs/installation-guides/svelte-kit)



Use the app template so Talivia loads once for the whole SvelteKit site.




## Add the script [#add-the-script]

Open `src/app.html` and place the snippet before the closing `</body>` tag.

```html
<body data-sveltekit-preload-data="hover">
  <div style="display: contents">%sveltekit.body%</div>
  <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
</body>
```

Replace the website ID. Copy the ID from Talivia Settings -> Tracking.

Talivia tracks normal page views and client-side route changes after the script loads.


---

# Tilda (https://talivia.com/docs/installation-guides/tilda)



Add Talivia as site-wide HTML so every published page is tracked.




## Site-wide code [#site-wide-code]

1. Open the Tilda project settings.
2. Find the custom code or HTML injection section.
3. Paste the Talivia script before the closing body tag.
4. Publish the project again.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Use the correct website ID. If you have multiple Tilda domains or projects, each one should use its own Talivia website ID.

After publishing, open the live site and check Talivia for a page view.


---

# Vue (https://talivia.com/docs/installation-guides/vue)



Add the Talivia script to the HTML file that loads your Vue app.




## Vue with Vite [#vue-with-vite]

Open `index.html` and place the snippet near the end of `body`.

```html
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

## Nuxt-style projects [#nuxt-style-projects]

If your Vue project has a global app template or head/script configuration, add the same tracker once globally. Avoid adding it inside individual pages.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Replace YOUR\_WEBSITE\_ID. Copy the real value from Talivia Settings -> Tracking.

After deploying, open any public page and check the Talivia dashboard for a new visit.


---

# Webflow (https://talivia.com/docs/installation-guides/webflow)



Use Webflow custom code to include Talivia on every published page.




## Add custom code [#add-custom-code]

1. Open the Webflow project.
2. Go to Project Settings.
3. Open the Custom Code section.
4. Paste the Talivia snippet before the closing body tag.
5. Save changes and publish the site.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Replace the website ID. Copy it from Talivia Settings -> Tracking for the Webflow domain.

Visit the published site and verify the new session in Talivia.


---

# Wix (https://talivia.com/docs/installation-guides/wix)



Use Wix custom code to load Talivia on every public page.




## Add custom code [#add-custom-code]

1. Open your Wix dashboard.
2. Go to the site's custom code or tracking tools area.
3. Add a new custom code snippet.
4. Paste the Talivia script.
5. Set it to load on all pages, near the end of the body.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Replace the website ID. Copy it from Talivia Settings -> Tracking for the Wix domain you are measuring.

Publish the Wix site, open it in a browser, and verify the new visit in Talivia.


---

# WordPress (https://talivia.com/docs/installation-guides/wordpress)



The safest WordPress setup is to add Talivia once site-wide through a child theme or a trusted custom-code plugin.




## Option 1: Child theme [#option-1-child-theme]

Add the script through the `wp_footer` hook in your child theme's `functions.php`.

```php
add_action('wp_footer', function () {
    ?>
    <script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
    <?php
});
```

## Option 2: Custom-code plugin [#option-2-custom-code-plugin]

Use a plugin that inserts code before the closing `</body>` tag and paste the universal snippet.

```html
<script defer src="https://talivia.com/script.js" data-website-id="YOUR_WEBSITE_ID"></script>
```

Keep it site-wide. Add the tracker once globally, not inside individual posts.

Open the WordPress site in a normal browser tab and check Talivia for a new session.


---

# Integrations (https://talivia.com/docs/integrations)



Integrations add context that the browser tracker cannot collect by itself. Connect a platform to see its activity alongside visitors, revenue, and other website metrics.




X mention monitoring

See conversations about your product or website alongside traffic and revenue.




GitHub commits

See your latest commits on the analytics chart and find what moves the needle.


---

# Show GitHub commits (https://talivia.com/docs/integrations/github-commits)



Install the GitHub App to see your latest commits on your analytics chart and find what moves the needle. Commits appear as markers on the main analytics chart, so you can connect a change you shipped with the visitors and revenue that followed.

## Why show commits? [#why-show-commits]

Commits give useful context to your website analytics:

* See exactly what shipped before a traffic or revenue change.
* Compare release activity with conversion trends over time.
* Share a chart where the whole team can see cause and effect.

## How it works [#how-it-works]

You install the Talivia GitHub App on your account or organization and grant it read access to one repository. Talivia then imports the latest commits from the default branch and keeps them in sync automatically, checking for new commits every 20 minutes.

Hover over a commit marker on the chart to preview the commit messages. Select it to see the complete list for that moment and open any commit on GitHub.

The app only requests read access to repository contents. Talivia never stores your code — only the commit metadata shown on the chart: the message, author, and time.

## Connect a repository [#connect-a-repository]

1. Open your website in Talivia.
2. Go to **Settings → Integrations**.
3. Find the **GitHub** integration and select **Connect GitHub**.
4. Install the app on your GitHub account or organization and choose the repository for this website.

If you grant access to a single repository, it connects automatically and Talivia backfills up to 300 commits from the last 30 days. If you grant access to several repositories, pick the one that belongs to this website when you return to the settings page.

## Use commits to understand a change [#use-commits-to-understand-a-change]

When you notice a change on the chart:

1. Find the commits shown near the same time.
2. Hover over them to read what shipped.
3. Compare the deploy with the change in visitors or revenue.
4. Open a commit on GitHub when you want the full diff.

Commits provide context rather than guaranteed attribution. Use them together with referrers, campaigns, and revenue data to understand what most likely influenced the change.


---

# Track X mentions (https://talivia.com/docs/integrations/x-mentions)



When visitors or revenue suddenly increase, it is not always obvious what caused the change. X mention monitoring adds relevant conversations to your analytics chart, helping you understand whether people were discussing your product or website at the same time.

## Why track X mentions? [#why-track-x-mentions]

X mentions give useful context to your website analytics:

* Understand unexpected traffic and revenue spikes.
* Discover conversations about your product or website.
* See what people were saying when website activity changed.
* Find Posts that may be worth responding to or sharing.

## How it works [#how-it-works]

Talivia checks X for mentions of your product or website and shows matching Posts on the main analytics chart.

Hover over a mention on the chart to preview the conversation. Select it to see the complete list for that moment and open an original Post on X.

Because mentions appear alongside visitors and revenue, you can compare the conversation with what was happening on your website without switching between separate tools.

## Set up X mention monitoring [#set-up-x-mention-monitoring]

1. Open your website in Talivia.
2. Go to **Settings → Integrations**.
3. Find the **X** integration and select **Connect**.

That is all. Mention monitoring starts automatically after you connect the integration; there is no separate manual sync step.

Talivia uses the product name and website address already saved in your website settings, so there is nothing else to configure.

## Use mentions to understand a spike [#use-mentions-to-understand-a-spike]

When you notice a change on the chart:

1. Find any mention shown near the same time.
2. Hover over it to read the related Posts.
3. Compare the conversation with the change in visitors or revenue.
4. Open a relevant Post on X when you want to see the full conversation.

Mentions provide context rather than guaranteed attribution. Use them together with referrers, campaigns, and revenue data to understand what most likely influenced the change.


---

# Links (https://talivia.com/docs/links)



Links are redirect URLs that Talivia can track separately from a full website script install.

Create a link from **Links**, set a destination URL, and copy the generated URL.

```txt
https://talivia.com/q/abc123xyz
```

When someone opens it, Talivia records a link event and redirects to the destination.

## When to use links [#when-to-use-links]

* Newsletter links.
* Social bio links.
* Affiliate links.
* Sponsor cards.
* Campaign URLs where you cannot install the script.

## Reporting [#reporting]

Link reports use the same core analytics panels as websites: visitors, referrers, countries, devices, events, and date filters.

Screenshot placeholder: link edit form with destination URL and generated tracking link.


---

# Performance (https://talivia.com/docs/performance)



Performance collection records Web Vitals as analytics events. Enable it when you want to connect page speed to visitors, sessions, and revenue.

## Enable Web Vitals [#enable-web-vitals]

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-performance="true"
></script>
```

Talivia can collect:

* `LCP` Largest Contentful Paint.
* `INP` Interaction to Next Paint.
* `CLS` Cumulative Layout Shift.
* `FCP` First Contentful Paint.
* `TTFB` Time to First Byte.

## Report [#report]

Open **Performance** to review pages with slow loading or interaction issues. Use filters to inspect a single path, browser, country, or traffic source.

## Practical workflow [#practical-workflow]

Start with pages that produce revenue. A slow pricing or checkout page matters more than a slow low-intent content page.


---

# Pixels (https://talivia.com/docs/pixels)



Pixels are lightweight URLs that record an event when requested. They are useful when a full JavaScript tracker is not available.

Create a pixel from **Pixels** and copy the generated URL.

```txt
https://talivia.com/p/abc123xyz
```

## Common uses [#common-uses]

* Email opens where images are allowed.
* Lightweight campaign impressions.
* Embedded assets in third-party pages.

## Limitations [#limitations]

Pixel requests do not have the same browser context as the JavaScript tracker. You may still see request-derived information like country, user agent, and timestamp, but not full client-side route behavior.


---

# Revenue (https://talivia.com/docs/revenue)



Revenue attribution shows which sessions, sources, pages, campaigns, and search queries produced money. The settings screen connects the payment account; the provider guides explain the checkout-specific implementation.

## Choose a revenue source [#choose-a-revenue-source]

| Source             | Use it when                                                                  | Setup guide                                         |
| ------------------ | ---------------------------------------------------------------------------- | --------------------------------------------------- |
| Stripe             | Checkout, Payment Links, invoices, or subscriptions run through Stripe       | [Stripe](https://talivia.com/docs/revenue-guides/stripe)               |
| Yolfi              | Payments and subscriptions run through Yolfi                                 | [Yolfi](https://talivia.com/docs/revenue-guides/yolfi)                 |
| Dodo Payments      | You use Dodo Payment Links or Checkout Sessions                              | [Dodo Payments](https://talivia.com/docs/revenue-guides/dodo-payments) |
| Manual Payment API | Your backend confirms revenue through a custom or unsupported payment system | [Manual Payment API](https://talivia.com/docs/revenue-guides/manual)   |

## How setup is divided [#how-setup-is-divided]

1. In **Website settings → Payments**, select the provider and connect its API key.
2. Open the provider guide from the final **Link payments with traffic** step.
3. Follow the checkout path that matches your implementation and make a test payment.
4. Confirm the payment has a source and session in Talivia.

The provider connection imports and receives revenue. Session metadata or a tracked return URL supplies the attribution signal that connects that revenue to the visit.

Connection and attribution are separate checks. A provider can be connected successfully while a payment remains unattributed if checkout did not include a Talivia session signal.

## Refunds [#refunds]

Refunds are shown as reversed revenue in charts. Talivia keeps the original paid context visible so you can see the money that would have counted and the amount refunded.

Screenshot placeholder: revenue chart with paid and refunded bars.


---

# Dodo Payments (https://talivia.com/docs/revenue-guides/dodo-payments)



Payment Link on your site

Use a normal Dodo link or linked button. Talivia handles attribution automatically.

Checkout Session

Add one Talivia session value when your backend creates the Dodo checkout.

Shared Payment Link

The payment is recorded, but a buyer who skips your site may be unattributed.

Test and troubleshoot Dodo Payments

Check the API environment, managed webhook, checkout metadata, and refunds.


---

# Dodo Checkout Session (https://talivia.com/docs/revenue-guides/dodo-payments/checkout-session)



Use this option when your backend creates a Dodo Checkout Session. It also covers Dodo Overlay and Inline Checkout because both start from a Checkout Session.

Connect your account in **Website settings → Revenue → Dodo Payments**, then pass the current Talivia session into the checkout metadata.

## Add the session to checkout metadata [#add-the-session-to-checkout-metadata]

Read the Talivia session cookie on the backend and merge it into the `metadata` object in your existing Dodo call.

```javascript title="Create a Dodo Checkout Session"
const taliviaSessionId = request.cookies.get('talivia_session_id')?.value;

const checkout = await dodo.checkoutSessions.create({
  product_cart,
  return_url: 'https://your-site.com/thanks',
  metadata: {
    // Keep your existing metadata fields here.
    ...(taliviaSessionId && { talivia_session_id: taliviaSessionId }),
  },
});
```

`metadata` is Dodo's standard metadata object. Keep any fields you already send and add only `talivia_session_id`. Talivia reads that value from the verified payment event and handles attribution.

## Checkout API on another origin [#checkout-api-on-another-origin]

If browser code calls a checkout API on another origin, include the opaque session value in that request:

```javascript title="Browser checkout handoff"
const sessionId = window.talivia.getSessionId();

await fetch('https://api.your-site.com/create-checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});
```

Validate the request normally and place the received value in `metadata.talivia_session_id` when the backend creates the Checkout Session. The session ID is an attribution identifier, not authentication.

See [Dodo Checkout Sessions](https://docs.dodopayments.com/developer-resources/checkout-session) for the provider-side checkout options.

No manual webhook setup is needed. Talivia configures and verifies the Dodo webhook when you connect the provider.


---

# Dodo Payment Link on your site (https://talivia.com/docs/revenue-guides/dodo-payments/payment-link-on-your-site)



Use this option when a customer opens a Dodo Payment Link from your website. First connect the account in **Website settings → Revenue → Dodo Payments**.

## Add the link to a tracked page [#add-the-link-to-a-tracked-page]

Use the complete Payment Link copied from Dodo in a normal `<a>` link or a linked button. No Talivia-specific checkout code is needed.

```html title="Dodo Payment Link"
<a href="https://checkout.dodopayments.com/buy/YOUR_PRODUCT_ID?redirect_url=https%3A%2F%2Fyour-site.com%2Fthanks">
  Buy now
</a>
```

The Talivia tracker adds the current session before opening checkout and preserves the parameters already present in the link. When Dodo reports the successful payment, Talivia matches it with the originating visit.

Automatic attribution applies when the customer clicks a normal Dodo link on a page where the Talivia tracker is running. If your application creates a Checkout Session through the Dodo API, use the [Checkout Session guide](https://talivia.com/docs/revenue-guides/dodo-payments/checkout-session) instead.

See [Dodo Payment Links](https://docs.dodopayments.com/developer-resources/integration-guide) for provider-side link configuration.

No manual webhook setup is needed. Connecting Dodo Payments in Website settings configures the webhook and imports the available revenue history.


---

# Shared Dodo Payment Link (https://talivia.com/docs/revenue-guides/dodo-payments/shared-payment-link)



No checkout code is required when you share a Dodo Payment Link directly. Connect Dodo Payments in **Website settings → Revenue** so Talivia can receive and record successful payments.

## When the payment is unattributed [#when-the-payment-is-unattributed]

If a buyer opens Dodo directly from an email, chat, social post, marketplace, or QR code without visiting your website, there is no Talivia website session to attach. The payment is still recorded, but it can appear as **Unattributed**.

This is expected: the provider webhook proves that the payment happened, but it does not create a website visit retroactively.

## Recommended flow [#recommended-flow]

For reliable attribution, share a landing page on your site instead of the raw Dodo checkout URL. Place the Payment Link on that tracked page:

```html title="Tracked landing page"
<a href="https://checkout.dodopayments.com/buy/YOUR_PRODUCT_ID">
  Buy now
</a>
```

Talivia can then attach the visitor's current session when they click **Buy**. Continue with [Payment Link on your site](https://talivia.com/docs/revenue-guides/dodo-payments/payment-link-on-your-site) for the complete behavior.

No manual webhook setup is needed. Direct and attributed Dodo payments use the same provider connection configured in Website settings.


---

# Test and troubleshoot Dodo Payments (https://talivia.com/docs/revenue-guides/dodo-payments/testing-and-troubleshooting)



Use the [shared payment testing setup](https://talivia.com/docs/revenue-guides/testing-payment-providers) to keep test revenue separate from production, then apply the Dodo-specific checks below.

## Connect the test account [#connect-the-test-account]

Create an API key with write access in the Dodo test environment and connect it to your sandbox Talivia website. Talivia detects whether the key belongs to Dodo Test or Live, then uses the matching API to validate the business, import available history, and create the webhook.

There is no Dodo environment selector in Talivia. If a current Dodo key does not contain an environment prefix, Talivia validates it against the provider environments and stores the successful connection.

## Minimum test matrix [#minimum-test-matrix]

| Scenario                               | Expected Talivia result                               |
| -------------------------------------- | ----------------------------------------------------- |
| Payment Link clicked on a tracked page | Payment matched to the originating session            |
| API-created Checkout Session           | Payment matched through `metadata.talivia_session_id` |
| Overlay or Inline Checkout             | Same result as its underlying Checkout Session        |
| Link opened without visiting your site | Payment recorded as **Unattributed**                  |
| Full or partial refund                 | Original payment remains and net revenue is reduced   |
| Repeated webhook                       | No duplicate payment or refund                        |

## The connection fails [#the-connection-fails]

* **Rejected in both environments:** copy a new API key from Dodo and try again.
* **Webhook creation is forbidden:** enable write access for the key.
* **No business is found:** confirm the key belongs to a Dodo account with an available business or brand.

Reconnecting updates the managed endpoint for the Talivia webhook URL. When the account or environment changes, Talivia imports the new history and removes the previous managed endpoint.

## No payment appears [#no-payment-appears]

In the Dodo webhook settings, confirm the Talivia endpoint is enabled and the `payment.succeeded` delivery returned a successful response. Refund updates require `refund.succeeded`.

If delivery is missing, reconnect Dodo so Talivia can repair the webhook and retrieve its signing secret. If delivery is rejected, confirm the event came from the same Dodo environment as the connected key.

## The payment is unattributed [#the-payment-is-unattributed]

* **Payment Link:** open it through a normal link on a page where the Talivia tracker is running.
* **Checkout Session, Overlay, or Inline Checkout:** add the current session as `metadata.talivia_session_id` when your backend creates the Checkout Session.
* **Shared raw link:** an unattributed payment is expected when the buyer never visits your tracked website.

Do not use the Talivia session id as authentication. It is only an opaque attribution value.


---

# LemonSqueezy (https://talivia.com/docs/revenue-guides/lemonsqueezy)



Checkout Links

Hosted checkout or a standard Lemon.js overlay link on your tracked site.

Checkout API

Create custom checkout on your backend and pass the Talivia session explicitly.

Return URL fallback

Match an order when metadata cannot be added to the original checkout.

Subscriptions and renewals

Preserve the first attributed checkout across recurring payments and lifecycle changes.

Test and troubleshoot LemonSqueezy

Verify the key mode, managed webhook, custom data, subscriptions, and refunds.


---

# LemonSqueezy Checkout API (https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-api)



Use this flow when your backend calls `POST /v1/checkouts` and returns the generated checkout URL to the browser.

## Send the session to your backend [#send-the-session-to-your-backend]

Read the current session on the tracked page and include it in your own checkout request:

```javascript title="Start checkout from the browser"
const sessionId = window.talivia.getSessionId();

const response = await fetch('/api/create-checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});

const { checkoutUrl } = await response.json();
window.location.assign(checkoutUrl);
```

Treat the session ID only as attribution context. Validate the customer, product, price, and authorization independently on your backend.

## Add custom checkout data [#add-custom-checkout-data]

Merge the received value into `attributes.checkout_data.custom` in the LemonSqueezy request:

```javascript title="Create the LemonSqueezy checkout"
const checkout = await fetch('https://api.lemonsqueezy.com/v1/checkouts', {
  method: 'POST',
  headers: {
    Accept: 'application/vnd.api+json',
    'Content-Type': 'application/vnd.api+json',
    Authorization: `Bearer ${process.env.LEMONSQUEEZY_API_KEY}`,
  },
  body: JSON.stringify({
    data: {
      type: 'checkouts',
      attributes: {
        checkout_data: {
          custom: {
            talivia_session_id: sessionId,
          },
        },
      },
      relationships: {
        store: { data: { type: 'stores', id: process.env.LEMONSQUEEZY_STORE_ID } },
        variant: { data: { type: 'variants', id: variantId } },
      },
    },
  }),
}).then(response => response.json());

return Response.json({ checkoutUrl: checkout.data.attributes.url });
```

LemonSqueezy copies custom checkout data to `meta.custom_data` in the signed webhook. This works for hosted custom checkouts and programmatically opened overlays.

Keep the LemonSqueezy API key on the server and preserve any other custom fields your application already sends.


---

# LemonSqueezy Checkout Links (https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-links)



Use this flow when a customer clicks a reusable LemonSqueezy Checkout Link on a page where the Talivia tracker is installed.

## Add the link to your site [#add-the-link-to-your-site]

Use the original share URL containing `/checkout/buy/`. Do not copy the single-use cart URL created after checkout opens.

```html title="Hosted LemonSqueezy checkout"
<a href="https://YOUR_STORE.lemonsqueezy.com/checkout/buy/VARIANT_ID">
  Buy now
</a>
```

Talivia adds the current session without removing discount, quantity, or other existing query parameters:

```text
checkout[custom][talivia_session_id]=s_...
```

LemonSqueezy returns this value as `meta.custom_data.talivia_session_id` in order and subscription webhook events. Talivia uses it to connect the revenue to the originating visit.

## Checkout overlay [#checkout-overlay]

The same automatic behavior works when a normal Checkout Link is used as a Lemon.js overlay button:

```html title="Lemon.js overlay link"
<a
  class="lemonsqueezy-button"
  href="https://YOUR_STORE.lemonsqueezy.com/checkout/buy/VARIANT_ID"
>
  Buy now
</a>
```

The link must still be a standard anchor on the tracked page. If your application creates a custom checkout or calls `LemonSqueezy.Url.Open()` with a URL generated elsewhere, continue with [Checkout API](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-api).

No manual webhook setup is needed. Connecting LemonSqueezy in Website settings creates the signed order, subscription, and refund webhook.


---

# LemonSqueezy Return URL Fallback (https://talivia.com/docs/revenue-guides/lemonsqueezy/return-url)



Direct session metadata is the strongest attribution method. Use the return URL only when you cannot modify the checkout link or the API request.

## Add the order ID to the return link [#add-the-order-id-to-the-return-link]

In the LemonSqueezy product settings, set the confirmation modal button link to a tracked page and include the supported `order_id` variable:

```text title="Confirmation button URL"
https://your-site.com/thanks?order_id=[order_id]
```

After payment, LemonSqueezy replaces `[order_id]` with the real order ID. When the customer opens that page, the Talivia tracker records the order reference and matches it with the verified `order_created` webhook.

## Limits of return attribution [#limits-of-return-attribution]

* The tracker must be installed on the return page.
* The customer must click the confirmation button and return in the same browser.
* If the customer opened a shared checkout without first visiting your site, Talivia can record the payment but there is no earlier acquisition session to recover.
* Do not use the return page to fulfil the order; the signed webhook remains the payment source of truth.

For links rendered on your tracked website, use [Checkout Links](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-links) instead. For server-created checkout, use [Checkout API](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-api).


---

# LemonSqueezy Subscriptions and Renewals (https://talivia.com/docs/revenue-guides/lemonsqueezy/subscriptions-and-renewals)



Attribute the first subscription checkout with the same Talivia session field used for a one-time order. Use automatic decoration for a standard [Checkout Link](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-links), or set `checkout_data.custom.talivia_session_id` through the [Checkout API](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-api).

LemonSqueezy includes that custom data in the initial order and subscription webhooks. Talivia stores the LemonSqueezy customer and subscription relationship so later renewals can stay connected even though no new browser checkout occurs.

## Events Talivia maintains [#events-talivia-maintains]

The managed webhook processes:

* subscription creation and updates;
* cancellation, resumption, pause, unpause, and expiration;
* successful, failed, and recovered subscription payments;
* subscription payment refunds.

Successful renewal invoices become new revenue payments. Failed payments update subscription state without creating paid revenue, and refunds reduce the original payment's net revenue.

## Keep the customer relationship stable [#keep-the-customer-relationship-stable]

Do not create a new LemonSqueezy customer for every renewal or plan change. Keeping the provider customer and subscription IDs stable lets Talivia reuse the attribution established by the initial checkout.

If a renewal is unattributed, first confirm the initial checkout contained `meta.custom_data.talivia_session_id`, then confirm later events use the same LemonSqueezy customer and subscription.


---

# Test and troubleshoot LemonSqueezy (https://talivia.com/docs/revenue-guides/lemonsqueezy/testing-and-troubleshooting)



Use the [shared payment testing setup](https://talivia.com/docs/revenue-guides/testing-payment-providers) to keep sandbox revenue separate from production, then apply the LemonSqueezy checks below.

## Connect test mode [#connect-test-mode]

1. Create or select a LemonSqueezy store in test mode.
2. Create an API key while LemonSqueezy is in test mode.
3. Connect that Store ID and API key to your sandbox Talivia website.

Talivia detects the API key mode and creates the webhook with the matching `test_mode` value. There is no environment selector in Talivia.

## Minimum test matrix [#minimum-test-matrix]

| Scenario                    | Expected Talivia result                                 |
| --------------------------- | ------------------------------------------------------- |
| One-time order              | One payment with the order amount and currency          |
| Subscription signup         | Initial payment and an active subscription              |
| Subscription renewal        | One new payment connected to the same customer          |
| Failed or recovered renewal | Subscription state changes without duplicate revenue    |
| Full or partial refund      | The original payment remains and net revenue is reduced |
| Repeated webhook            | No duplicate payment or subscription                    |

## The connection fails [#the-connection-fails]

* Confirm the API key can read the Store ID you entered.
* Confirm both values were copied from the same LemonSqueezy environment.
* Create a new API key if LemonSqueezy returns `401` or `403`.
* Reconnect after rotating the key; Talivia creates a new signed webhook and removes the previous managed endpoint.

## No payment appears [#no-payment-appears]

Open **Settings → Webhooks** in LemonSqueezy and find the Talivia endpoint for the connected store. Confirm the delivery succeeded and that the event is one Talivia processes, such as `order_created`, `subscription_payment_success`, `order_refunded`, or `subscription_payment_refunded`.

If the endpoint is missing or has the wrong `test_mode`, reconnect the provider from Talivia with the API key for the intended environment.

## The payment is unattributed [#the-payment-is-unattributed]

* **Standard link or overlay:** follow [Checkout Links](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-links) and confirm checkout started from a tracked page.
* **Server-created checkout:** follow [Checkout API](https://talivia.com/docs/revenue-guides/lemonsqueezy/checkout-api) and confirm `checkout_data.custom.talivia_session_id` was included.
* **Metadata is unavailable:** configure the [Return URL fallback](https://talivia.com/docs/revenue-guides/lemonsqueezy/return-url).

For the first two flows, inspect the delivered webhook and confirm the session appears in `meta.custom_data.talivia_session_id`.


---

# Manual Payment API (https://talivia.com/docs/revenue-guides/manual)



Use the Manual Payment API when revenue comes from a custom checkout, bank transfer, crypto processor, app store, invoice system, or another provider that Talivia does not connect to directly.

## Create an API key [#create-an-api-key]

Open **Website settings -> API keys** and generate a key. Talivia creates it for the current
website.

Copy the secret immediately because it is shown only once. Store it only on your backend and do not
expose it in browser code.

## Send a payment [#send-a-payment]

Send payment events to Talivia after your backend confirms the money was received.

Before checkout, send `window.talivia.getSessionId()` to your backend and keep it with the order as `sessionId`.

```javascript title="Record a confirmed payment"
await fetch('https://talivia.com/api/payments/manual', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-talivia-api-key': process.env.TALIVIA_API_KEY,
  },
  body: JSON.stringify({
    websiteId: 'YOUR_WEBSITE_ID',
    transactionId: 'order_123',
    amount: 49,
    currency: 'USD',
    providerName: 'manual',
    providerPaymentId: 'payment_123',
    providerCustomerId: 'customer_123',
    sessionId: order.sessionId,
  }),
});
```

Use stable ids. `transactionId` should be unique for the payment in your system. Reuse the same id if you retry the request.

## Supported attribution fields [#supported-attribution-fields]

Send the session field when possible:

* `sessionId`
* `providerCustomerId`
* `externalCustomerId`
* `email`
* `emailHash`

Talivia uses `sessionId` to connect the payment to the exact visitor journey. Customer fields can reconnect later renewals after the initial payment has been matched.

## Verify [#verify]

1. Send a test payment from your backend.
2. Open Talivia payments for the website.
3. Confirm the amount, currency, provider name, and transaction id.
4. Open the session detail and verify the spend amount appears on the matched session.


---

# Polar (https://talivia.com/docs/revenue-guides/polar)



Checkout API

Create a checkout on your backend and attach the Talivia session directly.

Checkout Links

Use a no-code Polar link and match the payment when the buyer returns.

Embedded Checkout

Open Polar inside your site while keeping the same return-based attribution.

Subscriptions and renewals

Keep the original customer identity across recurring orders and lifecycle changes.

Other methods

Attribute custom integrations through a stable Polar customer identity.

Test and troubleshoot Polar

Check token permissions, sandbox checkout, attribution, subscriptions, and refunds.


---

# Polar Checkout API (https://talivia.com/docs/revenue-guides/polar/checkout-api)



This is the most reliable Polar integration. Talivia receives the same session ID in the signed `order.paid` webhook and can attribute the order without depending on a return visit.

## Send the Talivia session to your backend [#send-the-talivia-session-to-your-backend]

```javascript title="Browser checkout handoff"
const sessionId = window.talivia.getSessionId();

const response = await fetch('/api/create-polar-checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});

const { url } = await response.json();
window.location.assign(url);
```

The session ID is an attribution identifier, not authentication. Validate the product and signed-in user on your backend as usual.

## Add metadata when checkout is created [#add-metadata-when-checkout-is-created]

Keep the Polar access token on the server. Polar copies checkout metadata to the resulting order and subscription, so one field covers both one-time and recurring products.

```javascript title="Create a Polar Checkout Session"
import { Polar } from '@polar-sh/sdk';

const polar = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN,
});

const checkout = await polar.checkouts.create({
  products: [process.env.POLAR_PRODUCT_ID],
  successUrl:
    'https://your-site.com/thanks?checkout_id={CHECKOUT_ID}',
  returnUrl: 'https://your-site.com/pricing',
  externalCustomerId: user.id,
  customerEmail: user.email,
  metadata: {
    talivia_session_id: sessionId,
  },
});

return Response.json({ url: checkout.url });
```

`externalCustomerId` should be a stable ID from your own application. It gives Talivia a second matching signal for future renewals. Keep `checkout_id={CHECKOUT_ID}` in the success URL as a useful fallback and debugging signal.


---

# Polar Checkout Links (https://talivia.com/docs/revenue-guides/polar/checkout-links)



Checkout Links do not let your server attach fresh Talivia metadata for every buyer. Use Polar's success URL placeholder so Talivia can connect the completed checkout to the browser session when the buyer returns.

## Configure the link [#configure-the-link]

1. Create or edit the Checkout Link in Polar.
2. Set its success URL to a tracked page on your site.
3. Include the exact `checkout_id={CHECKOUT_ID}` query parameter.

```text title="Success URL"
https://your-site.com/thanks?checkout_id={CHECKOUT_ID}
```

Place the link on a page where the Talivia tracker is installed.

```html title="Checkout Link"
<a href="https://buy.polar.sh/polar_cl_YOUR_LINK">Buy now</a>
```

After payment, the Polar webhook records the order. The return page sends the checkout ID from the URL to Talivia, which supplies the session-side match.

Shared links have a natural limit. If a buyer opens the link from email or social media and never visits your tracked site, Talivia records the revenue but cannot invent a traffic source. The payment remains unattributed unless customer identity provides another match.

For logged-in products, also call `identify` with the same application customer ID used by Polar. See [Other methods](https://talivia.com/docs/revenue-guides/polar/other-methods).


---

# Polar Embedded Checkout (https://talivia.com/docs/revenue-guides/polar/embedded-checkout)



Polar Embedded Checkout is a Checkout Link presented in an iframe. Attribution follows the same rule as a normal link: keep the checkout success URL on your tracked domain with `checkout_id={CHECKOUT_ID}`.

## Add the checkout trigger [#add-the-checkout-trigger]

```html title="Embedded Checkout"
<a
  href="https://buy.polar.sh/polar_cl_YOUR_LINK"
  data-polar-checkout
  data-polar-checkout-theme="dark"
>
  Buy now
</a>

<script
  src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@0.1/dist/embed.global.js"
  defer
  data-auto-init
></script>
```

Configure the underlying Checkout Link success URL before using the embed:

```text title="Success URL"
https://your-site.com/thanks?checkout_id={CHECKOUT_ID}
```

## React or programmatic embed [#react-or-programmatic-embed]

```javascript title="Open checkout programmatically"
import { PolarEmbedCheckout } from '@polar-sh/checkout/embed';

await PolarEmbedCheckout.create(
  'https://buy.polar.sh/polar_cl_YOUR_LINK',
  'dark',
);
```

Do not treat the client-side `success` event as the source of truth for revenue. Talivia records revenue from Polar's signed `order.paid` webhook and uses the browser return only for attribution.

If you create an embedded Checkout Session through the API instead of a static link, set `embedOrigin` to your site's origin and use [Checkout API metadata](https://talivia.com/docs/revenue-guides/polar/checkout-api) for the strongest match.


---

# Other Polar methods (https://talivia.com/docs/revenue-guides/polar/other-methods)



Some integrations create customers or orders through another billing layer and cannot pass `talivia_session_id`. In that case, link the visitor to the same customer identity that appears in Polar webhooks.

## Use a stable external customer ID [#use-a-stable-external-customer-id]

Set Polar's `external_customer_id` to your own immutable user ID whenever your integration supports it. Then identify the signed-in visitor with that value.

```javascript title="Identify the application customer"
window.talivia.identify(user.id, {
  email: user.email,
  externalCustomerId: user.id,
  providerName: 'polar',
});
```

If your backend already knows the Polar customer UUID, include it too.

```javascript title="Identify the Polar customer"
window.talivia.identify(user.id, {
  email: user.email,
  externalCustomerId: user.id,
  providerName: 'polar',
  polarCustomerId: 'YOUR_POLAR_CUSTOMER_ID',
});
```

Use [Checkout API](https://talivia.com/docs/revenue-guides/polar/checkout-api) whenever you control checkout creation. Direct session metadata is deterministic; customer identity is a fallback for checkouts and the primary signal for renewals.

If none of session metadata, a checkout return, external customer ID, Polar customer ID, or matching verified email is available, Talivia will still record the order but show it as unattributed.


---

# Polar subscriptions and renewals (https://talivia.com/docs/revenue-guides/polar/subscriptions-and-renewals)



Talivia listens for Polar subscription lifecycle events and records paid renewal orders from `order.paid`. The first checkout should carry both a Talivia session ID and a stable application customer ID.

```javascript title="Create a recurring checkout"
const checkout = await polar.checkouts.create({
  products: [process.env.POLAR_RECURRING_PRODUCT_ID],
  successUrl:
    'https://your-site.com/thanks?checkout_id={CHECKOUT_ID}',
  externalCustomerId: user.id,
  customerEmail: user.email,
  metadata: {
    talivia_session_id: sessionId,
  },
});
```

Polar copies checkout metadata to the created subscription. Talivia stores the subscription state and reuses the customer identity for later orders where there is no new browser session.

## Identify signed-in customers [#identify-signed-in-customers]

Call `identify` after login and again when you learn the Polar customer ID.

```javascript title="Link the Polar customer"
window.talivia.identify(user.id, {
  email: user.email,
  externalCustomerId: user.id,
  providerName: 'polar',
  polarCustomerId: polarCustomer.id,
});
```

The external ID is usually enough when you set the same value during checkout. Adding the Polar customer ID makes matching more resilient.

## What Talivia imports [#what-talivia-imports]

* the initial paid order and later paid renewals;
* cumulative full or partial refunds;
* subscription creation and status changes;
* active subscription context during the initial connection backfill.

Trials without a paid order are stored as subscription state, not revenue.


---

# Test and troubleshoot Polar (https://talivia.com/docs/revenue-guides/polar/testing-and-troubleshooting)



Start with the [shared payment testing setup](https://talivia.com/docs/revenue-guides/testing-payment-providers), then use the Polar-specific connection and attribution checks below.

## Connection checklist [#connection-checklist]

In Polar, create an Organization Access Token for the correct organization with these permissions:

* Checkout Read;
* Orders Read;
* Organization Read;
* Products Read;
* Subscription Read;
* Webhook Write.

In **Website settings → Revenue → Polar**, paste the token, then select **Connect Polar**. Talivia detects the token's organization and whether it belongs to production or sandbox, validates every permission, creates the signed webhook, imports the previous 30 days of orders, and syncs subscription state.

You do not need to copy a webhook secret or create an OAuth application.

## End-to-end test [#end-to-end-test]

1. Create a separate Talivia website and connect a Polar Sandbox organization there.
2. Open checkout from a tracked browser session.
3. Complete an order with Polar's sandbox payment flow.
4. Confirm the payment appears in Talivia with provider **Polar**.
5. Open the payment and verify its session, source, entry page, and amount.
6. Create a refund in Polar and confirm the same payment's refunded amount is updated.

## Payment is unattributed [#payment-is-unattributed]

For Checkout API, inspect the created checkout and confirm `metadata.talivia_session_id` equals the value returned by `window.talivia.getSessionId()`.

For Checkout Links and Embedded Checkout, confirm the Polar success URL is a tracked page and contains:

```text
checkout_id={CHECKOUT_ID}
```

For subscriptions or custom flows, confirm Polar's customer `external_id` matches the `externalCustomerId` sent to `window.talivia.identify`.

## Connection fails [#connection-fails]

* **Organization not found:** confirm the token has Organization Read and was created as an Organization Access Token.
* **Permission error:** recreate or update the token with every permission in the checklist.
* **Webhook error:** confirm Webhook Write is enabled and reconnect; Talivia will repair or recreate its endpoint.
* **Production versus sandbox:** Talivia detects the environment from the token automatically. Keep
  sandbox and production in separate Talivia websites so their revenue is not mixed.


---

# Stripe (https://talivia.com/docs/revenue-guides/stripe)



Checkout Sessions

Hosted or embedded Stripe Checkout. The best default for most new integrations.

Payment Links

No-code checkout through a 

buy.stripe.com

 link.

Payment Intents

A custom checkout that creates Payment Intents directly.

Subscriptions and invoices

Recurring plans, renewals, and invoice payments.

Other methods

Custom billing layers, third-party processors, or unsupported Stripe objects.

Test and troubleshoot Stripe

Verify events, attribution, subscriptions, refunds, and Payment Links.


---

# Stripe Checkout Sessions (https://talivia.com/docs/revenue-guides/stripe/checkout-sessions)



Use this integration for Stripe-hosted Checkout and for embedded checkout built with the Checkout Sessions API.

## Pass the Talivia session to your backend [#pass-the-talivia-session-to-your-backend]

If your checkout request starts in browser code, include the current opaque session ID.

```javascript title="Browser checkout handoff"
const sessionId = window.talivia.getSessionId();

const response = await fetch('/api/create-checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});

const { url } = await response.json();
window.location.assign(url);
```

When checkout is created on the same site as the Talivia tracker, your backend can read the `talivia_session_id` first-party cookie instead. Validate request input normally; the session ID is an attribution identifier, not authentication.

## One-time payment [#one-time-payment]

Set metadata on both the Checkout Session and its underlying Payment Intent. This preserves attribution whichever successful event Stripe delivers first.

```javascript title="Create a one-time Checkout Session"
const session = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: [{ price: 'price_123', quantity: 1 }],
  success_url:
    'https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://your-site.com/pricing',
  metadata: {
    talivia_session_id: sessionId,
  },
  payment_intent_data: {
    metadata: {
      talivia_session_id: sessionId,
    },
  },
});
```

Top-level `metadata` appears on `checkout.session.completed`. `payment_intent_data.metadata` is copied to the Payment Intent and appears on `payment_intent.succeeded`.

## Subscription checkout [#subscription-checkout]

For recurring plans, copy the session ID to the Subscription so renewals and lifecycle events keep the original customer context.

```javascript title="Create a subscription Checkout Session"
const session = await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: 'price_monthly', quantity: 1 }],
  success_url:
    'https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://your-site.com/pricing',
  metadata: {
    talivia_session_id: sessionId,
  },
  subscription_data: {
    metadata: {
      talivia_session_id: sessionId,
    },
  },
});
```

Continue with [Subscriptions and invoices](https://talivia.com/docs/revenue-guides/stripe/subscriptions-and-invoices) for renewals, failed invoices, and customer identity.

## Delayed payment methods [#delayed-payment-methods]

Bank debits, vouchers, and some local payment methods can complete Checkout before money is confirmed. Talivia does not record an unpaid completed session as revenue. It waits for Stripe's asynchronous success event and imports only sessions whose `payment_status` is `paid`.

## Return URL fallback [#return-url-fallback]

Keep `{CHECKOUT_SESSION_ID}` in the success URL even when metadata is present. The return visit gives Talivia a second matching signal and helps diagnose missing metadata.


---

# Other Stripe methods (https://talivia.com/docs/revenue-guides/stripe/other-methods)



Choose the narrowest integration that still gives Talivia a server-verified payment.

## Stripe objects remain in your connected account [#stripe-objects-remain-in-your-connected-account]

If the third-party checkout creates a Payment Intent in the same Stripe account connected to Talivia, use [Payment Intents](https://talivia.com/docs/revenue-guides/stripe/payment-intents). Attach `talivia_session_id` when the third party lets you supply Payment Intent metadata.

If metadata cannot be supplied, identify the signed-in customer with the same email or Stripe Customer ID present on the Stripe payment:

```javascript title="Connect customer identity"
window.talivia.identify('user_123', {
  email: currentUser.email,
  stripeCustomerId: currentUser.stripeCustomerId,
});
```

This links identity; it does not create or confirm revenue in the browser. Stripe's signed webhook remains the source of truth for the payment.

## The processor hides Stripe payment objects [#the-processor-hides-stripe-payment-objects]

Use the [Manual Payment API](https://talivia.com/docs/revenue-guides/manual) after your backend confirms the payment. Send the Talivia session stored with the order and a stable transaction ID.

```javascript title="Record a third-party confirmed payment"
await fetch('https://talivia.com/api/payments/manual', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-talivia-api-key': process.env.TALIVIA_API_KEY,
  },
  body: JSON.stringify({
    websiteId: 'YOUR_WEBSITE_ID',
    providerName: 'your-billing-provider',
    transactionId: payment.id,
    providerCustomerId: payment.customerId,
    email: payment.customerEmail,
    amount: payment.amount,
    currency: payment.currency,
    sessionId: order.taliviaSessionId,
  }),
});
```

## Why there is no browser payment command [#why-there-is-no-browser-payment-command]

A public `payment` event can be replayed or fabricated. Talivia therefore separates the two responsibilities:

* browser tracking and `identify` provide attribution context;
* a signed Stripe webhook or authenticated backend API confirms revenue.

This keeps amounts and payment status trustworthy while still supporting custom billing flows.


---

# Stripe Payment Intents (https://talivia.com/docs/revenue-guides/stripe/payment-intents)



Use this guide when your backend calls `stripe.paymentIntents.create` directly. For most new web integrations, Stripe recommends Checkout Sessions with the Payment Element because it manages more checkout behavior for you.

## Carry the session into payment creation [#carry-the-session-into-payment-creation]

Send the Talivia session ID to the backend that owns the Payment Intent. Never create Payment Intents with a secret Stripe key in browser code.

```javascript title="Browser handoff"
const sessionId = window.talivia.getSessionId();

const response = await fetch('/api/create-payment-intent', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});

const { clientSecret } = await response.json();
```

Create the Payment Intent on your server and attach the session directly to its metadata.

```javascript title="Create a Payment Intent"
const paymentIntent = await stripe.paymentIntents.create({
  amount: 2500,
  currency: 'usd',
  automatic_payment_methods: { enabled: true },
  customer: stripeCustomerId,
  receipt_email: customerEmail,
  metadata: {
    talivia_session_id: sessionId,
  },
});

return Response.json({ clientSecret: paymentIntent.client_secret });
```

Talivia listens for `payment_intent.succeeded`, records `amount_received`, and deduplicates the payment by Payment Intent ID. Payment Intents associated with Stripe invoices are left to invoice events so renewal and subscription context is not lost.

## Mobile and web-to-app checkout [#mobile-and-web-to-app-checkout]

Pass the original web session ID through your authenticated checkout handoff or deep-link state and store it with the order on your backend. The mobile app does not need the Talivia browser tracker; the backend only needs to attach the previously captured opaque ID when it creates the Payment Intent.

## Identity fallback [#identity-fallback]

Supplying a stable Stripe Customer and receipt email improves matching for later payments. After login or signup on the tracked website, connect that identity:

```javascript title="Identify the Stripe customer"
window.talivia.identify('user_123', {
  email: 'buyer@example.com',
  stripeCustomerId: 'cus_123',
});
```

Identity is a fallback and renewal bridge. Metadata remains the strongest signal for attributing the first payment to the exact checkout session.


---

# Stripe Payment Links (https://talivia.com/docs/revenue-guides/stripe/payment-links)



Payment Links need no custom checkout endpoint. Talivia supports a direct link signal and a return-URL fallback.

## Direct attribution from the link [#direct-attribution-from-the-link]

When the Talivia tracker sees a standard `https://buy.stripe.com/...` anchor, it adds the current session as Stripe's `client_reference_id` before navigation.

```html title="Standard Stripe Payment Link"
<a href="https://buy.stripe.com/test_123">Buy now</a>
```

Stripe includes that reference on the resulting Checkout Session, and Talivia uses it when the payment webhook arrives.

Talivia never overwrites an existing `client_reference_id`. If your product already uses that parameter for a cart or customer ID, configure the return URL below as the attribution signal.

Automatic decoration has boundaries. It applies to normal links on `buy.stripe.com`. A custom Stripe domain or navigation performed directly with `window.location` should use the return URL or your own Checkout Session integration.

## Configure the return URL [#configure-the-return-url]

1. Open the Payment Link in the Stripe Dashboard.
2. Open **After payment**.
3. Choose **Redirect customers to your website**.
4. Set the URL to include Stripe's literal placeholder:

```text title="Payment Link redirect"
https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}
```




Keep the Talivia tracker installed on the destination page. Talivia detects the Checkout Session ID, matches it with the verified Stripe webhook, and recalculates attribution even if the webhook arrived before the browser returned.

The return method works best when checkout and the destination page are opened in the same browser. Direct `client_reference_id` attribution does not depend on the customer returning after payment.


---

# Stripe subscriptions and invoices (https://talivia.com/docs/revenue-guides/stripe/subscriptions-and-invoices)



Recurring revenue has two related attribution problems: matching the original subscription signup and reconnecting later invoice payments to the same customer journey.

## Attribute subscription signup [#attribute-subscription-signup]

When Checkout creates the subscription, set the Talivia session on both the Checkout Session and the downstream Subscription.

```javascript title="Subscription metadata"
const metadata = {
  talivia_session_id: sessionId,
};

await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: 'price_monthly', quantity: 1 }],
  success_url:
    'https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}',
  metadata,
  subscription_data: { metadata },
});
```

Stripe exposes Checkout metadata on Checkout events and subscription metadata on Subscription events. For invoices created by a subscription, Stripe places that metadata under the invoice's subscription details. Talivia reads both the current `parent.subscription_details.metadata` shape and the earlier `subscription_details.metadata` shape.

## Connect the customer identity [#connect-the-customer-identity]

Call `identify` when the customer logs in, signs up, or reaches the authenticated product.

```javascript title="Link a Talivia visitor to Stripe"
window.talivia.identify('user_123', {
  email: currentUser.email,
  stripeCustomerId: currentUser.stripeCustomerId,
});
```

Talivia can then attribute a renewal through the Stripe customer even though the renewal happens without a new browser checkout session.

## Events Talivia maintains [#events-talivia-maintains]

The managed Stripe webhook receives:

* successful and failed invoice payments;
* subscription creation, updates, cancellation, pause, resume, trials, and pending updates;
* successful refunds and refund updates;
* dispute creation, updates, closure, and funds movements.

Initial Checkout and invoice events can arrive in either order. Talivia reconciles them into one payment using the Payment Intent, Checkout Session, customer, amount, and event time instead of counting the signup twice.


---

# Test and troubleshoot Stripe attribution (https://talivia.com/docs/revenue-guides/stripe/testing-and-troubleshooting)



Start with the [shared payment testing setup](https://talivia.com/docs/revenue-guides/testing-payment-providers), then test the actual Stripe checkout path used by your product rather than sending only a generic webhook fixture.

## Minimum test matrix [#minimum-test-matrix]

| Scenario                       | Expected Talivia result                                         |
| ------------------------------ | --------------------------------------------------------------- |
| One-time Checkout Session      | One paid payment matched to the checkout session                |
| Direct Payment Intent          | One payment keyed by the `pi_...` ID                            |
| Payment Link                   | Payment matched through `client_reference_id` or the return URL |
| Delayed payment method         | No revenue before asynchronous success                          |
| Subscription signup            | One initial payment plus an active subscription                 |
| Subscription renewal           | One renewal connected to the original customer                  |
| Failed invoice                 | Subscription lifecycle changes without paid revenue             |
| Full or partial refund         | Original payment remains visible and net revenue is reduced     |
| Dispute                        | Dispute state is connected to the original payment              |
| Repeated or out-of-order event | No duplicate payment                                            |

## The connection succeeds but no payment appears [#the-connection-succeeds-but-no-payment-appears]

Check the Stripe Dashboard webhook delivery for the website endpoint. The relevant successful event must be one of:

* `checkout.session.completed` or `checkout.session.async_payment_succeeded`;
* `payment_intent.succeeded` for a direct Payment Intent;
* `invoice.paid` or `invoice.payment_succeeded` for an invoice.

Confirm the event belongs to the same test or live mode as the restricted key connected in Talivia.

## The payment appears but is unattributed [#the-payment-appears-but-is-unattributed]

Inspect the Stripe object used by your flow:

* Checkout Session: `metadata.talivia_session_id`;
* direct Payment Intent: `metadata.talivia_session_id`;
* Subscription: `metadata.talivia_session_id`;
* Payment Link Checkout Session: Talivia-like `client_reference_id` beginning with `s_`;
* return page: `?session_id=cs_...` and a working Talivia tracker.

If metadata is absent, confirm `window.talivia.getSessionId()` returned a value before your backend created checkout.

## Payment Link is not decorated [#payment-link-is-not-decorated]

Automatic decoration requires a normal anchor whose hostname is `buy.stripe.com`. Talivia preserves an existing `client_reference_id`. For custom domains, programmatic navigation, or an existing merchant reference, configure the tracked return URL with `{CHECKOUT_SESSION_ID}`.

## A renewal is unattributed [#a-renewal-is-unattributed]

Confirm the first subscription payment was attributed and that later invoices use the same Stripe Customer. Add `subscription_data.metadata` during signup and call `window.talivia.identify` with the Stripe Customer ID after authentication.

## Reconnect Stripe [#reconnect-stripe]

Pasting an updated restricted key makes Talivia reconcile the existing Stripe webhook URL and event list instead of creating a duplicate endpoint. If the original connection predates managed endpoint IDs, the first update creates and stores a new managed endpoint.


---

# Testing payment integrations (https://talivia.com/docs/revenue-guides/testing-payment-providers)



Talivia does not have a **Live / Test** switch. The credential connected to a website determines which provider environment Talivia calls and where it provisions the managed webhook.

Keep the data separate. Use one Talivia website for staging or sandbox payments and another for production. This keeps test revenue out of production conversion and attribution reports.

## Use two websites [#use-two-websites]

| Talivia website   | Tracked experience            | Provider credential          | Data it should contain      |
| ----------------- | ----------------------------- | ---------------------------- | --------------------------- |
| Product — Sandbox | Staging site or test checkout | Test or sandbox key/token    | Test payments only          |
| Product           | Production site and checkout  | Live or production key/token | Real customer payments only |

The provider environment is only a connection detail. Talivia verifies and processes every supported event delivered by that connection; it does not classify, hide, or filter revenue by a separate payment mode.

## Shared test flow [#shared-test-flow]

1. Create the sandbox Talivia website and install the tracker on the staging experience.
2. Connect the provider's test credential in **Website settings → Revenue**.
3. Complete checkout from a tracked browser session.
4. Confirm the payment amount, currency, status, and provider.
5. Confirm the payment is matched to the expected session and traffic source.
6. Follow the provider guide for refunds, subscriptions, delivery logs, and provider-specific errors.

When the flow is verified, connect the live credential to the production Talivia website. Keep the sandbox website for later integration changes.

## Provider-specific checks [#provider-specific-checks]

Stripe

Checkout events, Payment Links, invoices, disputes, and refunds.

Dodo Payments

Environment detection, webhook delivery, checkout metadata, and refunds.

LemonSqueezy

Key mode, webhook events, custom checkout data, and subscriptions.

Polar

Token permissions, sandbox checkout, attribution, and refunds.

Yolfi

Event routing, signatures, metadata, and subscription updates.

Manual Payment API

Stable transaction IDs, session matching, and safe retries.


---

# Yolfi (https://talivia.com/docs/revenue-guides/yolfi)



Connect your Yolfi organization once to start receiving revenue in Talivia.

## Connect Yolfi [#connect-yolfi]

1. In the Talivia dashboard, select your website and open **Settings**.




2. Select **Payments** and choose **Yolfi**. Then [create an API key in Yolfi](https://app.yolfi.com/settings/api-keys),
   paste it into Talivia, and click **Connect Yolfi**.




## Match payments to sessions [#match-payments-to-sessions]

Choose how customers open Yolfi checkout. Both options use the Checkout Session ID from the
return URL; you do not need to send Talivia metadata.

Payment Links

Match payments from links created in the Yolfi dashboard.

Checkout Session API

Match payments from Checkout Sessions created by your backend.

Having trouble? [Test your Yolfi integration](https://talivia.com/docs/revenue-guides/yolfi/testing-and-troubleshooting).


---

# Yolfi Checkout Session API (https://talivia.com/docs/revenue-guides/yolfi/checkout-session)



Complete the [Yolfi connection setup](https://talivia.com/docs/revenue-guides/yolfi#connect-yolfi) before
continuing.

Use this guide only when your backend creates a Checkout Session. If you created a reusable link
in the Yolfi dashboard, follow the [Payment Links guide](https://talivia.com/docs/revenue-guides/yolfi/payment-link-on-your-site).

## Create the Yolfi Checkout Session [#create-the-yolfi-checkout-session]

Keep your Yolfi API key on the backend. Set `successUrl` with the literal
`{CHECKOUT_SESSION_ID}` placeholder:

```javascript title="Create a Yolfi Checkout Session"
const checkout = await fetch('https://app.yolfi.com/api/checkout-sessions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.YOLFI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    paylinkId: process.env.YOLFI_PAYLINK_ID,
    successUrl: 'https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}',
  }),
}).then(response => response.json());

return Response.json({ url: checkout.data.url });
```

Send the customer to `checkout.data.url`. After payment, Talivia reads `session_id` from the
return page and matches the payment automatically. No Talivia metadata is required.

For subscriptions, use the same `successUrl` for the first checkout. Renewals are connected to
the original payment automatically.

See [Yolfi Checkout Sessions](https://docs.yolfi.com/en/paylinks/checkout-sessions) for the full
request and response schema.


---

# Attribute revenue with Yolfi Payment Links (https://talivia.com/docs/revenue-guides/yolfi/payment-link-on-your-site)



Complete the [Yolfi connection setup](https://talivia.com/docs/revenue-guides/yolfi#connect-yolfi) before
continuing.

In Yolfi, open your Payment Link and go to **After Completion**.

For **Action After Payment**, choose **Redirect** and use:

```text
https://your-site.com/thanks?session_id={CHECKOUT_SESSION_ID}
```




That is all you need. Talivia reads `session_id` when the customer returns and matches the
payment automatically. No Talivia metadata is required.

## Shared links and QR codes [#shared-links-and-qr-codes]

The same redirect works when you share the Payment Link in email, chat, social media, or a QR
code. If the customer never returns to a page with the Talivia tracker, the payment is still
recorded but cannot be matched to a web session.

## Subscriptions [#subscriptions]

Use the redirect for the first subscription checkout. Later renewals are connected to the
original payment automatically and do not need another browser redirect.


---

# Test and troubleshoot Yolfi (https://talivia.com/docs/revenue-guides/yolfi/testing-and-troubleshooting)



## Test a payment [#test-a-payment]

1. [Connect Yolfi](https://talivia.com/docs/revenue-guides/yolfi#connect-yolfi).
2. Open checkout from a page with the Talivia tracker installed.
3. Complete a payment and return to your site.
4. Confirm the payment appears in Talivia with the expected traffic source.

## The connection fails [#the-connection-fails]

* Create a new key in [Yolfi API settings](https://app.yolfi.com/settings/api-keys).
* Confirm the key belongs to the organization you want to connect.
* Paste the new key into Talivia and connect again.

## No payment appears [#no-payment-appears]

Confirm that Yolfi is still connected in **Website Settings → Payments**, then complete a new test
payment. You do not need to add a website ID or Talivia metadata to the payment.

## The payment is unattributed [#the-payment-is-unattributed]

Confirm that your success page has the Talivia tracker and that the redirect URL contains:

```text
https://merchant.example/thanks?session_id={CHECKOUT_SESSION_ID}
```

For renewals, the first subscription payment must be matched before later payments can reuse its
attribution.


---

# Sessions (https://talivia.com/docs/sessions)



Sessions show how one visitor moved through your website during a visit. Talivia combines page views, custom events, source information, tracker parameters, and payment activity into a single activity timeline.

## Session list [#session-list]

Open **Sessions** from a website to see recent sessions. Each row includes source, visits, events, activity, and spend when the session is connected to revenue.




Open the full Sessions report. Select the expand icon in the upper-right corner of
the Sessions panel. From the full report, select any session to inspect its detailed activity
timeline, source, device, location, events, and attributed spend.

## Session detail [#session-detail]

The session detail view shows:

* Arrival source, referrer, page, and tracking parameters.
* Page views and custom events in chronological order.
* Browser, OS, device, country, region, and city.
* Payment activity and spend when attributed.
* Session replay when recording is enabled.

## Sorting [#sorting]

Activity can be viewed oldest-first or newest-first. Use oldest-first when you want to understand the journey as the visitor experienced it.


---

# Subdomain tracking (https://talivia.com/docs/subdomain-tracking)



Use one Talivia website ID and the same root `data-domain` on every subdomain:

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-domain="example.com"
></script>
```

This covers flows such as:

```text
example.com -> app.example.com -> checkout.example.com
```

If the website only runs on one hostname, this setup is optional: tracking works with a host-only cookie. Talivia Cloud includes `data-domain` in the generated snippet so a later move to subdomains does not silently split visitor identity.

Talivia stores an anonymous visitor cookie for 365 days and refreshes the shared session cookie for 30 minutes after activity. Tabs and subdomains therefore remain in one journey instead of creating separate visitors.

Use the registrable root domain (`example.com`). Do not set `data-domain="app.example.com"` when the visitor also moves through `example.com`.


---

# Tags (https://talivia.com/docs/tags)



Tags let you mark events coming from a specific script installation or environment.

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-tag="marketing-site"
></script>
```

Every event sent by that script includes the tag.

## Common uses [#common-uses]

* Separate marketing and app shells when both use the same website id.
* Mark embedded experiences.
* Compare rollout versions.
* Debug staging traffic without creating a second website.

## Filtering [#filtering]

Tags appear as an event dimension and can be used in filters, breakdowns, and event-level investigation.


---

# Team (https://talivia.com/docs/team)



Team access is managed separately for each website. Shared websites appear directly in the invited user's dashboard, so there is no separate team-switching flow.

## Invite someone [#invite-someone]

Open **Settings -> Team**, enter the email of a registered Talivia user, choose a role, and click **Invite**. The user should sign in with the same email address to see the website.




## Roles [#roles]

* **Viewer** has read-only access to dashboards, reports, and sessions.
* **Member** can also update website settings and integrations.
* **Owner** manages invitations and access, and can delete the website.

## Manage access [#manage-access]

The Team page shows the website owner and every invited user with their current role. The owner can change access or remove a user when it is no longer needed.

Review the list after contractor work, agency handoffs, or other temporary collaboration.


---

# Track events (https://talivia.com/docs/track-events)



Use custom events for actions that matter more than a page view: signups, checkout clicks, demo requests, external links, and activation steps.

## HTML attributes [#html-attributes]

Add `data-talivia-event` to an element:

```html
<button data-talivia-event="signup-click">Start free trial</button>
```

Add event data with `data-talivia-event-*` attributes:

```html
<button
  data-talivia-event="checkout-click"
  data-talivia-event-plan="pro"
  data-talivia-event-location="pricing"
>
  Checkout
</button>
```

Talivia automatically reads these attributes on click.

## Track when an element becomes visible [#track-when-an-element-becomes-visible]

Add `data-talivia-visible` to any element that matters: a pricing section, CTA, banner, alert, or modal.

```html
<section data-talivia-visible="pricing-seen">
  <h2>Simple pricing</h2>
</section>
```

Talivia sends the `pricing-seen` event once per page view when 50% of the element is visible.

Use optional attributes when the default is not right for an element:

```html
<button
  data-talivia-visible="signup-cta-seen"
  data-talivia-visible-threshold="0.7"
  data-talivia-visible-delay="700"
>
  Start free trial
</button>
```

* `data-talivia-visible-threshold` accepts `0.1` through `1`. The default is `0.5`.
* `data-talivia-visible-delay` waits for the element to remain visible before sending the event. The default is `0` milliseconds.

Visibility events include `visibility_percentage`, `threshold`, and `delay` in their event data. They work like any other Talivia event in Sessions, Goals, and Funnels.

## Links [#links]

For normal links, Talivia waits for the event request before navigating when possible.

```html
<a href="/pricing" data-talivia-event="pricing-link">Pricing</a>
```

External links, modifier-key clicks, and `_blank` links are not blocked.

## JavaScript [#javascript]

```js
window.talivia.track('invite-sent', {
  role: 'viewer',
});
```

Use JavaScript when the event depends on application state, form results, or a server response.

## Event data tips [#event-data-tips]

* Use stable names like `signup-click`, not user-facing button text.
* Keep numeric values as numbers when you want to compare them later.
* Avoid sending personal information unless it is needed for payment attribution and allowed by your privacy policy.


---

# Tracker configuration (https://talivia.com/docs/tracker-configuration)



The tracker reads configuration from `data-*` attributes on the script tag. For a normal Talivia Cloud installation, copy the complete snippet from **Settings -> Tracking** and leave its generated attributes unchanged.

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-domain="example.com"
  data-auto-track="true"
></script>
```

Only `data-website-id` is required for tracking one hostname. Talivia Cloud normally generates `data-domain` too, which is safe to keep and allows the same anonymous identity to continue across subdomains.

## Domain attributes [#domain-attributes]

These similarly named attributes solve different problems:

| Attribute                   | Use it for                                                                                                                     |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `data-domain`               | Set the cookie scope. Use one root such as `example.com` when the same visitor moves between `example.com` and its subdomains. |
| `data-domains`              | Restrict the hostnames where this script is allowed to collect. It does not share identity.                                    |
| `data-cross-domain-domains` | Continue a journey between unrelated roots such as `example.com` and `example.net` with a signed linker.                       |

For a website that only runs on one hostname, no manual domain configuration is required. For subdomains, follow [Subdomain tracking](https://talivia.com/docs/subdomain-tracking). For unrelated roots, use [Cross-domain tracking](https://talivia.com/docs/cross-domain-tracking).

## Available attributes [#available-attributes]

| Attribute                   | Description                                                                                                                               |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `data-website-id`           | Required website id.                                                                                                                      |
| `data-host-url`             | Override the collection endpoint origin for self-hosting or a custom reverse proxy. Do not set it on a normal Talivia Cloud installation. |
| `data-domain`               | Optional cookie domain shared by the website and its subdomains. Talivia Cloud generates it from the configured website domain.           |
| `data-auto-track`           | Set to `false` to disable the first automatic page view.                                                                                  |
| `data-domains`              | Optional comma-separated hostname allowlist. Subdomains do not need to be listed for shared identity.                                     |
| `data-cross-domain-domains` | Comma-separated root domains allowed to receive a signed Talivia linker.                                                                  |
| `data-do-not-track`         | Set to `true` to respect browser Do Not Track.                                                                                            |
| `data-exclude-search`       | Set to `true` to remove query strings before sending URLs.                                                                                |
| `data-exclude-hash`         | Set to `true` to remove hash fragments before sending URLs.                                                                               |
| `data-tag`                  | Attach a tag to every event from this script.                                                                                             |
| `data-before-send`          | Name of a global function that can edit or cancel payloads.                                                                               |
| `data-fetch-credentials`    | Fetch credentials mode. Defaults to `omit`.                                                                                               |
| `data-performance`          | Set to `true` to collect Web Vitals.                                                                                                      |

## beforeSend [#beforesend]

```html
<script>
  window.taliviaBeforeSend = (type, payload) => {
    if (payload.url?.includes('/internal-preview')) return null;

    return payload;
  };
</script>

<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-before-send="taliviaBeforeSend"
></script>
```

Return `null` or `undefined` to cancel the event.

## Domain allowlist [#domain-allowlist]

This is an optional restriction, not a requirement for subdomain tracking.

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-domains="example.com"
></script>
```

One root entry covers that domain and its subdomains. This is useful when the same layout can render on staging, preview, and production domains.

## Collection host [#collection-host]

The script automatically sends data to Talivia Cloud. `data-host-url` exists for self-hosted installations and custom reverse proxies where the browser must send collection requests to another origin. It is not an additional URL for your tracked website and should be omitted from normal Cloud snippets.

## Identity storage [#identity-storage]

Talivia stores its anonymous visitor and rolling session identifiers in first-party cookies.

## Visitor and session lifetime [#visitor-and-session-lifetime]

* The anonymous visitor cookie lasts for 365 days.
* The session cookie lasts for 30 minutes and refreshes whenever the tracker sends activity.
* Closing a tab does not split an active session. All tabs and configured subdomains reuse the same rolling session.

When multiple subdomains must share identity, use the root registrable domain for `data-domain`, such as `example.com`, not `app.example.com`. Copy the generated snippet from **Settings -> Tracking** and review [Subdomain tracking](https://talivia.com/docs/subdomain-tracking) before changing the value manually.

## Sensitive query parameters [#sensitive-query-parameters]

Talivia removes OAuth credentials, signed cross-domain tokens, and checkout session ids from stored URL queries. Payment return detection still runs before sanitization, so Stripe and other checkout attribution continues to work without displaying secrets in analytics.


---

# Tracker functions (https://talivia.com/docs/tracker-functions)



The tracker exposes a small browser API after the script loads.

## Track a page view [#track-a-page-view]

```js
window.talivia.track();
```

Use this when automatic tracking is disabled or when you need to manually send a page view after a route transition.

## Track a custom event [#track-a-custom-event]

```js
window.talivia.track('signup-button');
```

Event names are limited to 50 characters.

## Track an event with data [#track-an-event-with-data]

```js
window.talivia.track('signup-button', {
  plan: 'pro',
  location: 'pricing',
});
```

Event data can include strings, numbers, arrays, and nested objects. Keep payloads small: Talivia truncates long strings and limits object shape so reports stay fast.

## Override page properties [#override-page-properties]

```js
window.talivia.track({
  website: 'YOUR_WEBSITE_ID',
  url: '/pricing',
  title: 'Pricing',
});
```

## Use a function [#use-a-function]

```js
window.talivia.track(props => ({
  ...props,
  url: '/checkout',
  title: 'Checkout',
}));
```

The function receives the current tracker payload and returns the payload to send.

## Identify a visitor [#identify-a-visitor]

```js
window.talivia.identify('user_123', {
  email: 'founder@example.com',
  stripeCustomerId: 'cus_123',
});
```

Use identify after login or signup. Talivia stores session data and can connect a payment provider customer to the visitor.

## Read checkout context [#read-checkout-context]

```js
const sessionId = window.talivia.getSessionId();

await fetch('/api/create-checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sessionId }),
});
```

`getSessionId()` returns the opaque value stored in the `talivia_session_id` first-party cookie. Send only this value to your backend and attach it as `talivia_session_id` provider metadata. It is an attribution identifier, not an authentication credential.


---

# Tracking overview (https://talivia.com/docs/tracking)



Talivia's browser tracker records page views automatically and exposes a small JavaScript API for custom events, identity, and checkout attribution.

## Script [#script]

```html
<script
  defer
  src="https://talivia.com/script.js"
  data-website-id="YOUR_WEBSITE_ID"
  data-domain="example.com"
></script>
```

The script reads browser context, watches client-side route changes, and sends page views. By default, Talivia keeps an anonymous visitor cookie for one year and a rolling 30-minute session cookie.

A single hostname works without `data-domain`. Talivia Cloud includes it in the generated snippet so `example.com`, `app.example.com`, and other subdomains can share the same visitor and session when needed. Keep the complete snippet from **Settings -> Tracking** instead of rebuilding it from this example.

Use [Tracker configuration](https://talivia.com/docs/tracker-configuration) for optional script settings and [Subdomain tracking](https://talivia.com/docs/subdomain-tracking) for a complete shared-cookie setup.

## Runtime API [#runtime-api]

When the script loads, it creates `window.talivia`:

```js
window.talivia.track();
window.talivia.track('signup-click');
window.talivia.identify('user_123', { email: 'founder@example.com' });
window.talivia.getSessionId();
```

## Collection endpoint [#collection-endpoint]

The tracker sends data to Talivia's collection endpoint and receives signed cache and cross-domain tokens. Tokens are short-lived and contain anonymous tracking keys, not account or payment credentials.

## Revenue context [#revenue-context]

For checkout flows, follow the connected provider's revenue guide. Stripe and Yolfi use a unique
Checkout Session ID on the browser return. Providers without that return signal can use
`window.talivia.getSessionId()` in their supported checkout metadata.


---

# Getting updates (https://talivia.com/docs/updates)



Talivia Cloud updates automatically. You do not need to upgrade the tracker script manually when the hosted app ships new features.

## Tracker updates [#tracker-updates]

The script is loaded from Talivia with `defer`, so visitors receive the latest compatible tracker when their browser requests `script.js`.

If your site uses a strict Content Security Policy, make sure the Talivia script origin and collection endpoint are allowed.

## Product updates [#product-updates]

New dashboard features can appear without a site change. For example, revenue attribution, search keyword reports, and session replay use the data already flowing through the tracker and connected integrations.

## When to change your code [#when-to-change-your-code]

You only need to update your site code when you intentionally enable a new tracking behavior, such as:

* Adding custom event attributes.
* Calling `window.talivia.identify`.
* Passing `window.talivia.getSessionId()` into checkout.
* Enabling performance collection with `data-performance="true"`.


---

# UTM (https://talivia.com/docs/utm)



Talivia records standard UTM parameters from page URLs:

* `utm_source`
* `utm_medium`
* `utm_campaign`
* `utm_content`
* `utm_term`

It also records common click IDs such as `gclid`, `fbclid`, `msclkid`, `ttclid`, `li_fat_id`, and `twclid`.

## Campaign workflow [#campaign-workflow]

1. Add UTM parameters to campaign links.
2. Send traffic to a tracked page.
3. Review UTM reports and breakdowns.
4. Connect revenue to see which campaigns produce paid sessions.

## Query cleanup [#query-cleanup]

Use **Settings -> Attribution -> Ignored query params** to remove noisy parameters from stored page queries.
