Registro delle modifiche all'API
Changelog dell'API
Panoramica di tutte le modifiche e i miglioramenti apportati all'API REST di xoPort.
Versioni
v2.122.13 Versione attuale
20 ottobre 2026Correzioni di bug relativi allo stato del contratto, all'elenco dei prodotti per categoria e al conto di credito, oltre alla maschera dei client OAuth2 e allo sconto fedeltà nell'esportazione degli ordini di openTRANS. Confronto numerico dei numeri di versione: la versione 2.122.13 segue la versione 2.122.12. A partire dalla versione 4.9.174 dello Shop.
Contratti: stato del contratto
- ⚠️ Modificato: l’endpoint di stato
PUT /Import/JSON/contracts/{id}/status, l’oggettostatuse il campocontracts_status_idnell’importazione dei contratti verificano l’ID rispetto allo stato dei contratti dello Shop, come nel backend. Fino alla v2.122.12, l’endpoint di stato e l’oggetto effettuavano la verifica rispetto agli stati degli ordini, mentrecontracts_status_idveniva scritto senza alcuna verifica. È valido qualsiasi stato del contratto del negozio, anche uno disattivato. Leggere gli ID dacontracts_statuses[], daGET /Export/JSON/contractso daerror.valid_status_ids, mai da/order_statuses. - L'ID viene letto in modo rigoroso: un numero intero o una stringa di cifre; gli spazi a margine non vengono conteggiati.
true,[65],"1e3"o54.9non sono ID: all'endpoint di stato viene restituito un errore HTTP 400INVALID_STATUS, mentre nell'importazione del contratto viene visualizzato l'avvisoCONTRACT_STATUS_UNKNOWN. Finora ne sono stati ricavati 1, 1, 1000 e 54.
| Caso | fino alla v2.122.12 | a partire dalla v2.122.13 |
|---|---|---|
| Stato del contratto che non esiste anche come stato dell’ordine, all’endpoint di stato | HTTP 400 INVALID_STATUS | scritto |
… nell’oggetto status dell’importazione del contratto | ignorato silenziosamente | scritto |
| ⚠️ ID che esistono solo come stato dell'ordine, nell'endpoint dello stato | come stato del contratto, new_status_name con il nome dello stato dell’ordine | HTTP 400 INVALID_STATUS |
⚠️ … nell’oggetto status dell’importazione del contratto | scritto come stato del contratto | Stato invariato, avviso CONTRACT_STATUS_UNKNOWN |
ID sconosciuto nell’oggetto status o status senza status_id | ignorato, il record è stato considerato come creato o modificato | Stato invariato, avviso CONTRACT_STATUS_UNKNOWN |
⚠️ contracts_status_id senza uno stato contrattuale valido (solo ID di stato dell’ordine, 0, "abc", true) | scritto senza verifica ("abc" pari a 0, true pari a 1) | non scritto, mentre gli altri campi sì; l'avviso CONTRACT_STATUS_UNKNOWN |
INVALID_STATUSindica gli ID validi nel messaggio e inerror.valid_status_ids. L'avvisoCONTRACT_STATUS_UNKNOWNè presente inwarnings[]e nella voce del record inrecords[], concontracts_idefield(status.status_id,statusocontracts_status_id). Il record continua a essere considerato creato o modificato, solo lo stato non è stato scritto.new_status_nameNella risposta dell’endpoint di stato è ora presente il nome dello stato del contratto.- Un "
contracts_status_id" valido viene registrato come in precedenza senza alcuna voce nella cronologia dello stato. Per registrare un cambio di stato con cronologia, utilizzare l'oggettostatuse l'endpoint dello stato. - ⚠️ Le integrazioni che finora hanno inviato un ID dello stato dell’ordine come stato del contratto ricevono ora un codice di stato HTTP 400 o l’avviso (righe contrassegnate con ⚠️). Ulteriori informazioni: Contratti.
Elenco prodotti per categoria
- ⚠️ Modificato:
/categories/{id}/productlistrestituisce esattamente questa categoria,/categories/{a}:{b}/productlistle categorie da a a b e/categories/{a}:/productlistle categorie a partire da a. Fino alla v2.122.12, con codice di stato HTTP 200 veniva restituito l’elenco dei prodotti di tutte le categorie, mentre per{id}veniva visualizzato l’avvisoRANGE_START_NOT_SINGLE_RECORD; tale avviso non è più presente. - ⚠️ L’uso di
?categories_id=in aggiunta all’ID o all’intervallo nel percorso genera un errore HTTP 400FILTER_NOT_APPLICABLE. È consentito solo lo stesso valore dell’ID del singolo percorso. Un?categories_id=vuoto o composto esclusivamente da spazi viene considerato come non inviato.
| Richiesta | fino alla v2.122.12 | a partire dalla v2.122.13 |
|---|---|---|
/categories/5/productlist | HTTP 200, tutte le categorie, avviso RANGE_START_NOT_SINGLE_RECORD | Categoria 5 |
/categories/5:10/productlist | HTTP 200, tutte le categorie | Categorie da 5 a 10 |
/categories/5/productlist?categories_id=5 | Categoria 5 | invariato Categoria 5 |
⚠️ /categories/5/productlist?categories_id=7 | HTTP 200, categoria 7 | HTTP 400 FILTER_NOT_APPLICABLE |
⚠️ /categories/5:10/productlist?categories_id=5 | HTTP 200, categoria 5 | HTTP 400 FILTER_NOT_APPLICABLE |
/categories/productlist?categories_id=5 | Categoria 5 | invariato |
- ⚠️ Le richieste con ID o intervallo nel percorso e un
?categories_id=diverso ricevevano fino alla versione v2.122.12 la categoria del parametro, mentre ora ricevono un codice HTTP 400 (righe contrassegnate con ⚠️). Inviare la categoria nel percorso o come parametro. - Senza
?language=, il nome della categoria viene visualizzato nella lingua con il valore più basso dilanguages_id(negli shop XONIC 1 = inglese), non nella lingua predefinita dello shop. Finora l’ordine delle righe nella tabella delle lingue era determinante, ma poteva variare, ad esempio dopo la cancellazione e la ricreazione di una lingua. Inviare un’e-mail a?language=se la lingua è importante. Ulteriori informazioni: Categorie.
Conto crediti: filtro per fonte
- ⚠️ Modificato:
GET /Export/JSON/wallet_logs?source=solo con uno spazio (?source=%20) significa «non impostato», come indicato su/orders?source=. Fino alla v2.122.12 l’endpoint filtrava quindi in base a una fonte vuota e forniva solitamente un elenco vuoto.
| Richiesta | fino alla v2.122.12 | a partire dalla v2.122.13 |
|---|---|---|
/wallet_logs?source=%20 | Filtro su una fonte vuota, solitamente un elenco vuoto | come se non ci fosse alcun filtro source |
/wallet_logs?source=0 | Il filtro viene ignorato, come se non ci fosse source | solo voci con la fonte 0 (di solito una lista vuota) |
- Invariato:
?source=con un altro valore; gli spazi vuoti ai margini del valore non venivano già conteggiati in precedenza.
Backend: client OAuth2
- Nessuna modifica all’API. A partire dalla versione 4.9.174 di Shop, la funzione «Modifica client» mostra all’amministratore, per un client illimitato, un campo vuoto con l’indicazione «Illimitato (impostato da XONIC)», e se salvato vuoto il client rimane illimitato. ⚠️ Fino alla versione Shop 4.9.173 il valore era 5000 e ogni salvataggio da parte dell’amministratore scriveva 5000, anche se venivano modificati solo il nome o la nota. Inoltre: client OAuth2, sezione «Limite di richieste».
- Se l’amministratore di XONIC crea un client con il campo vuoto, ora il client è sempre illimitato; fino alla versione 4.9.173 di Shop, a seconda dello schema del database, gli veniva assegnato il valore 5000.
- Durante la creazione di un client, il nome e la nota vengono salvati senza backslash aggiuntivo (
O'Reillyinvece diO\'Reilly).
Interfaccia XML: sconto fedeltà in openTRANS
- ⚠️ Modificato: l’esportazione degli ordini con il modello openTRANS (
/Export/XML/order/{id}/opentrans) riporta lo sconto fedeltà (ot_loyalty_discount) come detrazione, come voce simile alle altre righe di totale, e lo include inTOTAL_ITEM_NUM. Fino alla v2.122.12 il modello richiedevaot_loyality_discount(errore di battitura): La detrazione mancava e le voci risultavano maggiorate di tale importo rispetto aTOTAL_AMOUNT. - Rimangono invariati: il calcolo delle righe di totale, l’esportazione JSON e gli altri modelli XML. Le varianti personalizzate del modello che hanno ripreso l’elenco delle righe di totale da
orders-opentrans.xslmantengono l’errore di battitura.
v2.122.12
19 ottobre 2026Correzione di un errore: i parametri di query e i segmenti di percorso vengono considerati così come vengono verificati dal negozio. Confronto numerico dei numeri di versione: la versione 2.122.12 segue la versione 2.122.11. A partire dalla versione 4.9.173 del negozio.
Spazio vuoto a margine: vale il valore verificato
- Modificato: la verifica dei valori (a partire dalla v2.122.10) valuta ogni valore senza spazi ai margini: spazio (nell’indirizzo anche
+), tabulatore%09, interruzione di riga%0A/%0D,%00e%0B. Fino alla versione v2.122.11, molti endpoint leggevano il valore non troncato e un valore che superava il controllo veniva interpretato in modo diverso. Ora, nell'endpoint, viene applicato esattamente il valore verificato, per le operazioni di esportazione, importazione ed eliminazione. - Modificato: Un valore vuoto o costituito solo da spazi vuoti significa «non impostato» per ogni parametro con regola fissa (numero, ID, pulsante, valore di selezione, data, ora, lingua, nome file, lettere e cifre), anche negli endpoint che finora verificavano solo la presenza del parametro.
| Richiesta | fino alla v2.122.11 | a partire dalla v2.122.12 |
|---|---|---|
?_strict=%20true durante l’importazione | modalità rigorosa disattivata, l’importazione ha scritto in parte | in modalità rigorosa |
?_strict=true%0A durante l'esportazione, con filtro o campo sconosciuto | HTTP 200 con avviso | HTTP 400 come con ?_strict=true |
/tickets?type=%20job | ticket e lavori | solo lavori |
/categories?parent_id=5%00, così come i filtri numerici e di selezione su contratti, ticket, progetti, attività, scadenze e altri endpoint | Filtro omesso | Il filtro è attivo |
/products?bundles=%201, così come marketplaces e bonus_free_features | il blocco mancava | Blocco presente |
/products_options_values?orphaned=%20true | tutti i valori | solo quelli orfani |
/porters?status=%20, /products_options?listing_status=%20 | filtrati a 0, quindi per i Porter quelli inattivi | non impostati |
/porters?status=%001, /products_options_values?option_id=%005 (%00 prima del numero) | interpretati come 0: i Porter inattivi o i valori dell’attributo 0 | il valore inviato |
/faqs?language=, così come /faqcats, /cms, /sliders e /categories?language=%20 | un elenco vuoto | tutte le lingue, come se non ci fosse nulla language |
/medias?entity_type= | un elenco vuoto con una nota | le immagini dei prodotti, come senza entity_type |
/products_options?with_values= rispettivamente %20 | HTTP 400 | non impostato |
GET /seohistorys?type=%20p | Voci di tutti i tipi | solo tipo p |
DELETE /seohistorys?type=p&base_id=42%00 | ha eliminato ogni voce del tipo p | solo le voci relative all'articolo 42 |
DELETE /seohistorys?type=%20p&base_id=42 | ha eliminato le voci di ogni tipo relative all'ID 42 | solo quelle di tipo p con ID 42 |
⚠️ DELETE /seohistorys?type=%20p senza ulteriori filtri, così come ?base_id=42%00 o ?expired=1%00 da soli | HTTP 400 MISSING_FILTER, nulla cancellato | elimina tutte le voci di tipo p con ID 42 o tutte quelle scadute |
⚠️ DELETE /medias?entity_id=7%00 | HTTP 400 NO_TARGETS oppure solo gli ID dal corpo del messaggio | inoltre tutte le immagini dell’articolo 7 |
⚠️ DELETE /ticket_department/{id}?reassign_to=%005 | HTTP 409 DEPARTMENT_IN_USE | Ticket spostati al reparto 5, reparto cancellato |
- ⚠️ Un comando Delete non cancella mai più di quanto indicato dai valori verificati, ma cancella più rispetto alla versione v2.122.11: le richieste che in precedenza venivano respinte per mancanza di una condizione valida, ora vengono elaborate (righe contrassegnate con ⚠️).
- Invariati: valori senza spazi ai margini, testo libero (termini di ricerca, nomi, codici), filtri con verifica autonoma dei valori (filtri per prodotto, cliente e coupon; per gli ordini, data e paese di consegna; in questi casi il valore verificato era già valido), nonché scorrimento e ordinamento. Tutti i casi: API di esportazione, sezione «Spazio libero ai margini».
Segmento di percorso nell’esportazione JSON
- Modificato: il segmento successivo all’endpoint è un numero intero con un massimo di 18 cifre (
/product/42), un intervallo con limiti interi (/orders/100:200,/orders/100:),new:{datum}per clienti e ordini oppure il sottoperCORSOproductlistper/categories. Qualsiasi altra combinazione genera un errore HTTP 400INVALID_RANGEe il messaggio riporta il nome del segmento. Fino alla versione v2.122.11, un segmento non valido con codice di stato HTTP 200 restituiva l’elenco sfogliato. - Lo spazio vuoto ai margini del segmento non viene conteggiato:
/product/42%20è l’articolo 42. Un segmento composto esclusivamente da spazio vuoto genera un errore HTTP 400.
| Richiesta | fino alla v2.122.11 | dalla v2.122.12 |
|---|---|---|
/product/42%20, /order/42%0A | HTTP 200, l’elenco | Record 42 |
/product/42x, /order/42%2B, /product//42, /products/productlist | HTTP 200, l'elenco | HTTP 400 INVALID_RANGE |
⚠️ /product/42.0, /order/+5, /product/1e3, /products/1.5:3 | Record 42, 5 o 1000, intervallo da 1 a 3 | HTTP 400 INVALID_RANGE |
⚠️ /orders/new%3A2026-10-01 (codificato con i due punti) | HTTP 200, l'elenco completo anziché il delta | HTTP 400 INVALID_RANGE |
⚠️ /contracts/10/20 | Contratti a partire da 10 senza limite massimo | HTTP 400; l'intervallo è /contracts/10:20 |
/categories/5/Productlist, /product/42/x | Categoria 5 o articolo 42 | HTTP 400 INVALID_RANGE |
/orders/ con 19 o più cifre | un limite al di là di qualsiasi ID; a partire da 309 cifre, l'elenco completo | HTTP 400 INVALID_RANGE |
- ⚠️ Anche le integrazioni che finora ricevevano il record di dati previsto ricevono ora un HTTP 400 (righe contrassegnate con ⚠️): inviare l’ID come numero intero senza decimali e senza segno, tipico per i valori provenienti da tabelle. Inviare i due punti dopo
newnon codificati. /categories/{id}/productlistrimane consentito, ma non valuta l’ID: la risposta contiene tutte le categorie (a partire dalla v2.122.13 filtro per categoria, vedere lì). Per recuperare una categoria utilizzare/categories/productlist?categories_id={id}.- Invariato: esportazione in formato XML, CSV e TXT (in cui un segmento senza numero corrisponde al nome di un modello), importazione ed eliminazione. Inviare gli ID anche durante l’eliminazione come numeri interi.
v2.122.11
18 ottobre 2026Terza parte delle estensioni per l’integrazione con i sistemi di gestione delle scorte e l’automazione, soprattutto in fase di scrittura. Confronto numerico dei numeri di versione: la versione 2.122.11 segue la versione 2.122.10. A partire dalla versione 4.9.171 di Shop.
Ordini
- Modificato: se un’integrazione invia i prezzi delle voci con l’
tax_flage 1 (lordo), lo Shop ora salva la voce al netto, come in un ordine proveniente dal registratore di cassa, così come i propri sovrapprezzi per caratteristiche. Finora nella voce era indicato il prezzo lordo e l’editor degli ordini, il PDF della fattura, l’e-mail dell’ordine e il successivo allegato delle voci applicavano l’imposta una seconda volta.orders:readfornisce quindi tali voci al netto (products_price,final_price,attributes[].options_values_price; da 10,00 al 19% diventa8.40336134). Le interfacce che leggono questi campi e li confrontano con i dati inviati effettuano la conversione. I totali dell’ordine rimangono invariati. - In due casi ora prevale il valore del registratore di cassa: il sovrapprezzo delle caratteristiche preselezionate (
apply_default_attributes) su una voce di questo tipo viene conteggiato ai fini fiscali, e una tabella delle spese di spedizione in base al valore della merce (compute_shipping) calcola sul valore al netto. Di conseguenza, le spese di spedizione e l’importo totale possono variare; unexpected_totaladattato al vecchio valore segnala quindiTOTAL_DRIFT. Gli ordini esistenti non vengono ricalcolati; se si aggiunge qualcosa a un ordine precedente con voci salvate al lordo, la doppia imposta su di esse rimane in vigore. - Novità: campo «
service» (Tipo di posizione) durante la creazione (POSTePUTconproducts_mode: "append"):1= servizio,0= merce, anchetrue/falseoppure"1"/"0". Il valore inviato ha la precedenza sui dati del prodotto, ad esempio nel caso di una voce di servizio libera senzaproducts_idper un cliente aziendale in un altro paese dell’UE. In assenza di questo campo, si applica come in precedenza la regola del prodotto: una voce libera è considerata merce. Un valore diverso genera l’avviso «service_invalid» inrecords[].warnings. Finora il campo veniva ignorato come «UNKNOWN_FIELD». - Modificato: «
products_mode: "update"» rifiuta «service». Il record viene rifiutato con l’errore «FIELD_NOT_UPDATABLE», non viene scritto nulla, nemmeno nei campi rimanenti. Finora veniva visualizzato un avviso e il record veniva considerato «updated». - Modificato: la riga di spedizione di un ordine al netto (
tax_flag0) riportatax0 e l’aliquota fiscale intax2, come un ordine al netto proveniente dal registratore di cassa; anche gli ordini esenti da imposta (tax_flag2) riportano 0 in modalitàverbatime 0. Chi legge l’aliquota di spedizione solo datotals[].tax, per gli ordini al netto utilizzatax2. I totali rimangono invariati, così come gli ordini salvati. La fattura elettronica di tali ordini riporta ora la spedizione con l’importo corretto. - Quando si aggiungono articoli tramite
PUT, ora viene inclusa anche l’imposta di spedizione di un ordine al netto proveniente dalla cassa; in precedenza mancava dal totale.
Clienti: disattivazione della newsletter
- Novità:
customers_nl_lockè modificabile tramitePOST/PUT /customers:0/1,true/falseo"0"/"1". Il valore esportato può essere rinviato, anche con?_strict=true. Se il valore manca o ènullovvero vuoto, il blocco rimane invariato. Un valore non valido genera l’avvisoINVALID_FIELD_VALUE, mentre il resto del record viene salvato. Finora il campo eraUNKNOWN_FIELD(con?_strict=trueHTTP 400). - Modificato:
1cancella ogni abbonamento dell’account, sia nel negozio che presso il fornitore della newsletter. La disiscrizione viene quindi considerata come opposizione alla pubblicità e rimane valida anche dopo0; le importazioni successive rifiuteranno l’indirizzo. Anche un’esportazione restituita concustomers_nl_lock = 1comporta la cancellazione; presso il fornitore non è possibile annullare l’operazione, un abbonamento può essere ripristinato solo tramite una nuova conferma. Se il fornitore non riesce a elaborare la richiesta, la risposta riportaNEWSLETTER_UNSUBSCRIBE_FAILED; il blocco viene salvato, l’abbonamento rimane attivo.0revoca solo il blocco. - ⚠️ Le e-mail promozionali provenienti da Marketing & Automazioni (xoMarketing) non vengono ancora bloccate in Shop 4.9; questa funzionalità sarà disponibile con Shop 4.10.
- Le cancellazioni presso il fornitore avvengono direttamente nella richiesta stessa, una per ogni indirizzo. È quindi consigliabile suddividere in gruppi più piccoli i grandi lotti con molti account bloccati.
- Nel CSV-Porter (colonna «customers newsletter lock») e nell’importazione clienti XML (colonna
customers_nl_lock, solo con XSL personalizzato, rispostanewsletter.locked_removed) viene riportato anche1. A differenza di quanto avviene tramite API, in questi casi una cella vuota e qualsiasi altro valore revocano il blocco. Il messaggio di erroreNEWSLETTER_LOCKEDinviato aPOST /newsletter_subscribers(per i client concustomers:read, altrimentiNOT_SUBSCRIBABLE) indica ora la procedura per rimuovere il blocco:PUT /customersconcustomers_nl_lock = 0.
Progetti
- Novità:
relationships[]collega un progetto anche ai contratti (target_typecontracts_id). Finora un record di questo tipo generava un errore (“Invalid relationships”). - Modificato: non viene più creato un collegamento a un ordine, un ticket o un contratto inesistente, mentre il resto del record viene salvato;
warnings[]segnalaPROJECT_RELATIONSHIP. Chi reinvia un’esportazione tramitePUTperde i collegamenti alle destinazioni cancellate, poichéPUTsostituisce tutti i collegamenti. - Modificato: se
relationshipsnon è un elenco, il record non viene elaborato. FinoraPOSTcreava il progetto senza collegamenti, mentrePUTli eliminava silenziosamente tutti. L’esportazione fornisce ora solo collegamenti dei tre tipiorders_id,ticket_idecontracts_id.
Caratteristiche
- Se
POST/PUT /products_optionsmodifica un valore collegato anche a un'altra caratteristica, viene creato, come in precedenza, un clone con un nuovo ID. Il clone ora eredita dall'originale i valoriimageesort_idnon inviati; in precedenza riceveva un'immagine vuota e l'ordinamento 0. Prevalgono i valori inviati. I cloni già creati rimangono invariati: l’immagine e l’ordinamento devono essere aggiunti tramitePUT.
Prodotti: pacchetti
- Novità: campo
bundlesul prodotto con le impostazioni e i componenti di un bundle. L’esportazione lo fornisce solo con?bundles=1, anche nella consultazione singola e nelle sezioni; senza bundle vi comparenull.?bundles=accetta solo0o1, altrimenti HTTP 400. - Modificato: finora un
bundleinviato veniva ignorato comeUNKNOWN_FIELD. Ora il bundle lo modifica:nulllo rimuove,items[]sostituisce tutte le parti, senza la chiave tutto rimane invariato. Unbundlenon valido fa fallire l’intero record di dati (INVALID_BUNDLE), non viene scritto nulla, nemmeno il prezzo.bundle_auto_priceebundle_auto_price_percentnon sono presenti in Shop 4.9 (avvisoBUNDLE_SETTING_UNAVAILABLE). - Negozi provenienti da una versione precedente alla 4.9.155: dopo l’aggiornamento, aprire una volta il backend prima che l’integrazione scriva i bundle.
Prodotti: marketplace
- Novità:
?marketplaces=1fornisce per ogni articolomarketplaces[], una voce per ogni canale del negozio con stato e status:code,status,upload_status,sync_state,last_updated,external_id,messages[]e altri. In Shop 4.9,liveè semprenull. Un valore diverso da0/1genera un errore HTTP 400 invece dell’avvisoUNKNOWN_FILTER. - Novità: l'invio di
marketplaces[]aPOST/PUT /productsimposta l'opzione per ciascun canale (canale tramitecodeomarketplace_id,status,0/1); i canali non inviati rimangono invariati. La modifica viene applicata solo ai canali con licenza nel negozio. Finora la chiave eraUNKNOWN_FIELD. - L’impostazione ha effetto alla successiva sincronizzazione del canale: su Amazon, eBay, Kaufland e Idealo,
1crea un’offerta, mentre0la rimuove. I canali Mirakl e Shöpping.at non rimuovono le offerte su0; Mirakl crea un'offerta solo con dati Mirakl aggiornati; Check24, Etsy e i canali senza integrazione non trasferiscono nulla dal negozio (dettagli nella pagina Prodotti). Anche un’esportazione rinviata conmarketplaces[]include i campi relativi agli stati. UnPUTcontenente solo l’ID articolo (products_idoproducts_model) emarketplacesnon modifica la data di modifica dell’articolo; la riga del canale modificata viene contrassegnata per la sincronizzazione (last_updated1970-01-01 00:00:00). - Novità: filtro marketplace su
/products:?marketplace=con?marketplace_status=,?marketplace_upload_status=o?marketplace_sync_state=, ad esempio tutti gli articoli Idealo non aggiornati in un’unica richiesta. Finora i nomi venivano ignorati comeUNKNOWN_FILTERe l’elenco veniva restituito senza filtri. - Modifica (Idealo): un ritiro (
status0 tramite API, maschera articolo, CSV o XML) ora viene mantenuto anche in caso di disponibilità pari a 0. Viene reinserita solo un'offerta che il negozio ha disattivato autonomamente a causa di scorte pari a 0; successivamente rimane supendingfino alla successiva sincronizzazione. Se un filtro della sincronizzazione ha disattivato l'offerta (ad esempio per mancanza di immagine o GTIN), questa non viene ripristinata automaticamente dopo la correzione: inviare nuovamentestatus1. - Maschera articolo: le approvazioni e i dati del canale vengono salvati solo in caso di salvataggio riuscito. I dati di un canale che è stato attivato tra l’apertura e il salvataggio, ad esempio tramite API, vengono mantenuti. La maschera aperta in precedenza riporta comunque l’interruttore al proprio stato al momento del salvataggio: ricaricare le maschere aperte dopo un’autorizzazione tramite API.
Prodotti: selezione dei campi
- Novità:
?fields=nell’esportazione dei prodotti indica le chiavi per ciascun prodotto, ad esempio?fields=products_model,products_price,products_quantity;products_idviene sempre incluso. Vengono caricati solo i dati necessari: in un test, una pagina con 250 articoli è passata da 4,3 MB a 52 KB. Le chiavi non menzionate mancano del tutto, invece di essere vuote. È possibile inviare una selezione tramitePUT, che modifica solo gli elementi in essa contenuti. - Modificato: Chi invia già
?fields=ora riceve solo le chiavi specificate invece dell’intero set di dati con l’avvisoUNKNOWN_FILTER. Un elenco non valido genera un errore HTTP 400INVALID_FILTER_VALUE, un nome sconosciuto genera l’avvisoUNKNOWN_FIELD(con?_strict=truesi ottiene un errore HTTP 400).bundle,bonus_free_featuresemarketplacesrichiedono il nome tramite?fields=; il flag da solo non funziona in questo caso (avvisoSWITCH_IGNORED).
Limite di richieste
- Novità: ogni risposta inviata a un client con limite di richieste include le intestazioni
X-RateLimit-Limit,X-RateLimit-RemainingeX-RateLimit-Reset.GET /meriporta a questo propositorate_limit_window,rate_limit_remainingerate_limit_reset. - Modificato: in caso di codice di stato HTTP 429,
Retry-Afterindica i secondi che mancano alla prossima accettazione (da 1 a 3600) anziché un valore fisso di 3600, e la risposta riportaerror.retry_after. Il messaggio ora recita «Rate limit of N requests per 3600 s (sliding window) exceeded.»; Le integrazioni valutanoerror.code, non il testo. All’endpoint del token viene calcolato allo stesso modoRetry-After(da 1 a 300).
Indirizzo del negozio → ID
- Novità: filtri precisi per gli indirizzi del negozio:
?seo_string=su/categoriese/seohistorys,?seo_name=su/products. A un indirizzo proveniente dalla Search Console, da una vecchia Sitemap o da un’e-mail del cliente vengono così associati la categoria, l’articolo o la destinazione di un reindirizzamento. Finora venivano riportati i nomiUNKNOWN_FILTERe l’elenco veniva fornito senza filtri. Se ci sono più risultati, vengono visualizzati tutti. Se due categorie condividono un indirizzo, il negozio effettua la scelta senza un ordine prestabilito: il primo risultato non è necessariamente la pagina visualizzata. - Modificato:
DELETE /seohistory(s)?seo_string=restituisce un errore HTTP 400, non viene eliminato nulla. Finora il nome veniva ignorato e venivano eliminati solo?type=e?base_id=. Le voci si eliminano tramite il lorosh_id. - Modificato: un valore composto esclusivamente da virgole su
products_model,products_eaneseo_name(/products), nonché suemail,lastname,companyecustomers_id_extern(/customers) restituisce un codice HTTP 400 anziché l’elenco non filtrato. Un elemento vuoto tra i valori continua a essere ignorato.
Valori non validi
- Modificato:
GET /coupons?type=composto esclusivamente da virgole, ad esempio un elenco vuoto, restituisce un codice di errore HTTP 400 anziché l’elenco completo dei buoni con i codici di credito. - Modificato: un filtro di data composto esclusivamente da segni di punteggiatura (
?date_to=,,?last_modified=.,?valid_on=,) restituisce un errore HTTP 400INVALID_FILTER_VALUE; in precedenza veniva interpretato come “ora”. Ciò riguardadate_fromedate_toindirizzati a/tickets,/contracts,/projects,/appointmentse/wallet_logs,due_fromedue_toindirizzati a/project_tasks,sinceindirizzati a/medias,last_modifiedindirizzati a/productsevalid_onindirizzati a/coupons. Uno spazio vuoto in questi casi viene ora interpretato in modo uniforme come “non impostato”. Un «+» nell’indirizzo corrisponde a uno spazio; inviare un segno più come «%2B». - Modificato:
POST /mediaePUT /media/{id}: un campo con un solo valore come elenco (entity_id[]=5, nel corpo JSON un array) genera un errore HTTP 400INVALID_FIELD_VALUEconfield; non viene letto né scritto nulla. In precedenza veniva restituito un errore HTTP 500 o un altro valore, come ad esempio l’immagine nell’articolo 1. Più file vengono inviati come più richieste. - Le risposte di errore con UTF-8 non valido nel nome o nel valore ripetuto vengono ora restituite con un corpo in cui i caratteri illeggibili sono indicati come
U+FFFD: nomi di parametri sconosciuti (avvisoUNKNOWN_FILTER, in precedenza una risposta vuota), rifiuti della verifica dei valori che generano un 404 su/ticket_attachment/{id}ed errori daPOST /mediacomemultipart/form-data. - Ulteriori correzioni relative alla verifica dei valori riguardano gli endpoint interni.
Endpoint dei token
- Modificato: uno scope richiesto che non può essere letto (UTF-8 non valido o un elenco come
scope[]=…) restituisce un errore HTTP 400invalid_scope; non viene emesso alcun token.client_idoclient_secretcome elenco restituiscono un errore HTTP 400invalid_request.
E-mail, n8n e cronologia degli ordini
- I testi liberi, i dati dei clienti, i prezzi e i dati inseriti nei moduli vengono riportati alla lettera nel testo dell’e-mail, nell’oggetto e nella cronologia degli ordini; un
$con una cifra non va più perso (ad esempio, «Contrassegno $100» diventava in precedenza «Contrassegno 0»). Ciò vale anche per le e-mail che attivano un'integrazione. - Il negozio inserisce nelle e-mail solo come testo il nome, la ragione sociale e l’indirizzo presenti nell’ordine e nell’account cliente. Le nuove voci della cronologia derivanti da cambiamenti di stato, il cui testo utilizza segnaposto, riportano quindi tali valori mascherati (
GET /orders→status_history[].comments, ad esempioMüller & Söhne), così comecommentnell’evento n8norder.status_changed;comment_textrimane in chiaro. Le voci esistenti rimangono invariate.
Prospettive
- Con Shop 4.10 saranno introdotte, tra le altre cose, ulteriori funzionalità relative ai pacchetti, lo stato in tempo reale per ogni marketplace (
live),?fields=su ulteriori elenchi e con sottocodici, ulteriori forme di ricerca su/seohistorys, nonché ulteriori rafforzamenti interni.
v2.122.10
15 ottobre 2026Seconda parte delle estensioni per l’integrazione con i sistemi di gestione delle scorte e l’automazione, soprattutto in fase di lettura. Confronto numerico dei numeri di versione: la versione 2.122.10 succede alla versione 2.122.9. A partire dalla versione 4.9.169 di Shop.
Clienti: codici ordine e carrelli
- Novità: ogni cliente presenta i
order_statsconorders_count,orders_count_valid,first_order_date,last_order_date,first_valid_order_dateelast_valid_order_date. I valori convalidnon includono gli ordini annullati né le offerte. Le integrazioni con tipizzazione rigorosa devono riconoscere il nuovo campo. - Novità: filtro
?ordered_since=su/customersper i clienti con almeno un ordine a partire da tale data. - Novità:
GET /customers_baskets,/customers_basket/{customers_id}e l’area/customers_baskets/{von}:{bis}forniscono il carrello per ciascun cliente con articoli, caratteristiche,basket_last_modifiedelast_activity. Filtri:customer_id,sinceebasket_type. Un carrello vuoto non viene visualizzato. - L’ambito
customers:readcomprende quindi i carrelli e gli indicatori relativi agli ordini. Si prega di verificare le autorizzazioni dei clienti e la propria informativa sulla privacy.
Formati dei percorsi e tempistiche
- I formati di percorso di
/orderse/customers, ad esempio/order/{id},/orders/{von}:{bis}e/orders/new:{datum}, ora scorrono il database in ordine crescente in base all’ID. In questo modo, le aree di grandi dimensioni non causano più un errore di memoria. Senza?limit=, la risposta rimane non ordinata fino al limite massimo; oltre tale limite, viene fornita in formato standard conhas_more. - Modificato:
new:{datum}viene verificato (YYYY-MM-DD,YYYY-MM-DD HH:MMoYYYY-MM-DD HH:MM:SS), altrimenti viene restituito un errore HTTP 400INVALID_RANGE. Se viene specificata l’ora, l’indicazione è precisa al secondo. Questo formato è valido solo per/customer(s)e/order(s); gli altri endpoint rispondono con un errore HTTP 400 e, se disponibile, indicano il proprio filtro di data. - Modificato: gli intervalli di tempo nei filtri devono ora essere indicati solo in formati fissi:
YYYY-MM-DD,YYYY-MM-DD HH:MMoYYYY-MM-DD HH:MM:SS, facoltativamente con il fuso orario (Zo±HH:MM; inviare il segno più come%2B). Indicazioni comeyesterdayo01.10.2026generano un errore HTTP 400INVALID_FILTER_VALUE. Ciò riguarda/customers,/customers_baskets,/newsletter_subscribers,/orderse/coupons. - Novità:
?last_modified=su/orderscome variante ortografica disince(notaFILTER_ALIAS). - Modificato:
/customers/{von}:e/products/{von}:sono intervalli aperti a partire dall’ID specificato. Finora entrambi fornivano solo un unico record.
Parametri di query non validi
- Modificato: i valori non validi e i valori di elenco (
?x[]=,?x[k]=) generano un errore HTTP 400INVALID_FILTER_VALUEcondetails[]su tutti gli endpoint JSON. La verifica avviene prima che venga letto, scritto o cancellato qualsiasi dato. Finora un filtro di questo tipo veniva in parte omesso e la risposta conteneva il contenuto non filtrato. I valori validi rimangono invariati, mentre un valore vuoto viene considerato come non impostato. - All’indirizzo
/orders, un elenco separato da virgole, un testo o un numero decimale generano un errore HTTP 400 sustatus,customer_id,marketplace_id,products_idecategories_id. L’indicazione di più paesi di consegna, se non sotto forma di elenco separato da virgole, sudelivery_country. /categories/productlistaccettacategories_ideinclude_inactive_productssenza avvisare.parent_iderecursivenon funzionano in quel contesto e segnalanoUNKNOWN_FILTER.
Abbonati alla newsletter
- Modifica: l'invio di
?last_modified=a/newsletter_subscribersinclude anche gli iscritti che hanno confermato tramite double opt-in o il cui trasferimento al fornitore della newsletter è ancora in sospeso. Di conseguenza, il delta diventa più ampio. Gli indirizzi cancellati e quelli che si sono disiscritti non compaiono in nessun delta, pertanto è necessario effettuare regolarmente una sincronizzazione completa. - Novità:
customer_idelanguage_idcome elenco separato da virgole.?email=continua a cercare una parte dell’indirizzo, mentre%e_sono considerati caratteri. L’elenco scorre nel database.
Prodotti
- Novità: dati bonus e gratuiti dell’articolo come blocco
bonus_free_features(status_bonus,bonus_points,max_bonus,status_free,bonus_value,max_free,auto_free). L’esportazione li fornisce solo con?bonus_free_features=1. Nell’importazione, una chiave mancante lascia i dati invariati,nullli rimuove, un oggetto modifica solo i campi inviati. I valori non validi causano il rifiuto del record (INVALID_BONUS_FREE_FEATURES), viene rispettato il blocco di importazionebonus. - Modificato: un articolo non esistente risponde nella richiesta singola (
/product/{id}) con HTTP 404NOT_FOUNDinvece che con HTTP 200 condatavuoto. - Modificato: gli articoli senza immagine principale non restituiscono più una voce immagine vuota (
images_id0). Le esportazioni precedenti contenenti questa voce possono essere rinviate senza errori; l’immagine principale salvata rimane invariata. - Modificato:
products_statusaccetta solo 0 o 1. Lo stato 2 viene impostato dal negozio stesso se l’articolo non ha un percorso di categoria sempre attivo (avvisoNO_ACTIVE_CATEGORY_PATH). Un 2 inviato o un valore non valido non viene scritto (READONLY_VALUEoINVALID_FIELD_VALUE). Novità nella risposta:records[].products_status. - Modificato:
products_xoportaccetta al massimo 64 caratteri. Un valore più lungo causa il rifiuto del record, anziché essere abbreviato automaticamente. - Novità: blocco di importazione
costper il prezzo di acquisto, impostabile tramiteimport_blocks. Verificare primaapi_version: i negozi più vecchi non salvano il tipo e, fino alla versione 2.122.8, un elenco rimuove solo i blocchi esistenti dacost.
Buoni
- Novità: l'operazione «
?last_modified=» su/couponsfunziona senza avvisi, anche con?_strict=true. - Modificato: i valori delle liste nei filtri dei buoni e gli orari al di fuori dei formati prestabiliti generano un errore HTTP 400 invece dell’elenco completo dei buoni. Le copie create con “Copia buono” compaiono nel delta in base alla loro data di creazione.
Stato dell’ordine
- Novità:
GET /order_statuses,/order_status/{id}e le sezioni forniscono tutti gli stati degli ordini con nomi per lingua, colori, ordinamento e i codiciis_default,is_cancelled,is_offer,counts_as_revenue,is_paideis_shipped. Ambitoorders:read; uno stato non esistente genera un errore HTTP 404.
n8n e input precedenti
- Modificato: l'evento n8n
order.status_changedcontiene anchecomment_textin chiaro.commentcontiene il testo della voce della cronologia con i segnaposto risolti; i contributi con$vengono mantenuti alla lettera. - Rimosso: i vecchi indirizzi
api/n8n/eapi/order-status.phprestituiscono un errore HTTP 404. Le modifiche di stato avvengono tramitePUT /Import/JSON/orders.
Porting CSV e XML
- Sezione CSV «Modulo Bonus/Omaggio»: una cella vuota imposta il valore su 0, una colonna mancante lo lascia invariato. Le categorie con lo stato
deleliminano l’intero ramo. - Importazione prodotti XML: un nodo vuoto
<bonus_free_features>mantiene lo stato «Bonus» e «Gratis», mentre un «0» esplicito lo disattiva.
v2.122.9
13 ottobre 2026Prima parte delle estensioni per l’integrazione con i sistemi di gestione delle scorte e di automazione. A partire dalla versione 4.9.168 di Shop.
Ordini
- Novità: filtro
?delivery_country=su/orderscon codici paese ISO, a due o tre cifre e separati da virgola. Un codice sconosciuto genera un errore HTTP 400INVALID_FILTER_VALUE. - Modificato: i filtri su un percorso del tipo
/order(s)ora agiscono in aggiunta al percorso stesso. In precedenza lo sostituivano:/order/{id}?status=3restituiva tutti gli ordini con stato 3.
Prodotti
- Modificato: l’esportazione dei prodotti contiene solo gli articoli della query, nessun elemento senza
products_id.xsellsvengono riportati per intero e doposort_order;unit_single,unit_multieunit_basevengono compilati, mentre quelli senza unità rimangono vuoti al posto dinull. L’esportazione personalizzata può essere rinviata con?_strict=true; i campi di sola lettura segnalanoREADONLY_FIELD. - Modificato: un elenco
import_blockssenza voci utilizzabili non modifica più i blocchi; in precedenza venivano rimossi tutti. È possibile impostare tutti i tipi di blocco del negozio. Novità:import_blocks_mode(replace,mergeoappend,remove) erecords[].import_blocks. I negozi meno recenti ignorano questa modalità, pertanto inviare solo insieme a?_strict=true. - Modificato: un
categories_modenon valido, una categoria sconosciuta,categoriesoimagessenza elenco e unimages[]senza voce utilizzabile causano il rifiuto del record prima della scrittura (INVALID_CATEGORIES_MODE,INVALID_CATEGORIES,INVALID_IMAGES). Finora veniva in parte scritto. Ogni rifiuto è indicato con un codice inrecords[]. - Modificato:
options_replace,options_strict_names,apply_value_defaults,videos_replaceecustomers_prices_replacesi attivano solo contrue,1,"1"o"true";"false"e"no"non si attivano più. - Novità: i caricamenti di immagini (
POST /media,PUT /media/{id}con file) segnalanoreplaced_existingethumbnails_removed. Una cache a monte come Cloudflare non viene svuotata; sureplaced_existing: trueaggiornare manualmente l’indirizzo dell’immagine. - L’importazione dei prodotti con MPN non termina più con un errore HTTP 500 nei negozi senza integrazione con eBay. Dopo un’importazione da
shop_idssotto forma di elenco, la maschera del backend mostra correttamente i negozi associati.
Buoni sconto
- Modificato:
restrictions.categoriescontiene anche categorie salvate con sottocategorie; la nuova versione èrestrictions.categories_with_subcategories. In questo modo, le integrazioni vedono un numero maggiore di ID categoria. - Modificato:
coupon_coderimane testo, anche in caso di codici puramente numerici come «4711». Verificare i confronti con lo stesso tipo di dati.
Configurazione
- Modificato: i dati di accesso, le chiavi di licenza, di sessione e di interfaccia, nonché le impostazioni interne, non sono né leggibili né modificabili tramite
/configuration, anche se sono stati autorizzati (CONFIG_KEY_BLOCKED). Rimuovere tali chiavi dall’elenco delle autorizzazioni; se i dati di accesso erano stati autorizzati, aggiornarli presso il fornitore. - Modificato:
PUT /configurationscrive solo testo in chiaro e numeri interi entro i limiti della maschera del backend. Le chiavi che nel backend attivano un'azione successiva sono solo leggibili e vengono modificate nel backend.
Abbonati alla newsletter
- Modificato:
POST /newsletter_subscribersrifiuta gli indirizzi con blocco della newsletter o opposizione alla pubblicità (NEWSLETTER_LOCKED,OPTED_OUToNOT_SUBSCRIBABLE). Gli indirizzi disiscritti possono essere reiscritti solo tramitesend_doi. - Modificato: nel negozio con procedura double opt-in, un POST senza
subscribe_confirminvia autonomamente l’e-mail di conferma, al massimo una per indirizzo ogni 24 ore. - Novità:
send_doi,records[].confirmederecords[].doi_mail.subscribe_confirmaccetta solo un orario o sì/no. Il PUT non conferma più nulla (FIELD_IGNORED_ON_UPDATE). - Modificato:
DELETE /newsletter_subscriber(s)verifica il risultato presso il fornitore della newsletter. Se la cancellazione non va a buon fine, il percorso singolo risponde con codice HTTP 502NEWSLETTER_UNSUBSCRIBE_FAILED. - Importazione clienti XML:
<newsletter>0cancella l’indirizzo e registra un’opposizione alla pubblicità.
n8n, webhook e invio
- Modificato:
order.status_changedviene utilizzato solo in caso di un vero e proprio cambiamento di stato; ora conold_status. Gli eventi vengono inviati solo dopo che quanto segnalato è stato salvato. La firma viene generata come in precedenza in base al contenuto inviato; l’esempio di verifica riportato nella documentazione è stato corretto. - La reazione di marketing «Invia webhook» ripete l’operazione dopo un errore, invece di bloccare la destinazione.
compute_shippingIn caso di valore della merce pari a 0, restituisce la riga di spedizione anziché l’avvisoSHIPPING_AUTO_FAILED.
Interfaccia XML
- Modificato: «
<products_to_marketplaces>» senza voci non produce più alcun effetto; in precedenza tutte le autorizzazioni venivano impostate a 0. Le voci hanno effetto solo per i marketplace noti e autorizzati con stato 0 o 1. I feed che intendevano disattivare tutto con un nodo vuoto inviano voci con stato 0. Nuovo blocco di rispostamarketplaces.
v2.122.8
11 ottobre 2026Correzioni di bug
- Registrazione degli ordini (
orders:write): le voci con importo fiscale negativo, ad esempio i rimborsi, ottengono la propria riga fiscale. Quando si aggiungono voci tramite PUT, viene conteggiata anche l’imposta delle voci negative; finora la somma risultava troppo elevata. - Le nuove voci d’ordine, al momento della creazione, registrano, come nel checkout, se si tratta di merce o di un servizio. I documenti relativi alle forniture e ai servizi intracomunitari rimangono così invariati.
/cms,/faqcatse/faqs: i filtri?status=e?module=(solo/cms) restituivano un errore HTTP 500 se utilizzati senza il formato del percorso. Ora il filtraggio avviene senza avvisiUNKNOWN_FILTER.?module=è il codice esatto del modulo.DELETE /customerAnonimizza preventivamente la cronologia dei prodotti visualizzati dal cliente.- Importazione categorie XML: i campi vuoti non sovrascrivono più nulla. La risposta riporta inoltre
categories{inserted, updated, unchanged, deleted, paths_changed, cyclic_parents}. - CSV-Porter: l’importazione delle caratteristiche imposta lo stato sull’intera catena di caratteristiche. I feed convertono gli importi in valuta estera. A partire dalla versione 4.9.167 dello Shop.
v2.122.7
6 ottobre 2026I blocchi dei gruppi di clienti nell’importazione
restricted_customer_groupssu prodotti e categorie applica solo i gruppi di clienti esistenti, espressi come numero intero. Se l’elenco non contiene alcun gruppo esistente o non è un elenco, i blocchi salvati rimangono invariati (avvisoCUSTOMER_GROUP_RESTRICTION_KEPT). Un articolo creato in questo modo non presenta alcun blocco.- La presenza di voci sconosciute accanto a quelle note genera l’avviso
CUSTOMER_GROUP. Il comando «[]» continua a rimuovere tutti i blocchi; gli elenchi validi funzionano come prima. La stessa regola si applica nel CSV-Porter. A partire dalla versione 4.9.155 dello Shop.
v2.122.6
6 ottobre 2026Esportazione delle recensioni dei prodotti
- Novità:
GET /reviews,GET /review/{reviews_id}e l’areaGET /reviews/{von}:{bis}con l’ambitoproducts:read. Finora l’API forniva per ogni prodotto solo la media e il numero delle recensioni (products_rating,products_rating_count). - Per ogni recensione:
reviews_id,products_id,products_model,reviews_rating,status,promo_status,author,verified_purchase,helpful_count,review_external_id,date_added,last_modifiededescriptions[]per ogni lingua conreviews_title,reviews_textereviews_reply(risposta del negozio). - Filtri:
products_id(anche come elenco separato da virgole),status(1= approvato, impostazione predefinita;0= in attesa di approvazione;all) esince(dalla data di creazione o dell’ultima modifica). La navigazione avviene come per i prodotti conlimitepage. - Nessun dato cliente:
authorè il nome visualizzato anche nella pagina del prodotto. L’endpoint non fornisce l’ID cliente, l’e-mail e il numero d’ordine, ma soloverified_purchase. A partire dalla versione 4.9.153 dello Shop.
v2.122.5
1 ottobre 2026Interfaccia XML: esportazione dei prodotti e dei fornitori
- L’esportazione dei prodotti in formato XML si interrompeva con un errore HTTP 500 non appena un articolo non era ancora presente nell’indice di ricerca rapida. Ora questi articoli vengono esportati normalmente; l’esportazione in formato JSON non era interessata dal problema.
- L’importazione dei prodotti in formato XML ora sincronizza il nodo
suppliers, invece di eliminare e ricreare i fornitori. Il codice articolo dei fornitori permanenti viene mantenuto. A partire dalla versione 4.9.139.
v2.122.4
30 settembre 2026Caratteristiche e ticket
- Caratteristiche: «
options[].cost» è ora un altro nome per «ext_cost». Finora, un prezzo di acquisto scritto in questo modo finiva in una posizione che né la pagina del prodotto, né il checkout, né l’editor riuscivano a leggere. Se vengono inviati entrambi, vale «ext_cost». Il prezzo di acquisto e il prezzo di vendita consigliato vengono verificati come importo; i valori non validi generano l’avviso «OPTION_META_INVALID». - Ticket:
DELETE /ticketsora rimuove tutti i dati associati al ticket, come i responsabili, gli iscritti, i collegamenti a date e progetti. A partire dalla versione 4.9.135 dello Shop.
v2.122.3
30 settembre 2026Creazione degli ordini: prezzi con calcolo lordo
orders:writecontax_flag = 1: i prezzi calcolati dallo Shop (recalc) e la spedizione dacompute_shippingsono valori netti. Finora venivano conteggiati come lordi, mentre l’imposta mancava dal totale. Ora vengono ricalcolati. I prezzi che inviate voi stessi rimangono lordi come prima.- Chi ha adeguato
expected_totalall’importo troppo basso, ora riceve l’avvisoTOTAL_DRIFT(constrict_totalsHTTP 422). - I supplementi di formula delle caratteristiche standard (
apply_default_attributes) vengono calcolati come nella pagina del prodotto. Finora una formula restituiva 0 €. Le formule che possono essere valutate solo dalla pagina del prodotto segnalano l’avvisoDEFAULT_ATTRIBUTE_FORMULA. A partire dalla versione 4.9.134 dello Shop.
v2.122.2
29 settembre 2026Clienti: modificare parzialmente gli indirizzi senza che il Paese torni al valore precedente
PUT /Import/JSON/customersconaddresses[]eaddress_book_id(o l’oggettoaddress) vengono scritti solo i campi inviati. Finora ogni aggiornamento senza indicazione del Paese impostava il Paese su quello del negozio e la zona su 0. Un semplice aggiornamento della via trasformava così un indirizzo austriaco in uno tedesco.- Il Paese e la zona cambiano solo se li si invia insieme ai dati. In caso di Paese sconosciuto, la risposta segnala l’avviso
ADDRESS_COUNTRY. Un aggiornamento mantiene quindi il Paese memorizzato, mentre un nuovo indirizzo riceve, come in precedenza, il Paese del negozio. - È stato risolto anche il seguente problema: gli apostrofi venivano salvati con la barra rovesciata e i valori troppo lunghi venivano troncati byte per byte senza alcun avviso. Ora il troncamento avviene carattere per carattere, con l’avviso
ADDRESS_TRUNCATED. Le cifre presenti inentry_countrynon sono considerate come ID del Paese. - Negozi con versione precedente: in caso di aggiornamenti dell’indirizzo, inviate sempre anche il Paese. A partire dalla versione 4.9.132 di Shop.
v2.122.1
27 settembre 2026Sicurezza: esportazione di clienti e ordini senza dati relativi alle password
- Le esportazioni
/customerse/orders(JSON e XML) non forniscono più l’hash della password né i token per il ripristino della password e la cancellazione dell’account:customers_password,customers_password_request,customers_password_request_timeecustomers_hashvengono eliminati senza sostituzione. - Inoltre, il record dei dati del cliente non contiene più né
ibannébic. Nel record dell’ordine entrambi i campi vengono mantenuti. A partire dalla versione 4.9.123 di Shop.
v2.121.0
19 settembre 2026L'importazione delle notizie crea le lingue mancanti
POST /Import/JSON/newsdesk, al momento della creazione, integra ogni lingua attiva per la quale non è stato inviato un blocco specifico, attingendo dalla lingua principale (il bloccode, altrimenti il primo blocco inviato). Se la traduzione DeepL è configurata, tradurrà queste lingue al prossimo ciclo. Finora, un articolo creato solo conderimaneva permanentemente monolingue.- Anche i testi modificati nel formato annidato
languagesvengono ora ritradotti. A partire dalla versione 4.9.106 di Shop.
I numeri di versione 2.119.1, 2.121.1 e 2.122.0 riguardano endpoint interni, mentre la versione 2.120.0 non è ancora stata pubblicata.
v2.119.0
18 settembre 2026API REST: sempre con token, opzionalmente limitata anche a indirizzi fissi
- Importante: l’autorizzazione IP dell’interfaccia XML (
XML_PORT_IP_FILTER) non dà più diritto all’accesso all’API JSON/REST. REST richiede sempre un token OAuth2 e si applicano i relativi ambiti (scopes). Un client che finora ha utilizzato REST senza token, semplicemente tramite un indirizzo autorizzato, riceverà401conreason: deny_token_required. - Una novità è l’impostazione
XOPORT_REST_IP_LISTcome protezione aggiuntiva. Se compilata, una richiesta deve provenire da un indirizzo presente nell’elenco e contenere un token valido; in caso contrario, verrà restituito il messaggio di errore403conreason: deny_ip_not_listed. - Se l’API rifiuta una richiesta, ne indica il motivo nel campo
reasone nell’intestazioneX-XoPort-Deny-Reason. L’interfaccia XML rimane invariata. A partire dalla versione 4.9.83 di Shop.
v2.118.1
17 settembre 2026Ticket: non viene più visualizzato un avviso errato per gli appuntamenti collegati
linked_appointmentsnei campiPOST/PUT /Import/JSON/ticketsveniva segnalato anche l’avvisoUNKNOWN_FIELD(“will be ignored”), sebbene gli appuntamenti vengano creati a partire dalla v2.43.0. L’avviso viene eliminato, ma l’elaborazione rimane invariata. A partire dalla versione 4.9.75 di Shop.
v2.118.0
17 settembre 2026Ticket: richiesta di elaborazione
- Il nuovo endpoint
PUT /Import/JSON/ticket_claims(ambitotickets:write) mostra chi sta lavorando su un ticket. Campi obbligatori:ticket_id,admin_idestate(claimedoreleased), campi opzionali:ttl_minutes(valore predefinito 60, da 5 a 240),labeleforce. - Risultato per ogni record in
records[].status:claimed,refreshed,taken_over,released,unchangedoconflict. ⚠ Un conflitto viene indicato comefailed. GET /ticketseGET /ticket/{id}restituiscono i nuovi campiclaimeedit_lock(il ticket è attualmente aperto nel backend), mentrenullviene restituito se non è presente alcuna informazione.- Una risposta pubblica (tramite API o nel backend) e il passaggio a uno stato di chiusura sbloccano automaticamente il reclamo, mentre una nota interna no. Il reclamo è un avviso, non un blocco, e non modifica né
ticket_date_last_modifiedné la cronologia. A partire dalla versione 4.9.73 dello Shop. - I numeri di versione v2.116.0 e v2.117.0 fanno parte delle novità che saranno disponibili con la prossima release di funzionalità; verranno poi aggiunti qui.
v2.115.0
15 settembre 2026Gli importatori XML verificano il file del feed durante il caricamento
- Se un file contiene caratteri non consentiti da XML 1.0 (ad es. caratteri di controllo nei testi descrittivi), tutti e otto gli importatori XML rimuovono tali caratteri ed elaborano il file. Finora, un file di questo tipo restituiva 0 record, veniva comunque archiviato e la risposta indicava esito positivo.
- Se un file non è leggibile nemmeno dopo questa operazione, viene spostato in
xoport/xml/import/error/anziché essere archiviato e, come l’archivio, verrà eliminato al termine del periodo di conservazione. - Nuovi campi di risposta:
outcome(ok,partial,failed),files.failedewarnings.invalid_xml_chars_removed.files.processed.filenamesnon elenca più i file rifiutati. - ⚠ Se tutti i file di un'esecuzione falliscono, l'importazione risponde con
"state": "error"e codice HTTP 422. Le integrazioni che valutano lo stato HTTP rilevano quindi per la prima volta un tale errore; i singoli file rifiutati sono riconoscibili daoutcome: "partial". A partire dalla versione 4.9.65 di Shop.
v2.114.0
14 settembre 2026Prodotti esclusi dai buoni sconto
GET /couponseGET /coupon/{id}forniscono il nuovo camporestrictions.excluded_products: gli ID dei prodotti che non ricevono mai sconti tramite il buono.- L'esclusione si applica in aggiunta a tutte le altre restrizioni e ha la precedenza su
restrictions.products. Un articolo principale escluso include le sue varianti, mentre una variante esclusa include solo se stessa. - I coupon senza esclusioni restituiscono un elenco vuoto
[].
v2.113.1
14 settembre 2026Buoni: correzione di restrict_mode
- ⚠ Finora
restrict_modeveniva esportato al contrario. La versione corretta è:allow_only= solo articoli nelle categorie elencate,deny= tutti tranne quelli, a meno che l’articolo non si trovi anche in una categoria non elencata, oradeny_strict= tutti tranne gli articoli che si trovano in una qualsiasi categoria elencata. - Il campo descrive esclusivamente
restrictions.categories.restrictions.productserestrictions.manufacturerssono sempre elenchi positivi; se l’elenco dei prodotti è completo, le categorie e i produttori non vengono valutati. - Chi analizza questo campo a partire dalla versione v2.102.0 dovrebbe verificare la propria assegnazione.
v2.113.0
13 settembre 2026Assegnazione del numero di fattura tramite l’interfaccia
- Nuovo campo
assign_invoice_numbersuPOSTePUT /Import/JSON/orders: contrueil negozio assegna il numero successivo dalla propria serie di numeri di fattura. Il numero stesso non è impostabile e, una volta assegnato, è immutabile. - La risposta riporta
invoice_number_assigned; in caso di esito positivo, vengono restituiti ancheinvoice_id_individuelleinvoice_date. In caso contrario,invoice_number_reasonindica il motivo (mode_disabled,already_assigned,locked), accompagnato dall’avvisoINVOICE_NUMBER_NOT_ASSIGNED. - Le assegnazioni simultanee sono bloccate tra loro. All’indirizzo
lockedil negozio non assegna intenzionalmente alcun numero al posto di uno già assegnato; in tal caso, inviare nuovamente la richiesta.
v2.112.0
13 settembre 2026Nuove categorie con le impostazioni della maschera di backend
- ⚠ Se si crea una categoria senza
sitemaposhop_ids, ora si applicano gli stessi valori della maschera di backend:sitemap = 1e tutti i negozi come elenco completo. Finora venivano applicate le impostazioni delle colonne (nessuna mappa del sito, nessuna assegnazione al negozio). - L’avviso
CATEGORY_DEFAULTS_APPLIEDriporta i valori impostati. Gli aggiornamenti delle categorie esistenti non sono interessati da questa modifica.
v2.111.0
13 settembre 2026Rimuovere video e numeri di spedizione
videos[]: rimuovere singole voci con_action: "delete"oppure, convideos_replace: true, importare l’elenco inviato come stato completo (solo su richiesta espressa). Il file video stesso rimane intatto, viene rimossa solo l’assegnazione.trackings[]:_action: "delete"tramiteid_trackingoppureservice_providerecode. In questo modo è possibile rimuovere e ricreare un numero di spedizione con un'unica operazione.- In entrambi i casi, verificare che la voce appartenga al prodotto o all’ordine specificato.
v2.110.0
13 settembre 2026Caratteristiche di una voce d'ordine esistente
products_mode: "update"ora accettaattributes. L'elenco inviato sostituisce completamente le caratteristiche della posizione, mentre[]le rimuove tutte.- Un sovrapprezzo diverso non modifica il prezzo della voce: in questo caso l’interfaccia emette un avviso. Se si desidera modificare il prezzo, annullare la voce e reinserirla.
- La modifica è bloccata per gli ordini già fatturati, poiché le caratteristiche figurano sulla fattura e sulla bolla di consegna.
v2.109.0
13 settembre 2026Lettura e attivazione dei file CSV/XLS
- Novità:
GET /Export/JSON/porters,/porter/{id}ePUT /Import/JSON/porterscon gli scopeporters:readeporters:write. activeimposta lo stato (true= attivo in seguito) invece di commutarlo. Senzaactivela richiesta viene respinta. Al momento della disattivazione, lo shop rimuove il file di esportazione generato come nel backend.- La richiesta singola fornisce all’indirizzo
columnsla mappatura completa delle colonne del Porter.
v2.108.0
13 settembre 2026Leggere e modificare le impostazioni
- Novità:
GET /Export/JSON/configurationePUT /Import/JSON/configurationcon gli scopeconfiguration:readeconfiguration:write. - ⚠ Sono visibili solo le chiavi che l’amministratore rende disponibili in
XOPORT_CONFIG_API_KEYS– l’impostazione predefinita è vuota. I dati di accesso, le impostazioni di licenza e di sessione rimangono bloccati anche se rese disponibili. - Vengono modificate solo le chiavi esistenti; ogni modifica viene registrata. L’avviso
SHOP_OVERRIDE_ACTIVEsegnala una sovrascrittura del dominio che annulla il valore di base modificato.
v2.107.0
13 settembre 2026Responsabile nella cronologia dell’ordine
user_idrelativo a un ordinePUTinserisce il responsabile operativo nella voce della cronologia. Viene acquisito solo un identificativo di responsabile esistente.customer_notifiedviene comunque scritto, ma l’interfaccia segnala conNO_MAIL_SENTche non invia alcuna e-mail di stato.
v2.106.0
13 settembre 2026Caricamento di video dei prodotti, immagini delle opzioni e sottocartelle
- Caricamento multimediale con
entity_type: "product_video"(fino a 100 MB) eentity_type: "option"per le immagini delle opzioni. subfoldersalva le immagini in una sottocartella (un livello, lettere minuscole, cifre,_e-).- L’estensione del file viene determinata in base al tipo di file riconosciuto, non al nome del file inviato.
v2.105.0
13 settembre 2026L’esportazione dei prodotti può essere inviata nuovamente
- Sono modificabili altri 68 campi del prodotto, tra cui i prezzi scalari con soglie quantitative, l’opzione eBay
ebay_allowed(modulo eBay classico), il blocco Amazon Payamazon_allowed, FSK 18, merci soggette a restrizioni, prezzo di listino, punti bonus e data di acquisto. - 14 campi di sola lettura vengono segnalati come
READONLY_FIELD, anziché essere scartati senza alcun commento. - ⚠ I valori non validi (valore di selezione sconosciuto, testo troppo lungo, numero illeggibile) rifiutano il record, invece di scriverlo solo a metà. I campi Sì/No inviati vuoti rimangono invariati.
- Correzione: inizialmente qui era riportato «i pulsanti del marketplace». Tuttavia, «
amazon_allowed» non è un pulsante del marketplace, bensì il blocco per Amazon Pay:1nasconde i pulsanti Express di Amazon Pay finché l’articolo si trova nel carrello. Il significato dei campi è riportato nella sezione «Prodotti», sottosezione «Altri campi del prodotto».
v2.104.0
13 settembre 2026Le immagini dei prodotti sostituite ricevono nuove anteprime
- Se un’immagine viene sostituita con lo stesso nome file, il negozio rimuove le relative anteprime in tutti i formati. La risposta segnala
thumbnails_removedereplaced_existing. - Le voci in
videos[]vengono controllate per verificare la presenza di nomi di campo sconosciuti; con?_strict=trueun errore di digitazione causa un errore HTTP 400.
v2.103.0
13 settembre 2026Sezioni dei ticket
- Novità:
GET /Export/JSON/ticket_departments(?active=),/ticket_department/{id},POST/PUT /Import/JSON/ticket_departmentseDELETE /Delete/JSON/ticket_department/{id}. - I reparti sono multilingue; le lingue vuote assumono il nome della lingua predefinita.
- Se a un reparto è ancora assegnato un ticket, l’operazione di cancellazione restituisce il messaggio
409 DEPARTMENT_IN_USE.?reassign_to={id}riorganizza preventivamente i ticket, mentre?force=1procede comunque alla cancellazione.
v2.102.0
13 settembre 2026Buoni e coupon in formato JSON
- Novità:
GET /Export/JSON/couponse/coupon/{id}con i filtri?code=,?type=,?active=,?kind=e?valid_on=. - Le restrizioni sono indicate come elenchi di ID, insieme ai campi leggibili
restrict_modeeis_credit_voucher.0nei limiti di riscatto indica "illimitato". - Risolto: il nome e la descrizione di un buono mancavano finora nell'esportazione.
v2.101.0
13 settembre 2026L’esportazione XML verifica le autorizzazioni
- ⚠ Un token OAuth2 con ambito limitato riceve ora nell’esportazione XML
403per le aree senza autorizzazione:customers:read,orders:read(anche per i buoni),products:read,categories:read,manufacturers:read. - I collegamenti tramite AppKey o autorizzazione IP non sono interessati.
v2.100.0
13 settembre 2026Configurazione dei filtri delle pagine delle categorie
- Novità:
GET /Export/JSON/products_filterse/products_filter/{fid}con?options_id=e?categories_id=– quali filtri offre una pagina di categoria. - Nota: la versione 2.100.0 succede alla 2.99.0. Confrontare le versioni utilizzando
version_compare(), non come numero decimale.
v2.99.0
13 settembre 2026Esportazione clienti con filtri e sfogliamento
- Nuovi filtri su
/customers:customers_id,customers_group_id,language_id,email,lastname,company,customers_id_extern, i filtri con prefissoemail_prefix,lastname_prefix,company_prefix, nonchépurchased_without_account,sort,orderepage. - I database con un numero elevato di clienti vengono sfogliati anziché caricati integralmente.
- Un valore di filtro non valido genera l'errore
400 INVALID_FILTER_VALUE, anziché essere semplicemente ignorato.
v2.98.0
12 settembre 2026Numeri di spedizione, richiesta di valutazione, campi delle voci
trackings(al plurale, come nell’esportazione) viene accettato. I numeri di spedizione duplicati vengono saltati e segnalati, un link mancante viene integrato dal corriere.rating_mailè modificabile.products_mode: "update"Modifica i campi delle voci esistenti (prezzo di acquisto, nome, codice articolo, EAN, unità, profilo di spedizione, campi data). Quantità, prezzi e aliquota fiscale vengono rifiutati.
v2.97.0
12 settembre 2026Rimuovere gli allegati dal ticket, inviare nuovamente l’e-mail
- Novità:
DELETE /Delete/JSON/ticket_attachment/{tshid}?filename=. notify_history_idL'invio aPUT /Import/JSON/ticketsreinvia l'e-mail di risposta relativa a una voce esistente della cronologia, senza crearne una nuova.apply_value_defaultsAl primo assegnamento di una caratteristica, adotta le impostazioni predefinite del valore dell’opzione (su richiesta espressa, poiché le impostazioni predefinite possono comportare un sovrapprezzo).
v2.96.0
12 settembre 2026Caratteristiche e valori delle opzioni come endpoint separati
- Novità:
GET /Export/JSON/products_options,/products_option/{id},/products_options_valuesePOST/PUT /Import/JSON/products_options. values[]Non si tratta di un elenco completo: viene rimosso solo ciò che contiene_action: "delete", mentre_action: "attach"condivide un valore esistente.- ⚠ Un
option_idsconosciuto nell’importazione dei prodotti viene ora rifiutato conOPTION_NOT_FOUND, invece di creare silenziosamente un attributo.
v2.95.0
12 settembre 2026Eliminazione di singole voci della cronologia
- Novità:
DELETE /Delete/JSON/order_status_history/{id}eDELETE /Delete/JSON/ticket_status_history/{id}. Lo stato dell’ordine o del ticket viene aggiornato come nella maschera. - La voce più vecchia di un ordine è protetta (
409 FIRST_HISTORY_ENTRY).
v2.94.0
12 settembre 2026Profili dei tempi di consegna
- Novità:
/shipping_profilese/shipping_profile/{id}in lettura e scrittura, con livelli, intervalli di consegna e testi personalizzati per ogni lingua. - A livello di prodotto, l’esportazione fornisce inoltre
shipping_profile_effective,_name,_stepe_text.
v2.93.0
12 settembre 2026Ricerca rapida e individuazione tramite l’ID del prodotto
- I prodotti creati o modificati tramite interfaccia vengono inclusi nella ricerca rapida. L’esportazione mostra all’indirizzo
quicksearchlo stato dell’indice per ciascuna lingua. - Risolto: un
PUTconproducts_idpoteva terminare con un errore HTTP 500 e le modifiche agli indirizzi non generavano alcun reindirizzamento in questo modo.
v2.92.0
12 settembre 2026Regole delle opzioni del configuratore
options_rules[]sul prodotto, in lettura e in scrittura. Se il campo manca, le regole esistenti rimangono invariate.- I blocchi di regole attivi vengono verificati per assicurarne la completezza prima della scrittura; in assenza della licenza corrispondente, l’operazione viene rifiutata.
v2.91.0
12 settembre 2026Cronologia dello stato e testi dei documenti per ogni ordine
- L’esportazione dell’ordine fornisce
status_history[]con tutte le voci della cronologia. indiv_text0indiv_text4(testi sostitutivi per ogni documento), nonché e (nomi dei file PDF archiviati) sono modificabili.indiv_rgindiv_ls- Gli avvisi relativi a un
PUTdegli ordini vengono ora visualizzati nella rispettiva voce inrecords[].
v2.90.0
12 settembre 2026Classi fiscali e dettagli dei biglietti
- Novità:
GET /Export/JSON/tax_classese/tax_class/{id}con le aliquote fiscali per ciascuna zona fiscale. - La cronologia dei ticket fornisce l’ID del messaggio delle e-mail ricevute e
ticket_event_type. - Risolto: una semplice modifica del titolo del video causava un errore HTTP 500.
v2.89.0
12 settembre 2026Vengono segnalati i successi parziali
- Risolto: durante l’aggiunta di voci, sulla fattura poteva comparire un codice lingua al posto del titolo fiscale.
- Senza un
admin_idvalido non viene più creata alcuna voce nella cronologia dei ticket. outcomeSegnalapartialse una parte dell’ordine è stata rifiutata. È stata inoltre introdotta la nuova funzione?order_id=su/tickets.
v2.88.0
12 settembre 2026Scheda del prodotto multilingue
tabsviene accettata nella forma piatta, in quella con le lingue annidate e in quella di esportazione; l’esportazione fornisce un bloccolanguagesper ogni scheda.- Le nuove categorie prive di
sitemap/shop_idssi registrano conCATEGORY_DEFAULTS_APPLIED.
v2.87.0
12 settembre 2026È possibile modificare le commissioni e il numero di riferimento dell’ordine
handling_fee,transaction_fee,selling_fee,other_feeepo_numberpossono essere impostati tramitePOSTePUT.- Gli importi al di fuori dell’intervallo di valori e i riferimenti troppo lunghi vengono rifiutati anziché essere abbreviati. È stata introdotta la nuova opzione di filtro
?po_number=su/orders.
v2.86.0
12 settembre 2026Scorrimento e ordinamento
?sort=e?order=su/orderse/products;?page=è stato implementato e viene confermato comestats.page.pageInsieme aoffsetsi verifica un errore. Un riferimento troncato alimitrestituisceLIMIT_CAPPED.
v2.85.0
12 settembre 2026Prezzi speciali completi nell'esportazione
- Finora i prezzi speciali senza etichetta mancavano nell’esportazione. Ora vengono inclusi tutti i campi, compresi gruppo clienti, periodo, etichetta e tipo.
- I prodotti appena creati riportano l’indicazione «
products_last_modified» e compaiono quindi nel filtro delle modifiche.
v2.84.0
12 settembre 2026I blocchi delle categorie sono modificabili
subs_blocke «tree_block» sono modificabili. ⚠ «subs_block» influisce sui reindirizzamenti e sulla mappa del sito dell’intero ramo della categoria.
v2.83.0
12 settembre 2026Tutti gli endpoint di esportazione verificano i propri filtri
- I filtri sconosciuti vengono segnalati in ogni endpoint di esportazione con
UNKNOWN_FILTER; con?_strict=truela chiamata viene interrotta.
v2.82.0
12 settembre 2026Il produttore tramite il nome
manufacturers_namee il blocco del produttore dell’esportazione vengono risolti. I nomi sconosciuti o ambigui vengono rifiutati, non creati ex novo.- È stato documentato quali dati vengono rimossi con
DELETE /product– spessoproducts_status = 0è la scelta migliore.
v2.81.0
12 settembre 2026Prezzi speciali e campi aggiuntivi restituibili
specialviene accettato come elenco o oggetto singolo,slp_valuecome nome dell’etichetta.extra_fieldsViene visualizzato come elenco vuoto anche in assenza di voci.
v2.80.0
12 settembre 2026Reinvio senza perdita di dati
- Risolto: le assegnazioni alle categorie nel modulo di esportazione spostavano i prodotti nella categoria 1.
- Gli elenchi di immagini vengono prima verificati e poi salvati; un'immagine principale rimane tale.
v2.79.0
12 settembre 2026Aggiornamento parziale delle categorie
- Un
PUTe di categoria non richiede più il blocco lingua. categories_mode: "append"Aggiunte le associazioni ai prodotti; la sincronizzazione completa segnala le associazioni rimosse tramiteCATEGORY_ASSIGNMENTS_REPLACED.
v2.78.0
12 settembre 2026Riferimento al cliente di un ticket tramite PUT
ticket_customers_orders_id,ticket_customers_id,ticket_customers_nameeticket_customers_emailvengono registrati suPUT. L’indirizzo e-mail non può essere lasciato vuoto.
v2.77.0
12 settembre 2026Tutto o niente durante l’importazione
?_strict=truerifiuta completamente prodotti, categorie, clienti e ordini con campi sconosciuti (400 UNKNOWN_FIELD) prima che venga scritto qualsiasi dato.
v2.76.0
12 settembre 2026Indirizzare i prodotti tramite l'ID
- È sufficiente un
PUTconproducts_id. I codici articolo assegnati più volte vengono rifiutati invece di associarsi a un articolo qualsiasi.
v2.75.0
12 settembre 2026Filtri precisi per i prodotti
- Novità:
products_modeleproducts_eancome filtri esatti,products_idcome filtro;manufacturers_idora funziona. - Se un singolo ID in un percorso plurale restituisce più record, viene segnalato con
RANGE_START_NOT_SINGLE_RECORD.
v2.74.0
12 settembre 2026Ticket: nessun invio in caso di allegato mancante
- Se un allegato viene rifiutato, non viene inviata alcuna e-mail al cliente; il commento rimane salvato.
- Nuovo campo di risposta
outcome(ok,partial,failed) come criterio affidabile di esito positivo.
v2.73.0
12 settembre 2026Numeri nel JSON senza perdita silenziosa di dati
- Se il riconoscimento dei numeri converte i valori (ad es. zeri iniziali), viene segnalato con
NUMERIC_CHECK_APPLIED.?numeric_check=falserestituisce tali valori invariati come testo.
v2.72.0
12 settembre 2026Recupero dei documenti senza effetti collaterali
- Risolto: il recupero di una rettifica di fattura tramite
order_documentpoteva generare un numero di rettifica. In assenza di una rettifica esistente, l’endpoint ora risponde con409. - I campi non utilizzati di un ordine
PUTrestituiscono il messaggioFIELD_IGNORED_ON_UPDATE. Il metodo di pagamento, l’indirizzo di fatturazione e quello di consegna sono modificabili tramitePUT.
v2.71.0
12 settembre 2026Lettura e scrittura complete delle caratteristiche
- ⚠ Le assegnazioni delle caratteristiche esistenti vengono aggiornate anziché ignorate; i campi non inviati rimangono invariati.
options_replaceeffettua il confronto per differenza – le immagini delle opzioni, il fattore di prezzo base e il prezzo di acquisto non vanno più persi._action: "delete"rimuove una singola assegnazione.- Le caratteristiche appena create vengono segnalate con «
OPTION_CREATED»; «options_strict_names» respinge invece i nomi sconosciuti.
v2.70.0
12 settembre 2026L'eliminazione richiede ora il metodo DELETE
- ⚠ Si prega di verificare la propria connessione. Gli endpoint all’indirizzo
Delete/JSON/accettano d’ora in poi esclusivamente il metodo HTTPDELETE. Qualsiasi altro metodo riceve dall’interfaccia la risposta405 METHOD_NOT_ALLOWEDcon il campo dell’intestazioneAllow: DELETE– e ciò prima che avvenga qualsiasi operazione. - Perché era necessario: finora l’interfaccia non verificava affatto il metodo in questa fase. Una semplice chiamata dell’indirizzo nel browser, un’anteprima di un link o un robot di un motore di ricerca potevano quindi cancellare un record. Era sufficiente che un token di accesso comparisse una sola volta in un indirizzo.
- Impatto pratico: presumibilmente nessuno. Abbiamo analizzato i log di accesso prima della modifica: tutte le richieste di cancellazione osservate utilizzavano già
DELETE. Se invece il vostro programma utilizzaGEToPOST, vi preghiamo di modificarlo.
I messaggi di errore sono ora analizzabili
- Indirizzi sconosciuti, intervalli di numeri non validi ed endpoint inesistenti ora rispondono con JSON e il codice di stato HTTP corretto (
404,400,501) anziché con una riga di testo. Finora, a seconda della modalità operativa dell’ambiente PHP, il server restituiva il codice200– una gestione degli errori che analizza il codice di stato considerava quindi la richiesta andata a buon fine. - Gli oggetti di errore seguono la struttura consueta:
error.code(NOT_FOUND,INVALID_RANGE,NOT_IMPLEMENTED) eerror.message.
v2.69.0
7 settembre 2026I destinatari in copia (CC/BCC) sono ora modificabili
- Nuovo campo «
receivers» suPOST/PUT /ticket(s):{ mode, cc, bcc }. Finora i destinatari erano solo in lettura; la gestione era possibile esclusivamente nella maschera del negozio. - La modalità «
add» (impostazione predefinita) aggiunge, «replace» sostituisce solo gli elenchi specificati, mentre «remove» rimuove singoli indirizzi. Gli indirizzi vengono verificati come nel backend; un elenco contenente solo indirizzi non validi lascia l’elenco invariato – un errore di digitazione non può svuotare un elenco di destinatari. - L’operazione viene eseguita prima dell’inserimento di un commento e dell’invio dell’e-mail nella stessa chiamata: «Aggiungi indirizzo e rispondi» viene quindi eseguito in un’unica operazione.
v2.68.0
31 agosto 2026Categoria principale per ogni prodotto
- Nuovo campo «
main_category_id» nell’entità del prodotto. Determina quale delle diverse assegnazioni di categoria fornisce il percorso della categoria nell’indirizzo, l’indirizzo canonico, la voce nella mappa del sito e l’indicazione della categoria nei feed dei portali dei prezzi. - ⚠ La semantica di importazione si discosta volutamente da
categories: se il campo manca, l’inventario rimane invariato. In caso contrario, qualsiasi programma esistente che aggiorna i prodotti cancellerebbe la categoria principale al primo ciclo. Il valore0annulla questa impostazione. - Una categoria che non è affatto assegnata al prodotto viene rifiutata e segnalata: un’importazione non deve generare un’assegnazione che non corrisponde a nulla.
v2.67.0
26 agosto 2026Il tipo di garanzia è ora importabile
-
warranty_typeNuovo campo «physical» nell’importazione dei prodotti. Sono ammessi «» e «digital»; la grafia viene corretta. Si applica la consueta semantica «array_key_exists»: se la chiave manca, la colonna rimane invariata; una stringa vuota la svuota. - L’esportazione ha sempre fornito questo campo, ma l’importazione non lo riconosceva. Era quindi impossibile effettuare un ciclo completo «esportare, modificare, riscrivere». La versione 2.63.0 aveva colmato la stessa lacuna per i campi relativi alle scorte di magazzino.
- ⚠ Un valore non valido viene rifiutato, non corretto. Riceverete un avviso in
warnings[], mentre il valore esistente rimane invariato. Si tratta di una scelta intenzionale: il campo contribuisce a determinare se il negozio tratta una voce come merce o come contenuto digitale – e quindi influisce sui dati obbligatori relativi alla garanzia.
Senza contratto API, ma risolto contestualmente
- Importazione CSV:
warranty_periodviene ora verificato rispetto ai valori consentiti. Finora, un testo libero veniva semplicemente convertito in minuscolo e poi inserito – modificato, ma altrettanto non valido. Lo stesso vale per una garanzia del produttore non valida, che in precedenza veniva silenziosamente azzerata, cancellando così un dato correttamente inserito. - Importazione prodotti XML: riconosce per la prima volta i sei campi relativi alla garanzia. Se il vostro feed non li fornisce, rimangono invariati – un feed puramente di inventario o di prezzo non modifica nulla.
v2.66.1
25 agosto 2026Gli appuntamenti cancellati scompaiono dall’esportazione dei ticket
- L’esportazione dei ticket continuava a fornire appuntamenti cancellati in modo provvisorio. Chi verificava la cancellazione tramite il ticket la considerava fallita. Il campo interessato era «
linked_appointments[]» di «GET /Export/JSON/tickets». - La causa era un’omissione, non un errore di battitura. Il blocco risale alla v2.11.0 – quattro mesi prima dell’introduzione della cancellazione temporanea degli appuntamenti (v2.44.0) – e non è mai stato aggiornato con il filtro. La funzione “soft-delete” lascia intenzionalmente la riga di collegamento (Undelete e lapide CalDAV), pertanto ogni lettore deve applicare il filtro autonomamente. Il modulo del ticket e il widget degli appuntamenti nel backend lo facevano da sempre – l’API era quindi in contrasto con la propria interfaccia dello stesso negozio.
- ⚠ Modifica del comportamento senza adeguamento da parte vostra:
linked_appointments[]potrebbe diventare più breve e le voci potrebbero scomparire tra due accessi, senza che sia cambiato nulla nel ticket. In questo ramo non ci sono «lapidi». - Le «lapidi» continuano a esistere – e sono più complete:
GET /Export/JSON/appointments?ticket_id={id}&include_deleted=1forniscedeleted_ate le descrizioni in tutte le lingue; per il recupero in batch?include_deleted=1&last_modified=…insieme arelationships[]. Alla risorsa «ticket» non viene assegnato intenzionalmente uninclude_deleted: il nome sarebbe ambiguo in quel contesto, poiché i ticket non prevedono la cancellazione temporanea (soft-delete). - Risolta la stessa causa anche nel backend: otto query collegavano progetti, ordini e ticket tramite appuntamenti, senza verificare la tabella degli appuntamenti. Un appuntamento cancellato continuava a creare collegamenti e i link agli appuntamenti generati da esso portavano a una pagina vuota.
v2.66.0
24 agosto 2026Blocco delle importazioni per la classe fiscale
- Nuovo tipo di blocco «
tax» inimport_blocks. Il motivo è stato il prezzo fisso dei libri: il blocco del prezzo da solo non salva un prezzo di vendita fisso; se il prezzo netto rimane invariato e la classe fiscale cambia durante l’importazione, il prezzo lordocambia comunque, ed è proprio questo il valore fisso. Per i prodotti a prezzo fisso, quindi, impostare sempre insieme aprice. - Il tipo è globale (senza riferimento alla lingua) e viene valutato da tutti gli importatori di prodotti. Nell’esportazione appare automaticamente, poiché
import_blocks[]è indipendente dal tipo. - Correlato nel backend: la scheda articolo presenta ora una scheda «Gestione merci» al posto delle due schede precedenti, che gestivano gli stessi blocchi e si cancellavano a vicenda al momento del salvataggio.
v2.65.0
24 agosto 2026Filtri lato server per l’elenco dei prodotti
- Finora erano disponibili solo
?limite?offset. Chi aveva bisogno di un sottoinsieme doveva recuperare l’intero catalogo pagina per pagina – con 62.000 articoli, 250 richieste per una domanda a cui il database risponde con un’unica query. - Nuovi filtri:
?status=,?tax_class_id=,?categories_id=,?ean_prefix=,?model_prefix=e?last_modified=. Una virgola separa un elenco inclusivo (massimo 100 valori); più filtri vengono combinati con l’operatore AND. Esempio:?ean_prefix=978,979,977&tax_class_id=0,1&status=1trova tutti gli articoli acquistabili con codice EAN “libro” che non rientrano nell’aliquota fiscale ridotta. - Si è scelto consapevolmente di non utilizzare l’operatore «diverso da», poiché l’API non lo riconosce per nessuna entità. «Tutto tranne la classe fiscale 2» va scritto come elenco inclusivo delle restanti classi; in questo modo si mantiene l’indicizzabilità, invece di introdurre un secondo linguaggio di interrogazione.
stats.totalora indica il numero di risultati. In precedenza vi figurava sempre il numero totale di prodotti, indipendentemente dalla richiesta –stats.has_moreera quindi errato.- Un valore di filtro non valido genera un errore (HTTP 400), non un avviso. Se il filtro venisse ignorato silenziosamente, verrebbe restituito il catalogo non filtrato – una ricerca di record errati restituirebbe quindi «nulla trovato». I filtri su una singola risorsa o su un intervallo di ID vengono rifiutati per lo stesso motivo.
include_inactive_productsNon applicabile. Il nome apparteneva all’elenco dei prodotti di una categoria, non è mai stato valutato durante l’esportazione dei prodotti ed è stato sostituito da?status=. Ora genera un avviso invece di rimanere silenziosamente inattivo.- Schema: nuovo indice su
products_last_modified(programma di installazione e autoriparazione; su cataloghi molto grandi viene invece proposto dall’HealthCheck) – senza di esso, il filtro delta comporterebbe una scansione completa della tabella.
v2.64.0
24 agosto 2026Gli indirizzi di consegna possono rimanere vuoti
- Le colonne relative all’indirizzo di un ordine ora supportano il valore NULL (via, città e codice postale per ciascun indirizzo del cliente, di consegna e di fatturazione). Le importazioni dal marketplace in due fasi creano gli ordini con ritiro già prima del pagamento – l’indirizzo non è ancora disponibile e viene aggiunto con il secondo richiamo.
- L’esportazione fornisce per tali ordini
nullinvece di una stringa vuota –nullsignifica «l’indirizzo non è ancora disponibile», una stringa vuota significa «vuoto». Ragione sociale, note aggiuntive sull’indirizzo e regione erano già da sempre compatibili con il valore NULL. - Correzione: i flag relativi alla discrepanza tra indirizzo di fatturazione e indirizzo di consegna ora effettuano un confronto che tiene conto del valore NULL. In precedenza, un campo vuoto veniva erroneamente classificato come «discrepante».
v2.63.0
17 agosto 2026Saldo magazzino leggibile, campi del saldo del magazzino principale modificabili
- L’esportazione fornisce
storages[]: l’esportazione dei prodotti ora include le giacenze di magazzino – per ogni riga di magazzinostorages_id,products_quantity,products_safe_quantity,products_reorder_level,products_storage_texteoptions_id. Fino alla v2.62.0 l’esportazione JSON non le forniva affatto: le giacenze erano scrivibili tramite API, ma non leggibili, rendendo impossibile un roundtrip. Il set di campi corrisponde esattamente a quello dell’importazione, quindi i dati di magazzino esportati possono essere reimportati senza modifiche. - Se il sistema di magazzino esteso è disattivato, la chiave manca del tutto (non come array vuoto): in questo modo un client distingue tra «funzione disattivata» e «nessuna riga di magazzino presente». Vengono visualizzate tutte le righe di magazzino del prodotto, comprese quelle relative ai magazzini inattivi.
- Magazzino principale impostabile tramite importazione:
products_reorder_leveleproducts_safe_quantitysono ora consentiti al livello più alto del prodotto e scrivono nel magazzino principale (la tabellaproducts). Entrambe le colonne erano già presenti nell’esportazione, ma l’importazione le scartava come campi sconosciuti – un prodotto esportato non poteva quindi essere riscritto senza perdite. - Da non confondere: i campi con lo stesso nome all’interno di
storages[]appartengono a un magazzino aggiuntivo.storages_id: 1è già il primo magazzino aggiuntivo – il magazzino principale non è presente nell’elenco dei magazzini. - Correzione
products_quantity: durante l’importazione, le giacenze non vengono più arrotondate a numeri interi. La colonna consente i decimali e, se è attivata l’opzione «Quantità frazionarie nel carrello», questi sono tecnicamente voluti (merci al metro, articoli a peso); finora, da0.5si passava a0, ovvero l’articolo risultava «non disponibile». Modifica visibile per le integrazioni che inviano cifre decimali: il valore ora viene ricevuto, invece di scomparire silenziosamente. - Invariato:
storages[]rimane un aggiornamento parziale senza sincronizzazione completa (v2.45.0); le righe di magazzino non inviate rimangono invariate. L’importazione CSV/XML e il salvataggio nel backend continuano a scrivere la riga di magazzino completa.
v2.62.0
13 agosto 2026Etichetta di garanzia UE (GARAN) tramite interfaccia
- Nuovi campi prodotto:
garan_label_enabled(0/1) attiva l’etichetta di garanzia UE ai sensi del regolamento (UE) 2025/1960 – obbligatoria a partire dal 27/09/2026. A tal fine:garan_brand(marca diversa da quella del catalogo) egaran_model(codice modello per il marchio); una stringa vuota cancella il rispettivo valore. Il codice modello è composto da circa 14 caratteri: valori più lunghi impediscono la visualizzazione del marchio. - L’etichetta è giuridicamente vincolante: ogni approvazione tramite l’interfaccia viene registrata. I requisiti vengono confermati dal gestore del negozio, non dall’API.
- Garanzia del produttore ora espressa in semestri:
manufacturer_guarantee_yearsè un valore decimale. I valori con virgola ("2,5") vengono accettati e arrotondati al semestrale inferiore più vicino, mai per eccesso. Attenzione per i parser rigorosi: l’esportazione ora fornisce"5.0"invece di"5".
v2.61.0
12 agosto 2026Recupero dei documenti giustificativi di un ordine
- Nuovo endpoint:
GET /Export/JSON/order_document/{orders_id}?type=rgfornisce il documento completo in formato JSON con PDF codificato in base64. Tipi di documenti disponibili:of(offerta),ab(conferma d’ordine),rg/rgqr(fattura, a scelta con la parte numerica del codice QR svizzero),ls(bolla di consegna),st(annullamento),pl(distinta di imballaggio),prg(fattura proforma),dr(attestato di donazione) eso. Ambito di applicazioneorders:read. - Perché base64 invece del flusso binario: il campo si chiama
content_base64– esattamente come per gli allegati dei ticket dalla versione 2.60.0. In questo modo è possibile allegare una ricevuta direttamente a un ticket senza bisogno di un file intermedio. - Viene generato esattamente lo stesso documento del backend: viene utilizzato lo stesso renderer degli allegati e-mail, in un processo separato e senza sessione. Se per un ordine è presente un file di fattura archiviato, questo viene fornito.
- Casi di errore evidenti: ordine sconosciuto →
404, documento di fatturazione senza data di fatturazione →409, tipo di documento non consentito →400– in ogni caso come JSON pulito. - Non inclusi: i tipi
eiv_*(XRechnung, ZUGFeRD) sono stati volutamente esclusi, poiché generano file XML anziché PDF.
v2.60.0
11 agosto 2026Gli allegati dei ticket sono ora modificabili
- Nuovo campo
attachments[]:POSTePUT /Import/JSON/ticketsora accettano file – per ogni voce unname(nome file inclusa estensione) econtent_base64(contenuto codificato in Base64). - Comportamento precedente: gli allegati erano solo in lettura (visualizzazione dell’elenco e download a partire dalla v2.9.0); era possibile caricarli solo tramite il modulo del backend. Un ticket creato tramite API rimaneva quindi privo di documentazione: PDF,
.emlo screenshot dovevano essere inviati manualmente in un secondo momento. - Gli allegati sono associati a una voce della cronologia, non al ticket: senza
ticket_commentsnella stessa richiesta non viene creata alcuna voce a cui il file possa essere associato. Il file viene quindi rifiutato con un messaggio di errore invece di essere semplicemente scartato. - Stesse regole del backend: lista bianca delle estensioni identica, stessa convenzione di denominazione e deduplicazione tramite hash per evitare il doppio salvataggio. Il nome del file effettivamente assegnato è riportato nella risposta per ogni record sotto
attachments. Il limite massimo per ogni file corrisponde all’endpoint/media(di default 10 MB). - Tolleranza agli errori: estensioni non consentite, Base64 non valido o superamento della dimensione generano un errore per ogni file; l’aggiornamento del ticket stesso va comunque a buon fine. In caso di risposta pubblica con notifica, i file vengono inviati tramite l’e-mail del cliente.
- Integrazioni esistenti: rimangono funzionanti senza modifiche – il campo è facoltativo, l’estensione è puramente aggiuntiva. Ambito
tickets:write.
Correzioni alla documentazione
- Campi dei commenti corretti: la pagina degli endpoint indicava, durante la creazione di un ticket, i campi
initial_commenteinitial_comment_admin_id– entrambi non esistono nell’interfaccia. Quelli corretti sonoticket_comments(testo del commento) eadmin_id. Anche in fase di aggiornamento,ticket_commentsè un testo, non un array di oggetti. Chi si è basato sulla vecchia descrizione non ha ricevuto alcun commento – e di conseguenza non può nemmeno allegare file, poiché senza una voce nella cronologia non è possibile allegare nulla. - Risposte pubbliche: l’avviso «Le risposte dirette ai clienti non sono possibili tramite l’API» era obsoleto dalla versione v2.25.0 ed è stato sostituito. I flag
is_public_reply,notify_customereappend_signaturesono ora descritti nella tabella dei campi. - Nessuna modifica al codice: questi due punti riguardano esclusivamente la documentazione; il comportamento dell’interfaccia rimane invariato.
v2.59.0
6 agosto 2026Estensioni interne
- Nessuna modifica agli endpoint documentati: questa versione estende esclusivamente un'interfaccia di supporto interna di XONIC. Le operazioni di esportazione, importazione e DELETE mantengono il loro comportamento invariato.
- Integrazioni esistenti: rimangono funzionanti senza necessità di adeguamenti – il numero di versione aumenta semplicemente di uno.
v2.58.0
6 agosto 2026Gruppi di caratteristiche combinati nell’esportazione dei prodotti
- Nuovo campo
option_groups[]: l’esportazione dei prodotti ora include le caratteristiche associate a un gruppo di caratteristiche nel negozio (tipicamente «Colore + Taglia»), compresi i membri del gruppo nell’ordine di visualizzazione e, per ciascuna combinazione, il codice articolo, l’EAN, la quantità, il prezzo e l’ordinamento corrispondenti. - Comportamento precedente: le caratteristiche raggruppate mancavano completamente nell’esportazione – senza campo vuoto e senza alcuna indicazione. Venivano esportate solo le caratteristiche non raggruppate (
options{}). - Perché due campi: in un gruppo di caratteristiche, il codice articolo e l’EAN fanno parte della combinazione di valori («nero / L» = un EAN), mentre in una singola caratteristica fanno parte del singolo valore.
options{}rimane quindi invariato – si tratta di un’estensione puramente additiva. - Invariato: i porter XML e CSV continuano a generare solo caratteristiche non raggruppate. L’importazione continua a richiedere il formato piatto
options[].
v2.57.1
22 luglio 2026Correzione di un bug: prezzi personalizzati per cliente nell’importazione dei prodotti in formato XML
- Importazione prodotti XML: il blocco
customersall’interno digroups(prezzi personalizzati per cliente per ogni prodotto) veniva scartato durante la lettura e non veniva mai inserito nel database; ora le voci vengono importate correttamente. L’assegnazione dei clienti avviene tramiteid(ID cliente del negozio) oexternal(numero cliente WaWi); i numeri cliente sconosciuti vengono ignorati. - Regole chiare per le voci incomplete:
price 0senza prezzi scalari non crea alcuna riga (Rimuovi = ometti la voce – l’importazione riflette integralmente l’elenco dei prezzi cliente per ciascun prodotto); i campiquantity_blocks/min_quantitymancanti vengono precompilati con 1, come nell’importazione REST.
v2.57.0
18 luglio 2026Sconti clienti e prezzi personalizzati
- Clienti: nuovo campo
discounts[]– Gestire gli sconti per i clienti (il campo «Sconti» della gestione clienti) tramite API. Semantica «replace-on-present»: se il campo contiene voci, i dati relativi agli sconti del cliente vengono completamente sostituiti; un[]vuoto rimuove tutti gli sconti; se il campo è assente, gli sconti rimangono invariati. L’esportazione dei clienti ora includediscounts(round-trip). - Importazione dei prodotti: nuovo campo
customers_prices[]– prezzi personalizzati per cliente, inclusi i prezzi scalari, come Partial Upsert (vengono scritte solo le colonne inviate)._action: "delete"rimuove la voce di un cliente,customers_prices_replace: trueattiva la sincronizzazione completa; il cliente viene identificato tramitecustomers_idocustomers_id_extern(numero cliente WaWi). - Importazione clienti:
customers_id_externecustomers_group_idsono ora modificabili;PUTpuò indirizzare il cliente anche senza e-mail tramitecustomers_idocustomers_id_extern(pura gestione degli sconti/dati anagrafici).
v2.56.0
16 luglio 2026Estensioni interne
- Nessuna modifica agli endpoint documentati: questa versione estende esclusivamente un'interfaccia di supporto interna di XONIC. Le operazioni di esportazione, importazione e DELETE rimangono invariate.
- Integrazioni esistenti: continuano a funzionare senza necessità di adeguamenti – il numero di versione aumenta semplicemente di conseguenza.
v2.55.0
15 luglio 2026Estensioni interne
- Nessuna modifica agli endpoint documentati: questa versione amplia esclusivamente un'interfaccia di supporto interna di XONIC. Le operazioni di esportazione, importazione e cancellazione (DELETE) funzionano come prima.
- Integrazioni esistenti: continuano a funzionare senza necessità di adeguamenti – il numero di versione aumenta semplicemente.
v2.54.0
14 luglio 2026Ordini: i campi data – in particolare la data di prestazione – possono ora essere impostati anche per ogni singola posizione. Ciò è necessario per le fatture collettive in cui ogni pacchetto di lavoro ha una propria data di prestazione (i documenti la riportano quindi sotto la rispettiva riga dell’articolo anziché una sola volta nell’intestazione del documento). Inoltre, tramite PUT /orders con products_mode: "append" è possibile aggiungere voci a un ordine esistente; i totali vengono quindi ricalcolati. Gli ordini che sono già considerati fatture – perché è stato assegnato un numero di fattura o perché la serie di numeri individuale è disattivata – vengono rifiutati con il messaggio « ORDER_ALREADY_INVOICED »: una fattura emessa non può essere modificata a posteriori. Gli aggiornamenti relativi allo stato, al tracciamento e alle date non ne sono interessati.
v2.53.0
14 luglio 2026Ordini: il gruppo di date dell’editor degli ordini è ora impostabile tramite API – service_date (data di prestazione), estimated_service_date, shipping_date, estimated_shipping_date, invoice_date (data di fatturazione), invoice_payment_term_date (termine di pagamento) e la data desiderata desired_delivery_date come testo libero. Valido per la creazione di un nuovo record (POST) e per l’aggiornamento (PUT); le date vengono analizzate con tolleranza.
v2.52.0
14 luglio 2026Importazione dei prodotti: con « import_blocks » è possibile proteggere in modo mirato singoli campi di un prodotto esistente dall’importatore XML – ad esempio quando la descrizione in tedesco proviene dal sistema di gestione delle merci, mentre quella in inglese viene gestita nel negozio online. È la controparte programmatica della scheda del backend «xoPort Interfaccia dati (XML)». È possibile proteggere il nome e la descrizione (in base alla lingua) nonché sette categorie di prezzo.
v2.51.0
11 luglio 2026Importazione prodotti: extra_fields ora accetta i campi aggiuntivi a scelta tramite l’ID campo o il nome del campo – come oggetto o come elenco, inclusa la struttura fornita dall’esportazione JSON (round-trip di esportazione/importazione). In precedenza veniva valutato esclusivamente l’elenco con products_extra_fields_id; le grafie divergenti venivano scartate senza alcun avviso. I campi aggiuntivi non risolvibili generano ora un avviso « EXTRA_FIELD », e un campo che si trova erroneamente al livello superiore anziché in extra_fields viene indicato nell’avviso insieme al relativo ID campo. Ciò riguarda, tra l’altro, i campi di Google Shopping.
v2.50.0
30 giugno 2026Ottimizzazioni interne e miglioramenti alla stabilità dell’API xoPort.
v2.49.0
25 giugno 2026DELETE /customer_group/{id} (Ambito customer_groups:delete): eliminazione di un gruppo di clienti con due meccanismi di protezione rigidi – il gruppo 0 (“Clienti finali”) non è eliminabile (403), e un gruppo con clienti ancora assegnati viene rifiutato (409, raggruppare prima). Elimina tutti i dati correlati (sconti, offerte speciali, prezzi di gruppo, voci di gating).
v2.48.0
25 giugno 2026Nuova entità customer_groups (Esportazione + Importazione): enumerare e gestire i gruppi di clienti tramite API – inclusa la lista restricted_categories_ids (lista di esclusione delle categorie del gruppo) già analizzata. POST/PUT con convalida dell’enumerazione e hardcoding dell’ID; POST richiede un customers_group_id esplicito (non AUTO_INCREMENT). Due nuovi ambiti: customer_groups:read + customer_groups:write.
v2.47.0
25 giugno 2026Lista di blocco per categorie e gruppi di clienti: restricted_customer_groups ora disponibile anche per le categorie (in precedenza solo per i prodotti). L’importazione sincronizza customers_groups.restricted_categories, l’esportazione restituisce il campo. Ricorsivo: se si blocca una categoria principale, vengono bloccate anche tutte le sottocategorie attive.
v2.46.0
20 giugno 2026Caricamento file multimediali entity_type=static: nuova modalità con caratteri jolly/lista di esclusione. Con XOPORT_MEDIA_STATIC_FOLDERS = '*' è possibile scrivere in tutte le sottocartelle di images/, ad eccezione di quelle gestite dal sistema immagini (source/, thumbnail/). L’impostazione predefinita rimane la lista di autorizzazione rigorosa; la modalità è opzionale. Rafforzamento della sicurezza: set di caratteri più restrittivo per i nomi delle cartelle, confinamento del percorso in images/ e protezione contro la sovrascrittura (file esistente solo con overwrite:true). Nuovi codici di errore PROTECTED_TARGET_FOLDER (403) e FILE_EXISTS (409).
v2.45.0
19 giugno 2026Importazione prodotti storages[]: aggiornamento parziale. Le giacenze per magazzino vengono ora registrate solo per i campi effettivamente trasmessi (INSERT … ON DUPLICATE KEY UPDATE anziché REPLACE). Un payload parziale come {"storages_id":1,"products_reorder_level":50} modifica quindi solo la giacenza dichiarata e non azzera più le altre colonne relative al magazzino. I payload completi rimangono retrocompatibili.
v2.44.0
18 giugno 2026API Appointments: endpoint calendario indipendente
- Nuova risorsa di primo livello
appointmentscon Full-CRUD:GET /appointments,POST/PUT /appointmentseDELETE /appointment/{id}(Soft-Delete → CalDAV-Tombstone). - Gli appuntamenti vengono creati tramite la logica centrale degli appuntamenti (CalDAV-UID,
updated_at) e compaiono immediatamente nel calendario degli amministratori competenti e nella sincronizzazione CalDAV. - Campi, tra gli altri:
startdate(obbligatorio),enddate/deadline,allday/vacation/private/done, promemoria, titolo/descrizione/luogo (multilingue),responsibilities,followers,categorieserelationships(collegamento a ticket, ordine, cliente o progetto). - Filtri di esportazione: intervallo di tempo, responsabilità, collegamento (ad es.
?ticket_id=) e?last_modified=per la sincronizzazione delta.PUTriceve i campi non specificati. - Tre nuovi ambiti:
appointments:read,appointments:write,appointments:delete.
v2.43.0
18 giugno 2026API dei ticket: creazione di appuntamenti collegati
POST/PUT /ticketsora accetta il campo opzionalelinked_appointments— per ogni ticket è possibile creare direttamente degli appuntamenti.- Ogni voce genera un appuntamento nel calendario e lo collega al ticket. Responsabile = gli amministratori assegnati al ticket, titolo di default = oggetto del ticket.
- Corrispondente al campo di esportazione già esistente
linked_appointments; ambito richiesto:tickets:write.
v2.42.0
15 giugno 2026Tipi di entità slider e slider delle notizie (a partire da Shop 4.8)
- A partire da XONIC 4.8 (tutte le versioni successive alla 4.7.15), la tabella
sliderutilizza la coppia di colonne polimorficheentity_type(category/content/news) +entity_idal posto dicategories_id+content_id. - Il payload dello slider (esportazione e importazione) punta ora a
entity_type+entity_id. I client che inviano ancoracategories_id/content_iddevono adeguarsi. - Nuovo tipo
news: ora è possibile allegare le diapositive anche agli articoli di attualità. Slider della pagina iniziale =entity_type=content,entity_id=0. - I filtri di esportazione
?categories_id=/?content_id=vengono mantenuti e mappati internamente al tipo di entità. I negozi esistenti vengono migrati automaticamente tramite Self-Heal.
v2.41.0
14 giugno 2026API multimediale: allegati a progetti e attività
POST /mediaconentity_type=project(otask) è possibile allegare documenti PDF direttamente a un progetto xoCRM o a un'attività.- Il file viene salvato nell’area file interna e protetta del progetto e appare immediatamente nella scheda «File» — ideale per documenti interni come i piani di progetto.
- Campi obbligatori:
entity_id(ID del progetto o dell’attività, viene verificato),file_namee una fonte (file_url,file_base64o caricamento multipart). - Attualmente sono supportati i file PDF (
application/pdf); ambito richiesto:media:write.
v2.40.0
11 giugno 2026API Projects: inserimento di uno stato senza modifica dello stato
PUT /projectsovvero/project_tasksconstatus_commentora inserisce una voce nella cronologia dello stato anche senza modifica dello stato — ideale per i verbali delle riunioni e le note di lavoro.- Le voci relative alle attività riportano l’
progress_percent: la barra di avanzamento appare nella cronologia.
v2.39.2
11 giugno 2026Correzione di un bug: costi opzionali una tantum nel frontend
- Durante l’importazione delle opzioni con preselezione, ora viene impostato anche
pre_optionnella maschera delle opzioni — in precedenza, la riga «zzgl.» per i costi una tantum delle opzioni non appariva nella pagina del prodotto.pre_optionè inoltre consentito come campo esplicito nel payload. - Correzione al core: il prezzo dell’opzione andava perso se la tabella dei dettagli dell’opzione era completamente vuota.
v2.39.1
11 giugno 2026Correzione di un bug: cache dei prodotti dopo l’importazione
- Dopo ogni importazione di prodotti, le cache dei prodotti vengono aggiornate (preselezione delle opzioni, etichette dei prezzi) — come quando si salva nel backend.
- In precedenza, i sovrapprezzi delle caratteristiche e le modifiche di prezzo impostati tramite API erano visibili nel frontend solo dopo un salvataggio manuale.
v2.39.0
11 giugno 2026Importazione dei prodotti: caratteristiche e opzioni (options[])
- Gli attributi dei prodotti possono ora essere creati tramite
POST/PUT /Import/JSON/products: per ogni voceoption_idoppureoption_name+value_idoppurevalue_name— le opzioni/i valori mancanti vengono creati automaticamente. - Campi di controllo:
option_type(ad es. 5 = solo visualizzazione),option_sort,option_required,price(supplemento),pre_select,status,model,ean,quantity,weight,image. - Le combinazioni già assegnate vengono saltate (avviso
OPTION_EXISTS_SKIPPED);options_replace: truericostruisce completamente gli attributi del prodotto.
v2.38.0
11 giugno 2026Prodotti: lista di blocco dei gruppi di clienti
- Nuovo campo
restricted_customer_groups[]nell'esportazione e nell'importazione dei prodotti: ID dei gruppi per i quali il prodotto è bloccato. - L’importazione sostituisce completamente l’elenco di blocco se il campo è presente nel payload; un array vuoto rimuove tutti i blocchi.
- Ciò consente di trasferire le restrizioni di visibilità (ad es. solo per un determinato gruppo di clienti) da un prodotto all’altro tramite API.
v2.37.0
11 giugno 2026Importazione dei prodotti: Click2Call e blocco dell’acquisto diretto
- Due nuovi flag di prodotto importabili:
click2call(pulsante di chiamata al posto del carrello) enon_directcart(nessun acquisto diretto) — tramitePOST/PUT /Import/JSON/products. - Comportamento come
non_cart/non_price: vengono modificati solo i campi impostati.
v2.36.0
11 giugno 2026API Progetti: voci di stato nell'esportazione
- I progetti e le attività ora forniscono
status_history[]con — tutte le voci di stato gestite nel backend, compresi i commenti (ad es. verbali delle riunioni). - Campi per ogni voce:
status_id+status_name,date_added,comments,progress_percent,user_id+user_name. - Si tratta di un aggiornamento puramente additivo, non introduce un nuovo Scope — è sufficiente
projects:readoproject_tasks:read.
v2.35.0
11 giugno 2026API Progetti: progetti xoCRM e attività di progetto
- Due nuovi tipi di entità:
projects(progetti xoCRM) eproject_tasks(attività di progetto) — con funzioni di esportazione, importazione ed eliminazione per ciascuna. - Endpoint:
GET /Export/JSON/projects(singolo/intervallo/filtro, opzionalmente?include_tasks=1con attività incorporate),POST/PUT /Import/JSON/projects,DELETE /Delete/JSON/project/{id}— analogamente perproject_tasks. - Sei nuovi ambiti:
projects:read/write/delete+project_tasks:read/write/delete. - Progetti: multilingue
descriptions[], categorie, assegnazione ai clienti (customer_scope), responsabili di progetto (leader_admin_ids), collegamenti a ordini/ticket (relationships[]),is_private. - Attività: priorità (1-5), avanzamento (0-100 %), scadenza, ore pianificate/effettive, assegnazione agli incaricati (
assigned_admin_ids). - Gestione degli stati: convalida rispetto alla gestione degli stati, inserimento automatico della cronologia degli stati al momento della creazione e al cambio di stato (
status_comment,admin_id). - Cascata di eliminazione: l’eliminazione del progetto rimuove anche tutte le attività associate; gli ordini/i ticket collegati vengono semplicemente scollegati.
v2.34.0
10 giugno 2026Importazione prodotti: automazione articoli di seconda scelta e nuovi campi
warranty_period: È possibile impostare il periodo di garanzia; una stringa vuota""sovrascrive il valore predefinito24m.products_xoport: Il campo «Marker» (ad es.googleblacklist) è ora importabile.images[]: Assegnazione di immagini aggiuntive del prodotto tramite nome file (sostituisce la galleria esistente), inclusi testi alternativi multilingue; formato array o oggetto.storages[]: Impostare le giacenze per magazzino (multimagazzino) — solo se il sistema multimagazzino è attivo; la giacenza totaleproducts_quantityrimane separata.downloads[]: Creare download di prodotti (ad es. PDF);d_srcrimanda a un file infiles/.- Caricamento di file multimediali:
POST /mediaconentity_type=downloadcarica file PDF/documenti sufiles/.
v2.33.0
9 giugno 2026Autori delle notizie: endpoint newsdesk_authors e author_id
- Nuovo endpoint
/newsdesk_authors: esportare gli autori delle notizie come risorsa a sé stante (GET /newsdesk_authors,GET /newsdesk_author/{id}) e scriverli (POST/PUT /newsdesk_authors). Ambitonews:read/news:write. - Campi: neutri dal punto di vista linguistico
authors_name,authors_image,authors_email,authors_url,authors_company(sovrascrittura del nome dell’azienda per autori esterni),authors_since_year,authors_status,sort_order; per ogni linguaauthors_jobtitleeauthors_bio. - Collegamento
author_id: la funzione di importazione/esportazione delle notizie (newsdesks) ora includeauthor_id— gli articoli possono essere collegati direttamente a un autore.
v2.32.0
7 giugno 2026Importazione ordini: corrispondenza al checkout per riga fiscale e dati aggiuntivi dell’indirizzo
- Riga fiscale per aliquota:
ot_taxviene ora visualizzata nel frontend con un titolo preciso per ogni aliquota — «più IVA al 19%» in modalità netto o «IVA inclusa al 19%» in modalità lordo (solo seMODULE_ORDER_TOTAL_PREFIX=true) — al posto della precedente riga collettiva statica «IVA:». Gli importi rimangono invariati. - Nuovo campo indirizzo
additional_address: ora presente nei campi indirizzo consentiti — l’aggiunta all’indirizzo viene ripresa dacustomers_additional_address,delivery_additional_addressebilling_additional_address(non viene più visualizzato l’avviso relativo aUNKNOWN_FIELD).
v2.31.0
7 giugno 2026Importazione ordini recalc: sconti per categoria e per cliente inclusi nel prezzo
- La modalità "
recalc" ora applica al prezzo della voce, oltre al prezzo di gruppo e alle offerte speciali, anche lo sconto per categoria/cliente (customers_discount+customers_groups_discount, inclusa l'ereditarietà delle sottocategorie — la stessa logica del frontend). - Il prezzo normale viene sempre scontato, mentre l’offerta speciale solo in caso di “
d_special=1”; prevale il prezzo effettivo più conveniente tra i due. In questo modo, l’ordine trasferito riporta esattamente il prezzo che il cliente pagherà al momento del checkout. - Best-effort: in caso di problemi, viene emesso l’avviso
CATEGORY_DISCOUNT_UNAVAILABLEe il calcolo viene effettuato senza sconto. Presupposto: un cliente per ogni richiesta. Gli ordini degli ospiti/del marketplace (senzacustomers_id) rimangono invariati.
v2.30.0
7 giugno 2026Importazione ordini: parità dropship al momento del checkout
- Caratteristiche di sola visualizzazione:
apply_default_attributesora gestisce anche le caratteristiche di visualizzazione con preselezione (tipo di opzione 5, ad es. «Versione»/«Grado di protezione»), compreso il sovrapprezzo indicato — esattamente come vengono riportate al momento del checkout. Restano escluse solo le caratteristiche nascoste interne (tipo 6). - Prezzo di acquisto e GTIN: in modalità
recalc, il prezzo di acquisto (products_ek_pricedaproducts_cost) e il GTIN/EAN (products_ean) vengono caricati nella voce d’ordine, a meno che chi effettua la chiamata non fornisca tali dati. - Nuovo flag
compute_shipping(livello superiore, valore predefinitofalse): in assenza di untotals.shippingesplicito, la spedizione più conveniente viene calcolata in modalità «headless» tramite lo stack di spedizione del frontend (shipping::cheapest()) per l’indirizzo di consegna e registrata comeot_shipping(aliquota fiscale = aliquota fiscale dominante del prodotto). Best-effort: non generano errori, ma restituiscono l’avvisoSHIPPING_AUTO_FAILEDoSHIPPING_AUTO_EMPTY— l’ordine rimane valido. - Caso d’uso: trasferimento in dropshipping (ad es. SPV → SST), in cui l’ordine successivo deve riportare caratteristiche, EK/GTIN e spese di spedizione esattamente come un ordine manuale effettuato sul negozio online.
v2.29.0
7 giugno 2026Importazione ordini: invio facoltativo della conferma d’ordine
- Nuovo flag «
send_confirmation_email» (livello superiore,true): una volta creato con successo l’ordine, la conferma d’ordine standard viene inviata all’acquirente — esattamente come nel normale checkout o negli importatori del marketplace, inclusi i destinatari della copia daSEND_EXTRA_ORDER_EMAILS_TO. - Destinatari e lingua: e-mail dall’ordine creato (con convalida), lingua dal payload o dall’ordine.
- Feedback: il risultato è disponibile come «
confirmation_email_sent» (true/false) nel rispettivo record di dati della risposta. Gli errori di posta elettronica non interrompono l’importazione. - Impostazione predefinita invariata: senza il flag non viene inviata alcuna e-mail (piena retrocompatibilità).
v2.28.0
7 giugno 2026Importazione ordini: compilazione automatica dei dati cliente, risoluzione degli SKU e attributi predefiniti automatici
- Indirizzo di fatturazione dal numero cliente: in caso di
customers_id > 0e dibillingincompleto/mancante, viene utilizzato l’indirizzo di fatturazione predefinito del cliente (anagrafica clienti + rubrica) — i campi forniti esplicitamente hanno la precedenza.deliveryrimane indipendente per indirizzi di consegna diversi. - Risoluzione SKU: le voci possono essere fornite esclusivamente tramite
products_model(= SKU) +products_quantity;products_ideproducts_namevengono integrati dal negozio. SKU sconosciuto → avvisoPRODUCT_MODEL_NOT_FOUND. - Attributi predefiniti automatici:
apply_default_attributes: trueinserisce nell’ordine, per ogni posizione priva di attributi propri, i valori delle opzioni preselezionati nel negozio, compreso il sovrapprezzo. - Correzione del calcolo delle quantità: nella modalità «
recalc», il prezzo unitario netto viene ora salvato correttamente (in precedenza, per quantità > 1, veniva raddoppiato nel subtotale).
v2.27.1
2 giugno 2026Ticket: risposta pubblica tramite API identica a quella dello strumento di backend
- Profilo autore: in modalità "
is_public_reply=true", la voce della cronologia appare sotto il profilo del ticket dell’amministratore che ha effettuato l’operazione (fonteadmin.ticket_settings) anziché sotto il nome e cognome di accesso. Ordine: opzionaleticket_admin_id→admin.ticket_settings→TICKET_DEFAULT_ADMIN_ID→ nome di accesso. - «Risposta incorporata»: il flag
ticket_customer_notified_embeddedviene impostato in caso di risposta pubblica con invio di e-mail — il testo della risposta viene incorporato nell’e-mail del cliente. - CC/BCC: i destinatari CC/BCC del ticket vengono registrati nella voce della cronologia (badge visibile) e inclusi nell’e-mail.
- Verifica dell’invio dell’e-mail: viene valutato il valore restituito dall’invio dell’e-mail — un invio non andato a buon fine genera ora un errore invece di un silenzioso
success.
v2.26.0
1 giugno 2026Esportazione ordini: impaginazione a livello SQL (correzione della memoria)
- Problema: finora
GET /Export/JSON/orderscaricava l’intero record dell’ordine (comprese le voci, i totali e il tracciamento) nella memoria di lavoro e solo successivamente lo suddivideva tramite?limit/?offset— nei negozi con molti ordini ciò causava un errore fatale PHP «Allowed memory size exhausted», anche con?limit=1. - Soluzione:
LIMIT/OFFSETvengono ora — analogamente all’endpoint/products— applicati direttamente alla queryorders_id. Viene caricata solo la pagina richiesta (impostazione predefinita 50, massimo 250 tramiteXOPORT_API_MAX_LIMIT). - Compatibile con i filtri:
stats.totalrispetta i filtri attivi (?status,?customer_id,?date_from/to,?since,?products_id, …); la risposta contienestats.total/limit/offset/has_more. - Invariato: la singola risorsa
/order/{id}e l’intervallo/orders/{a}:{b}rimangono volutamente senza paginazione (come per i prodotti).
v2.25.0
30 maggio 2026Ticket: firma dell’amministratore nelle risposte pubbliche
- Firma automatica: per
is_public_reply: true, il PUT/Import/JSON/ticketsora aggiunge automaticamente al testo della risposta la firma dell’amministratore associata al ticket (admin_settings.signatures.tickets) memorizzata nel backend — sia nella voce della cronologia che nell’e-mail inviata al cliente, esattamente come lo strumento di risposta del backend. - Lingua: lingua predefinita del negozio; in caso contrario, si ricorre alla prima firma memorizzata. Se l’amministratore non dispone di una firma, il testo rimane invariato.
- Opt-out: il flag opzionale
append_signature: false(strettamente booleano) disattiva l’aggiunta della firma. - Importante per i client: in
ticket_commentsnon inviare più una propria firma, altrimenti apparirà due volte.
v2.24.0
29 maggio 2026Ticket: risposte pubbliche + notifica al cliente
- Novità nel blocco Comment del PUT
/Import/JSON/tickets: due flag booleani opzionali per ogni elemento —is_public_reply(true → la voce nella cronologia diventa pubblica) enotify_customer(true → e-mail al cliente). Entrambi sono efficaci solo se rigorosamente=== true, tutti gli altri valori vengono ignorati. - Comportamento predefinito invariato: senza flag, il commento rimane interno (
ticket_internal_comment=1, nessuna e-mail) — retrocompatibile con tutti i client v2.11.0+. - L'invio delle e-mail utilizza lo stesso modello
$mail_ticket_update_with_contentdello strumento di backend (xpanel/tools-ticket-show.php), inclusi CC/BCC daticket_additional_data.receiverse allegati della rispettiva riga della cronologia. - Impostazione predefinita di sicurezza:
is_public_reply=truesenza unadmin_id > 0valido ricade automaticamente su «interno» + «senza e-mail» e restituisce unerror. Non è necessario un nuovo ambito (tickets:writeè sufficiente). - Caso d’uso: gli agenti IA o gli strumenti esterni possono ora rispondere ai ticket non solo come nota interna, ma come vera e propria risposta al cliente — con un chiaro flag di opt-in, in modo che la “pubblicazione accidentale” sia praticamente impossibile.
v2.23.0
29 maggio 2026Prodotti: correzione della risorsa singola + coerenza API
- Correzione di bug:
GET /products/{id}ora restituisce esattamente un prodotto. In precedenza, a causa del routing del percorso plurale, veniva applicata la semantica dell’intervalloWHERE products_id >= {id}— il client visualizzava tramite.data[0]un prodotto casuale tra i risultati della scansione. - MODIFICA SOSTANZIALE per le categorie: il formato di query
?id=introdotto nella v2.1.0 su/categories?id={id}è stato rimosso. A partire da ora, la risorsa singola è disponibile in tutta l’API solo nel formato percorso (/categories/{id},/products/{id}). Motivazione: un URL canonico per ogni risorsa, nessuna sovrapposizione con i filtri in blocco (?limit/?offset/?status/?language). - Rimangono invariati: il formato Range
/products/100:200e l’impaginazione in blocco (?limit=&offset=). - Nota (latente): lo stesso comportamento di routing dei percorsi plurali esiste strutturalmente in
suppliers/manufacturers/vouchers/customers/orders/newsdesks/cms/sliders— è previsto un ticket separato.
v2.22.0
26 maggio 2026API Slider: diapositive promozionali come nuovo tipo di entità
- Nuovi endpoint:
GET /slider(s),POST/PUT /slider,DELETE /slider/{ID}. - Tre nuovi ambiti:
slider:read,slider:write,slider:delete(ID 56–58). - Filtri:
status,type,categories_id,content_id,language. -
languages{}annidati contitle,description,direction,width,image,image_mobile,video,video_mobile. - Contesto: finora le slide promozionali potevano essere gestite solo tramite il backend. Il nuovo endpoint consente, ad esempio, di correggere a posteriori i link errati delle slide tramite
PUT /slider.
v2.21.0
19 maggio 2026Importazione ordini: modalità Totali, imposta automatica e controllo della deriva
- Derivazione automatica da
customers_group_id— Payload a cascata → record cliente → 0 (ospite). - Derivazione automatica da
tax_flagin base acustomers_groups.show_tax+customers_groups.tax_exempt(0=netto, 1=lordo, 2=esente da imposte). I valori espliciti del payload hanno la precedenza. - Tre modalità di calcolo dei totali (
totals_mode):auto(impostazione predefinita, si fa affidamento sui prezzi del chiamante),recalc(ricarica da DBproducts_price+products_tax, con riconoscimento del gruppo clienti e del Paese — ideale per importazioni da marketplace con solo SKU + quantità),verbatim(totals.totalviene salvato 1:1, ideale per rimborsi e reimportazioni storiche). - Controllo delle discrepanze end-to-end tramite
expected_total+strict_totals. In caso di discrepanza > 0,01 €: impostazione predefinita = avviso, constrict_totals: true= interruzione atomica tramiteOrderBuilderException('TOTAL_DRIFT', 422)prima del primo inserimento dei totali. - Convalida della whitelist per tutte le entità degli ordini (
orders,order_address,order_product,order_totals,order_external_reference) — le chiavi sconosciute generano un avviso di deduplicazioneUNKNOWN_FIELD, analogamente a products/customers. - Suite PHPUnit: 17 test, 33 asserzioni (
core/lib/classes/Tests/Order/OrderBuilderTest.php).
v2.20.0
19 maggio 2026Endpoint degli ordini e webhook generico
- Nuovo endpoint
POST/PUT /Import/JSON/orderscon ambitoorders:write— Creazione e aggiornamento degli ordini tramite API. - Servizio generico
\\Xonic\\Order\\OrderBuilder(core/lib/classes/Order/OrderBuilder.php) — riutilizzabile per gli importatori del Marketplace e WaWi. - Eccezioni tipizzate tramite
\\Xonic\\Order\\OrderBuilderExceptionconerrorCode,httpCodeedetails. - Calcolo delle imposte: supporta la modalità lorda (
tax_flag=1) e quella netta (tax_flag=0). - Registrazione delle giacenze tramite
xo_stock_change(Best-Effort: gli errori vengono restituiti comewarnings). - Tracciamento dei riferimenti esterni: inserimento automatico in
TABLE_ORDERS_EXTERNAL_REFERENCESin presenza di un ID esterno. - Risposta di marketing
send_webhook— webhook in uscita generico con firma HMAC-SHA256 e payload arricchito (prodotto, ordine, cliente, ticket).
v2.19.0
15 maggio 2026Endpoint multimediale: caricamenti statici di risorse (entity_type=static)
- Nuova modalità
entity_type=staticnell’endpoint multimediale — consente il caricamento di risorse di branding (loghi, immagini dell’interfaccia) senza collegamento al database. - Configurazione della whitelist: cartelle di destinazione consentite tramite
XOPORT_MEDIA_STATIC_FOLDERS(impostazione predefinita:schnittstellen,marketplaces) — impedisce gli attacchi di tipo path traversal. - Campi obbligatori:
entity_type,target_folder,file_namee una fonte (file_url,file_base64o caricamento multipart). - Comportamento predefinito: sovrascrive i file esistenti (
overwrite=true). La risposta contiene il percorso diretto dell’immagine. - Limitazioni: nessun record nel database, nessuna miniatura, nessun comando DELETE, nessun titolo multilingue. Il comando PUT con
staticviene rifiutato conSTATIC_UPDATE_NOT_SUPPORTED. - Caso d’uso: gestione tramite API di loghi del marketplace, branding delle interfacce e risorse statiche del frontend.
v2.18.0
12 maggio 2026Importazione/esportazione prodotti: upsell (aggiunte al carrello)
- Nuovo campo
upsellsnell’endpoint Products — analogo axsells, ma per i suggerimenti «Abbinamenti consigliati» nel carrello (tabellaproducts_upsell). - Esportazione: per ogni prodotto un array contenente
products_model,products_id(fonte) esort_order. L’esportazione di un singolo prodotto fornisce gli upsell del prodotto richiesto (filtro sul PID di origine). - Importazione tramite PUT: accetta un semplice array di stringhe di modello (
["MODEL-A", "MODEL-B"]) o un array di oggetti ([{"products_model": "MODEL-A", "sort_order": 0}]). - Semantica di sostituzione: gli upsell esistenti vengono completamente eliminati prima dell’inserimento (DELETE-then-INSERT). I riferimenti autoreferenziali e i modelli sconosciuti vengono tacitamente ignorati.
- Caso d’uso: compilazione dei suggerimenti di aggiunta al carrello tramite API — configurabile individualmente per ogni prodotto (nessun elenco predefinito globale).
v2.17.0
7 maggio 2026Importazione prodotti: offerte speciali/promozioni ampliate
- Blocco completo delle offerte speciali:
specials[]per ogni prodotto concustomers_group_id, prezzo speciale diretto odiscount_percent. - Periodo e stato:
specials_begin,specials_end(aliasexpires_date) estatus/special_status. - Denominazioni delle offerte:
specials_price_idoppurespecials_price_name(a seconda della lingua) con "upsert" automatico suslp. - Aggiornamento e cancellazione: «upsert» tramite
(products_id, customers_group_id), rimozione tramiteaction: deleteodelete: 1. Il vecchio bloccospecialrimane retrocompatibile.
v2.16.0
29 aprile 2026API multimediale – Endpoint /media completamente implementato
- Supporto CRUD completo: esportazione (GET), importazione (POST/PUT) ed eliminazione (DELETE) per la libreria delle immagini dei prodotti (
products_images) — finora tutte le operazioni erano stub501 Not Implemented. - Tre modalità di caricamento:
file_url(download dal server tramite cURL),file_base64(inline) emultipart/form-data(campofile). Scelta in base al client e alle dimensioni del file. - Convalida: MIME-Sniff (
image/jpeg|png|gif|webp), limite di dimensione del file tramiteXOPORT_MEDIA_MAX_FILESIZE(impostazione predefinita 10 MB), prevenzione automatica delle collisioni, sanificazione dei nomi dei file. - Titoli multilingue:
descriptions[]conlanguage_idolanguage_codeper ogni immagine. Il comando PUT condescriptionssostituisce completamente (semantica di sincronizzazione completa). - Promozione dell’immagine principale: l’
is_main=1opzionale nel POST imposta ancheproducts.products_image. - Miniature su richiesta: gli URL per mini/small/medium/large/xlarge vengono restituiti in ogni risposta — la generazione fisica avviene al volo tramite
image_thumb.phpal primo richiamo. - DELETE sicuro: rimuove il record, le righe di descrizione, il file sorgente e tutte le miniature — ma solo se nessun altro riferimento del database punta più al nome del file. Cancellazione in blocco tramite
?entity_id=o{ids:[…]}. - Nuovi ambiti:
media:read,media:write,media:delete.
v2.15.0
23 aprile 2026Importazione prodotti: campi Famiglia/Varianti + correzione automatica delle collisioni SEO
- Campi Famiglia/Varianti nell’importazione:
products_family(String-Tag),products_family_type(Integer,3= variante master-slave) eproducts_master(Integer, PID master o autoriferimento) sono ora accettati — consente raggruppamenti master-slave (ad es. varianti di pacchetti) tramite importazione JSON - Flusso di lavoro master-slave: creare il master → leggere il PID da
records[0].products_id→ eseguire un secondo PUT conproducts_master = eigene PIDper l’autoriferimento, quindi assegnare gli slave - Controllo di unicità SEO: durante l’importazione,
seo_name(o, in caso di fallback,products_name_as_seo) viene confrontato con tutti gli altri prodotti — analogamente alla logica del backend - Correzione automatica: in caso di conflitto tra gli slug, il nome viene automaticamente corretto in
<slug>-<PID>(tramitetep_search_new_seo()) — l’importazione proseguesuccess: true - Avvisi di risposta: le correzioni vengono segnalate in
warnings[]tramitetype: "SEO_NAME_CORRECTED", inclusirequested,correctedeconflicting_with.{products_id, products_model, products_name} - Risolve una vulnerabilità preesistente: il backend segnala le collisioni di slug, mentre l’API finora le ignorava, generando prodotti introvabili
v2.14.0
22 aprile 2026Importazione dei prodotti: alias brevi per i campi meta SEO
- Nuovi alias brevi:
title_tag,desc_tag,keywords_tagsono ora accettati nell’importazione dei prodotti — in linea con l’API delle categorie - Mappatura interna: gli alias vengono mappati alle colonne del database
products_head_title_tag,products_head_desc_tageproducts_head_keywords_tag - Priorità: i nomi completi delle colonne hanno la precedenza se vengono inviate entrambe le varianti
- Retrocompatibilità: i payload esistenti con i nomi dei campi lunghi funzionano senza modifiche
- Esportazione: continua a fornire i campi
products_head_*_tag(non gli alias)
v2.13.0
20 aprile 2026Reindirizzamenti automatici della cronologia SEO per tutti i tipi di entità
- In caso di modifiche ai nomi tramite importazione JSON (PUT), ora vengono create automaticamente voci
seo_historyper Products (p), Categories (c), Manufacturers (m), News (n) e CMS (s) — i vecchi URL vengono reindirizzati a quelli nuovi tramite reindirizzamento 301 - Prodotti: correzione — ora funziona anche in caso di rinominazione SENZA un
seo_nameesplicito (tramite rigenerazione automaticaproducts_name_as_seo) - Produttori: indipendente dalla lingua (una voce
sh_history, una riga di descrizione per lingua con lo stesso slug) - Notizie e CMS: specifico per lingua (come Categorie/Prodotti)
- Idempotente: lo stesso payload di rinominazione non genera una seconda voce
- Helper
persistSeoHistory()+buildSeoHistoryDeletestamp()estratti inImportJSON(DRY)
v2.12.0
20 aprile 2026Elenco prodotti per categoria (endpoint leggero)
- Nuovo sub-endpoint:
GET /categories/productlist— Mappatura leggera delle categorie agli ID prodotto e ai modelli - Parametri di query:
?categories_id=,?status=,?include_inactive_products=,?language= - Risposta: per ogni categoria, array contenente
categories_id,categories_name,products_counteproducts[]conid+model - Efficienza di memoria: una singola query SQL anziché 12+ relazioni
Prodotti: paginazione a livello SQL
- Correzione:
GET /productsora utilizza la paginazione a livello SQL (LIMIT/OFFSET direttamente nella query) - Prima: tutti i prodotti + le relazioni caricati in memoria, poi
array_slice() - Dopo: viene caricata dal database solo la pagina richiesta — nessun limite di memoria
- Il recupero singolo tramite
/products/{id}e gli intervalli rimane invariato
v2.11.0
13 aprile 2026
- Ticket CRUD completo: endpoint di importazione (POST/PUT) ed eliminazione per i ticket. Gli ambiti
tickets:writeetickets:deletesono ora attivi. - Esportazione:
linked_appointments[]: gli appuntamenti CRM collegati vengono ora inclusi nell’esportazione per ogni ticket (ID appuntamento, ora di inizio/fine, titolo, descrizione, luogo). - Importazione POST (Creazione): campi obbligatori
ticket_subject,ticket_customers_email,ticket_customers_name. Generaticket_link_id, crea la directory di upload, commento iniziale opzionale + assegnazioni amministrative. - Importazione PUT (Aggiornamento): modifica di stato/priorità/reparto, aggiunta di commenti interni (
ticket_internal_comment=1sempre).admin_idè un campo obbligatorio per i commenti (0 = Sistema). - Elimina: eliminazione a cascata (status_history → admins → followers → appointments_relationships → CRM followers → file → ticket).
- Ambiti:
tickets:write(Importa/Aggiorna),tickets:delete(Elimina) – precedentemente contrassegnati come «in programma», ora pienamente funzionanti.
v2.10.0
9 aprile 2026
- Impaginazione globale: tutti gli endpoint di esportazione supportano
?limit=n&offset=n. Limite predefinito 50, limite massimo 250 (configurabile tramiteXOPORT_API_MAX_LIMIT/XOPORT_API_DEFAULT_LIMIT). La risposta contienestats.count,stats.limit,stats.offset,stats.has_more. - Ticket – Nuovi filtri:
?admin_id=nper i ticket assegnati (INNER JOIN su ticket_to_admins) e?created_by_admin_id=nper il filtro per autore. - Protezione della memoria: l’impaginazione automatica per set di dati di grandi dimensioni impedisce l’esaurimento della memoria.
v2.9.0
8 aprile 2026
- API dei ticket (esportazione): nuovi endpoint
GET /ticketseGET /ticket/{id}per l’esportazione dei ticket con cronologia completa delle conversazioni, amministratori assegnati e follower. - Endpoint degli allegati:
GET /ticket_attachments/{id}per l’elenco dei metadati (nome, dimensione, tipo MIME) eGET /ticket_attachment/{id}?file=nameper il download di file binari con protezione dal path traversal. - Filtri di query:
?status=,?priority=,?department=,?customer_id=,?type=,?date_from=&date_to=,?last_modified=,?language= - Nuovi ambiti:
tickets:read(implementato),tickets:write,tickets:delete(implementato nella v2.11.0) - Metadati:
ticket_statuses,ticket_priorities,ticket_departmentsin ogni risposta
v2.8.1
11 marzo 2026
- Correzione di un bug: Categorie
last_modified: ora viene sempre impostato negli aggiornamenti PUT — anche se vengono aggiornati solo i datilanguages(descrizione, nome ecc.). In precedenza,last_modifiedveniva aggiornato solo se venivano inviati anche i campi della tabella principale (status, parent_id ecc.). - Newsletter
ALLOWED_FIELDS:languagesaggiunto all’elenco dei campi consentiti — non viene più visualizzato l’avviso relativo aUNKNOWN_FIELDdurante l’importazione di newsletter multilingue.
v2.8.0
6 marzo 2026
- API degli iscritti alla newsletter: nuovi endpoint per gli iscritti alla newsletter (Esporta/Importa/Elimina) con supporto DOI.
- API delle campagne di newsletter: nuovi endpoint per le campagne di newsletter (Esporta/Importa/Elimina) con formato multilingue.
- Nuovi ambiti:
newsletter:read,newsletter:write,newsletter:delete,newsletters:read,newsletters:write,newsletters:delete - Supporto DOI:
SHOP_NEWSLETTER_DOUBLE_OPT_INLa configurazione viene rispettata; e-mail di conferma quando il DOI è attivato. - Sincronizzazione con i provider: sincronizzazione automatica con provider esterni (Cleverreach, Mailchimp, Optimizely) tramite
xoNewsletter. - Conformità al GDPR: registrazione dei dati relativi alla privacy in caso di importazione/cancellazione, cancellazioni a cascata documentate.
- Controlli di sicurezza: campagne bloccate protette (
409 LOCKED), newsletter inviate non cancellabili (409 HAS_SENT_ENTRIES). - Filtri per gli iscritti:
?status=confirmed|unconfirmed,?email=,?customer_id=,?language_id=,?last_modified= - Filtro campagne:
?status=,?language_id= - Eliminazione in blocco: è possibile eliminare più iscritti tramite il corpo JSON (per ID o e-mail)
v2.7.0
25 febbraio 2026
- API dei contratti: nuovi endpoint per contratti/abbonamenti (Esporta/Importa/Elimina).
- Endpoint di stato: endpoint dedicato
PUT /contracts/{id}/statusper le modifiche di stato. - Nuovi ambiti:
contracts:read,contracts:write,contracts:delete,contracts:write - Filtri di query:
?status=,?customer_id=,?product_id=,?interval=,?date_from=&date_to=,?active=1 - Dati annidati: Attributi, Domini, Cronologia stati, Ordini
- Eliminazione a cascata: attributi → domini → collegamenti agli ordini → cronologia degli stati → contratto
v2.6.0
24 febbraio 2026
- API Cronologia SEO: nuovi endpoint per i reindirizzamenti SEO (Esporta/Importa/Elimina).
- Reindirizzamento automatico: in caso di modifiche a seo_name nell’importazione JSON di Prodotto/Categoria, vengono create automaticamente voci nella cronologia SEO (analogamente all’importazione XML).
- Nuovi ambiti:
seohistory:read,seohistory:write,seohistory:delete - Filtri di query:
?type=,?base_id=,?language=,?expired=1 - ELIMINAZIONE IN BLOCCO: eliminazione tramite corpo JSON o filtro di query
v2.5.0
23 febbraio 2026
- Campi prodotto estesi: 19 nuovi campi per i dati contrattuali e logistici nell’importazione dei prodotti.
- Campi relativi al contratto:
contract,contract_use_current_price,contract_option— I prodotti contrattuali possono ora essere creati interamente tramite API. - Campi logistici:
products_cost,products_inventory_management,products_min_qty,products_max_qty,products_qty_blocks,products_base_price - Campi articolo:
products_sort_order,products_ean,products_free_shipping,products_image - Flag:
service,sitemap,non_cart,non_price - Assegnazioni:
shipping_profile,products_unit_id,base_unit_id
v2.4.2
19 febbraio 2026
- Importazione prodotti: formato
languagesannidato: coerente con l’esportazione e tutte le altre entità (categorie, redazioni, CMS). Accetta{"languages": {"de": {...}, "en": {...}}}con codici ISO o ID numerici. - Compilazione automatica con INSERT: le lingue mancanti vengono automaticamente inserite con i dati della lingua principale.
- Formato flat rimosso:
products_name+language_ida livello superiore non è più supportato. - Roundtrip simmetrico: Esportazione → Importazione → Esportazione produce dati identici.
v2.4.1
19 febbraio 2026
- Campi SEO nell’importazione dei prodotti: 7 nuovi campi:
products_head_title_tag,products_head_desc_tag,products_head_keywords_tag,seo_name,products_url,products_checkout_description,products_image_title - Consente l'esportazione e l'importazione complete (roundtrip) per tutti i campi di descrizione del prodotto.
v2.4.0
6 febbraio 2026
- Endpoint CMS: nuovo tipo di entità
cmscon operazioni CRUD complete (Esportazione/Importazione/Eliminazione). - Nuovi ambiti:
cms:read,cms:write,cms:delete - Controlli di sicurezza: pagine di sistema (ID 1-999) protette,
content_lockrispettato - Parametri di query:
?status=,?module=,?language= - Supporto multilingua con formato
languagesannidato
v2.3.0
31 gennaio 2026
- CRUD fornitori: nuovi endpoint per i fornitori (Esporta/Importa/Elimina)
- Esportazione prodotti ampliata: campi
videos,suppliers,contenteditor - Esportazione prodotti ampliata:
categories_ids,groups,specials,extra_fields,badges,xsells,tabs,videos,suppliers,contenteditor - Importazione del produttore: tutti i campi GPSR (dati di contatto UE e extra-UE)
- Nuovi ambiti:
suppliers:read/write/delete - Stub: marketing, newsletter, endpoint multimediali (501 non ancora implementati)
v2.2.0
27 gennaio 2026
- Avvisi relativi ai campi sconosciuti: la risposta ora contiene un array
warningsper i campi sconosciuti/ignorati - Deduplicazione: ogni campo sconosciuto appare una sola volta, anche in presenza di oltre 100 record nell’importazione in blocco
- Campi annidati: verifica anche gli oggetti
languages.*eaddresses[] - Non bloccante: la richiesta viene elaborata con successo nonostante gli avvisi (Legge di Postel)
- Oggetto di avviso:
{type, field, entity, message, first_occurrence}
v2.1.0
27 gennaio 2026
- Separazione dei metodi HTTP RESTful:
POST= solo INSERT (creazione di nuovi record)PUT= solo UPDATE (aggiornamento di record esistenti)
- Convalida rigorosa: POST con ID esistente → 409 Conflict, PUT con ID sconosciuto → 404 Not Found
- Nuovo campo di risposta: array «
records» con «{index, entity_id, status}» per ogni record - HTTP 405 Method Not Allowed in caso di metodo errato (ad es. DELETE sull’endpoint di esportazione)
- Tutti gli 8 endpoint delle entità supportano POST/PUT: categories, products, customers, manufacturers, newsdesks, newsdeskcats, faq, faqcats
v2.0.3
26 gennaio 2026
- Endpoint DELETE per newsdesks e newsdeskcats
- Controlli di sicurezza: le categorie con sottocategorie o articoli collegati non possono essere eliminate
- Codici di errore:
HAS_SUBCATEGORIES,HAS_NEWS - Cancellazione della cache dopo DELETE
v2.0.2
26 gennaio 2026
- Newsdesk
categories_idsnell'esportazione e nell'importazione - Gli articoli di notizie ricevono assegnazioni di categoria (come i prodotti)
- Cancellazione della cache dopo l'importazione di newsdesks/newsdeskcats
- Importazione di newsdesk/newsdeskcats con formato "
languages" annidato
v2.0.1
26 gennaio 2026
- Importazione delle categorie con formato
languagesannidato - Chiavi di lingua utilizzabili come codice (
de,en) o ID - Client OAuth2 Interfaccia utente di amministrazione con ricerca in tempo reale e ordinamento
- Registrazione del payload con corpo della richiesta/risposta
v2.0.0 Modifiche compatibilità
26 gennaio 2026
- COMUNICATO: Credenziali client OAuth2 (RFC 6749)
- Chiavi API rimosse - Migrazione a OAuth2 necessaria
- Nuovi endpoint:
POST /oauth/token,GET /me - Nuove tabelle:
xoport_oauth_clients,xoport_oauth_tokens - Prefisso token:
xoat_, Prefisso ID client:xoc_ - Backend: Strumenti → Client OAuth2 di xoPort
v1.5.0
26 gennaio 2026
- Endpoint FAQ (faq/faqcategories Esporta/Importa/Elimina)
/meEndpoint per l'introspezione dell'ambito
v1.4.x
23 gennaio 2026
- Endpoint DELETE per categorie, prodotti, produttori, clienti
- Controlli di sicurezza contro la cancellazione accidentale
- Correzione di un bug: risolto il doppio escaping negli attributi HTML
v1.0.0 - v1.3.x
23 gennaio 2026
- API JSON iniziale con funzioni di esportazione/importazione
- Gestione di più indirizzi per i clienti
- Importazione delle categorie con auto-seo_name
- Filtro per lingua, codici paese ISO-2
- Autenticazione tramite chiave API (deprecata nella v2.0)
Rimani sempre aggiornato
In caso di modifiche sostanziali, vi terremo informati tramite la newsletter.