Contratto API V1
Raccomandiamo l’API server-to-server. JavaScript è solo un metodo analitico di riserva facoltativo e funziona esclusivamente dopo aver ottenuto il consenso alla misurazione analitica.
Contratto API V1 Link alla sezione Contratto API V1
Raccomandiamo l’API server-to-server. JavaScript è solo un metodo analitico di riserva facoltativo e funziona esclusivamente dopo aver ottenuto il consenso alla misurazione analitica.
Ordini, ricavi e metriche derivate vengono mostrati solo quando il monitoraggio delle conversioni è attivo. Servono esclusivamente per l’analisi e non modificano la fatturazione CPC.
schema_version
1.0
payload_contract
order_v1
Content-Type
application/json
request_limit
64 KiB
Come collegare la misurazione Link alla sezione Come collegare la misurazione
Raccomandiamo l’API server-to-server. JavaScript è solo un metodo analitico di riserva facoltativo e funziona esclusivamente dopo aver ottenuto il consenso alla misurazione analitica.
- 1 Salva il parametro zclid dell’URL di destinazione insieme al carrello o all’ordine per 30 giorni.
- 2 Sul server crea un’impronta HMAC-SHA-256 stabile dell’ID interno dell’ordine usando una chiave separata. Non inviare l’ID originale né dati personali.
- 3 Dopo la creazione dell’ordine, invia il JSON all’API e firma il corpo esatto della richiesta con la chiave segreta dell’integrazione.
- 4 Per pagamento, annullamento e rimborsi cumulativi riutilizza gli stessi zclid e order_id_hash. Mantieni invariati totali e righe finali.
La chiave segreta dell’integrazione viene mostrata una sola volta. Salvala nel gestore dei segreti sul server del negozio.
Consigliato: API server-to-server Link alla sezione Consigliato: API server-to-server
Il server del negozio invia gli ordini verificati, le variazioni di stato e i rimborsi direttamente a Zoneo. Non inserire mai la chiave segreta nel browser.
https://zoneo.it/api/v1/conversions
https://zoneo.it/api/v1/conversions/sandbox
Sul server crea un’impronta HMAC-SHA-256 stabile dell’ID interno dell’ordine usando una chiave separata. Non inviare l’ID originale né dati personali.
order_id_hash · PHP
$orderIdHash = hash_hmac(
'sha256',
"zoneo-order-v1\n".$internalOrderId,
$_ENV['ZONEO_ORDER_HASH_KEY'],
);
Esempio di richiesta Link alla sezione Esempio di richiesta
Dopo la creazione dell’ordine, invia il JSON all’API e firma il corpo esatto della richiesta con la chiave segreta dell’integrazione.
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": "it",
"expected_delivery_date": "2026-09-03"
}
| JSON | Campi obbligatori | 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 |
| items[] | Campi obbligatori | 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
Firma canonica Link alla sezione Firma canonica
Se non hai salvato la chiave segreta originale, usa Ripristina chiave segreta e salva subito la nuova chiave in modo sicuro.
| 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.it/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);
Creato → Rimborsato Link alla sezione Creato → Rimborsato
Per pagamento, annullamento e rimborsi cumulativi riutilizza gli stessi zclid e order_id_hash. Mantieni invariati totali e righe finali.
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 alla sezione Sandbox V1
Incolla un JSON V1 per verificare campi, totali e abbinamento al feed senza creare un ordine o influire sulla fatturazione.
https://zoneo.it/api/v1/conversions/sandbox
Misurazione facoltativa tramite JavaScript Link alla sezione Misurazione facoltativa tramite JavaScript
La libreria salva zclid dopo il consenso e invia solo l’evento placed iniziale dalla pagina di ringraziamento. Invia gli stati successivi in modo sicuro via S2S.
Il consenso è disattivato per impostazione predefinita. La funzione consent deve restituire true solo dopo aver ottenuto un valido consenso dell’utente alla misurazione analitica.
Caricamento e inizializzazione
<script src="https://zoneo.it/integrations/zoneo-conversion-v1.js"></script>
<script>
const zoneo = window.ZoneoConversions.init({
integrationId: 'zci_...',
apiBase: 'https://zoneo.it/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>
Stato dell’integrazione Link alla sezione Stato dell’integrazione
Eventi accettati e rifiutati negli ultimi 7 giorni.
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
Protezione dei dati Link alla sezione Protezione dei dati
Gli ultimi ordini ricevuti da Zoneo solo a fini analitici. ID ordine originali e dati personali non vengono mai mostrati.
Sul server crea un’impronta HMAC-SHA-256 stabile dell’ID interno dell’ordine usando una chiave separata. Non inviare l’ID originale né dati personali.
Ordini, ricavi e metriche derivate vengono mostrati solo quando il monitoraggio delle conversioni è attivo. Servono esclusivamente per l’analisi e non modificano la fatturazione CPC.
Come collegare la misurazione
Raccomandiamo l’API server-to-server. JavaScript è solo un metodo analitico di riserva facoltativo e funziona esclusivamente dopo aver ottenuto il consenso alla misurazione analitica.