/api/v1 e usano la chiave publishable (o il dominio del negozio).
Importi come stringhe. I campi decimali di prodotti, carrello, checkout e ordini
(
price, unit_price, subtotal, total…) arrivano come stringhe ("1199.00").
Convertili prima di fare calcoli: in JavaScript "10.00" + "5.00" concatena invece di
sommare. Per i soldi usa una libreria decimale o lavora in centesimi.1. Catalogo & ricerca
- I filtri
min_price,max_pricee l’ordinamentosort=price/sort=-pricelavorano sul prezzo effettivo (saldo attivo e prezzo speciale), emeta.totalcoincide sempre con le righe filtrate.in_stock=truetiene solo i prodotti con una variante acquistabile. - Nella lista,
sale_priceè il saldo attivo della variante oppure lo speciale, se più basso;nullsenza sconti attivi.
GET /products/{slug}) ci sono due campi nuovi:
sale_price è null fuori dalla finestra del saldo (sale_start–sale_end).
Una variante con track_inventory: false è acquistabile anche a giacenza 0.
2. Carrello
Il carrello funziona per ospiti (con un token di sessione) e per clienti loggati.Carrello cross-origin / headless. Il carrello ospite è legato a un token di sessione,
restituito nel campo
session_token della risposta. Se il tuo storefront gira su un dominio
diverso dall’API (es. xxxx.com → api.vellaro.io), il cookie cx_cart (SameSite=Lax) non
viaggia cross-site: salva session_token lato client (es. localStorage) e rimandalo su
ogni chiamata al carrello e al checkout come header X-Cart-Token. Così il carrello
persiste ovunque e si ripristina al ritorno (TTL 7 giorni). Se sei same-origin, basta il
cookie e l’header è opzionale.Il carrello all’accesso
Quando l’ospite accede, il suo carrello si unisce a quello dell’account alla prima chiamata autenticata al carrello, o al checkout, che porta ancora il token ospite (X-Cart-Token o
cookie cx_cart):
- lo stesso articolo si somma, ma mai oltre le scorte disponibili;
- gli articoli non più in vendita restano fuori;
- il carrello ospite viene eliminato, e lo stesso token non si unisce due volte.
- continua a mandare
X-Cart-Tokenanche dopo il login; - ricarica il carrello subito dopo l’accesso (password, social o registrazione), così il badge e il cassetto mostrano gli articoli uniti;
- quando la risposta del carrello ha
user_idvalorizzato, smetti di usare il token ospite; - all’uscita togli dallo schermo il carrello dell’account.
Il prezzo da mostrare è unit_price
Ogni riga porta il prezzo davvero applicato, che tiene già conto di saldo, prezzo speciale,
sconto a quantità e gruppo del cliente: unit_price, con line_total = unit_price × quantity.
Mostra quello. variant.price e variant.sale_price sono prezzi di listino e non vanno usati
per righe e totali.
Le regole del negozio
Il carrello espone le regole che il checkout applica, così puoi mostrarle prima del pagamento:min_order_total: ordine minimo sulsubtotal(zero = nessun minimo). Sotto la soglia, mostra quanto manca e disattiva il pulsante di pagamento.guest_checkout_enabled: confalseil negozio accetta ordini solo da clienti registrati. Chiedi login o registrazione prima del checkout.
3. Checkout & pagamento
Prendi i metodi di pagamento sempre dalla lista pubblica: il checkout accetta solo quelli. Ogni metodo è uncode stabile (stripe, paypal, pokpay, paysera, bank_transfer,
cod) da tradurre nel client.
client_secret/redirect da completare
lato client, altri confermano subito. Un ordine online mai pagato si può riaprire con
POST /orders/{order_id}/pay («Paga ora»): stessa risposta del checkout, stesso ordine.
Vedi la API Reference per lo schema esatto di POST /checkout.
Errori delle regole del negozio
Lo sconto di un coupon non supera mai il subtotale, e un coupon «spedizione gratuita» azzera
la spedizione.
Buono regalo
Il cliente inserisce il codice del buono e tu lo mandi invoucher_code. Il saldo paga il
totale dopo il coupon, spedizione compresa.
- Il saldo viene prenotato quando nasce l’ordine e diventa definitivo al pagamento: due checkout non possono spendere lo stesso saldo.
- Il saldo torna sul buono quando il tentativo di pagamento è chiuso davvero (pagamento annullato, tentativo sostituito da un nuovo checkout, ordine annullato dal negozio) e, per un ordine pagato, con il rimborso totale o l’annullo. Una carta rifiutata non libera il buono, perché lo stesso pagamento si può ritentare.
- Se il buono copre tutto il totale, la risposta ha
payment_method: "voucher"e nessun dato di gateway: l’ordine è già pagato, vai alla pagina di conferma. - La risposta porta
voucher_code,voucher_amount(importo usato) evoucher_remaining(saldo che resta, da mostrare al cliente). - Il buono non paga un abbonamento.
4. Ordini & tracking
history) che vede il cliente è filtrata:
- contiene solo cambi di stato (
event_type: "status_change") e note pubbliche (event_type: "note"); pagamenti, rimborsi, spedizioni ed email restano allo staff; - una riga di stato scritta dal sistema ha
comment: null: traduci lostatusnel client. Il commento resta solo se lo ha scritto lo staff e lo ha reso pubblico; - una nota ha
status: null.
payment_status può valere anche partially_refunded; payment_method può valere voucher.
5. Abbonamenti
Un prodotto può avere piani ricorrenti (recurrings nel dettaglio prodotto). Il cliente si
abbona al checkout con subscribe_recurring_id (serve il login e payment_method: "stripe").
- All’acquisto si paga il prezzo del prodotto; ai rinnovi il prezzo del piano (
price). - La «prova» sposta solo il primo rinnovo: arriva dopo
trial_lengthunità ditrial_frequencyinvece che dopo un intervallo.trial_pricenon è applicato. billing_intervaldice ogni quantefrequencysi rinnova;billing_chargesè il numero di addebiti in tutto, acquisto compreso (0= fino all’annullo).
GET /account/subscriptions lo stato può essere active, trialing, past_due,
paused, canceled oppure completed: concluso, tutte le rate addebitate e
next_billing_date: null. Su un abbonamento completed nascondi il pulsante di annullo:
POST /account/subscriptions/{id}/cancel risponde 409 subscription.already_completed.
Consulente rapido: la lista completa di parametri, corpi e risposte è nella
API Reference, generata dallo schema OpenAPI live — quindi sempre
allineata alla produzione.
Campagne
Un link di campagna ha la formahttps://<negozio>/…?cmp=<codice>. Quando lo storefront trova
il parametro cmp, chiama una volta per browser:
counted: false per le successive) e un
codice sconosciuto risponde 200 con counted: false. Limite: 30 richieste al minuto per IP.
Aspetto & configurazione
GET /settings/store-info— nome, contatti, social, appearance (logo, colori) per brandizzare il tuo frontend come il negozio. Contiene anche:catalog.items_per_page(prodotti per pagina,null= scegli tu) ecatalog.default_sort(ordinamento predefinito delle categorie, già nella sintassi diGET /products?sort=, oppurenull);seo.meta_title_defaulteseo.meta_description_default: titolo e descrizione per le pagine senza meta propri (stringa vuota = non impostati).
GET /banners,GET /information/<slug>— contenuti CMS e hero.GET /languages,GET /currencies— per selettori lingua/valuta.