फिनटेक इंजीनियरिंग हैंडबुक
(w.pitula.me)- जो सिस्टम पैसे को मुख्य state के रूप में संभालते हैं, उन्हें इस सिद्धांत पर डिज़ाइन किया जाना चाहिए कि वे डेटा नहीं बनाते, उसे खोते नहीं, और किसी चीज़ पर भरोसा नहीं करते
- रकम को represent करने में float से बचना चाहिए और
BigDecimal, सबसे छोटी इकाई वाले integers, rational numbers आदि को जिम्मेदारी के हिसाब से मिलाकर इस्तेमाल करना चाहिए; JSON number serialization भी IEEE-754 double की समस्या फिर से पैदा कर सकता है - ledger को double-entry bookkeeping, immutable audit trail, value time·booking time·settlement time के अलगाव, और correction·cancellation records के जरिए balances और reports को फिर से reconstruct करने योग्य बनाए रखना चाहिए
- असली पैसे के flow में reservations, idempotency, restartable state machines, external API·webhook verification, outbox·CDC, और reconciliation के जरिए double-spending और omissions को रोकना चाहिए
- access control, four-eyes approval, SDLC change tracking, property-based testing और fault injection, internal operators और code changes तक को trust boundary की तरह treat करने पर मजबूर करते हैं
Fintech systems के मूल सिद्धांत
- software engineering में, जहाँ पैसा system की मुख्य चिंता हो, सामान्य CRUD की तुलना में traceability, immutability और verifiability कहीं अधिक महत्वपूर्ण हैं
- लक्षित पाठक वे लोग हैं जो fintech में नए आए हैं, जो पहले से fintech में काम कर रहे हैं, या जो fintech के बाहर से यह समझना चाहते हैं कि money systems सामान्य systems से कैसे अलग होते हैं
- सभी patterns तीन सिद्धांतों को बनाए रखने के साधन हैं
- No invented data: पैसा कहीं से भी बनाया नहीं जा सकता, इसलिए duplicate processing और arbitrary balance changes की अनुमति नहीं होती
- No lost data: पैसे के साथ जो कुछ भी हुआ है, वह track और persist किया जाना चाहिए
- No trust: external providers, internal components और real world पर भरोसा नहीं किया जाता, बल्कि verify किया जाता है
पैसे को represent करने के तरीके
- रकम का representation financial systems का सबसे बुनियादी decision है; गलत चुनाव करने पर ऊपर की पूरी layer errors inherit करती है
- float/double unpredictable precision loss पैदा कर सकते हैं, इसलिए लगभग हमेशा अच्छा विकल्प नहीं हैं
- इनके फायदे हैं कि ये तेज़, memory-efficient होते हैं और extra libraries या data structures की जरूरत नहीं होती
BigDecimalजैसे arbitrary precision types calculation precision और rounding की जगह को explicit रूप से control करने देते हैं- ये FX या pricing calculations जैसे कई operations वाले intermediate calculations के लिए उपयुक्त हैं
- सबसे छोटी इकाई वाले integers में storage, ज्यादातर fiat currencies में central bank systems जैसी fixed precision का तरीका है
- €12.34 को
1234के रूप में store किया जाता है - ISO 4217 की decimal places का पालन करना चाहिए और यह assume नहीं करना चाहिए कि हमेशा 2 digits होंगे
- cryptocurrencies भी satoshi, wei जैसी smallest unit integers का इस्तेमाल करती हैं, लेकिन precision asset के हिसाब से अलग होती है और ERC-20 के
decimalsकी तरह token इसे define करता है - cryptocurrency amounts 64-bit integers से बड़े हो सकते हैं, इसलिए arbitrary-width integers की जरूरत पड़ सकती है
- €12.34 को
- rational numbers तब सबसे शक्तिशाली होते हैं जब precision loss स्वीकार्य नहीं होता, लेकिन ये धीमे होते हैं, दूसरे formats में बिना precision loss के convert करना मुश्किल होता है, और आम तौर पर custom type या library की जरूरत होती है
- storage method और calculation method अलग decisions हैं; एक system integer storage और
BigDecimalintermediate calculations दोनों साथ इस्तेमाल कर सकता है - amount serialization में भी boundaries संभालना महत्वपूर्ण है
- सामान्य JSON numbers ज्यादातर parsers में IEEE-754 double होते हैं, इसलिए internal representation में सावधानी रखने पर भी boundary पर float problem फिर से आ सकती है
- पैसा
"12.34"जैसी string या smallest unit integer के रूप में भेजना चाहिए
Rounding और currency handling
- Rounding division, currency conversion, fees, interest, ratios apply करने और precision shift में अनिवार्य है, इसलिए इसे implicit नहीं छोड़ना चाहिए
- rounding strategy एक business decision है
- कुछ cases में conservative तरीके से नीचे round करना पड़ता है, और statistical effect के लिए half-even भी इस्तेमाल किया जा सकता है
- leftover fractional part किसे मिलता है, इसके legal और tax implications हो सकते हैं
- जितना संभव हो उतनी देर तक full precision बनाए रखनी चाहिए, और आम तौर पर केवल boundaries पर, जैसे storage से पहले या user display से पहले, rounding करनी चाहिए
- किसी value को कई हिस्सों में बाँटकर round करने पर हिस्सों का sum original value से अलग हो सकता है
- context के अनुसार explicit rounding account की जरूरत पड़ सकती है
- पैसा सिर्फ number से represent नहीं किया जा सकता; उसे हमेशा currency के साथ handle करना चाहिए
Moneyजैसे newtype, struct, class, record में amount और currency को साथ बाँधने से errors की संभावना कम होती है- अलग-अलग currencies को add करना forbidden होना चाहिए, और conversion strictly controlled exchange rates से explicit रूप से किया जाना चाहिए
- arbitrary currency codes accept न करें; system boundaries पर controlled currency set से validate करें
- fiat currency codes identifiers के रूप में इस्तेमाल किए जा सकते हैं, लेकिन cryptocurrencies को
(network, contract address)जैसे ज्यादा complex identification की जरूरत होती है - pegged, bridged, wrapped cryptocurrencies underlying asset के बराबर नहीं होतीं
FX rates
- FX rate में हमेशा directionality होती है
- EUR/USD rate, USD/EUR का simple inverse नहीं है
- exchanges में buy और sell, bid/ask spread के कारण अलग-अलग prices वाले orders होते हैं
- exchange rate का timing भी result बदल देता है
- current exchange rate current holdings या अभी हुआ माना गया transaction value calculate करने के लिए इस्तेमाल होता है
- value-date exchange rate value changes या tax amount calculations में इस्तेमाल होता है
- conversion में दो तरह के exchange rates महत्वपूर्ण हैं
- Transactional rate वह rate है जिस पर actual conversion हुआ, और यह original amount तथा resulting amount से derived होता है
- Reference rate holdings value या tax basis जैसे valuation और equivalence judgments में इस्तेमाल होता है; यह actual trade price नहीं है
- कोई standard single exchange rate नहीं होता
- exchange rates market से आते हैं और trading venue या calculation method के अनुसार बदलते हैं
- central bank exchange rates standard के सबसे करीब होते हैं, लेकिन उन्हें केवल reference rate के रूप में इस्तेमाल किया जा सकता है, और alternative sources भी valid हो सकते हैं
- amount और reference rate के source को साथ store करना चाहिए ताकि बाद में verify किया जा सके
Ledger और double-entry bookkeeping
- पैसे की movement ऐसी तरह से record होनी चाहिए जिसे audit किया जा सके और कई साल बाद भी reconstruct किया जा सके
- Double-entry bookkeeping financial transactions को
(credit account, debit account, amount)के रूप में entries की list में store करने का widely used तरीका है- classic representation में हर movement के लिए debit row और credit row अलग-अलग होती हैं
- क्योंकि हर entry समान amount को एक account से दूसरे account में move करती है, ledger हमेशा balanced रहता है
- पैसे का हमेशा source और destination होता है
- external providers के भी dedicated accounts होने चाहिए ताकि system में आने और बाहर जाने वाले पैसे को track किया जा सके
- balances store नहीं किए जाते, बल्कि money movements से derive किए जाते हैं
- accounts के types होते हैं, जैसे asset, liability, equity
- accounting equation
assets = liabilities + equitymaintained रहती है - व्यवहार में fee revenue या write-off losses record करने के लिए revenue और expense accounts भी चाहिए होते हैं
- extended equation
assets = liabilities + equity + revenue - expensesहै
- accounting equation
- एक transaction आम तौर पर कई movements बनाता है
- net amount movement और fee movement अलग-अलग हो सकते हैं
- posted entry परंपरा के अनुसार immutable होती है, और correction original को offset करने वाली नई entry जोड़कर किया जाता है
Time model: value, booking, settlement
- transactions में आम तौर पर दो या अधिक, कभी-कभी तीन timestamps होते हैं
- Value time: वह समय जब transaction वास्तव में हुआ
- Booking time: वह समय जब इसे system में record किया गया
- Settlement time: वह समय जब पैसा वास्तव में transfer हुआ या materialize हुआ
- Settlement time हर transaction में मौजूद नहीं होता और आम तौर पर T+X से express किया जाता है
- T+2 का मतलब है value date से 2 दिन बाद settlement होता है
- value time और booking time लगभग हमेशा अलग होते हैं
- अगर booking > value है, तो यह backdated है, और reporting period बदलने पर खासकर महत्वपूर्ण होता है
- अगर booking < value है, तो यह forward-dated है, और scheduled payments या future-dated payments में होता है
- card payment example में flow यह है कि T1 पर payment होता है, T2 पर system इसे record करता है, और T3 पर payment provider account में पैसा transfer करता है
- business reports मुख्य रूप से value time या settlement time को देखते हैं, जबकि booking time traceability के लिए उपयोगी होता है
- कई time points को एक
created_atमें मिला देने से वह जानकारी खो जाती है जिसे बाद में reconstruct नहीं किया जा सकता
ऑडिट ट्रेल, Event Sourcing, Immutability
- वित्तीय सिस्टम regulatory audit के दायरे में आते हैं, और उन्हें यह साबित करना पड़ सकता है कि user funds और company funds मिले-जुले तो नहीं हैं, revenue explainable है या नहीं, बाहर दी गई जानकारी वास्तविकता से मेल खाती है या नहीं, funds protection की स्थिति क्या है, आदि
- audit trail सिर्फ current state नहीं, बल्कि उस state के बनने की पूरी history है
- क्या हुआ
- कब हुआ
- किसने या किस चीज़ ने trigger किया
- क्यों हुआ
- सिर्फ money movement ही नहीं, manual intervention, fee schedule, rate source, limit जैसे configuration changes और permission changes के लिए भी audit trail चाहिए
- compliance check या risk score जैसे decisions में केवल result store करना पर्याप्त नहीं हो सकता
- अगर ये DMN, Drools, Decisions4s जैसे decision table या rules engine में हों, तो यह एक replayable structure बन जाता है कि किस rule ने किन inputs पर run होकर क्या result दिया
- Event sourcing audit trail बनाने का एक व्यवस्थित तरीका है
- current state और log को अलग-अलग store करने के बजाय सिर्फ events store किए जाते हैं और state derive की जाती है
- double-entry ledger इस pattern का उदाहरण है, क्योंकि वह balance store नहीं करता बल्कि entries से calculate करता है
- Event sourcing में practical constraints भी काफी हैं
- हर जगह इसकी जरूरत नहीं होती; अगर ledger पहले से पैसे को cover करता है, तो आसपास के domains के लिए सामान्य model और भरोसेमंद change log पर्याप्त हो सकते हैं
- performance के लिए balance और projection को cache या snapshot किया जा सकता है
- event source पर efficient query करना कठिन होता है, इसलिए projection का काम बढ़ सकता है
- events कई साल तक रहते हैं, इसलिए आज के code को बहुत पुराने events भी पढ़ने पड़ेंगे
- audit trail अगर modify किया जा सके तो वह evidence नहीं रह जाता, इसलिए उसे append-only होना चाहिए
- append-only table, DB permissions से
UPDATE·DELETEहटाना, application layer में mutating operation रोकना, checksum या hash chain के जरिए tamper evidence—ये सभी tools हो सकते हैं
- append-only table, DB permissions से
- वास्तविक systems में bug की वजह से event log या audit trail को ठीक करना पड़ सकता है
- आमतौर पर data बाहर report हो जाने के बाद fixed होना चाहिए; report से पहले हो तो issue ढूंढकर system से बाहर जाने से पहले in-place correction संभव हो सकता है
Cancellation और correction
- गलत amount posting या गलत account posting जैसी गलतियां होती हैं
- immutability आगे की ओर correction करने का तरीका मांगती है
- नया compensating entry post करें और उसे original record से दोनों दिशाओं में link करें
- Reversal original को आर्थिक रूप से ऐसे पूरी तरह offset करता है जैसे वह हुआ ही न हो, लेकिन original और reversal दोनों history में रहते हैं
- Correction या adjustment वास्तविक record और सही value के अंतर को book करता है, या पहले reverse करके फिर सही value के साथ दोबारा posting करता है
- correction original से अलग reporting period में जा सकता है
- linking information होनी चाहिए ताकि reports correction को सही तरह से attribute कर सकें और actual activity तथा cleanup में फर्क कर सकें
- आमतौर पर पहले से बंद reporting period में backdate की अनुमति नहीं होती, इसलिए correction में past value time specify करना है या नहीं, यह reporting schedule पर निर्भर करता है
money flow execution: invariants और funds reservation
- Invariant वह property है जो system में हमेशा true रहनी चाहिए
- accounting equation इसका एक example है, और business stakeholders कई conditions define कर सकते हैं
- invariants enforce करने के तरीके एक-दूसरे के पूरक होते हैं
- creation stage में design ऐसा हो कि सिर्फ valid objects बनें
- runtime में assertion, tests, property-based testing से verify करें
- stored data का reconciliation job या nightly check से बाद में analysis करें
- external world से interact करने वाली transactions को race condition से बचना चाहिए
- external call के बाद ही insufficient balance पता चलना, या एक ही पैसे को दो बार spend करने जैसी situations रोकनी होंगी
- Funds reservation या hold-and-release external interaction से पहले किसी specific transaction के लिए funds reserve करने का pattern है
- successful होने पर reservation settle करें और transaction आगे बढ़ाएं
- failure होने पर release करके available balance में वापस डालें
- यह pattern total balance और available balance में फर्क करता है
available = total - reserved- balance check और नया reservation available balance के आधार पर किए जाते हैं
- final amount पहले की estimate से अलग हो सकती है
- fees या exchange rate बदलने पर expected amount reserve करें, actual amount settle करें और बाकी release करें
- reservation को settle या release करना अनिवार्य है
- orphan reservation user funds को lock करता है, लेकिन पैसे को खोता या बनाता नहीं है
- expiry या timeout safety net हो सकते हैं, लेकिन जरूरी नहीं
- balance check और reservation record linearizable होने चाहिए
- stale read में दो transactions दोनों check pass कर सकती हैं और उसी funds पर backing ले सकती हैं
Overdraft और idempotency
- Overdraft वह स्थिति है जिसमें account balance negative हो जाता है
- intentional overdraft credit product होता है जिसमें limit और interest होते हैं, और आमतौर पर इसे अलग overdraft account के रूप में model किया जाता है
- unintended overdraft policy के हिसाब से prohibited हो तो भी हो सकता है
- settlement reserved estimate से बड़ा आ सकता है, या reversal funds already निकल जाने के बाद आ सकता है
- funds reservation window को कम करता है, लेकिन खत्म नहीं करता
- “prohibited” और “unrepresentable” अलग चीजें हैं
- unsigned integer या
CHECK (balance >= 0)से negative balance को represent करना असंभव बना देंगे, तो जब real world में negative balance accept करना पड़ेगा तब crash, zero clamp, या गलत processing हो सकती है - negative balance को 0 पर clamp करने से पैसा बन जाता है
- unsigned integer या
- overdraft detect होने पर इसे investigation signal मानें, और future deposit व netting, repayment request, expense/loss account में write-off जैसे तरीकों से explicit रूप से recover या handle करें
- distributed systems में exactly-once delivery guarantee नहीं की जा सकती, इसलिए retries जरूरी हैं, और retries duplicate delivery बना सकती हैं
- Idempotency वह property है जिससे same message दो बार deliver होने पर भी processing का effect सिर्फ एक बार होता है
- explicit idempotency key payload-based deduplication की तुलना में आमतौर पर सरल और सुरक्षित होती है
- key को specific operation और client scope तक सीमित रखना चाहिए
- error को replay करना है या reprocess, यह decide करना चाहिए; permanent errors को वैसे ही replay करना आमतौर पर सरल होता है
- duplicate call payload original जैसा है या नहीं verify करना अच्छी practice है, लेकिन इससे implementation complexity और flexibility cost आती है
- large scale पर billions of requests की deduplication और concurrent access में atomic barrier की जरूरत होती है
- 24 घंटे जैसी idempotency window implementation को सरल बनाती है, लेकिन correctness cost बड़ी होती है
- retry tests और out-of-order retry handling भी जरूरी हैं
Resumable flows
- money flows कई steps में होते हैं और मानकर चलना चाहिए कि steps के बीच कहीं भी process मर सकता है
- Full resumability ऐसा design है जिसमें आधा पूरा हुआ flow हमेशा recoverable state में रहता है
- progress state memory में नहीं, persistent storage में store करनी चाहिए
- flow को explicit state machine के रूप में model करें और हर step completion को next step शुरू करने से पहले commit करें
- interrupted flow को फिर आगे धकेलने के लिए independent driver चाहिए
- scheduler, worker, poller को orchestrator crash के बाद भी incomplete flow process करना चाहिए
- resume करते समय पहले से partially हुए step को दोबारा execute किया जा सकता है, इसलिए हर step idempotent होना चाहिए
- external effects rollback नहीं किए जा सकते
- external world को call करने के बाद, उसे call न किए हुए state में वापस नहीं लौटा सकते
- complete होने तक roll forward करें, या later step permanent fail हो जाए तो saga pattern की तरह compensating action post करें
- Temporal, Camunda, Workflows4s, AWS Step Functions जैसे durable-execution engine इस्तेमाल किए जा सकते हैं, या खुद persistent state machine बनाया जा सकता है
बाहरी API का उपयोग
- payment provider, custodian, blockchain node, KYC vendor जैसे बाहरी API को defensively handle करना चाहिए, क्योंकि उनके code, quality और uptime को आप control नहीं कर सकते
- schema पर भरोसा नहीं करना चाहिए
- field missing हो सकते हैं, type बदल सकता है, या unexpected null आ सकता है
- critical हिस्सों को boundary पर validate करें और unexpected data पर जोरदार तरीके से fail करें
- जिन हिस्सों की जरूरत नहीं है उन्हें validate करने से third-party contract violation के कारण बेवजह outage हो सकता है
- बाहरी API में URL में token पास करना, precision loss, semantics से अलग HTTP code,
200के अंदर error body, inconsistent pagination, custom date format जैसी चीजें आसानी से हो सकती हैं - हर call fail हो सकती है, इसलिए timeout और retry जरूरी हैं
- Circuit breaker मुख्यतः overloaded server के प्रति courtesy है और client complexity बढ़ाता है
- हालांकि latency और thread, connection जैसे finite resources को बचाने के लिए इसकी जरूरत पड़ सकती है
- rate limit और quota के लिए expected call volume और provider limit को पहले से calculate करके match करना चाहिए
- सभी request और response को structured और queryable form में store करने से investigation, audit trail, provider behavior dispute के evidence, और bug के बाद reprocessing material मिलता है
- core areas में provider redundancy पर विचार किया जा सकता है
- जैसे दो blockchain node से data verification, backup bank partner, crypto custodian, KYC vendor
- development, fees और complexity की cost बहुत ज्यादा होती है
- sandbox production से काफी अलग हो सकता है, इसलिए canary release या कम impact वाले controlled usage के जरिए production test की तैयारी करनी चाहिए
Webhook processing
- webhook बाहरी system signals पाने का आम तरीका है, लेकिन उसे safe तरीके से process करना आसान नहीं है
- order को assume नहीं करना चाहिए
- messages out-of-order आ सकते हैं या stale data रख सकते हैं
- अभी मिले webhook को latest truth मानकर state overwrite नहीं करनी चाहिए
- validity को assume नहीं करना चाहिए
- webhook issuer के किसी दूसरे subsystem से आते हैं और उनमें stale या गलत transform किया हुआ data हो सकता है
- webhook body को सिर्फ trigger की तरह इस्तेमाल करना और API query करके authoritative state confirm करना बेहतर है
- API भी eventually consistent हो सकता है, इसलिए तुरंत query करने पर पुरानी state return कर सकता है; इसलिए retry जरूरी है
- delivery को assume नहीं करना चाहिए
- issuer strong redelivery policy का वादा करे तब भी webhook किसी न किसी समय खो जाएगा
- reconciliation जैसी independent process को data completeness की कमी पूरी करनी चाहिए
- single delivery भी assume नहीं करनी चाहिए
- वही webhook कई बार deliver हो सकता है और processing idempotent होनी चाहिए
- जल्दी acknowledge करना और asynchronously process करना चाहिए
- raw event को durable store में save करने के बाद तुरंत 2xx return करें और actual work asynchronously perform करें
- raw payload को ज्यों का त्यों store करना चाहिए
- stable processing, audit trail और bug के बाद reprocessing के लिए जरूरी है
- caller को verify करना चाहिए
- आम तौर पर issuer payload signature जोड़ता है, और receiver shared secret के HMAC या public-key based asymmetric signature से verify करता है
- signature verification re-serialized payload पर नहीं, बल्कि received raw bytes पर करनी चाहिए
- webhook को इस बात की truth नहीं, बल्कि इस बात का hint मानना चाहिए कि कुछ हुआ है
भरोसेमंद notifications: Outbox और CDC
- जब system changes को Kafka event, webhook call जैसे external channels पर reliably notify करना हो, तो transactionality problem बनती है
- ऐसी स्थिति हो सकती है कि publish successful हो गया लेकिन network issue के कारण response नहीं मिला और system state rollback कर दी गई, या state change commit हो गया लेकिन publish fail हो गया
- textbook answer 2-phase commit या distributed transaction है, लेकिन complexity और reuse standardization की कठिनाई के कारण इसका इस्तेमाल कम होता है
- practical choices कई तरह की हैं
- Outbox pattern: state change के साथ publishing intent को dedicated store में transactionally record करें और बाद में success होने तक process करें
- Change Data Capture: database write-ahead या replication log पढ़कर committed changes को event stream में बदलें
- Debezium और AWS DMS CDC provide करते हैं
- CDC table row form के raw event emit करता है, इसलिए internal schema leak से बचने के लिए postprocessing जरूरी है
- Listen-to-yourself पहले event publish करता है और फिर अपनी state उसी event से दोबारा बनाता है
- Event sourcing में event log पहले से DB में होता है, इसलिए वहीं से publish किया जा सकता है
- कोई भी mechanism चुनें, delivery at-least-once होती है
- relay या connector publish के बाद record करने से पहले crash हो जाए तो restart पर फिर से भेज सकता है
- consumer को stable event id से deduplicate करना और idempotently behave करना चाहिए
Reconciliation
- जो systems external data पर निर्भर करते हैं, वे दो systems की state mismatch होने वाली data drift के प्रति vulnerable होते हैं
- webhook miss हो सकता है, या ledger में transaction post हो गया हो लेकिन external provider system में reflect न हुआ हो
- Reconciliation दो systems को match करने की process है
- असल में ledger, payment processor, bank जैसे तीन या उससे अधिक systems भी हो सकते हैं
- cadence context और constraints के हिसाब से hourly, daily, monthly, yearly हो सकता है
- drift missing data हो सकता है, या एक ही transaction की amount अलग होने जैसे ज्यादा complex differences भी हो सकते हैं
- timing भी important है
- अगर settlement T+3 है, तो record 3 दिन तक unreconciled state में रह सकता है; unnecessary alert रोकने के लिए इसे process में reflect करना चाहिए
- matching algorithm मुख्य कठिनाई है
- आमतौर पर external provider id को internally store करने से matching आसान हो जाती है
- अगर यह न हो, तो amount और time based heuristic की जरूरत पड़ सकती है
- one-to-many reconciliation भी जरूरी है
- एक settlement transfer कई transactions को cover कर सकता है
- discrepancy को सिर्फ overwrite करके reconciliation से match नहीं कराना चाहिए
- cause समझने और fix करने के लिए correction record, webhook data reprocessing जैसी first-class support चाहिए
Control और access
- money systems में केवल data ही नहीं, बल्कि कौन कौन-सा action कर सकता है, इसे भी control करना होता है और बाद में procedure compliance साबित करनी होती है
- Segregation of duties ऐसा control है जो एक व्यक्ति को पूरा process own करने से रोकता है
- Four-eyes, maker-checker, dual control ऐसे तरीके हैं जिनमें किसी specific action के apply होने से पहले दूसरे व्यक्ति की approval जरूरी होती है
- यह उन actions पर लागू होता है जो funds move कर सकते हैं या उन्हें गलत दिखा सकते हैं, जैसे large-scale या manual withdrawal, manual ledger correction, treasury और cold-wallet movement, fee schedule या limit changes
- engineering पर भी यही controls लागू होते हैं
- code merge, production deploy, infrastructure change money systems में sensitive actions हैं, इसलिए review और approval जरूरी है
- approval खुद भी trail का हिस्सा है
- किसने request किया, किसने approve किया, और क्या दोनों व्यक्ति अलग थे—यह record करना चाहिए ताकि control साबित किया जा सके
- emergency के लिए explicit और strongly audited break-glass path चाहिए
- Access control system state का हिस्सा है और समय के साथ बदलता है
- humans और services दोनों को least privilege देना चाहिए
- per-person grant की बजाय RBAC prefer करने से review आसान होता है
- capability grant और revoke भी sensitive events हैं, इसलिए क्या, किसने और क्यों बदला—यह record करना चाहिए
- scheduled access review से पुरानी या inaccurate हो चुकी permission drift पकड़नी चाहिए
SDLC बदलावों की ट्रैकिंग
- नियामकीय माहौल में यह audit किया जा सकना चाहिए कि code production तक कैसे पहुँचता है
- source control बदलावों का record है
- commit history हर बदलाव को author से जोड़ती है, और review व linked ticket के जरिए उसके कारण से भी जोड़ती है
- इसे signed commit, protected branch, और shared history पर force-push रोककर सुरक्षित रखना चाहिए
- review और pipeline को अनिवार्य किया जाना चाहिए
- required review, status check, और main branch पर direct push रोकना महत्वपूर्ण है
- deployment traceable होना चाहिए
- कौन-सा version चल रहा है, किसने कब release किया—यह reconstruct किया जा सके, ताकि incident को उसके कारण बने बदलाव से जोड़ा जा सके
टेस्टिंग रणनीति
- पैसे से जुड़े systems में operation sequence का space बड़ा होता है और दिलचस्प failures combinations से निकलते हैं, इसलिए testing खास तौर पर महत्वपूर्ण है
- Property-based testing किसी खास output के बजाय उन properties को verify करती है जो किसी भी input पर सही रहनी चाहिए
- यह invariant और money math के लिए अच्छी तरह फिट बैठती है
- operation sequence generate करते समय सिर्फ अंत में नहीं, बल्कि हर step के बाद invariant check करना चाहिए
- इसे बड़े पैमाने पर manually करना कठिन है, इसलिए assertions को अपने-आप inject करने वाला testing harness चाहिए
- Generative idempotency testing यह verify करती है कि external world को छूने वाला हर operation दूसरी call पर कोई प्रभाव नहीं डालता
- Crash and resume injection यह verify करता है कि long flow किसी भी steps के बीच मर जाए तो भी recover करता है या नहीं
- Round-trip testing यह check करती है कि encode/decode, serialize/deserialize, convert/convert back के बाद हम शुरुआती point पर लौटते हैं या ज्ञात tolerance के भीतर रहते हैं
- money और currency type की boundary precision loss और serialization bug पकड़ने का यह तेज तरीका है
- Golden testing fee breakdown, statement, report जैसे calculation results को stored expected results से compare कर unintended diff सामने लाती है
- Backward-compatibility testing पुराने real-format payload corpus को बनाए रखती है और verify करती है कि current code अब भी सही तरह से deserialize और project करता है
- Production testing की जरूरत तब हो सकती है जब sandbox, production से काफी अलग हो
- canary release, छोटे blast radius वाला controlled rollout, और छोटी real amounts को लगातार flow कराने वाली synthetic transaction इसके उदाहरण हैं
- production test असली पैसा move करता है, इसलिए उसे भी वही ledger, reconciliation, audit trail से गुजरना चाहिए, और normal correction/reversal path से clean up करना चाहिए
domain terms और संदर्भ सामग्री
- fintech में शुरुआत करते समय code की तुलना में vocabulary और concepts ज्यादा कठिन हो सकते हैं, इसलिए core terms को अलग से整理 किया गया है
- accounting और ledger क्षेत्र में ledger, general ledger और sub-ledger, debit/credit, posting, chart of accounts, receivable/payable, IOU, accrual vs cash basis, trial balance, suspense/clearing account, write-off, commingling, reconciliation break शामिल हैं
- Money और FX क्षेत्र में Money type, minor units, basis point, notional, fiat vs crypto, stablecoin, pegged/wrapped/bridged, bid/ask/spread, mid-market rate, reference rate, mark-to-market शामिल हैं
- transaction और settlement क्षेत्र में value date, booking date, settlement date, T+X, clearing vs settlement, cut-off time, float, netting, backdating, reversal/correction शामिल हैं
- payments, cards, markets, crypto, compliance terms भी अलग से整理 किए गए हैं
- PSP, omnibus account, FBO account, chargeback, issuer/acquirer, authorization vs capture
- order book, market vs limit order, maker/taker, slippage, liquidity, derivative, futures, perpetual, liquidation
- custody, hot/cold wallet, private key, multisig, MPC, gas, confirmation/finality, reorg, UTXO vs account model
- KYC, AML/CFT, sanctions screening, PEP, SoF/SoW, Travel Rule, VASP, MiCA, least privilege, RBAC, audit trail
- संदर्भ सामग्री को accounting और ledger, payments और cards, markets और trading, crypto, engineering, KYC और AML में बांटा गया है
- Accounting for Computer Scientists: double-entry bookkeeping को graph और data model के रूप में समझाने वाला engineers के लिए लेख
- Modern Treasury, How to Scale a Ledger: production ledger को software engineering के नजरिए से समझाने वाली लेख श्रृंखला
- Designing Data-Intensive Applications: idempotency, log, consistency, failure mode को systems perspective से समझाती है
तीन end-to-end उदाहरण
-
Crypto withdrawal
- यह वह flow है जिसमें user 0.5 ETH को किसी external address पर withdraw करता है
- request में idempotency key शामिल होती है, ताकि duplicate submission केवल एक ही withdrawal बनाए
- 0.5 ETH और अनुमानित network fee को available balance से reserve किया जाता है
- compliance gate sanctions, AML और destination address की जांच करता है, और external calls व manual review की वजह से कई दिनों तक sleep कर सकता है
- on-chain broadcast idempotent होना चाहिए, और crash के बाद दूसरा broadcast करने के बजाय chain को फिर से check करना चाहिए
- पर्याप्त confirmations के बाद ledger में user account debit, external on-chain account credit, network fee expense और service fee revenue की posting की जाती है
- nightly job ledger और chain reality को reconcile करता है
-
Card deposit
- यह PSP के जरिए card top-up का flow है
- user amount और card information submit करता है और PSP में idempotency key के साथ deposit transaction खोलता है
- authorization केवल hold बनाता है; पैसा अभी company का नहीं होता, इसलिए user balance को credit नहीं किया जाता
capturedwebhook raw bytes signature verification, raw payload storage, तेज 2xx response के बाद async तरीके से process किया जाता है- webhook सिर्फ trigger है, इसलिए authoritative state PSP API से query की जाती है
- captured but not settled state को clearing account के जरिए post किया जाता है, और settlement T+X के बाद batch में आ सकता है
- chargeback को original को modify किए बिना linked compensating entry के रूप में handle किया जाता है
-
In-app conversion with cashback
- यह 1,000 EUR को USDC में बदलने और promotional cashback देने का flow है
- EUR→USDC quote, USDC→EUR का reciprocal नहीं होता; यह directional rate है
- EUR और USDC को आपस में जोड़ा नहीं जाता, और USDC की पहचान
(network, contract address)से होती है; यह pegged fiat के समान नहीं है - calculation पूरी precision बनाए रखती है और boundary पर explicit strategy से केवल एक बार round किया जाता है
- spread को revenue account में explicit रूप से book करना चाहिए; उसे rounding residual के रूप में गायब नहीं होना चाहिए
- cashback कोई free balance bump नहीं, बल्कि company promotional/expense account से user balance में move होने वाला वास्तविक पैसा है
- result publish outbox, CDC, event log जैसे mechanisms से reliable delivery सुनिश्चित करता है, और downstream consumer stable event id से dedupe करता है
1 टिप्पणियां
Hacker News की रायें
सरसरी तौर पर देखा, और मुझे लगता है कि यह handbook उथली है और कुछ क्षेत्रों में तो खराब सलाह के करीब है
उदाहरण के लिए, अगर मैं रकम को non-integer रूप में stored देखूं, तो शायद चीखते हुए भाग जाऊं। जैसे Rust का decimal JSON floating point के रूप में represent हो जाता है। जब तक कोई बहुत मजबूत वजह न हो, यह हमेशा integer होना चाहिए, और export होने वाला view चाहे कोई अजीब bitcoding format हो या कुछ और, हो सकता है
foreign exchange rates भी किसी एक खास समय-बिंदु से हल होने वाली समस्या नहीं हैं। buyer के संदर्भ-समय का rate, seller के संदर्भ-समय का rate, agreement, agreement tolerance, agreed final timestamp—ये सब असर डालते हैं
immutability की वजह से जहां भी money handle होता है, वहां event sourcing रखना चाहूंगा। अंतिम cleaned-up stream
A -> B -> Eजैसी दिख सकती है, लेकिन असली streamA0 -> Edit(A0, A) -> B -> C -> D -> Rollback(B) -> Eहो सकती हैआखिरकार Fintech भी सब एक जैसा Fintech नहीं होता। कुछ जगहों पर money को सामान के बोरे जैसा treat किया गया, और दूसरी जगहों पर money हर चीज़ के केंद्र में था
foreign exchange पर भी यह handbook की “कोई canonical rate नहीं है” वाली बात को मजबूत करता दिखता है। ऊपर से, लेख finalization के बाद के records से deal कर रहा है, और लगता है यह पक्ष finalization method की बात कर रहा है। यह अलग लक्ष्य के लिए valid nuance है, लेकिन यह छूटा हुआ या गलत है—ऐसा सबूत नहीं दिखता
immutability वाला हिस्सा भी लगता है कि लेख वही बात कह रहा है। फर्क क्या है, समझ नहीं आया
अगर आप interest rate paths पर Monte Carlo option pricing calculate कर रहे हैं, और duration, convexity, vega जैसे risk metrics में interest रखते हैं, तो rounding rules क्या हैं, इसकी किसी को परवाह नहीं होती। double पर्याप्त है।
exp(-rt)cashflowया normal cumulative distribution function को integer में कैसे force करेंगे?कुछ क्षेत्रों में integer सही है। लेकिन यह universal principle नहीं है; सही engineering choice करनी चाहिए
अगर आपका environment support करता है तो fixed point भी इस्तेमाल कर सकते हैं, लेकिन technically वह अभी भी integer ही है
display के लिए decimal values लौटाना safe है
amount को integer के रूप में store करने वाले system से भागना—ठीक है। तब शायद हम उसी system पर साथ काम नहीं करेंगे। आजकल तो उल्टा, अक्सर amounts को integer की तरह handle करने वाले systems से भागने का मन करता है। अगर codebase ideal हो और सिर्फ अनुभवी finance programmers ही उसे छूते हों, तो यह अच्छा चल सकता है, लेकिन ऐसे systems आम तौर पर बहुत exclusive या fragile हो जाने का risk रखते हैं
राशि दिखाने के लिए minor-unit precision रणनीति पर विचार कर रहे लोगों को सलाह दूँ तो: ऐसा न करना बेहतर है। कम-से-कम exchange/API data format के रूप में तो इसका इस्तेमाल नहीं करना चाहिए।
तेज integer operations, जोड़-घटाव में rounding की समस्या नहीं—यह सब चतुर लगता है, लेकिन किसी खास currency के लिए implicitly माने गए decimal places अगर दूसरे partner से अलग निकले, तो काम करते समय बहुत बुरी तरह फँस सकते हैं। खासकर stablecoins में यह और अहम है, क्योंकि वे जिस fiat currency को represent करते हैं, उससे उनके implicit decimal places अक्सर अलग होते हैं।
JSON-based API में राशि को string type के रूप में represent करना भी विचार करने लायक है। JSON decimal precision specify नहीं करता, इसलिए हमेशा यह पक्का करना पड़ता है कि आप और आपके सभी users/vendors के parser/serializer internally floating point से गुजरते हुए precision न खो दें। यह जल्दी ही messy हो सकता है, और string conceptually कम साफ लगती है, लेकिन यह इस समस्या को पूरी तरह bypass कर देती है। कुछ लोग इसे anti-pattern [1] कहेंगे, लेकिन users या shareholders के कंधों पर ideological purity के लिए यह लड़ाई मैं नहीं लड़ना चाहूँगा।
[1] https://blog.json-everything.net/posts/numbers-are-numbers-n...
high-frequency trading क्षेत्र में, अगर किसी {slice} के लिए पहले से एक consistent exponent तय किया जा सके, तो transmission space बचाई जा सकती है। उदाहरण के लिए product/tick size/asset class/exchange/feed/server जैसे scope में सिर्फ mantissa भेजा जाए और client hardcoded exponent इस्तेमाल करे।
लेकिन मिलते-जुलते क्षेत्रों में भी transmitted data में एक अतिरिक्त
uint32exponent भेजना अक्सर worthwhile होता है। इससे बाद में बदलाव किया जा सकता है, और “अभी तो सिर्फ cents चाहिए” जैसे शुरुआती design के कारण पैर नहीं बँधते। उदाहरण के लिए अचानक bitcoin price को full precision में support करना पड़ सकता है। fixed exponent adjust करना चाहें तो breaking change coordinate न करना पड़े—इसके लिए users आभारी होंगे।“कोई भी” वाला standard unreasonable है। यह एक unattainable standard है जो कोई practically provable value दिए बिना unlimited engineering budget मांग सकता है।
standards की कमी identify करना, real parsers कैसे behave करते हैं इस पर बात करना, gaps और unmet use cases discuss करना—यह सब अच्छा है। अधिक reasonable standard की जरूरत suggest करना भी अच्छा है। लेकिन सभी से “सारी संभावनाएँ” support करने की मांग करना—जिसकी किसी को सच में जरूरत नहीं, जिसका अर्थ भी unclear है, और जिसे सच में achieve भी नहीं किया जा सकता—अच्छा विचार नहीं है।
float/double, minor unit के हजारवें हिस्से या उससे भी छोटी unit की fixed-point arithmetic, arbitrary-precision decimals, या कोई बिल्कुल अलग तरीका?एक programmer के तौर पर, जब Fintech programmers को अपने-अपने अलग experiences और perspectives से बोलते देखता हूँ, तो सोचता हूँ कि programming में अच्छा होना आखिर है क्या।
xlii ने amount को floating point में store न करने को कहा—यह common IEEE 754 समस्या है। financial tracking immutable log या event-based records से करना सही है, लेकिन आसपास की हर service को event sourcing पर बनाना जरूरी नहीं लगता। ledger, settlement, orders, executions जैसी core logic पर ही apply करना काफी हो सकता है। xlii की पोस्ट पढ़कर यह ऐसी technique लगती है जो modeling सफल होने पर ही feasible होती है।
lxgr की बात minor-unit problem को पकड़ती है। अगर JSON numbers को language या parser floating point के रूप में parse करे तो precision loss हो सकता है। आम तौर पर value के साथ अलग decimal places field भी भेजते हैं। हालांकि सुना है कि high-frequency trading में वह overhead खुद ही बहुत महंगा होता है, इसलिए ऐसा नहीं करते।
antonymoose की बात कई किताबों में कही बातों से मेल खाती है। इसलिए foreign exchange या API context में ऐसे designs common हैं। यह protocol design जैसा भी महसूस होता है।
कुल मिलाकर, सभी अपने domain के भीतर सही हैं। xlii जैसे व्यक्ति senior programmer हों तो अच्छा लगेगा, लेकिन साथ ही मुझे लगता है कि शायद मैं ऐसा complex system design नहीं कर पाऊँगा। इस मायने में सबकी बातें valid हैं, और domain के हिसाब से opinions अलग होते देखना दिलचस्प है। लगता है शायद यही expertise है।
ऐसी चीजें देखकर अंदाजा लगाया जा सकता है कि programmer किस तरह के अनुभव से आया है। कभी-कभी programming सही जवाब खोजने के बजाय worldview चुनने जैसा महसूस होता है।
HN पर programmers अपने domain को कैसे model करते हैं, यह देखना हमेशा रोचक होता है। कभी-कभी profile क्लिक करके देखता हूँ और सोचता हूँ कि शायद कभी काम आए, इसलिए उनकी domain knowledge अपनी personal wiki में जोड़ लेता हूँ।
अच्छा है। इस किताब में बहुत सी अच्छी जानकारी है जो पहले से दूसरी जगहों पर भी मिल सकती है, लेकिन उसे एक जगह इकट्ठा कर देना ही काफी practical है। Kleppmann की Designing Data-Intensive Applications strongly recommend करता हूँ। पहला edition भी बहुत अच्छा था और हाल ही में दूसरा edition आया है।
FinTech में CTO के रूप में काम करते हुए मैंने पूरा software stack scratch से बनाया था, और किताब की सीख broadly सही है। “broadly” इसलिए क्योंकि हमेशा की तरह किसी खास project में “context पर निर्भर करता है” वाली बातें बहुत consider करनी पड़ती हैं। उदाहरण के लिए, मैंने full state calculation problem से बचने के लिए event sourcing इस्तेमाल नहीं किया। standard append-only audit trail ही पर्याप्त हो सकता है।
exactly-once delivery guarantee नहीं की जा सकती, लेकिन effectively-once processing configure की जा सकती है, और असल में आप यही चाहते हैं।
सभी requests और responses store करने की बात बिल्कुल सही है। सिर्फ API consume करते समय ही नहीं, बल्कि external world से कोई भी information collect करते समय भी ऐसा करना चाहिए, और संभव हो तो boundary के भीतर सभी intermediate transformation steps भी record करने चाहिए। content-addressed buckets और relational tables का combination अच्छा है।
साथ ही, text में data lineage के बारे में कुछ नहीं कहा गया है। अगर vendor ने दोपहर में कोई data update किया और आपको यह बात जरूर जाननी हो, तो क्या करेंगे? आपको उस बदलाव को explain करने में सक्षम होना चाहिए, साथ ही पुराने values का इस्तेमाल करने वाली calculations rerun करने पर वही result मिले। यह कोई विशेष रूप से कठिन समस्या नहीं है, लेकिन इसके लिए सोच-विचार चाहिए।
“खराब सलाह” कहना काफ़ी सभ्य ढंग से कहना है। ईमानदारी से कहूँ तो यह “handbook” ज़्यादातर LLM द्वारा लिखा हुआ लगता है
उदाहरण के लिए immutability सेक्शन में यह वाक्य है: “PII को financial data से अलग करने पर, रखने लायक financial history खोए बिना right to deletion का सम्मान किया जा सकता है”
financial institutions में स्पष्ट KYC/AML वजहों से दोनों साथ-साथ चलते हैं
अगर relevant period खत्म होने से पहले ग्राहक का नाम, पता आदि अनुरोध मिलते ही मिटा दें और सिर्फ financial data छोड़ दें, तो जब अपराध की ट्रेसिंग के लिए वैध एजेंसी डेटा माँगने आएगी, पूरे संगठन का दिन बहुत खराब होने वाला है
Fintech में काम करने की इच्छा रखने वाले लोगों को किसी अज्ञात jurisdiction के अज्ञात व्यक्ति द्वारा लिखे random “handbook” पर निर्भर नहीं होना चाहिए
Fintech में काम करने वाले लोगों को सिर्फ अपने employer के internal handbook/guidelines आदि के अनुसार ही काम करना चाहिए। ऐसे दस्तावेज़ कंपनी के वकीलों और compliance अधिकारियों ने मिलकर बनाए होंगे, ताकि employer जिन jurisdictions में operate करता है वहाँ के कानून और reporting requirements पूरे हों
मुझे तो यह अंततः delete किए जाने वाले PII और accounting equation/invariants में आने वाले data को अलग करने की सलाह देता दिखता है, जिसे आप व्यावहारिक रूप से स्थायी रूप से रखना चाहेंगे। ताकि relevant record retention period बीत जाने के बाद पहले वाले को delete किया जा सके
यह सही है कि किसी अज्ञात jurisdiction के अज्ञात व्यक्ति द्वारा लिखे “handbook” पर निर्भर नहीं होना चाहिए। लेकिन उसमें दिए गए ideas और practices को आँख बंद करके ignore करना या अपने संगठन के बाहर न देखना भी सही नहीं है। आदर्श रूप से उसे देखने के बाद अपनी knowledge और local regulations से मिलाकर adjust करना चाहिए
अगर दुनिया में सिर्फ perfect और error-free organizations होते, तो employer की internal guidance ही follow करने वाला approach reasonable लगता। लेकिन ऐसी बातचीत के बिना उस स्तर तक पहुँचा कैसे जा सकता है?
मुझे लगता है इस content का ज़्यादातर हिस्सा सिर्फ Fintech ही नहीं, बल्कि software engineering overall पर लागू होता है
उदाहरण के लिए retries, idempotency, event ordering आदि वाले हिस्से उन सभी systems पर लागू होते हैं जिन्हें कुछ हद तक correctness चाहिए, भले ही पैसा सीधे जुड़ा न हो। “कभी भी retry कर सकते हैं” वाली assumption पर बने बहुत सारे systems देखे हैं, लेकिन retry तभी संभव है जब failure पहले cleanly हो, और lower-level system वही स्तर की idempotency दे जो मैं सोच रहा हूँ। ये चीज़ें अक्सर सच में verify नहीं की जातीं
इसके बजाय मैं per-account database जैसे ज़्यादा radical approach की वकालत करने वाला लेख पढ़ना चाहूँगा। Fintech के अंदर जिनके अपने unique trade-offs हों
Fintech engineers या founders को मेरी सबसे बड़ी सलाह होगी कि day one से risk और compliance को गंभीरता से लें
financial systems trust पर आधारित होते हैं। अगर आप risk को provably mitigate नहीं कर पाए, तो trust खो देंगे, और अंततः पूरा business खो देंगे
floating point से बचने की बात सही नहीं है। मैंने Fintech में 20 साल काम किया है और ज़्यादातर double का इस्तेमाल किया है। Excel भी double इस्तेमाल करता है, frontend भी double इस्तेमाल करेगा, और हर database double support करता है। standard libraries double parsing जानती हैं, और JSON theory चाहे जो हो, practice में double इस्तेमाल करता है। कई ERP systems भी double इस्तेमाल करते हैं
double से currency handle करते समय मुख्य बात यह याद रखना है कि इसमें कुल 15 digits की precision आ सकती है। जब तक number
123456789.01या123.456789की तरह उससे ज़्यादा digits इस्तेमाल नहीं करता, financial calculations में perfect decimal precision हो सकती है। हर calculation के बाद और हर comparison से पहले result को हमेशा 15 digits precision के अंदर round कर दें। Excel यही करता हैdouble का सबसे बड़ा फायदा यह है कि यह व्यापक रूप से supported है, और system के अंदर अलग-अलग precision को mix किया जा सकता है। international finance या advanced financial products से deal करने पर ऐसा होता है। कुछ accounting में thousandth तक precision चाहिए होती है, और कुछ को 0.25 के multiples में round करना होता है। अंततः आप basic arithmetic का इस्तेमाल नहीं करेंगे और specialized accounting math library इस्तेमाल करेंगे, और वह library backend के रूप में floating point का बिल्कुल ठीक इस्तेमाल कर सकती है
Plaid balance check इस बात की guarantee नहीं है कि जल्द submit होने वाला ACH debit सफल होगा
balance एक million dollars हो, तब भी फर्क नहीं पड़ता। ACH process होने से पहले सारा पैसा (a) wire transfer से बाहर जा सकता है, (b) कल के ACHs—यानी bills, auto-debits आदि—और checks से clear हो सकता है, या (c) debit card/ATM पर spend हो सकता है
शायद बेहतर होगा कि मैं न बताऊँ कि मुझे कैसे पता है कि कुछ Fintechs इसे handle नहीं करते
सिर्फ idempotency keys सेक्शन ही पढ़ने लायक है। ज़्यादातर developers यह lesson कठिन तरीके से सीखते हैं
इनमें से कई idempotency के ज्ञान के widespread होने से पहले के हैं, इसलिए अक्सर कई globally unique लगने वाले fields को जोड़कर idempotency key जबरन बनाई जाती है। समस्या यह है कि वह कभी पूरी तरह unique नहीं होती। कभी-कभी परदे के पीछे झाँकने को मिल जाता है, जैसे जब bank एक ही date पर वही amount उसी recipient account में transfer करने से रोकता है
idempotency कैसे काम करनी चाहिए और क्यों ज़रूरी है, यह समझाने में मैंने बहुत समय लगाया है। ज़्यादातर teams इसकी ज़रूरत समझती हैं, लेकिन बहुत कम teams ने इसे शुरुआत से सोचा होता है
“Fintech” बहुत broad है, और जिसे Fintech कहा जाता है उसका ज़्यादातर हिस्सा असल में communication है। कंपनियों के बीच, traders के बीच, systems के बीच, ledgers के बीच communication। पूरी industry के लिए लागू कोई “सही” programming तरीका नहीं है। अंत में सही तरीका वही है जिसे मेरे communication counterpart समझ सके
अगर counterpart currency को cents में track करता है, तो उससे ज़्यादा precision में track करने पर rounding mismatch होगा। उल्टा, अगर मैं cents में हूँ और counterpart 0.1 cent में deal करता है, तब भी यही होगा। इस document की बाकी सलाहों को भी इसी तरह देखना चाहिए