Început rapid
Trei pași duc un magazin de la zero la o comandă sigură: integrați configuratorul, verificați oferta pe serverul dumneavoastră înainte de coș și acceptați webhookul semnat. Integrarea face pentru dumneavoastră apelurile din pagina magazinului; codul dumneavoastră se ocupă doar de partea de server.
URL de bază https://cfg.cutoptim.com · Versiunea contractului v1 · Document OpenAPI 3.1
Acces anticipat: API-ul pentru comercianți este construit și poate fi încercat într-un magazin sandbox; pluginurile pentru platformele de magazine sunt încă în dezvoltare. CutOptim nu încasează nicio plată: coșul, finalizarea comenzii și plata rămân în magazinul dumneavoastră.
Căile, numele câmpurilor, codurile de eroare, numele anteturilor și exemplele de cod rămân în engleză: ele sunt contractul.
1. Integrați configuratorul
Adăugați scriptul și elementul în pagina produsului, cu cheia dumneavoastră publică (pk_live_… sau o cheie de test pk_test_… cât construiți). Originea paginii trebuie să fie printre originile permise ale cheii. Integrarea apelează apoi singură GET /cfg/v1/config/public, POST /cfg/v1/preview, POST /cfg/v1/quote și POST /cfg/v1/order.
Când cumpărătorul comandă, serviciul stochează comanda semnată, iar elementul emite evenimentul de browser cutoptim:order cu { orderId, order, idempotencyKey }. Tratați acest eveniment ca pe un indiciu pentru pagina dumneavoastră, niciodată ca pe o dovadă a unui preț.
<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="ro">
</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ți pe serverul dumneavoastră înainte de coș
Serverul dumneavoastră trimite tokenul ofertei la POST /cfg/v1/quote/verify cu cheia secretă. Răspunsul este valid plus redeemed; un refuz este tot un 200, cu valid: false și un reason. Apoi caută comanda indicată de browser cu GET /cfg/v1/orders/{id} și compară hashul planului, hashul ofertei, moneda și totalurile cu tokenul verificat. Abia atunci creează linia de coș, la prețul verificat.
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. Primiți webhookul semnat
Publicați un endpoint de webhook în configurația magazinului dumneavoastră. Fiecare comandă reală trimite order.created, fiecare schimbare de stare order.status_changed. Citiți corpul brut, verificați antetul CutOptim-Signature, apoi stocați comanda o singură dată per CutOptim-Event-Id. Receptorul de mai jos este exemplul de referință, neschimbat.
// 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));
Mai departe
Chei, chei de test și origini: Chei și autentificare. Receptorul complet, versiunea PHP și programul reîncercărilor: Webhookuri. O versiune pas cu pas pentru propria platformă: Magazin propriu sau ERP.
Aici nu există intenționat un buton „încearcă”: cheia secretă aparține serverului dumneavoastră, niciodată unui browser. Magazinul demo arată integrarea și predarea comenzii funcționând de la cap la coadă.
JuridicTermenii configuratorului (EN) ·Acord de prelucrare a datelor (EN) ·Notă de confidențialitate pentru cumpărători ·Licențe terțe (EN)