Transaction Synchronisation Guide

1. Purpose

Integrators who run their own internal ledger must keep it faithfully aligned with the authoritative ledger held by the NoFrixion API. This guide explains a synchronisation pattern that blends webhooks (for low latency) with polling (for completeness).


2. Core Concepts

ConceptDescription
PayoutInstruction to move funds out of an account. Can complete successfully or end in a failure state.
TransactionImmutable ledger entry recorded when funds actually move: either outgoing (TransactionPayout) or incoming (TransactionPayin). Its presence is the authoritative proof that a payout succeeded.

Rule of thumb
If a Transaction for the payout exists → payout succeeded.

If no Transaction for the payout exists but the Payout has a failure status → payout failed.


3. High‑Level Strategy

  1. Subscribe to Webhooks for the critical resources:
    • Payout (Updated → failure states)
    • TransactionPayin (Created)
    • TransactionPayout (Created)
  2. On receipt of any of those webhooks trigger a sync job.
  3. Poll every five minutes (or a cadence that matches your latency tolerance) using:
    • GET /transactions/{accountID}/from/{sequenceNumber} – reconcile forward from your last processed sequence number.
    • GET /payouts/{merchantID}/failed – pick up any failures that weren’t already captured.
  4. Apply idempotent ledger logic (detailed in #5) to bring your ledger to a consistent, gap‑free state.


Why both? Webhooks give you near‑real‑time triggers, while polling guarantees you never miss an event even if a webhook delivery is lost.


4. Polling Endpoints

Use this endpoint to fetch only the transactions you have not yet processed. Supply the account’s UUID and the last accountSequenceNumber you stored; the API returns every newer entry in order, making catch‑up fast and deterministic.

curl -H "Authorization: Bearer {ACCESS_TOKEN}" \
     "https://api-sandbox.nofrixion.com/api/v1/transactions/{ACCOUNT_ID}/from/{LAST_SEQUENCE_NUMBER}?pageSize=20"
  • ACCOUNT_ID – UUID of the account whose ledger you are syncing.
  • LAST_SEQUENCE_NUMBER – The most recent accountSequenceNumber you have successfully applied (use 0 on initial sync).

Tip: store the highest accountSequenceNumber you see in each response and pass it back on the next call — that guarantees gap‑free replication.

Use this endpoint to retrieve only those payouts that have transitioned to a failure state. Supply the merchant’s UUID and, after your first run, a fromDateUtc filter so you never fetch the same failure twice.

curl -H "Authorization: Bearer {ACCESS_TOKEN}" \
     "https://api-sandbox.nofrixion.com/api/v1/payouts/{MERCHANT_ID}/failed?fromDateUtc={LAST_SYNC_DATE}&pageSize=20"
  • MERCHANT_ID – UUID of the merchant you are reconciling.
  • LAST_SYNC_DATE – Timestamp representing the last moment you successfully scanned for failures (omit on first call).

Tip: after processing, persist the most recent failure timestamp you saw and feed it back as fromDateUtc on the next call—this keeps queries light and idempotent.


Keeping two ledgers in agreement boils down to track, trigger, reconcile, repeat:

  1. Track your position
    • For each account, record the last accountSequenceNumber you processed. • For each merchant, record the timestamp when you last checked for failed payouts.
  2. Trigger a reconciliation whenever something important happens
    Start a sync run whenever you receive a webhook of type TransactionPayin Created, TransactionPayout Created, or Payout Updated (failure or completion). Webhooks are your nudge that new data probably exists.
  3. Reconcile
    • Pull new transactions using GET /transactions/\{accountID}/from/\{sequenceNumber} and record them in your ledger. • Pull recent payout failures using GET /payouts/\{merchantID}/failed?fromDateUtc=<your stored timestamp> and mark those payouts as failed.
  4. Repeat on a timer
    Run the same reconciliation on a schedule—say every five minutes—so you still catch events if a webhook is lost or delayed.

6. Example Timeline

TimeEventYour System Action
12:00Payout initiatedNo action.
12:00:05Payout Updated (status Processing) webhookTrigger sync. Nothing new yet.
12:01TransactionPayout Created webhookTrigger sync → pulls new Transaction (#123) via sequence API. Mark payout success.
12:04Network drops a webhookNo immediate action.
12:05Poller runsMissing Transaction #124 is detected and applied. Consistency restored.