Към основното съдържание

API договор V1

Препоръчваме server-to-server API. JavaScript е само опционален резервен аналитичен канал и работи единствено след предоставяне на аналитично съгласие.

API договор V1 Връзка към раздел API договор V1

Препоръчваме server-to-server API. JavaScript е само опционален резервен аналитичен канал и работи единствено след предоставяне на аналитично съгласие.

Поръчките, приходите и производните показатели се показват само при активно измерване на конверсии. Те са само за анализ и не променят CPC фактурирането.

schema_version

1.0

payload_contract

order_v1

Content-Type

application/json

request_limit

64 KiB

Как да свържете измерването Връзка към раздел Как да свържете измерването

Препоръчваме server-to-server API. JavaScript е само опционален резервен аналитичен канал и работи единствено след предоставяне на аналитично съгласие.

  1. 1 Запазете параметъра zclid от целевия URL адрес към количката или поръчката за 30 дни.
  2. 2 На сървъра създайте стабилен HMAC-SHA-256 отпечатък на вътрешния идентификатор на поръчката с отделен ключ. Не изпращайте необработения идентификатор или лични данни.
  3. 3 След създаване на поръчката изпратете JSON към API и подпишете точното тяло на заявката с тайния ключ за интеграцията.
  4. 4 При плащане, отказ и натрупващи се възстановявания използвайте същите zclid и order_id_hash. Не променяйте крайните суми и редовете.

Тайният ключ за интеграцията се показва само веднъж. Запазете го в мениджър за тайни на сървъра на магазина.

Препоръчително: server-to-server API Връзка към раздел Препоръчително: server-to-server API

Сървърът на магазина изпраща проверени поръчки, промени в състоянието и възстановявания на суми директно към Zoneo. Никога не поставяйте тайния ключ в браузъра.

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

На сървъра създайте стабилен HMAC-SHA-256 отпечатък на вътрешния идентификатор на поръчката с отделен ключ. Не изпращайте необработения идентификатор или лични данни.

order_id_hash · PHP

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

Пример за заявка Връзка към раздел Пример за заявка

След създаване на поръчката изпратете JSON към API и подпишете точното тяло на заявката с тайния ключ за интеграцията.

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": "bg",
    "expected_delivery_date": "2026-09-03"
}
order_v1 · JSON
JSON Задължителни полета 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[] Задължителни полета 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

Каноничен подпис Връзка към раздел Каноничен подпис

Ако не сте запазили първоначалния таен ключ, използвайте „Възстановяване на тайния ключ“ и незабавно съхранете сигурно новия ключ.

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

Създадена → Възстановена Връзка към раздел Създадена → Възстановена

При плащане, отказ и натрупващи се възстановявания използвайте същите zclid и order_id_hash. Не променяйте крайните суми и редовете.

Създадена · placed Платена · paid Отказана · cancelled Частично възстановена · partially_refunded Възстановена · 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 Връзка към раздел Sandbox V1

Поставете V1 JSON, за да проверите полетата, сумите и съпоставянето с фийда, без да създавате поръчка или фактура.

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

Опционално измерване чрез JavaScript Връзка към раздел Опционално измерване чрез JavaScript

Библиотеката запазва zclid след съгласие и изпраща само началното събитие placed. Следващите състояния изпращайте защитено чрез S2S.

Съгласието е изключено по подразбиране. Функцията consent трябва да връща true само след валидно аналитично съгласие от потребителя.

Зареждане и инициализация

<script src="https://zoneo.bg/integrations/zoneo-conversion-v1.js"></script>
<script>
const zoneo = window.ZoneoConversions.init({
  integrationId: 'zci_...',
  apiBase: 'https://zoneo.bg/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>

Състояние на интеграцията Връзка към раздел Състояние на интеграцията

Приети и отхвърлени събития през последните 7 дни.

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

Защита на личните данни Връзка към раздел Защита на личните данни

Последните аналитични поръчки, получени от Zoneo. Не показваме оригинални номера на поръчки или лични данни.

На сървъра създайте стабилен HMAC-SHA-256 отпечатък на вътрешния идентификатор на поръчката с отделен ключ. Не изпращайте необработения идентификатор или лични данни.

Поръчките, приходите и производните показатели се показват само при активно измерване на конверсии. Те са само за анализ и не променят CPC фактурирането.

Как да свържете измерването

Препоръчваме server-to-server API. JavaScript е само опционален резервен аналитичен канал и работи единствено след предоставяне на аналитично съгласие.