Resources / Engineering

Fintech software design principles we follow

Practical engineering rules for software that handles money: correctness, idempotency, auditability, verified webhooks, and privacy by design.

By the Jinhub Technologies team · Updated October 2026 · 3 min read

Money software has a different bar

In most applications a small bug is an annoyance. In software that records, moves or summarises money, a small bug can mean a customer is charged twice, a balance silently drifts, or a report cannot be explained to an auditor. Users rarely forgive those mistakes, and they are expensive to unwind.

The principles below are the ones we apply to anything at Jinhub that touches financial data, from our Portfolio Management tool to the payment flow on this website's Contribute page.

Correctness first: store money exactly

Binary floating-point numbers cannot represent most decimal fractions exactly, so they should never be used to store or calculate money. Use integer amounts in the smallest unit (paise) or a decimal type, and decide explicitly where and how rounding happens. We cover this in detail in our article on handling money in software.

Correctness also means handling the boring edge cases deliberately: refunds larger than the original charge, corrections to past records, currency precision, and dates near month or financial-year boundaries.

Make operations safe to retry

Networks fail at inconvenient moments. A user taps 'pay', the request reaches the server, the payment succeeds, and the response is lost on the way back. The app sees a timeout and the user taps again.

Payment and transaction endpoints should therefore be idempotent: repeating the same request must have the same effect as sending it once. Common techniques:

  • Attach a unique key to each operation and refuse to process the same key twice.
  • Record a payment's state transitions (created, authorised, captured, refunded) and ignore transitions that have already happened.
  • Use database constraints, not only application code, to prevent duplicate records.

Verify everything that arrives from outside

Payment gateways typically notify your server of events through webhooks. Anyone who discovers a webhook URL can send requests to it, so a webhook must never be trusted just because it arrived.

Gateways such as Razorpay, which processes contributions on this site, sign each webhook payload with a shared secret. The receiving server recomputes the signature and rejects anything that does not match. Beyond that, confirm the payment status with the gateway before granting anything of value, handle duplicate deliveries gracefully, and keep secrets in environment configuration rather than in source code.

Auditability by default

A trustworthy financial system can always answer: what changed, when, why, and who or what made the change. That is far easier to design in than to add later.

  • Prefer appending correcting entries over editing or deleting historical records.
  • Keep references to external identifiers, such as gateway payment IDs, so every record can be matched against a third-party statement.
  • Log state changes with timestamps in a consistent time zone.
  • Make reconciliation a routine job, not an emergency procedure.

Good audit trails also cut support time: when a user asks why a number looks wrong, the answer is a lookup rather than an investigation.

Privacy as a product feature

Financial data is among the most sensitive information people share. Collect only what the product needs, never store full card details when a payment gateway can hold them instead, restrict who inside the organisation can view personal financial records, and encrypt data in transit with HTTPS everywhere.

Clear language matters as much as technical controls. Users should be able to understand what is stored and why without reading a legal document.

Design for explanation

Finally, every number shown to a user should be explainable. If a dashboard shows a total, the user should be able to see what it is made of. This single rule prevents a large class of support problems and is the most visible sign to users that the software can be trusted.