Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
When a NestJS fintech backend’s transaction totals do not match the payment processor, recording status changes and reconciling records solve different parts of the problem. Keep a traceable history of each state transition, then regularly compare internal transactions with processor records. Save mismatches as durable exceptions and route them to someone who can investigate them.
That is the repair described by Peace Melodi in an account of a backend where the internal ledger and processor records were “off by a small amount.” The article describes a few transactions and a few dollars, but provides no measured totals, sample size, or independently verified outcome. Treat it as a useful incident pattern, not proof of a quantified result. Read the original account.
Why a mutable transaction status is not enough
A field such as status = 'settled' tells you the current value, but not who or what changed it, when it changed, or whether competing code paths tried to update it. If a webhook handler, a scheduled task, and an API request can all write transaction state, overwriting the field erases useful provenance.
Recommended Free Tools
Melodi’s proposed event record includes a transaction ID, event type, source, and creation time. The current status can then be derived from the latest event rather than being the only surviving evidence of the transaction’s history. The article’s example is a sketch, not a complete ledger design: it does not define deterministic ordering for simultaneous events, duplicate-event handling, concurrent writes, reversal rules, access controls, or retention.
#1 Best Overall
Event history makes changes explainable, but it cannot show an external event that never reached your service. It also cannot repair a discrepancy that existed before the history was introduced. Those are reasons to pair it with reconciliation.
How to reconcile internal records with the processor
Run a recurring process that compares your internal transaction records with the payment processor’s records. The schedule and matching criteria depend on the processor and business; the incident account does not prescribe a specific interval, API, or matching algorithm. At a minimum, define which transactions are in scope and how to match them reliably, then distinguish missing records, amount differences, and state differences.
Do not make the reconciliation job’s only output a log line. Persist each mismatch as an exception with enough context to investigate, assign it an owner-visible status, and notify the finance or operations team responsible for resolving it. Track the investigation through resolution instead of silently overwriting the original transaction state.
History and reconciliation are complementary: history helps explain how internal state changed, while reconciliation can surface drift between internal and external records. Neither alone prevents duplicate writes or ensures that every detected exception gets resolved.
Rank #3
Make retries and concurrent writes safe
Recording events does not automatically make event appends safe. A request can be retried, multiple instances can process the same webhook, or two code paths can race. Enforce idempotency at the write boundary and retain the business-state checks that determine whether a transition is allowed.
NestJS’s idempotency guidance describes using a stable idempotency key backed by shared, durable storage. An in-memory key is lost on restart and is not shared between application instances. Use atomic store operations, scope keys appropriately, and pass a derived stable key to the payment provider where supported so a failure after a charge does not lead to a second charge on retry.
Rank #4
Be explicit about the boundary: an idempotency record is not automatically committed as part of the business database transaction. Design for the failure cases between recording the request, changing business state, and calling the provider.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsNestJS workflow guidance also warns that workflow effects can run at least once. Pass the stable step idempotency key to external services. If a workflow must be coupled atomically to a business write, the documentation describes starting it within that business transaction. See the NestJS workflow documentation.
Best Value
Keep monetary representation precise
Status-history fixes do not address arithmetic errors. Binary floating-point values approximate some decimal fractions, including 0.1, so avoid treating ordinary floating-point numbers as exact currency amounts. A NestJS.io tutorial on handling money describes integer minor units as a common option and fixed-precision numeric values as an alternative when calculations require fractional minor units.
- Integer minor units: Store amounts as whole units such as cents where the currency and operation permit it. Choose a type with sufficient range; the tutorial’s bounded SQL integer example is not suitable for every balance.
- Fixed precision: Use an appropriately defined decimal type when the domain requires fractional minor units or precise decimal calculations. Define scale and rounding rules explicitly.
- Currency policy: The currency’s scale and the application’s rounding rules are domain decisions, not universal constants. PostgreSQL’s
MONEYformatting and precision are locale-dependent, according to the tutorial.
Model corrections and balance updates deliberately
For financial records, consider whether a correction should change or delete prior history, or instead create a new compensating entry such as a reversal. A public NestJS ledger repository demonstrates immutable journal entries, reversal entries, atomic materialized-balance updates, deterministic lock ordering, BigInt arithmetic, and a transactional outbox. These are examples from one individual implementation, not a framework guarantee or independently verified standard. View the repository.
Whatever model you use, define the invariants that must hold across entries and derived balances, and ensure related writes commit together. NestJS’s database page describes a transaction as a coherent unit of work, but the cited example is from the version 7 documentation; consult current documentation for the ORM and database APIs in your application before adopting its code. NestJS database documentation.
Quick Recap
A practical repair sequence
- Preserve evidence: Add a durable transition history with transaction ID, event type, source, and timestamp. Specify ordering, uniqueness, and permitted transitions rather than assuming timestamps alone settle races.
- Protect writes: Make event processing idempotent with stable keys and shared atomic storage. Keep business-state validation at the point where a write occurs.
- Compare both sides: Implement recurring reconciliation against the processor’s records, with explicit matching rules and handling for records that are absent or disagree.
- Make exceptions actionable: Persist mismatches, assign investigation ownership, alert the appropriate team, and retain a resolution trail.
- Review money and transaction boundaries: Choose a suitable exact representation, set currency-specific rounding rules, and keep journal, balance, and workflow changes consistent under failure.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

