Zum Hauptinhalt springen
← API-Referenz

Schnellstart

Drei Schritte führen einen Shop von null zu einer sicheren Bestellung: den Configurator einbetten, das Angebot vor dem Warenkorb auf Ihrem Server prüfen und den signierten Webhook annehmen. Das Embed erledigt die Aufrufe der Shopseite für Sie; Ihr Code übernimmt nur die Serverseite.

Basis-URL https://cfg.cutoptim.com · Vertragsversion v1 · OpenAPI-3.1-Dokument

Early Access: Die Händler-API ist gebaut und lässt sich in einem Sandbox-Shop ausprobieren; Plug-ins für Shopsysteme sind noch in Entwicklung. CutOptim nimmt keine Zahlung entgegen: Warenkorb, Kasse und Zahlung bleiben in Ihrem Shop.

Pfade, Feldnamen, Fehlercodes, Header-Namen und Codebeispiele bleiben englisch: Sie sind der Vertrag.

1. Den Configurator einbetten

Fügen Sie Skript und Element mit Ihrem öffentlichen Schlüssel (pk_live_…, oder während der Entwicklung ein Testschlüssel pk_test_…) in die Produktseite ein. Die Origin der Seite muss zu den erlaubten Origins des Schlüssels gehören. Das Embed ruft dann GET /cfg/v1/config/public, POST /cfg/v1/preview, POST /cfg/v1/quote und POST /cfg/v1/order selbst auf.

Wenn der Kunde bestellt, speichert der Dienst die signierte Bestellung, und das Element löst das Browser-Ereignis cutoptim:order mit { orderId, order, idempotencyKey } aus. Betrachten Sie dieses Ereignis als Hinweis für Ihre Seite, nie als Beweis für einen Preis.

<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="de">
</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. Auf Ihrem Server vor dem Warenkorb prüfen

Ihr Server sendet das Angebots-Token mit dem geheimen Schlüssel an POST /cfg/v1/quote/verify. Die Antwort lautet valid plus redeemed; eine Ablehnung ist weiterhin ein 200 mit valid: false und einem reason. Dann ruft er die vom Browser genannte Bestellung mit GET /cfg/v1/orders/{id} ab und vergleicht Plan-Hash, Angebots-Hash, Währung und Summen mit dem geprüften Token. Erst danach legt er die Warenkorbposition zum geprüften Preis an.

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. Den signierten Webhook empfangen

Veröffentlichen Sie in Ihrer Shop-Konfiguration einen Webhook-Endpunkt. Jede Live-Bestellung sendet order.created, jede Statusänderung order.status_changed. Lesen Sie den rohen Body, prüfen Sie den Header CutOptim-Signature und speichern Sie die Bestellung dann einmal pro CutOptim-Event-Id. Der Empfänger unten ist das unveränderte Referenzbeispiel.

// 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));

Weiter

Schlüssel, Testschlüssel und Origins: Schlüssel und Authentifizierung. Der vollständige Empfänger, die PHP-Version und der Wiederholungsplan: Webhooks. Eine Schritt-für-Schritt-Fassung für Ihre eigene Plattform: Eigener Shop oder ERP.

Eine Schaltfläche "Ausprobieren" gibt es hier mit Absicht nicht: Der geheime Schlüssel gehört auf Ihren Server, nie in einen Browser. Der Demo-Shop zeigt Einbettung und Bestellübergabe von Anfang bis Ende.

RechtlichesKonfigurator-Bedingungen (EN) ·Auftragsverarbeitungsvertrag (EN) ·Datenschutzhinweis für Käufer ·Drittanbieter-Lizenzen (EN)