Hoppa till huvudinnehållet
V1 Teknisk dokumentation

API-avtal V1

Vi rekommenderar server-till-server-API. JavaScript är endast en valfri reservlösning för analys och fungerar bara efter att analytiskt samtycke har lämnats.

API-avtal V1 Länk till avsnittet API-avtal V1

Vi rekommenderar server-till-server-API. JavaScript är endast en valfri reservlösning för analys och fungerar bara efter att analytiskt samtycke har lämnats.

Beställningar, intäkter och härledda nyckeltal visas endast när konverteringsmätningen är aktiv. De används bara för analys och ändrar inte CPC-faktureringen.

schema_version

1.0

payload_contract

order_v1

Content-Type

application/json

request_limit

64 KiB

Så ansluter du mätningen Länk till avsnittet Så ansluter du mätningen

Vi rekommenderar server-till-server-API. JavaScript är endast en valfri reservlösning för analys och fungerar bara efter att analytiskt samtycke har lämnats.

  1. 1 Spara parametern zclid från mål-URL:en tillsammans med varukorgen eller beställningen i 30 dagar.
  2. 2 Skapa ett stabilt HMAC-SHA-256-fingeravtryck av det interna beställnings-ID:t på servern med en separat nyckel. Skicka inte det oförändrade ID:t eller personuppgifter.
  3. 3 När beställningen har skapats skickar du JSON till API:et och signerar den exakta begärandetexten med integrationens hemliga nyckel.
  4. 4 Återanvänd samma zclid och order_id_hash för betalning, avbokning och kumulativa återbetalningar. Ändra inte slutsummor eller rader.

Integrationens hemliga nyckel visas endast en gång. Spara den i butikens serverbaserade secrets manager.

Rekommenderas: server-till-server-API Länk till avsnittet Rekommenderas: server-till-server-API

Butikens server skickar verifierade beställningar, statusändringar och återbetalningar direkt till Zoneo. Lägg aldrig den hemliga nyckeln i webbläsaren.

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

Skapa ett stabilt HMAC-SHA-256-fingeravtryck av det interna beställnings-ID:t på servern med en separat nyckel. Skicka inte det oförändrade ID:t eller personuppgifter.

order_id_hash · PHP

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

Exempel på begäran Länk till avsnittet Exempel på begäran

När beställningen har skapats skickar du JSON till API:et och signerar den exakta begärandetexten med integrationens hemliga nyckel.

order_v1 · JSON

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

Kanonisk signatur Länk till avsnittet Kanonisk signatur

Om du inte har sparat den ursprungliga hemliga nyckeln använder du Återställ hemlig nyckel och sparar den nya nyckeln säkert direkt.

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.se/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);

Lagda → Återbetald Länk till avsnittet Lagda → Återbetald

Återanvänd samma zclid och order_id_hash för betalning, avbokning och kumulativa återbetalningar. Ändra inte slutsummor eller rader.

Lagda · placed Betald · paid Avbruten · cancelled Delvis återbetald · partially_refunded Återbetald · 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 Länk till avsnittet Sandbox V1

Klistra in V1 JSON för att säkert kontrollera fält, summor och flödesmatchning utan att skapa en beställning eller påverka faktureringen.

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

Valfri mätning via JavaScript Länk till avsnittet Valfri mätning via JavaScript

Biblioteket sparar zclid efter samtycke och skickar endast den första placed-händelsen från tacksidan. Skicka senare statusar säkert via S2S.

Samtycke är avstängt som standard. Funktionen consent måste returnera true först efter att användaren har lämnat ett giltigt analytiskt samtycke.

Laddning och initiering

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

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

Integrationsstatus Länk till avsnittet Integrationsstatus

Godkända och avvisade händelser under de senaste 7 dagarna.

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

Dataskydd Länk till avsnittet Dataskydd

De senaste beställningarna som Zoneo tagit emot enbart för analys. Råa order-ID:n och personuppgifter visas aldrig.

Skapa ett stabilt HMAC-SHA-256-fingeravtryck av det interna beställnings-ID:t på servern med en separat nyckel. Skicka inte det oförändrade ID:t eller personuppgifter.

Beställningar, intäkter och härledda nyckeltal visas endast när konverteringsmätningen är aktiv. De används bara för analys och ändrar inte CPC-faktureringen.

Så ansluter du mätningen

Vi rekommenderar server-till-server-API. JavaScript är endast en valfri reservlösning för analys och fungerar bara efter att analytiskt samtycke har lämnats.