# SDK für eigene Anbindungen

Nicht jeder Kunde hat WooCommerce oder Shopware. Ein Fitnessstudio verkauft
keine Artikel, es bucht Probetrainings; ein Buchungssystem hat gar keinen
Warenkorb. Für alles außerhalb der Plugins gibt es das SDK.

## Im Browser

```js
import { init, viewItem, purchase } from "@trackdolphin/sdk";

init({ shopId: "shop_meinshop_de_ab12cd", url: "https://td.meinshop.de/collect" });

viewItem([{ id: "SKU-1", name: "Laufschuh", price: 119.9 }], 119.9);
```

Das SDK übernimmt dabei still einiges, was sonst schiefgeht:

- **First-Touch-Attribution** über 90 Tage, damit der Kanal auch beim zweiten
  Besuch noch bekannt ist
- **Klick-IDs** aus der Adresszeile in Cookies sichern (`gclid`, `gbraid`,
  `wbraid`, `fbclid`)
- **Besucherkennung** als First-Party-Cookie — sie verbindet die anonyme Reise,
  bis eine gehashte E-Mail bekannt wird
- **Warteschlange**, solange keine Einwilligung vorliegt

## Auf dem Server

Der Abschluss gehört auf den Server — dort kann ihn kein Werbeblocker
verhindern und niemand fälschen.

```ts
import { createClient } from "@trackdolphin/sdk/server";

const td = createClient({
  shopId: "shop_meinshop_de_ab12cd",
  url: "https://td.meinshop.de/collect",
});

await td.track({
  type: "purchase",
  event_id: `order_${order.id}`,   // aus der Bestellnummer, nicht zufällig
  value: order.total,
  currency: "EUR",
  email: order.email,              // wird lokal gehasht, nie im Klartext gesendet
  phone: order.phone,
});
```

## Reihenfolge: erst das Geschäft, dann die Messung

```ts
const lead = await createLead(input);   // zuerst
try {
  await td.track({ type: "lead", event_id: `lead_${lead.id}`, email: input.email });
} catch (e) {
  logger.error("Tracking fehlgeschlagen — Lead ist gesichert", e);
}
```

Fällt das Tracking aus, ist der Lead trotzdem da. Andersherum kostet ein
Ausfall bei uns dich einen Kunden — das darf nie passieren.

## Die event_id leiten, nicht würfeln

```ts
event_id: `order_${order.id}`
```

Eine abgeleitete Kennung macht jeden Versand wiederholbar: Zeitüberschreitung,
Neustart, doppelter Webhook — die Plattform erkennt die Dublette und zählt
einmal. Ein Zufallswert erzeugt bei jedem Versuch eine neue Conversion.

## Klartext bleibt bei dir

E-Mail und Telefonnummer werden **lokal** gehasht, bevor irgendetwas das Gerät
oder deinen Server verlässt. Telefonnummern nach E.164 ohne Plus — `0171…` wird
zu `49171…`, sonst trifft der Hash bei Meta und Google nie.

Siehe [Match-Qualität](/docs/matching.md).

## Historie einspielen

Auch der Backfill läuft über das SDK — siehe [Historie und
Erkennungsquote](/docs/backfill.md).
