Vai al contenuto principale
Questa guida mostra il flusso principale di uno storefront. Tutti gli endpoint sono sotto /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_price e l’ordinamento sort=price / sort=-price lavorano sul prezzo effettivo (saldo attivo e prezzo speciale), e meta.total coincide sempre con le righe filtrate. in_stock=true tiene solo i prodotti con una variante acquistabile.
  • Nella lista, sale_price è il saldo attivo della variante oppure lo speciale, se più basso; null senza sconti attivi.
Nel dettaglio prodotto (GET /products/{slug}) ci sono due campi nuovi:
Nelle varianti 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.
Cosa fare nel client:
  1. continua a mandare X-Cart-Token anche dopo il login;
  2. ricarica il carrello subito dopo l’accesso (password, social o registrazione), così il badge e il cassetto mostrano gli articoli uniti;
  3. quando la risposta del carrello ha user_id valorizzato, smetti di usare il token ospite;
  4. 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 sul subtotal (zero = nessun minimo). Sotto la soglia, mostra quanto manca e disattiva il pulsante di pagamento.
  • guest_checkout_enabled: con false il 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 è un code stabile (stripe, paypal, pokpay, paysera, bank_transfer, cod) da tradurre nel client.
La risposta di checkout indica il flusso di pagamento (Stripe, PayPal, PokPay, Paysera, contrassegno, bonifico): alcuni restituiscono un 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 in voucher_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) e voucher_remaining (saldo che resta, da mostrare al cliente).
  • Il buono non paga un abbonamento.

4. Ordini & tracking

La cronologia (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 lo status nel 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_length unità di trial_frequency invece che dopo un intervallo. trial_price non è applicato.
  • billing_interval dice ogni quante frequency si rinnova; billing_charges è il numero di addebiti in tutto, acquisto compreso (0 = fino all’annullo).
In 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 forma https://<negozio>/…?cmp=<codice>. Quando lo storefront trova il parametro cmp, chiama una volta per browser:
La stessa visita conta una volta ogni 30 minuti (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) e catalog.default_sort (ordinamento predefinito delle categorie, già nella sintassi di GET /products?sort=, oppure null);
    • seo.meta_title_default e seo.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.