Guida rapida
Tre passaggi portano uno shop da zero a un ordine sicuro: incorporare il configuratore, verificare il preventivo sul tuo server prima del carrello e accettare il webhook firmato. L'embed esegue per te le chiamate della pagina dello shop; il tuo codice si occupa solo del lato server.
URL di base https://cfg.cutoptim.com · Versione del contratto v1 · Documento OpenAPI 3.1
Accesso anticipato: l'API per i commercianti è pronta e si può provare in uno shop sandbox; i plug-in per le piattaforme di e-commerce sono ancora in sviluppo. CutOptim non incassa alcun pagamento: il carrello, il checkout e il pagamento restano nel tuo shop.
Percorsi, nomi dei campi, codici di errore, nomi degli header ed esempi di codice restano in inglese: sono il contratto.
1. Incorpora il configuratore
Aggiungi lo script e l'elemento alla pagina prodotto, con la tua chiave pubblicabile (pk_live_…, oppure una chiave di test pk_test_… mentre sviluppi). L'origine della pagina deve essere tra le origini consentite della chiave. L'embed chiama poi da solo GET /cfg/v1/config/public, POST /cfg/v1/preview, POST /cfg/v1/quote e POST /cfg/v1/order.
Quando il cliente ordina, il servizio memorizza l'ordine firmato e l'elemento genera l'evento del browser cutoptim:order con { orderId, order, idempotencyKey }. Considera questo evento un suggerimento per la tua pagina, mai una prova del prezzo.
<script type="module" src="https://cfg.cutoptim.com/embed/assets/cutoptim-configurator.js"></script>
<button data-cutoptim-open="#cut">…</button>
<cutoptim-configurator id="cut" mode="modal" key="pk_live_your_publishable_key" lang="it">
</cutoptim-configurator>
<script>
document.getElementById('cut').addEventListener('cutoptim:order', (e) => {
// e.detail = { orderId, order, idempotencyKey } - send it to YOUR server, which verifies it
});
</script>2. Verifica sul tuo server prima del carrello
Il tuo server invia il token del preventivo a POST /cfg/v1/quote/verify con la chiave segreta. La risposta è valid più redeemed; un rifiuto è comunque un 200 con valid: false e un reason. Poi recupera l'ordine indicato dal browser con GET /cfg/v1/orders/{id} e confronta l'hash del piano, l'hash del preventivo, la valuta e i totali con il token verificato. Solo allora crea la riga del carrello, al prezzo verificato.
curl -X POST https://cfg.cutoptim.com/cfg/v1/quote/verify \
-H "Authorization: Bearer $CUTOPTIM_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"quoteToken":"<order.quote.quoteToken>"}'
# {"valid":true,"redeemed":true,"claims":{…},"test":false}
curl https://cfg.cutoptim.com/cfg/v1/orders/<orderId> \
-H "Authorization: Bearer $CUTOPTIM_API_SECRET"
# {"orderId":"…","status":"received","priced":true,"planHash":"…","quoteHash":"…","totals":{…}}3. Ricevi il webhook firmato
Pubblica un endpoint webhook nella configurazione del tuo shop. Ogni ordine reale invia order.created, ogni cambio di stato order.status_changed. Leggi il corpo grezzo, controlla l'header CutOptim-Signature, poi memorizza l'ordine una sola volta per ogni CutOptim-Event-Id. Il ricevitore qui sotto è l'esempio di riferimento, invariato.
// example-server.mjs - a webhook endpoint on node:http, to read and adapt. CUTOPTIM_WEBHOOK_SIGNING=whsec_... node example-server.mjs
// (whsec_REPLACE_ME is a placeholder: the real secret comes from the CutOptim admin route.)
import { createServer } from 'node:http';
import { createWebhookReceiver } from './cutoptim-verify.mjs';
const secret = process.env.CUTOPTIM_WEBHOOK_SIGNING;
if (!secret) { console.error('set CUTOPTIM_WEBHOOK_SIGNING (whsec_REPLACE_ME is a placeholder)'); process.exit(1); }
const receive = createWebhookReceiver({
secrets: [secret],
async onEvent(event) {
// event.type === 'order.created'; event.data.order is the signed order document. Store it in YOUR order table here,
// keyed by event.data.orderId, in the same transaction that records the event id as seen.
console.log('order.created', event.data.orderId);
},
});
createServer(async (req, res) => {
if (req.method !== 'POST') { res.writeHead(405).end(); return; }
const chunks = []; let size = 0;
for await (const c of req) { size += c.length; if (size > 2_000_000) { res.writeHead(413).end(); return; } chunks.push(c); }
const out = await receive({ rawBody: Buffer.concat(chunks), headers: req.headers }); // the RAW bytes, not parsed JSON
res.writeHead(out.status, { 'Content-Type': 'application/json' }).end(JSON.stringify({ result: out.reason }));
}).listen(Number(process.env.PORT ?? 8787));
Avanti
Chiavi, chiavi di test e origini: Chiavi e autenticazione. Il ricevitore completo, la versione PHP e la pianificazione dei nuovi tentativi: Webhook. Una versione passo per passo per la tua piattaforma: Shop personalizzato o ERP.
Qui non c'è un pulsante "provalo" di proposito: la chiave segreta appartiene al tuo server, mai a un browser. Lo shop demo mostra l'incorporamento e il passaggio dell'ordine in funzione da un capo all'altro.
Note legaliCondizioni del configuratore (EN) ·Accordo sul trattamento dei dati (EN) ·Informativa privacy per gli acquirenti ·Licenze di terze parti (EN)