Zugangsdaten bleiben auf Ihrem Backend
Dauerhafte Zugangsdaten gehören nicht in Browsercode und können bei Bedarf erneuert werden.
TRUSTIKS API
Eine klar umrissene Schnittstelle für Softwareteams, die ein eindeutiges Ergebnis benötigen, ohne selbst eine vollständige Prüfinfrastruktur betreiben zu müssen.
Für den zuverlässigen Betrieb entwickelt
Dauerhafte Zugangsdaten gehören nicht in Browsercode und können bei Bedarf erneuert werden.
Jede Browserprüfung erhält einen eigenen Token; das Endergebnis wird zusätzlich von Ihrem Server bestätigt.
Jede Entscheidung lässt sich auf die verwendete Regelwerks- und Modellversion zurückführen.
EINDEUTIGES ERGEBNIS ALS STANDARD
Sie integrieren eine kompakte Schnittstelle. TRUSTIKS übernimmt Qualitätskontrolle, Verarbeitung und die abschließende Entscheidung anhand des hinterlegten Regelwerks.
POST /v1/verifications
{
"id": "vrf_123456",
"status": "approved"
}SHOP-INTEGRATION
Binden Sie das TRUSTIKS-Widget in Ihren Shop ein, öffnen Sie es vor einer geschützten Aktion und bestätigen Sie jedes Ergebnis auf Ihrem eigenen Server.
Direkt vor </body> im globalen Theme oder Layout einfügen.
Trustiks.verify vor Warenkorb, Checkout oder geschütztem Zugriff aufrufen.
sessionToken an Ihr Backend senden und nur bei approved fortfahren.
Browser-Ablauf und Serverbestätigung vor der Freigabe für Kunden testen.
Nur die öffentliche Widget-ID gehört in Browser-Code. Dauerhafte Zugangsdaten bleiben auf Ihrem Server.
| Kennung | Ausgabe | Speicherort | Öffentlich? |
|---|---|---|---|
pub_… · Öffentliche Widget-ID | Beim Erstellen eines Website-Geräts | HTML und Trustiks.verify | Ja |
dk_… + ds_… · Gerätezugangsdaten | Widget → 02 · API Credentials; Secret einmal sichtbar | Server-Umgebungsvariablen | Nein |
sessionToken · Prüfungs-UUID | Pro Prüfung; result.sessionToken | Mit Bestellung/Session verknüpfen und als verwendet speichern | Ja, aber niemals vertrauen |
Das Browser-Ergebnis dient nur der Benutzeroberfläche. Ihr Backend bestätigt die Entscheidung bei TRUSTIKS.
Device Key und einmal sichtbares Secret unter Widget → 02 · API Credentials kopieren.
TRUSTIKS_DEVICE_KEY und TRUSTIKS_DEVICE_SECRET ausschließlich im Backend speichern.
sessionToken und Ihre Bestell-/Session-ID empfangen und TRUSTIKS mit beiden Headern aufrufen.
Nach 1–2 Sekunden wiederholen. Nach 120 Sekunden wird eine offene Prüfung als rejected gemeldet.
Akzeptierten Token dauerhaft genau einer Bestellung/Session zuordnen und nie zweimal annehmen.
Deployment vorbereiten, Secret neu erzeugen und Env sofort aktualisieren. Das alte Secret wird sofort ungültig.
GET {API_BASE}/v1/verifications/{sessionToken}X-Device-Key: dk_…{"id":"<uuid>","status":"approved|rejected|in_progress"}Es werden keine Zeitstempel geliefert. Abgeschlossene Ergebnisse verfallen nicht.Für Prüfungen gibt es keine Webhooks: verwenden Sie Polling. Der Serverbestätigungstest im Dashboard gilt erst als abgeschlossen, wenn Ihr Server diesen authentifizierten GET für die Testprüfung ausführt.
Ersetzen Sie die öffentliche Widget-ID im HTML. Geräteschlüssel und Secret gehören ausschließlich in Server-Umgebungsvariablen.
<!-- Add once before </body> in your site-wide layout. -->
<script src="https://www.trustiks.com/widget.js"
data-client-id="YOUR_PUBLIC_WIDGET_ID"></script>
<button id="age-checkout" type="button">Continue to checkout</button>
<script>
document.getElementById("age-checkout").addEventListener("click", function () {
Trustiks.verify({
onComplete: async function (result) {
const response = await fetch("/api/verify-age", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ sessionToken: result.sessionToken, orderId: "YOUR_ORDER_ID" })
});
const decision = await response.json();
if (response.status === 200 && decision.approved === true) {
window.location.href = "/checkout";
} else if (decision.status === "in_progress") {
alert("Verification is still processing. Please try again shortly.");
} else {
alert("Age verification was not approved.");
}
}
});
});
</script>// Express server. Implement the two storage helpers with durable storage.
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
app.post("/api/verify-age", express.json(), async (req, res) => {
const { sessionToken, orderId } = req.body;
if (typeof sessionToken !== "string" || typeof orderId !== "string")
return res.status(400).json({ approved: false });
// session_token must have a UNIQUE constraint.
if (await sessionTokenWasUsed(sessionToken))
return res.status(409).json({ approved: false, status: "already_used" });
// ~15 s at most: stay inside your server's request timeout. The widget has
// already waited for the result, so in_progress here is rare; on 202 the
// browser can simply ask again.
for (let attempt = 0; attempt < 10; attempt += 1) {
const response = await fetch(
process.env.TRUSTIKS_API_URL + "/v1/verifications/" + encodeURIComponent(sessionToken),
{ headers: {
"X-Device-Key": process.env.TRUSTIKS_DEVICE_KEY,
"X-Device-Secret": process.env.TRUSTIKS_DEVICE_SECRET
}}
);
if (!response.ok) return res.status(502).json({ approved: false });
const result = await response.json();
if (result.status === "in_progress") {
await wait(1500); // Poll again after 1–2 seconds.
continue;
}
if (result.status === "rejected")
return res.status(403).json({ approved: false, status: "rejected" });
if (result.status === "approved") {
// Atomically bind the token to this order; false means it was reused.
const saved = await useSessionTokenOnce(sessionToken, orderId);
if (!saved) return res.status(409).json({ approved: false, status: "already_used" });
return res.status(200).json({ approved: true, status: "approved" });
}
return res.status(502).json({ approved: false });
}
return res.status(202).json({ approved: false, status: "in_progress" });
});<?php
// PHP server. Implement both storage helpers with durable storage.
$payload = json_decode(file_get_contents('php://input'), true);
$sessionToken = $payload['sessionToken'] ?? '';
$orderId = $payload['orderId'] ?? '';
header('Content-Type: application/json');
if (!is_string($sessionToken) || $sessionToken === '' || !is_string($orderId) || $orderId === '') {
http_response_code(400);
echo json_encode(['approved' => false]);
exit;
}
// session_token must have a UNIQUE constraint.
if (session_token_was_used($sessionToken)) {
http_response_code(409);
echo json_encode(['approved' => false, 'status' => 'already_used']);
exit;
}
$lastStatus = '';
// ~15 s at most: stay inside max_execution_time. The widget has already
// waited for the result, so in_progress here is rare; on 202 ask again.
for ($attempt = 0; $attempt < 10; $attempt++) {
$url = getenv('TRUSTIKS_API_URL') . '/v1/verifications/' . rawurlencode($sessionToken);
$curl = curl_init($url);
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [
'X-Device-Key: ' . getenv('TRUSTIKS_DEVICE_KEY'),
'X-Device-Secret: ' . getenv('TRUSTIKS_DEVICE_SECRET'),
]]);
$body = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) break;
$status = (json_decode($body ?: '{}', true)['status'] ?? '');
$lastStatus = $status;
if ($status === 'in_progress') { usleep(1500000); continue; }
if ($status === 'rejected') {
http_response_code(403);
echo json_encode(['approved' => false, 'status' => 'rejected']);
exit;
}
if ($status === 'approved') {
// Atomically bind the token to this order; false means it was reused.
$saved = use_session_token_once($sessionToken, $orderId);
http_response_code($saved ? 200 : 409);
echo json_encode(['approved' => $saved, 'status' => $saved ? 'approved' : 'already_used']);
exit;
}
break;
}
http_response_code($lastStatus === 'in_progress' ? 202 : 502);
echo json_encode(['approved' => false, 'status' => $lastStatus]);TRUSTIKS gibt bewusst nur drei Prüfstatus aus. Die geschützte Aktion bleibt gesperrt, bis Ihr Server approved erhält.
approvedErst nach einer aktuellen Serverbestätigung fortfahren. sessionToken als verwendet speichern, damit er keine weitere Bestellung freigibt.
rejectedNicht fortfahren. Dies umfasst Ablehnung, Abbruch durch den Kunden, Timeout und internen Fehler. Falls erlaubt, eine neue Prüfung starten.
in_progressNoch nicht fortfahren. TRUSTIKS nach kurzer Verzögerung erneut vom Server abfragen und nach Ihrem eigenen Timeout aufhören.
Der Browser-Callback aktualisiert die Oberfläche. Die Server-zu-Server-Antwort entscheidet über den Zugriff.
Eine fertige Shopify-Integration ist für Mitte Oktober 2026 geplant.
Eine fertige WooCommerce- und WordPress-Integration ist für Ende November 2026 geplant.
TRUSTIKS
Beschreiben Sie uns Ihren Automatenpark, Ihr Zahlungsterminal, Ihre Website oder Ihren Shop. Erstellen Sie ein Konto oder schreiben Sie an integration[at]trustiks.com.