Перейти до основного вмісту

Контракт API V1

Рекомендуємо API server-to-server. JavaScript є лише необов’язковим резервним аналітичним каналом і працює тільки після надання аналітичної згоди.

Контракт API V1 Посилання на розділ Контракт API V1

Рекомендуємо API server-to-server. JavaScript є лише необов’язковим резервним аналітичним каналом і працює тільки після надання аналітичної згоди.

Замовлення, дохід і похідні показники відображаються лише за активного вимірювання конверсій. Вони призначені тільки для аналітики й не змінюють CPC-рахунки.

schema_version

1.0

payload_contract

order_v1

Content-Type

application/json

request_limit

64 KiB

Як підключити вимірювання Посилання на розділ Як підключити вимірювання

Рекомендуємо API server-to-server. JavaScript є лише необов’язковим резервним аналітичним каналом і працює тільки після надання аналітичної згоди.

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

Секретний ключ інтеграції відображається лише один раз. Збережіть його в менеджері секретів на сервері магазину.

Рекомендовано: API server-to-server Посилання на розділ Рекомендовано: API server-to-server

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

POST https://zoneo.com.ua/api/v1/conversions
Sandbox https://zoneo.com.ua/api/v1/conversions/sandbox

На сервері створіть стабільний відбиток HMAC-SHA-256 внутрішнього ID замовлення за допомогою окремого ключа. Не надсилайте необроблений ID або персональні дані.

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": "UAH",
    "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": "uk",
    "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 · UAH
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 · UAH · 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.com.ua/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

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

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

Необов’язкове вимірювання через JavaScript Посилання на розділ Необов’язкове вимірювання через JavaScript

Бібліотека зберігає zclid після згоди й надсилає зі сторінки подяки лише початкову подію placed. Подальші стани надсилайте безпечно через S2S.

Згоду за замовчуванням вимкнено. Функція consent має повертати true лише після дійсної аналітичної згоди користувача.

Завантаження та ініціалізація

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

zoneo.track({
  order_id_hash: 'SERVER_HMAC_SHA256',
  currency: 'UAH',
  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": "UAH",
        "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 лише для аналітики. Початкові ID замовлень і персональні дані не відображаються.

На сервері створіть стабільний відбиток HMAC-SHA-256 внутрішнього ID замовлення за допомогою окремого ключа. Не надсилайте необроблений ID або персональні дані.

Замовлення, дохід і похідні показники відображаються лише за активного вимірювання конверсій. Вони призначені тільки для аналітики й не змінюють CPC-рахунки.

Як підключити вимірювання

Рекомендуємо API server-to-server. JavaScript є лише необов’язковим резервним аналітичним каналом і працює тільки після надання аналітичної згоди.