Zum Hauptinhalt springen

API-Vertrag V1

Wir empfehlen die Server-to-Server-API. JavaScript ist nur ein optionaler analytischer Fallback und funktioniert nur nach Erteilung der Einwilligung zur Analyse.

API-Vertrag V1 Link zum Abschnitt API-Vertrag V1

Wir empfehlen die Server-to-Server-API. JavaScript ist nur ein optionaler analytischer Fallback und funktioniert nur nach Erteilung der Einwilligung zur Analyse.

Bestellungen, Umsatz und abgeleitete Kennzahlen werden nur bei aktiver Conversion-Messung angezeigt. Sie dienen nur der Analyse und ändern die CPC-Abrechnung nicht.

schema_version

1.0

payload_contract

order_v1

Content-Type

application/json

request_limit

64 KiB

So verbinden Sie die Messung Link zum Abschnitt So verbinden Sie die Messung

Wir empfehlen die Server-to-Server-API. JavaScript ist nur ein optionaler analytischer Fallback und funktioniert nur nach Erteilung der Einwilligung zur Analyse.

  1. 1 Speichern Sie den Parameter zclid aus der Ziel-URL 30 Tage lang beim Warenkorb oder bei der Bestellung.
  2. 2 Erstellen Sie auf dem Server einen stabilen HMAC-SHA-256-Hash der internen Bestell-ID mit einem eigenen Schlüssel. Senden Sie weder die unveränderte ID noch personenbezogene Daten.
  3. 3 Senden Sie nach der Erstellung der Bestellung JSON an die API und signieren Sie den exakten Anfrageinhalt mit dem Integrationsschlüssel.
  4. 4 Für Zahlung, Storno und kumulierte Erstattungen dieselbe zclid und order_id_hash verwenden. Endsummen und Positionen unverändert lassen.

Der geheime Integrationsschlüssel wird nur einmal angezeigt. Speichern Sie ihn in der Geheimnisverwaltung auf dem Server des Shops.

Empfohlen: Server-to-Server-API Link zum Abschnitt Empfohlen: Server-to-Server-API

Der Server des Shops sendet geprüfte Bestellungen, Statusänderungen und Rückerstattungen direkt an Zoneo. Fügen Sie den geheimen Schlüssel niemals in den Browser ein.

POST https://zoneo.at/api/v1/conversions
Sandbox https://zoneo.at/api/v1/conversions/sandbox

Erstellen Sie auf dem Server einen stabilen HMAC-SHA-256-Hash der internen Bestell-ID mit einem eigenen Schlüssel. Senden Sie weder die unveränderte ID noch personenbezogene Daten.

order_id_hash · PHP

$orderIdHash = hash_hmac(
    'sha256',
    "zoneo-order-v1\n".$internalOrderId,
    $_ENV['ZONEO_ORDER_HASH_KEY'],
);

Beispielanfrage Link zum Abschnitt Beispielanfrage

Senden Sie nach der Erstellung der Bestellung JSON an die API und signieren Sie den exakten Anfrageinhalt mit dem Integrationsschlüssel.

order_v1 · JSON

{
    "schema_version": "1.0",
    "zclid": "018fb72a-7d8e-7c3c-a4da-f37ce07ad739",
    "order_id_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "currency": "EUR",
    "occurred_at": "2026-08-31T12:34:56Z",
    "status": "placed",
    "refund_amount_minor": 0,
    "totals": {
        "items_gross_minor": 14000,
        "discount_minor": 1500,
        "shipping_gross_minor": 390,
        "fees_gross_minor": 100,
        "tax_minor": 2165,
        "order_total_gross_minor": 12990
    },
    "items": [
        {
            "merchant_item_id": "ITEM_ID_FROM_FEED",
            "item_group_id": "MODEL-10",
            "variant_id": "size:42",
            "name": "PRODUCT_NAME",
            "gtin": "8581234567890",
            "quantity": 2,
            "unit_price_gross_minor": 7000,
            "line_total_gross_minor": 14000
        }
    ],
    "order_locale": "de-at",
    "expected_delivery_date": "2026-09-03"
}
order_v1 · JSON
JSON Pflichtfelder V1
schema_version = "1.0"
zclid UUID
order_id_hash HMAC-SHA-256 · [a-f0-9]{64}
currency ISO 4217 · EUR
occurred_at ISO 8601 · UTC
status placed | paid | cancelled | partially_refunded | refunded
refund_amount_minor integer ≥ 0 · Σ · monotonic
totals object · integer · gross
items array[1..100]
order_locale BCP 47
expected_delivery_date YYYY-MM-DD
order_v1 · items[]
items[] Pflichtfelder V1
merchant_item_id feed.ITEM_ID · stable
quantity integer · 1..1000
unit_price_gross_minor integer ≥ 0
line_total_gross_minor unit_price_gross_minor × quantity
item_group_id string
variant_id string
name string · PRODUCT_NAME · PII = 0
gtin [0-9]{8,14}

totals · EUR · integer

totals.items_gross_minor = sum(items[].line_total_gross_minor)

totals.order_total_gross_minor = totals.items_gross_minor - totals.discount_minor + totals.shipping_gross_minor + totals.fees_gross_minor

line_total_gross_minor = unit_price_gross_minor × quantity

Kanonische Signatur Link zum Abschnitt Kanonische Signatur

Wenn Sie den ursprünglichen geheimen Schlüssel nicht gespeichert haben, wählen Sie „Geheimen Schlüssel wiederherstellen“ und speichern Sie den neuen Schlüssel sofort sicher.

HTTP · HMAC-SHA-256
HTTP V1
Content-Type application/json
X-Zoneo-Integration-ID zci_...
X-Zoneo-Timestamp Unix · UTC
X-Zoneo-Nonce CSPRNG · unique · len ≥ 16
Idempotency-Key order:{hash}:{status}
X-Zoneo-Signature v1=HMAC_SHA256_HEX

HMAC-SHA-256 · canonical request

UPPERCASE_HTTP_METHOD
/exact/request/path
unix_timestamp
nonce
idempotency_key
sha256_hex_of_exact_raw_body

body_hash = SHA256(raw_body)
signature = HMAC_SHA256(api_secret, canonical_request)
X-Zoneo-Signature = "v1=" + lowercase_hex(signature)

S2S · PHP

<?php

$path = '/api/v1/conversions';
$body = json_encode($payload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
$timestamp = time();
$nonce = bin2hex(random_bytes(16));
$idempotencyKey = 'order:'.$orderIdHash.':'.$payload['status'];
$canonical = implode("\n", [
    'POST',
    $path,
    (string) $timestamp,
    $nonce,
    $idempotencyKey,
    hash('sha256', $body),
]);
$signature = hash_hmac('sha256', $canonical, $_ENV['ZONEO_API_SECRET']);

$headers = [
    'Content-Type: application/json',
    'X-Zoneo-Integration-ID: '.$_ENV['ZONEO_INTEGRATION_ID'],
    'X-Zoneo-Timestamp: '.$timestamp,
    'X-Zoneo-Nonce: '.$nonce,
    'Idempotency-Key: '.$idempotencyKey,
    'X-Zoneo-Signature: v1='.$signature,
];

$curl = curl_init('https://zoneo.at/api/v1/conversions');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);

Erstellt → Erstattet Link zum Abschnitt Erstellt → Erstattet

Für Zahlung, Storno und kumulierte Erstattungen dieselbe zclid und order_id_hash verwenden. Endsummen und Positionen unverändert lassen.

Erstellt · placed Bezahlt · paid Storniert · cancelled Teilweise erstattet · partially_refunded Erstattet · refunded

order_v1 · lifecycle

placed -> paid | cancelled | partially_refunded | refunded
paid -> partially_refunded | refunded
partially_refunded -> refunded
cancelled, refunded -> terminal

0 <= refund_amount_minor <= totals.order_total_gross_minor
new_refund_amount_minor >= previous_refund_amount_minor

Idempotency-Key · retry

nonce₁ != nonce₂
retry = nonce₂ + Idempotency-Key₁ + SHA256(JSON₁)
Idempotency-Key₁ + SHA256(JSON₁) -> HTTP 200
Idempotency-Key₁ + SHA256(JSON₂) -> HTTP 409 idempotency_conflict

Sandbox V1 Link zum Abschnitt Sandbox V1

Fügen Sie eine V1-JSON-Nutzlast ein, um Felder, Summen und Feed-Zuordnung zu prüfen, ohne eine Bestellung oder Abrechnung zu erzeugen.

POST https://zoneo.at/api/v1/conversions/sandbox
persisted = false billing_impact = false

Optionale Messung über JavaScript Link zum Abschnitt Optionale Messung über JavaScript

Die Bibliothek speichert zclid nach Einwilligung und sendet nur das erste placed-Ereignis von der Danke-Seite. Weitere Status sicher per S2S senden.

Die Einwilligung ist standardmäßig deaktiviert. Die Funktion consent darf erst nach einer gültigen Einwilligung der Nutzerin oder des Nutzers zur Analyse true zurückgeben.

Laden und Initialisieren

<script src="https://zoneo.at/integrations/zoneo-conversion-v1.js"></script>
<script>
const zoneo = window.ZoneoConversions.init({
  integrationId: 'zci_...',
  apiBase: 'https://zoneo.at/api/v1/conversions',
  consent: () => analyticsConsent === true
})

zoneo.track({
  order_id_hash: 'SERVER_HMAC_SHA256',
  currency: 'EUR',
  occurred_at: new Date().toISOString(),
  status: 'placed',
  totals: {
    items_gross_minor: 12990,
    discount_minor: 0,
    shipping_gross_minor: 0,
    fees_gross_minor: 0,
    tax_minor: 2165,
    order_total_gross_minor: 12990
  },
  items: [{
    merchant_item_id: 'ITEM_ID_FROM_FEED',
    quantity: 1,
    unit_price_gross_minor: 12990,
    line_total_gross_minor: 12990
  }]
})
</script>

Zustand der Integration Link zum Abschnitt Zustand der Integration

Angenommene und abgelehnte Ereignisse der letzten 7 Tage.

201 · created = true
200 · idempotent = true | deduplicated = true
4xx · error.code

HTTP 201 · JSON

{
    "data": {
        "conversion_reference": "6bfca33e-3ac7-48dc-a733-c1f313853269",
        "status": "placed",
        "source": "s2s",
        "verification": "hmac_current",
        "schema_version": "1.0",
        "payload_contract": "order_v1",
        "totals": {
            "items_gross_minor": 14000,
            "discount_minor": 1500,
            "shipping_gross_minor": 390,
            "fees_gross_minor": 100,
            "tax_minor": 2165,
            "order_total_gross_minor": 12990
        },
        "refund_amount_minor": 0,
        "net_revenue_minor": 12990,
        "items": {
            "count": 1,
            "quantity_total": 2,
            "matched_count": 1,
            "match_status": "complete"
        },
        "totals_reconciled": true,
        "warnings": [],
        "currency": "EUR",
        "created": true,
        "idempotent": false,
        "deduplicated": false,
        "provisional": false,
        "billing_impact": false
    }
}

HTTP 4xx · JSON

{
    "error": {
        "code": "order_total_mismatch",
        "field": "totals.order_total_gross_minor",
        "details": {
            "expected_minor": 12990,
            "received_minor": 13000
        }
    }
}
invalid_signature stale_timestamp replayed_nonce pii_not_allowed items_total_mismatch order_total_mismatch currency_mismatch click_not_eligible store_or_market_mismatch not_last_zoneo_click attribution_window_expired invalid_state_transition order_definition_conflict refund_amount_decreased order_attribution_conflict

Datenschutz Link zum Abschnitt Datenschutz

Die neuesten rein analytischen Bestellungen bei Zoneo. Unverschlüsselte Bestellnummern und personenbezogene Daten werden nie angezeigt.

Erstellen Sie auf dem Server einen stabilen HMAC-SHA-256-Hash der internen Bestell-ID mit einem eigenen Schlüssel. Senden Sie weder die unveränderte ID noch personenbezogene Daten.

Bestellungen, Umsatz und abgeleitete Kennzahlen werden nur bei aktiver Conversion-Messung angezeigt. Sie dienen nur der Analyse und ändern die CPC-Abrechnung nicht.

So verbinden Sie die Messung

Wir empfehlen die Server-to-Server-API. JavaScript ist nur ein optionaler analytischer Fallback und funktioniert nur nach Erteilung der Einwilligung zur Analyse.