DEV Community

Cover image for Designing a Secure Transaction Lifecycle: From Intent Creation to Settlement Confirmation
Vaibhav Shakya
Vaibhav Shakya

Posted on

Designing a Secure Transaction Lifecycle: From Intent Creation to Settlement Confirmation

Designing a Secure Transaction Lifecycle: From Intent Creation to Settlement Confirmation

A payment transaction is not a single API call. It is a distributed workflow across the customer device, backend, external payment systems, message infrastructure, ledger, and reconciliation process.

These components do not share one transaction boundary. They may time out independently, deliver duplicate or delayed events, or temporarily disagree about the result.

Begin With a Server-Owned Intent

The mobile application should request a payment, not determine its financial truth.

The backend retrieves the authoritative order, calculates the amount from server-controlled data, verifies ownership and eligibility, and creates a stable transaction intent.

Individual external interactions should be stored as separate attempts. This preserves the history of unresolved outcomes, declines, retries, and eventual capture.

Make Retries Idempotent

A request may begin or complete processing even when its response is lost. If the customer retries with a new operation identity, the platform can create a duplicate charge.

The client should reuse the same operation key for the same logical action. The backend should bind that key to the authenticated principal, operation, and canonical request fingerprint.

Durable uniqueness is essential because concurrent requests can reach different API instances. Application-level checks alone do not close that race.

Use an Explicit State Machine

Transaction status should be governed by validated transitions rather than arbitrary updates.

A lifecycle may include CREATED, PROCESSING, REQUIRES_CUSTOMER_ACTION, AUTHORIZED, CAPTURED, SETTLEMENT_PENDING, and SETTLED.

The exact states depend on the payment rail. Each transition should preserve its source, previous state, timestamp, correlation identifier, and reason.

Keep the Mobile Client Outside the Trust Boundary

Mobile clients can initiate transactions and present results, but they should not declare financial success.

Redirects, deep links, and SDK callbacks are user-experience signals. The backend should determine state through authenticated external events, server-to-server queries, or other appropriate evidence.

Integrity and application-attestation signals can strengthen risk decisions, but their coverage and behaviour vary. They do not prove customer identity or eliminate fraud.

Authenticate and Deduplicate Webhooks

External events should be authenticated, validated, durably recorded, and processed idempotently.

Deduplicating an event identifier prevents repeated handling of that event object, but separate events may still describe the same business transition. State guards and business-level idempotency remain necessary.

For reliable internal propagation, write the state change and outbox record in the same local database transaction. Downstream consumers must still tolerate repeated delivery.

Separate Transaction State From the Ledger

A transaction record describes operational progress. A ledger records how balances changed.

Ledger postings should be balanced and append-oriented. Fees, refunds, reversals, chargebacks, and settlements should create additional postings instead of rewriting financial history.

Capture Is Not Settlement

Authorization, capture, settlement, and payout describe different facts, although some payment methods may combine or hide particular stages.

Settlement should be confirmed using the evidence available for the applicable payment rail. Reconciliation should compare identifiers, amounts, currency, fees, and merchant ownership.

When values disagree, preserve both sides and create an exception instead of forcing the internal record to match.

Design for Ambiguous Outcomes

Assume that an external system can succeed while the backend times out, an event can arrive more than once, and fulfilment can fail after capture.

Correctness comes from stable identifiers, durable idempotency, controlled transitions, balanced ledger postings, and reconciliation—not from assuming every request has a clean response.

Practical Takeaway

A secure transaction lifecycle needs:

  • A server-owned intent
  • Separate payment attempts
  • Durable idempotency
  • Explicit state transitions
  • Authenticated asynchronous events
  • Idempotent consumers
  • Balanced, append-oriented ledger postings
  • Settlement reconciliation
  • Complete audit and repair trails

Read the complete Medium article: https://medium.com/@vaibhav.shakya786/designing-a-secure-transaction-lifecycle-from-intent-creation-to-settlement-confirmation-272666741fa9

Top comments (0)