Real-Time 3rd-Party Decisioning

Live processor-agnostic contract for calling an external decisioning provider during transaction authorization

Production: This integration is live. Use the request and response shapes, timeout behavior, and webhook flow below when connecting your decisioning provider to Custodia.

Overview

This document describes the contract for real-time authorization decisioning: normalized request payloads, provider responses, timeout handling, and the asynchronous outcome webhook used when deadlines are missed.

Request Payload (Processor-Agnostic)

Use a normalized authorization event with core required fields and optional enrichment fields.

The decisionDeadlineMs field is the time budget for your provider to return a decision. Appropriate values are dependent on processor requirements and how your program is configured. Speak with a Custodia representative to choose a deadline that fits your processors and use case. The JSON below uses 100 ms as a documentation default only; production values are often different.

{
  "eventId": "uuid",
  "timestamp": "2026-05-13T18:56:00Z",
  "decisionDeadlineMs": 100,
  "transaction": {
    "id": "network_or_processor_txn_id",
    "type": "authorization",
    "channel": "card_present|ecommerce|moto|recurring|wallet",
    "amount": 125.45,
    "currency": "USD",
    "merchant": {
      "id": "mid_if_available",
      "name": "MERCHANT NAME",
      "mcc": "5411",
      "country": "US"
    }
  },
  "card": {
    "token": "internal_card_token",
    "panLast4": "4242",
    "bin": "424242",
    "expiryMonth": 12,
    "expiryYear": 2029,
    "brand": "VISA",
    "funding": "credit|debit|prepaid"
  },
  "cardholder": {
    "customerId": "cust_123",
    "accountId": "acct_456"
  },
  "riskSignals": {
    "avsResult": "Y|N|U|null",
    "cvvResult": "M|N|U|null",
    "is3DS": true,
    "eci": "05",
    "posEntryMode": "chip|swipe|manual|ecom",
    "isInternational": false
  },
  "networkData": {
    "processor": "processor_name",
    "network": "visa|mc|amex|discover",
    "authCode": null,
    "stan": "123456",
    "rrn": "123456789012"
  },
  "metadata": {
    "tenantId": "corp_abc",
    "programId": "program_xyz",
    "idempotencyKey": "same_as_eventId_or_hash"
  },
  "raw": {
    "processorPayload": {}
  }
}

Expected Provider Response

Do not include score or rules metadata in the response. Include totalMs (provider processing time).

{
  "eventId": "uuid",
  "decision": "APPROVE|DECLINE|REVIEW|NO_DECISION",
  "reasonCode": "POLICY_###",
  "reason": "human-readable explanation",
  "totalMs": 87,
  "metadata": {
    "providerRequestId": "abc-123"
  }
}

Required Fields

  • eventId
  • decision
  • totalMs

Optional Fields

  • reasonCode
  • reason
  • metadata.providerRequestId

Timeout / No-Response Handling

If no response is received within the configured timeout (the examples on this page use 100 ms; your production timeout should match the decisionDeadlineMs and limits agreed with Custodia for your processors), support these customer-selectable modes:

  1. Fail-open: authorize on timeout.
  2. Fail-closed: decline on timeout.
  3. Risk-tiered fallback: approve or decline by local risk thresholds (amount, MCC, geography, channel, and so on).
  4. Stand-in local rules: execute internal deterministic policy when the provider is unavailable.
  5. Circuit breaker mode: temporarily bypass the provider after repeated timeout or error thresholds.

Recommended Default

  • Provider timeout: 100 ms in this documentation only; confirm with Custodia based on processor requirements and your decisionDeadlineMs.
  • Default mode: Risk-tiered fallback

Operational safety

  • Require idempotency by eventId.
  • Require schema versioning (schemaVersion) in future revisions.
  • Capture provider latency from totalMs plus internal measured end-to-end latency.

Asynchronous Outcome Webhook (Late Reply Reconciliation)

Why This Exists

There are cases where the provider believes it replied in time, but our platform has already hit timeout and taken an action. In those scenarios, we send a webhook event with the actual final outcome for that stage so both systems reconcile to the same truth.

Card processing is usually a chain of events (for example authorization, incremental authorizations, clearing, reversals, and network advice)-not a single moment-so there may be multiple outcomes or multiple webhook deliveries over the life of one transaction. Each event describes the outcome Custodia applied at that point in the chain, which may differ from what a provider assumed if timing or subsequent network steps changed state.

Webhook Direction

  • Sender: Custodia platform
  • Receiver: Third-party provider webhook endpoint
  • Timing: near-real-time after the final authorization outcome is known

Webhook Event Type

auth.finalized

Webhook Payload

{
  "eventType": "auth.finalized",
  "eventId": "webhook_event_uuid",
  "occurredAt": "2026-05-13T18:56:01Z",
  "correlation": {
    "authEventId": "uuid",
    "providerRequestId": "abc-123"
  },
  "finalOutcome": {
    "decisionApplied": "APPROVE|DECLINE",
    "decisionSource": "PROVIDER_REALTIME|TIMEOUT_FALLBACK|LOCAL_POLICY|MANUAL_OVERRIDE",
    "reasonCode": "TIMEOUT_FAIL_OPEN",
    "reason": "Provider response arrived after decision deadline."
  },
  "timing": {
    "decisionDeadlineMs": 100,
    "providerReportedTotalMs": 115,
    "internalEndToEndMs": 128
  },
  "transaction": {
    "id": "network_or_processor_txn_id",
    "amount": 125.45,
    "currency": "USD",
    "merchant": {
      "id": "mid_if_available",
      "name": "MERCHANT NAME",
      "mcc": "5411",
      "country": "US"
    }
  },
  "metadata": {
    "tenantId": "corp_abc",
    "programId": "program_xyz"
  }
}

Webhook Delivery Requirements

  • At-least-once delivery with retries.
  • Deterministic backoff between delivery attempts, in order: 1 s, then 5 s, then 30 s, then 2 m (120 s), then 10 m (600 s), until a 2xx response or the retry budget is exhausted.
  • Treat HTTP 2xx as success; retry on non-2xx and network timeout.
  • Include an idempotency key using the webhook eventId.

Webhook Security

  • Require an HTTPS endpoint.
  • Sign each event with HMAC (for example X-Custodia-Signature).
  • Include a timestamp header to prevent replay attacks.
  • The provider validates the signature and timestamp window before accepting.

State and Decision Rules

  • The real-time decision path remains authoritative for authorization timing.
  • A late provider response does not change an already-applied authorization decision.
  • Each webhook communicates the final applied decision for that stage of the chain-for audit, analytics, and model tuning-so you can correlate a stream of events to network reality.