Przejdź do głównej treści

Kontrakt API V1

Zalecamy API server-to-server. JavaScript jest tylko opcjonalną zapasową ścieżką analityczną i działa wyłącznie po udzieleniu zgody na analitykę.

Kontrakt API V1 Link do sekcji Kontrakt API V1

Zalecamy API server-to-server. JavaScript jest tylko opcjonalną zapasową ścieżką analityczną i działa wyłącznie po udzieleniu zgody na analitykę.

Zamówienia, przychód i wskaźniki pochodne są wyświetlane tylko przy aktywnym pomiarze konwersji. Służą wyłącznie do analityki i nie zmieniają rozliczeń CPC.

schema_version

1.0

payload_contract

order_v1

Content-Type

application/json

request_limit

64 KiB

Jak połączyć pomiar Link do sekcji Jak połączyć pomiar

Zalecamy API server-to-server. JavaScript jest tylko opcjonalną zapasową ścieżką analityczną i działa wyłącznie po udzieleniu zgody na analitykę.

  1. 1 Zapisuj parametr zclid z docelowego adresu URL przy koszyku lub zamówieniu przez 30 dni.
  2. 2 Na serwerze utwórz stabilny odcisk HMAC-SHA-256 wewnętrznego identyfikatora zamówienia, używając oddzielnego klucza. Nie wysyłaj surowego identyfikatora ani danych osobowych.
  3. 3 Po utworzeniu zamówienia wyślij JSON do API i podpisz dokładną treść żądania tajnym kluczem integracji.
  4. 4 Dla płatności, anulowania i narastających zwrotów używaj tych samych zclid i order_id_hash. Nie zmieniaj końcowych sum ani pozycji.

Tajny klucz integracji zostanie wyświetlony tylko raz. Zapisz go w menedżerze sekretów na serwerze sklepu.

Zalecane: API server-to-server Link do sekcji Zalecane: API server-to-server

Serwer sklepu wysyła zweryfikowane zamówienia, zmiany statusu i zwroty bezpośrednio do Zoneo. Nigdy nie umieszczaj tajnego klucza w przeglądarce.

POST https://izoneo.pl/api/v1/conversions
Sandbox https://izoneo.pl/api/v1/conversions/sandbox

Na serwerze utwórz stabilny odcisk HMAC-SHA-256 wewnętrznego identyfikatora zamówienia, używając oddzielnego klucza. Nie wysyłaj surowego identyfikatora ani danych osobowych.

order_id_hash · PHP

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

Przykład żądania Link do sekcji Przykład żądania

Po utworzeniu zamówienia wyślij JSON do API i podpisz dokładną treść żądania tajnym kluczem integracji.

order_v1 · JSON

{
    "schema_version": "1.0",
    "zclid": "018fb72a-7d8e-7c3c-a4da-f37ce07ad739",
    "order_id_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "currency": "PLN",
    "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": "pl",
    "expected_delivery_date": "2026-09-03"
}
order_v1 · JSON
JSON Wymagane pola V1
schema_version = "1.0"
zclid UUID
order_id_hash HMAC-SHA-256 · [a-f0-9]{64}
currency ISO 4217 · PLN
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[] Wymagane pola 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 · PLN · 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

Podpis kanoniczny Link do sekcji Podpis kanoniczny

Jeśli nie masz zapisanego pierwotnego tajnego klucza, użyj opcji Odzyskaj tajny klucz i natychmiast bezpiecznie zapisz nowy klucz.

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://izoneo.pl/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);

Złożone → Zwrócone Link do sekcji Złożone → Zwrócone

Dla płatności, anulowania i narastających zwrotów używaj tych samych zclid i order_id_hash. Nie zmieniaj końcowych sum ani pozycji.

Złożone · placed Opłacone · paid Anulowane · cancelled Częściowo zwrócone · partially_refunded Zwrócone · 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 do sekcji Sandbox V1

Wklej JSON V1, aby sprawdzić pola, sumy i dopasowanie do feedu bez tworzenia zamówienia ani wpływu na rozliczenia.

POST https://izoneo.pl/api/v1/conversions/sandbox
persisted = false billing_impact = false

Opcjonalny pomiar za pomocą JavaScript Link do sekcji Opcjonalny pomiar za pomocą JavaScript

Biblioteka zapisuje zclid po zgodzie i wysyła ze strony podziękowania tylko początkowe zdarzenie placed. Kolejne statusy wysyłaj bezpiecznie przez S2S.

Zgoda jest domyślnie wyłączona. Funkcja consent musi zwrócić true dopiero po uzyskaniu ważnej zgody użytkownika na analitykę.

Ładowanie i inicjalizacja

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

zoneo.track({
  order_id_hash: 'SERVER_HMAC_SHA256',
  currency: 'PLN',
  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>

Stan integracji Link do sekcji Stan integracji

Zaakceptowane i odrzucone zdarzenia z ostatnich 7 dni.

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": "PLN",
        "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

Ochrona danych osobowych Link do sekcji Ochrona danych osobowych

Najnowsze zamówienia odebrane przez Zoneo wyłącznie do analityki. Nie pokazujemy surowych identyfikatorów zamówień ani danych osobowych.

Na serwerze utwórz stabilny odcisk HMAC-SHA-256 wewnętrznego identyfikatora zamówienia, używając oddzielnego klucza. Nie wysyłaj surowego identyfikatora ani danych osobowych.

Zamówienia, przychód i wskaźniki pochodne są wyświetlane tylko przy aktywnym pomiarze konwersji. Służą wyłącznie do analityki i nie zmieniają rozliczeń CPC.

Jak połączyć pomiar

Zalecamy API server-to-server. JavaScript jest tylko opcjonalną zapasową ścieżką analityczną i działa wyłącznie po udzieleniu zgody na analitykę.