B2B API Manuale

Manuale di integrazione per i partner B2B — versione 1.0.

Questo manuale descrive come trasmettere ordini al sistema Drako tramite API REST/JSON su HTTPS. Le credenziali (chiave + secret) sono fornite da Drako per singolo cliente e sono gestibili dalla tua area riservata (sezione “API Import Ordini”).

1. Panoramica

Il servizio permette al tuo gestionale di inviare ordini a Drako in automatico (tipicamente con uno script schedulato), senza inserimento manuale. Per ogni ordine ricevuto Drako crea l'ordine, impegna la merce dal magazzino e risponde con il numero d'ordine Drako. È pensato in particolare per gli ordini in dropshipping (spedizione diretta al cliente finale).

Cosa non devi gestire: i prezzi (li applica Drako col tuo listino riservato), la numerazione degli ordini, il calcolo dell'IVA.

2. Endpoint

OperazioneMetodoURL
Import ordiniPOST/drako_catalog/api/v1/import.php
Annulla ordinePOST/drako_catalog/api/v1/cancel.php
Sblocca ordine on-holdPOST/drako_catalog/api/v1/release.php
Stato ordinePOST/drako_catalog/api/v1/status.php

Base produzione: https://www.drako.it/drako_catalog/api/v1/. Tutte le chiamate in HTTPS, Content-Type: application/json, testo UTF-8.

3. Autenticazione

Ogni richiesta richiede tre header:

  • X-Drako-Key — la chiave API fornita da Drako
  • X-Drako-Timestamp — Unix epoch in secondi al momento della chiamata
  • X-Drako-Signature — firma HMAC-SHA256 (esadecimale) calcolata così:
stringa_da_firmare = X-Drako-Timestamp + "\n" + corpo_grezzo_della_richiesta
X-Drako-Signature  = HMAC_SHA256( secret , stringa_da_firmare )   // esadecimale minuscolo

Il secret è il segreto condiviso (diverso dalla chiave). Firma e invia lo stesso identico corpo, byte per byte. Sincronizza l'orologio: il timestamp deve essere entro ±300 secondi dall'ora del server (anti-replay).

Esempio PHP:

$ts   = (string) time();
$body = json_encode($payload);
$sig  = hash_hmac('sha256', $ts . "\n" . $body, $secret);

Esempio Python:

import time, hmac, hashlib, json
ts = str(int(time.time()))
body = json.dumps(payload)
sig = hmac.new(secret.encode(), (ts + "\n" + body).encode(), hashlib.sha256).hexdigest()

3.1 Modalità Sandbox (test) vs Live

Il tuo account ha due set di credenziali (come Stripe/PayPal): la chiave Live (prefisso drk_live_) crea ordini reali e impegna lo stock; la chiave Sandbox (drk_test_) simula tutto — validazione completa (prodotti, prezzi, disponibilità in sola lettura) ma nessun ordine reale e nessuno scarico di magazzino. La modalità è decisa dalla chiave usata; in sandbox la risposta ha "sandbox": true e orders_id: null. Usa la chiave sandbox per integrare e collaudare in sicurezza, poi passa alla chiave live. Annulla/sblocca/stato in sandbox operano solo sugli ordini sandbox: le due modalità sono completamente separate.

Esempio risposta sandbox (orders_id: null è normale, NON un errore):

{ "ok": true, "results": [ { "ok": true, "sandbox": true, "reference": "ORD-2026-000123", "orders_id": null, "status": "created", "total": 244.00, "backorder": [], "message": "SANDBOX: ordine simulato" } ] }

4. Import ordini — corpo richiesta

{
  "orders": [
    {
      "reference": "ORD-2026-000123",
      "hold": false,
      "payment_note": "Bonifico",
      "shipping": {
        "name": "Mario Rossi", "company": "",
        "street": "Via Roma 10", "postcode": "20100",
        "city": "Milano", "state": "MI", "country": "IT",
        "phone": "0212345678", "email": "[email protected]"
      },
      "lines": [
        { "sku": "DRK-ABC-123", "qty": 2 },
        { "sku": "DRK-XYZ-999", "ean": "4012345678901", "qty": 1 }
      ],
      "notes": "Consegna piano terra"
    }
  ]
}

Campi ordine:

  • reference (obbligatorio, max 96, solo ASCII: lettere, cifre, . _ - /) — identificativo univoco tuo. Garantisce l'idempotenza: reinviare lo stesso reference NON crea duplicati; lo stesso reference con contenuto diverso viene rifiutato (duplicate_reference_mismatch).
  • hold (bool) — true = ordine in SOSPESO (on-hold): impegna la merce ma resta fuori dalla lavorazione finché non lo sblocchi o annulli. Default false.
  • payment_note — nota libera (es. “Bonifico”). Solo informativa.
  • shipping (obbligatorio) — destinatario spedizione (per i drop = cliente finale).
  • lines (obbligatorio, min 1) — righe prodotto.
  • notes — note operative riportate sull'ordine.

Campi shipping: obbligatori name, street, postcode, city; facoltativi company, state (sigla provincia, consigliato), country (ISO2, default IT), phone, email.

Identificazione prodotto: sku = codice prodotto Drako (campo primario). ean facoltativo: se fornito insieme allo sku viene usato come controllo incrociato (se non corrisponde, la riga — e l'ordine — viene rifiutata). I codici si ottengono dal feed catalogo per-cliente.

Prezzi: non vanno trasmessi. Drako applica il listino riservato del tuo account + IVA. Se un prodotto non ha prezzo riservato, la riga viene rifiutata con errore esplicito.

Articolo non disponibile: l'ordine viene comunque creato e l'articolo va in backorder; la risposta segnala i codici in backorder. Un prodotto disabilitato a catalogo viene invece rifiutato (product_inactive), non va in backorder.

Limiti: max 200 ordini per chiamata; rate limit predefinito 120 richieste/minuto.

5. Import ordini — risposta

{
  "ok": true,
  "summary": { "received": 1, "created": 1, "duplicate": 0, "errors": 0 },
  "results": [
    {
      "ok": true, "reference": "ORD-2026-000123",
      "orders_id": 2017139001, "status": "created",
      "on_hold": false, "total": 244.00, "backorder": [],
      "message": "Ordine creato"
    }
  ]
}

orders_id = numero d'ordine Drako confermato. status = created (flusso normale) oppure onhold. Ogni ordine è processato indipendentemente: un errore su un ordine non blocca gli altri. Ordine già ricevuto: "duplicate": true con l'orders_id originale.

6. Ordini on-hold (SOSPESO) e finestra di cancellazione

Con "hold": true l'ordine entra in stato SOSPESO: impegna la merce ma è ignorato dalla preparazione finché non viene sbloccato o annullato. Lo sblocco/annullamento avviene via API (release.php / cancel.php) oppure manualmente lato Drako.

Finestra massima: 48 ore dall'import. Trascorse le 48h senza conferma, l'ordine on-hold viene annullato e la merce torna disponibile. La cancellazione via API è consentita solo per ordini in stato Sospeso o Registrato (non ancora in lavorazione); negli altri stati l'API risponde not_cancellable e la modifica va richiesta agli operatori Drako.

7. Annulla / Sblocca / Stato

Annulla (cancel.php) — ripristina lo stock:

{ "reference": "ORD-2026-000123" }   // oppure { "references": ["...","..."] }

Sblocca (release.php) — da SOSPESO a flusso normale:

{ "reference": "ORD-2026-000123" }

Stato (status.php):

{ "references": ["ORD-2026-000123"] }

La risposta riporta, per ogni reference: orders_id, import_status, order_status_id, order_status (testo), on_hold, hold_expires_at e le date.

8. Codici di errore

HTTPerrorSignificato
400https_requiredConnessione non HTTPS
400invalid_json / too_many_ordersBody non valido / oltre 200 ordini
401missing_token / invalid_tokenHeader X-Drako-Key assente o non valido
401missing_timestamp / timestamp_skewTimestamp assente o fuori finestra
401bad_signatureFirma HMAC non valida
403ip_not_allowedIP sorgente non autorizzato
429rate_limitedTroppe richieste

Errori a livello di singolo ordine (in results, HTTP 200): invalid_reference, no_lines, invalid_shipping, invalid_qty, product_not_found, product_sku_ean_mismatch, no_group_price, not_cancellable, not_on_hold, not_found, product_inactive, duplicate_reference_mismatch, in_progress, claim_failed, state_update_failed (errori temporanei interni: ritentare).

9. Esempio completo (curl)

KEY="drk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"   # produzione; per i test usa la chiave drk_test_
SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
TS=$(date +%s)
BODY='{"orders":[{"reference":"ORD-2026-000123","hold":false,"shipping":{"name":"Mario Rossi","street":"Via Roma 10","postcode":"20100","city":"Milano","state":"MI","country":"IT"},"lines":[{"sku":"DRK-ABC-123","qty":2}]}]}'
SIG=$(printf '%s\n%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')

curl -X POST "https://www.drako.it/drako_catalog/api/v1/import.php" \
  -H "X-Drako-Key: $KEY" -H "X-Drako-Timestamp: $TS" -H "X-Drako-Signature: $SIG" \
  -H "Content-Type: application/json" --data-binary "$BODY"

10. FAQ

Posso reinviare lo stesso ordine? Sì: se il reference è già stato ricevuto, Drako non crea un duplicato e restituisce l'orders_id originale.

Articolo esaurito? L'ordine viene creato e l'articolo va in backorder; la risposta elenca i codici.

Ordini in attesa di pagamento? Inviali con "hold": true: restano in SOSPESO finché li confermi (release) o annulli (cancel). Limite 48h.

Ho perso la chiave. Rigenerala dalla tua area cliente (sezione “API Import Ordini”): la vecchia smette di funzionare.

Errore bad_signature? Verifica: stesso body firmato e inviato; formula HMAC_SHA256(secret, timestamp + "\n" + body) in esadecimale; orologio sincronizzato.

Per assistenza tecnica contatta il tuo riferimento commerciale Drako.