GODAMRI
Fintech•Jan 2025•11 min read

Designing Payment Systems for Failure

Idempotency keys, reconciliation loops, and surviving third-party gateway timeouts in high-volume QRIS transaction flows.

In payment engineering, failure is not an edge case; it is the default state of the network. Third-party acquiring banks timeout, QRIS provider webhooks drop, and users frantically double-tap "Pay" on unstable cellular connections.

When handling real money, distributed transactions cannot afford the luxury of two-phase commits across external vendor APIs. Here are the core patterns we rely on to guarantee financial correctness and zero double-debits.


1. Cryptographic Idempotency Keys

Every state mutation begins with a client-supplied or gateway-generated idempotency key:

$$\text{Key} = \text{SHA256}(\text{TenantID} + \text{OrderID} + \text{AttemptNumber})$$

Before charging any ledger, the worker acquires a transactional lock with a unique constraint:

sql
source
INSERT INTO payment_requests (
    idempotency_key, 
    order_id, 
    amount_cents, 
    status, 
    created_at
) VALUES (
    $1, $2, $3, 'PENDING', NOW()
)
ON CONFLICT (idempotency_key) DO NOTHING
RETURNING id;

If the insert returns null, the request is a duplicate. We immediately return the status of the ongoing or completed transaction rather than dispatching a duplicate payment call to the acquirer.


2. The Asynchronous Reconciliation Loop

Never trust a single synchronous HTTP response from an upstream payment gateway. A network timeout on your outgoing request does not mean the customer's card was not charged.

We treat all outgoing charges as UNKNOWN until verified:

plain
source
[Payment Initiated] ──(Acquirer Gateway)──> [Network Timeout / Socket Drop]
         │
         ▼
[Mark Status: PENDING_VERIFICATION]
         │
         ▼
[Reconciliation Worker Cron (Every 30s)]
  ├─ Query Acquirer Gateway Status API
  ├─ Verify Signature & Settlement Reference
  └─ If Settled: Credit Ledger
     If Expired: Reverse Hold & Notify User

This asynchronous reconciliation worker ensures that even if our servers crash mid-transaction, ledger integrity is restored within seconds of system recovery.