> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tagada.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tagada Radar

> Install Tagada Radar on every page where you sell. It reports where each payment comes from, and gives each payment a proof of its origin.

# Tagada Radar

Tagada Radar is a small script you install on every page where you sell. It reports the website and page a customer is on, and gives each payment a proof of its origin. TagadaPay matches that origin with the websites declared for your store.

> [!NOTE]
>
> **Radar is enabled on request, account by account.** Until your account is enabled, nothing changes and you have nothing to install. Ask your account manager: we enable Radar first in observe mode, where payments are never refused, check together that every website you sell on is declared, and only then turn on enforcement, with notice.

> [!WARNING]
>
> **Under `enforce`, a payment without a valid Radar token does not run.** It is refused before it reaches the card networks, and your customer is not charged. Your account is in one of three settings, set by TagadaPay: `off` reads nothing, `observe` records what it finds and never refuses, `enforce` refuses.

> [!NOTE]
>
> Tagada Radar is not Stripe Radar. The `requireAction: "radar"` step of a payment is the fraud check of a processor, described in [Accept a payment with your own cart](https://docs.tagada.io/developer-tools/payments/core-js-payments.md). Tagada Radar reports the origin of the payment, and it works whichever processor you use.

***

## How it works

```
┌──────────────────┐   page, referrer  ┌──────────────────┐
│  Your website    │ ────────────────► │  TagadaPay       │
│  + Tagada Radar  │ ◄──────────────── │  Payments API    │
└──────────────────┘    radar token    └──────────────────┘
         │                                     ▲
         │ browser confirm + radar token       │ checks the token
         └─────────────────────────────────────┘
```

1. **Radar loads** on your page with your publishable key.
2. **Radar reports** the page to `POST /v1/radar/tokens`. The website is the `Origin` your browser sends, never something the page says.
3. **Your checkout sends the token** when it confirms the payment.
4. **TagadaPay checks the token**: its signature, its expiry, that it was never used, that it comes from the same website and the same account as the payment.

***

## Before you start

You need:

* a **publishable key** (`tpk_live_…` or `tpk_test_…`) of your store;
* **every website you sell on declared** for your store, including separate checkout domains. A website is declared when it is allowed for the store's publishable key: your verified custom domains and your funnel addresses are added for you when a funnel is saved.

***

## Install

### Script tag

Once Radar is enabled on your account, add this inside the `<head>` of every page, including product, cart and checkout pages:

```html theme={null}
<script
  src="https://cdn.jsdelivr.net/npm/@tagadapay/radar/dist/radar.min.js"
  data-publishable-key="tpk_live_xxx"
  async
></script>
```

The script starts by itself and exposes `window.TagadaRadar`.

### npm

```bash theme={null}
npm install @tagadapay/radar
```

```typescript theme={null}
import { loadRadar } from '@tagadapay/radar';

const radar = await loadRadar({ publishableKey: 'tpk_live_xxx' });
```

Later calls with the same key return the same instance, even from another copy of the package on the page.

### Shopify

Add the script tag to `theme.liquid`, inside `<head>`. If your checkout runs on a separate domain, install it there too.

### WooCommerce

Add the script tag through your theme header or a header-scripts plugin, so that it loads on every page, including checkout.

### TagadaPay hosted checkout and funnels

Studio pages hosted by TagadaPay load Radar themselves at the moment of payment, once your account is not `off`. You still install it on your own pages that send customers to them if you want those pages reported.

***

## Send the token with the payment

### Headless SDK

If the Radar script tag is on the page, the token is attached for you when your account is not `off`.

### Your own checkout with core-js

Read the token just before you confirm:

```typescript theme={null}
import { loadPayments } from '@tagadapay/core-js/payments-v3';

const payments = await loadPayments({ publishableKey: 'tpk_live_xxx' });
const radarToken = await radar.getToken();

await payments.confirmPayment({ clientSecret, paymentMethod, returnUrl, radarToken });
```

A token is valid for 15 minutes and for one payment. Always read a new one with `getToken()`.

### Server-to-server payments

A payment your server confirms with its own key has no browser origin to check. Radar does not check it and does not refuse it.

### Subscription renewals

A renewal has no page and no customer present. It is not checked and never refused, and it stays linked to the original purchase. You have nothing to send.

***

## API

| Member | Description |
| - | - |
| `loadRadar({ publishableKey, apiBase?, debug? })` | Starts Radar and reports the page. Returns a `Promise<Radar>`, which does not wait for the answer. |
| `radar.getToken()` | Returns a `Promise<string>` with a token no other call received. |
| `radar.reportPage()` | Reports the current page again, after a client-side navigation. |
| `radar.ready` | `true` once the server has answered a report with a token. |
| `radar.on('error', callback)` | Calls `callback` with a `RadarError` (`code`, `message`) when a report fails. Returns the function that stops it. |

`code` is one of `website_not_declared`, `network_error`, `request_rejected`, `invalid_response` or `invalid_publishable_key`.

***

## Check your installation

Set `debug: true`, or add `data-debug="true"` to the script tag, then open your browser console. You should see:

```
[TagadaRadar] ready · https://shop.example.com · declared
```

In your CRM, a store's settings list its websites once Radar has reported or your account is not `off`:

| State | Meaning | What to do |
| - | - | - |
| **Declared**, with a last seen date | Radar reported from this website in the last 7 days | Nothing |
| **Declared**, not seen | Radar has not reported from this declared website in the last 7 days | Install the script, then open a page |
| **Undeclared** | Radar was reported from a website not declared for the store. Payments from it are not accepted | If it is yours, ask us to add it |

In test mode (`tpk_test_…`) the same rule applies: a website counts as declared when the test key allows it. `localhost` does not, unless the key lists it.

***

## Errors

Under `enforce`, refused confirms answer HTTP 403 with one of these codes:

| Code | Cause | What to do |
| - | - | - |
| `radar_token_missing` | The confirm has no token | Install Radar and send its token |
| `radar_token_invalid` | The token is expired, already used or malformed | Read a new one with `getToken()` |
| `radar_origin_mismatch` | The token was issued to another website than the one confirming | Read the token on the page that confirms |
| `radar_key_mismatch` | The token was issued for another key or account | Use the publishable key of this store |

A request from a website the key does not allow is refused earlier, with `permission_denied` and `param: "Origin"`, on every route of the API. On `POST /v1/radar/tokens` it also leaves the website on your store's list. Radar's script reads it as `website_not_declared`.

These are platform refusals, not card declines: no processor was called. Do not ask your customer to try another card: fix the cause, then ask them to try again. The payment stays open and can be confirmed with a new token.

***

## What Radar collects

| Data | Why |
| - | - |
| Website, from the browser's `Origin` | To know where the payment comes from |
| Page path, without its query string | To know which page was open |
| Referring page, without its query string | To follow the customer's path to the checkout |
| Browser session identifier, per tab | To tie the page to the payment |
| User agent, from the browser's header | To tell real visits from automated traffic |

Radar does not read card details, and it does not read what your customers type into forms. Mention it in your privacy policy as a payment security and fraud prevention tool.

***

## Content Security Policy

If your site sets a Content Security Policy, allow:

```
script-src https://cdn.jsdelivr.net;
connect-src https://api.tagada.io;
```

***

## FAQ

> [accordion] I have several websites. What do I do?
>
> Declare each of them for your store, and install Radar on each. The publishable key is the same.

> [accordion] Does Radar slow down my website?
>
> No. The script loads asynchronously and weighs under 5 KB, so it does not block your page from displaying.

> [accordion] What happens if an ad blocker stops Radar?
>
> `getToken()` fails and the confirm goes without a token. Under `observe` the payment runs and the absence is recorded. Under `enforce` the payment is refused with `radar_token_missing`: show your customer a message asking them to allow your site.

> [accordion] Can I load Radar only on the checkout page?
>
> Payments work if Radar runs on the page that confirms the payment, but install it on every page: the website list then shows everywhere you sell.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.