Docs

Custom platform integration

If your platform can sign an HTTP request with HMAC-SHA256, it can talk to Fraud Command Center.

Overview

Custom integrations are a single HTTP POST per order. There is no SDK to install, no library version to keep up with — just a stable JSON contract and an HMAC signature.

Step 1 — Issue credentials

Create an API key for your store in Settings → API keys. You'll receive:

  • An API key (begins with fcc_live_).
  • An HMAC secret, shown once. Store it somewhere safe — you can't recover it later, only rotate.

Step 2 — Build the request

Construct the canonical string and HMAC-SHA256 it with your secret:

canonical = "{timestamp}.{nonce}.{body}"
signature = hmac_sha256(hmac_secret, canonical).hexdigest()

Python example

import time, uuid, hmac, hashlib, json, requests

API_KEY = "fcc_live_..."
HMAC_SECRET = "..."  # the secret you received once

def score_order(order):
    body = json.dumps(order, separators=(",", ":"))
    timestamp = str(int(time.time()))
    nonce = str(uuid.uuid4())
    canonical = f"{timestamp}.{nonce}.{body}"
    signature = hmac.new(
        HMAC_SECRET.encode(),
        canonical.encode(),
        hashlib.sha256,
    ).hexdigest()

    return requests.post(
        "https://api.fraudcommandcenter.com/v1/analyze",
        data=body,
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {API_KEY}",
            "X-Fraudshield-Key": API_KEY,
            "X-Fraudshield-Timestamp": timestamp,
            "X-Fraudshield-Nonce": nonce,
            "X-Fraudshield-Signature": signature,
        },
        timeout=5,
    ).json()

Node example

import { createHmac, randomUUID } from "node:crypto";

async function scoreOrder(order) {
  const body = JSON.stringify(order);
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const nonce = randomUUID();
  const canonical = `${timestamp}.${nonce}.${body}`;
  const signature = createHmac("sha256", HMAC_SECRET).update(canonical).digest("hex");

  const res = await fetch("https://api.fraudcommandcenter.com/v1/analyze", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${API_KEY}`,
      "X-Fraudshield-Key": API_KEY,
      "X-Fraudshield-Timestamp": timestamp,
      "X-Fraudshield-Nonce": nonce,
      "X-Fraudshield-Signature": signature,
    },
    body,
  });
  return res.json();
}

Step 3 — Act on the verdict

The response has risk_score, risk_level, and recommended_action. Wire your storefront to:

  • approve — capture as normal.
  • review — surface in your ops queue (or leave the dashboard to handle it).
  • hold — don't capture; the order sits pending until a human decides.

Idempotency

Send the same order_id twice and you'll get the same score back. The analyzer is deterministic on identical inputs and de-duplicates within an hour via Redis keyed by (store_id, order_id).

Retries

On 5xx, retry with the same body and headers — the nonce will be invalidated, but a fresh nonce and timestamp are fine. On 401 due to bad signature, the nonce is deliberately released so a legitimate retry isn't blocked.

Limits

  • Per-store rate limit: 100 requests / minute by default. Email us to raise.
  • Request body: 256 KB max.
  • Timestamp skew: 300 seconds.