When a payment changes state, Fintech Core delivers a webhook to every active endpoint the venture has registered. Each endpoint has its own signing secret.

Events

EventWhen
PAYMENT_COMPLETEDPayment was paid
PAYMENT_REFUSEDDeclined by the issuer/processor
PAYMENT_REFUNDEDA paid payment was refunded
PAYMENT_CANCELEDAuthorization reversed/canceled
PAYMENT_FAILEDTechnical or unknown terminal failure
PAYMENT_EXPIREDExpired without completion

Payload

A POST with Content-Type: application/json:
{
  "event": "PAYMENT_COMPLETED",
  "payment_id": "…",
  "venture_id": "…",
  "order_ref": "INV-1042",
  "satim_order_id": "…",
  "status": "PAID",
  "amount": "5000.00",
  "currency": "012",
  "occurred_at": "2026-05-29T10:00:00Z"
}

Verifying the signature

Each request carries an X-Signature: sha256=<hex> header — an HMAC-SHA256 of the raw request body using that endpoint’s secret. Always verify it before trusting the payload:
import hmac, hashlib

def verify(secret: str, raw_body: bytes, header: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
Compute the HMAC over the exact bytes received (do not re-serialize the JSON first).

Delivery & retries

  • Each (endpoint, event) is delivered independently; a 2xx marks it delivered.
  • Non-2xx or network errors are retried with exponential backoff (up to 8 attempts), then marked failed.
  • Retries resend identical bytes, so the signature stays valid. Deduplicate on payment_id + event if you process at-least-once.
Manage endpoints (add, rotate secret, disable) in Managing ventures.