Buku Pegangan Rekayasa Fintech
(w.pitula.me)- Sistem yang menangani uang sebagai status inti harus dirancang di atas prinsip tidak membuat data, tidak menghilangkan data, dan tidak memercayai apa pun
- Representasi nominal harus menghindari float dan menggabungkan
BigDecimal, bilangan bulat satuan terkecil, bilangan rasional, dan lainnya sesuai tanggung jawabnya; serialisasi angka JSON juga dapat memunculkan kembali masalah IEEE-754 double - Buku besar menjaga saldo dan laporan tetap dapat direkonstruksi melalui pembukuan berpasangan, jejak audit yang tidak dapat diubah, pemisahan value time·booking time·settlement time, serta catatan koreksi·pembatalan
- Aliran uang nyata harus mencegah pengeluaran ganda dan kelalaian melalui reservasi, idempotensi, state machine yang dapat dimulai ulang, verifikasi API eksternal·webhook, outbox·CDC, dan rekonsiliasi
- Kontrol akses, persetujuan four-eyes, pelacakan perubahan SDLC, pengujian berbasis properti, dan injeksi kegagalan membuat operator internal hingga perubahan kode diperlakukan sebagai batas kepercayaan
Prinsip dasar sistem fintech
- Dalam rekayasa perangkat lunak ketika uang menjadi perhatian utama sistem, keterlacakan, imutabilitas, dan kemampuan verifikasi jauh lebih penting daripada CRUD biasa
- Pembaca sasaran adalah orang yang baru bergabung di fintech, orang yang sudah bekerja di fintech, dan orang di luar fintech yang ingin memahami bagaimana sistem uang berbeda dari sistem umum
- Semua pola adalah sarana untuk menjaga tiga prinsip
- No invented data: uang tidak dapat tercipta dari ketiadaan, sehingga pemrosesan duplikat dan perubahan saldo secara sewenang-wenang tidak diperbolehkan
- No lost data: semua hal yang terjadi pada uang harus dilacak dan dipersistenkan
- No trust: jangan memercayai penyedia eksternal, komponen internal, maupun dunia nyata; semuanya harus diverifikasi
Cara merepresentasikan uang
- Representasi nominal adalah keputusan paling mendasar dalam sistem keuangan; jika salah memilih, seluruh lapisan di atasnya akan mewarisi kesalahan
- float/double hampir selalu bukan pilihan yang baik karena dapat menimbulkan kehilangan presisi yang sulit diprediksi
- Namun, ada keunggulan berupa cepat, efisien memori, serta tidak memerlukan library atau struktur data tambahan
- Tipe presisi arbitrer seperti
BigDecimalmemungkinkan kontrol eksplisit atas presisi perhitungan dan titik pembulatan- Cocok untuk perhitungan antara ketika beberapa operasi berantai, seperti FX atau perhitungan harga
- Penyimpanan bilangan bulat satuan terkecil adalah cara yang memakai presisi tetap seperti sistem bank sentral pada sebagian besar mata uang fiat
- €12,34 disimpan sebagai
1234 - Harus mengikuti jumlah digit ISO 4217 dan tidak boleh berasumsi selalu 2 digit
- Aset kripto juga memakai bilangan bulat satuan terkecil seperti satoshi dan wei, tetapi presisinya berbeda-beda per aset dan ditentukan oleh token, seperti
decimalspada ERC-20 - Nominal aset kripto dapat melampaui bilangan bulat 64-bit, sehingga mungkin memerlukan bilangan bulat dengan lebar arbitrer
- €12,34 disimpan sebagai
- Bilangan rasional adalah yang paling kuat ketika kehilangan presisi tidak dapat diterima, tetapi lambat, sulit dikonversi ke format lain tanpa kehilangan presisi, dan biasanya memerlukan tipe kustom atau library
- Cara penyimpanan dan cara perhitungan adalah keputusan terpisah; satu sistem dapat menggunakan penyimpanan bilangan bulat sekaligus perhitungan antara dengan
BigDecimal - Penanganan batas juga penting dalam serialisasi nominal
- Angka JSON biasa pada sebagian besar parser adalah IEEE-754 double, sehingga meski representasi internal sudah hati-hati, masalah float dapat muncul kembali di batas sistem
- Uang harus dikirim sebagai string seperti
"12.34"atau sebagai bilangan bulat satuan terkecil
Pembulatan dan penanganan mata uang
- Pembulatan tidak terhindarkan dalam pembagian, konversi mata uang, biaya, bunga, penerapan rasio, dan perpindahan presisi, sehingga tidak boleh dibiarkan implisit
- Strategi pembulatan adalah keputusan bisnis
- Ada kasus yang harus dibulatkan turun secara konservatif, dan bisa juga memakai half-even untuk efek statistik
- Siapa yang mengambil sisa pecahan dapat memiliki dampak hukum dan perpajakan
- Pertahankan presisi penuh selama mungkin, dan biasanya lakukan pembulatan hanya di batas seperti sebelum penyimpanan atau sebelum ditampilkan kepada pengguna
- Jika nilai dibagi menjadi beberapa bagian lalu dibulatkan, jumlah bagian dapat berbeda dari nilai asal
- Tergantung situasinya, rounding account eksplisit mungkin diperlukan
- Uang tidak dapat direpresentasikan hanya dengan angka dan harus selalu ditangani bersama mata uangnya
- Mengikat nominal dan mata uang bersama dalam newtype, struct, class, atau record seperti
Moneymengurangi kemungkinan kesalahan - Penjumlahan mata uang yang berbeda harus dilarang, dan konversi harus dilakukan secara eksplisit dengan kurs yang dikontrol ketat
- Jangan menerima kode mata uang arbitrer; validasikan terhadap kumpulan mata uang yang dikontrol di batas sistem
- Kode mata uang fiat dapat digunakan sebagai pengenal, tetapi aset kripto memerlukan identifikasi yang lebih kompleks seperti
(network, contract address) - Aset kripto pegged, bridged, dan wrapped tidak setara dengan aset dasarnya
- Mengikat nominal dan mata uang bersama dalam newtype, struct, class, atau record seperti
Kurs FX
- FX rate selalu memiliki arah
- Kurs EUR/USD bukan sekadar kebalikan sederhana dari USD/EUR
- Di bursa, beli dan jual adalah order dengan harga berbeda karena bid/ask spread
- Waktu kurs juga mengubah hasil
- Kurs saat ini digunakan untuk menghitung nilai kepemilikan saat ini atau nilai transaksi yang diasumsikan terjadi sekarang
- Kurs value-date digunakan untuk perubahan nilai atau perhitungan pajak
- Dalam konversi, dua jenis kurs penting
- Transactional rate adalah kurs saat konversi benar-benar terjadi, dan diturunkan dari nominal asal dan nominal hasil
- Reference rate digunakan untuk penilaian dan penentuan kesetaraan seperti nilai kepemilikan atau dasar pajak, dan bukan harga transaksi nyata
- Tidak ada kurs tunggal yang standar
- Kurs berasal dari pasar dan berbeda bergantung pada tempat perdagangan atau metode perhitungan
- Kurs bank sentral paling mendekati standar, tetapi hanya dapat digunakan sebagai reference rate, dan sumber alternatif juga bisa valid
- Sumber nominal dan reference rate harus disimpan bersama agar dapat diverifikasi nanti
Buku besar dan pembukuan berpasangan
- Pergerakan uang harus dicatat dengan cara yang dapat diaudit dan direkonstruksi bahkan bertahun-tahun kemudian
- Pembukuan berpasangan adalah cara yang banyak digunakan untuk menyimpan transaksi keuangan sebagai daftar entry berbentuk
(credit account, debit account, amount)- Representasi klasik menempatkan debit row dan credit row terpisah untuk setiap perpindahan
- Karena setiap entry memindahkan nominal yang sama dari satu akun ke akun lain, buku besar selalu seimbang
- Uang selalu memiliki asal dan tujuan
- Penyedia eksternal juga harus memiliki akun khusus agar uang yang masuk dan keluar sistem dapat dilacak
- Saldo tidak disimpan, melainkan diturunkan dari pergerakan uang
- Akun memiliki tipe seperti asset, liability, dan equity
- accounting equation
assets = liabilities + equitydipertahankan - Dalam praktiknya, akun revenue dan expense juga diperlukan untuk mencatat pendapatan biaya atau kerugian write-off
- Persamaan yang diperluas adalah
assets = liabilities + equity + revenue - expenses
- accounting equation
- Satu transaksi biasanya menghasilkan beberapa perpindahan
- Perpindahan nominal bersih dan perpindahan biaya dapat muncul secara terpisah
- Posted entry secara konvensi bersifat tidak dapat diubah, dan koreksi dilakukan dengan menambahkan entry baru yang mengimbangi entry asli
Model waktu: value, booking, settlement
- Transaksi biasanya memiliki dua, kadang tiga, timestamp
- Value time: waktu transaksi benar-benar terjadi
- Booking time: waktu dicatat di sistem
- Settlement time: waktu uang benar-benar dipindahkan atau diwujudkan
- Settlement time tidak ada pada semua transaksi dan biasanya dinyatakan sebagai T+X
- T+2 berarti settlement terjadi 2 hari setelah value date
- Value time dan booking time hampir selalu tidak sama
- Jika booking > value, itu backdated, dan sangat penting terutama ketika periode pelaporan berubah
- Jika booking < value, itu forward-dated, dan terjadi pada pembayaran terjadwal atau pembayaran bertanggal masa depan
- Contoh pembayaran kartu adalah alur ketika pembayaran terjadi pada T1, sistem mencatatnya pada T2, dan penyedia pembayaran mentransfer uang ke rekening pada T3
- Laporan bisnis terutama melihat value time atau settlement time, sedangkan booking time berguna untuk keterlacakan
- Jika beberapa titik waktu digabung menjadi satu
created_at, informasi yang tidak dapat direkonstruksi nanti akan hilang
Jejak audit, event sourcing, imutabilitas
- Sistem keuangan menjadi objek audit regulasi, dan mungkin perlu membuktikan apakah dana pengguna dan dana perusahaan tercampur, apakah pendapatan dapat dijelaskan, apakah informasi yang diberikan ke pihak eksternal sesuai dengan kenyataan, status perlindungan dana, dan sebagainya
- Audit trail adalah seluruh riwayat tentang bagaimana suatu status terbentuk, bukan hanya status saat ini
- Apa yang terjadi
- Kapan terjadi
- Siapa atau apa yang memicunya
- Mengapa itu terjadi
- Bukan hanya perpindahan uang, intervensi manual, perubahan pengaturan seperti fee schedule, rate source, limit, serta perubahan hak akses juga memerlukan jejak audit
- Untuk keputusan seperti compliance check atau risk score, menyimpan hasilnya saja bisa jadi tidak cukup
- Jika berada di decision table atau rules engine seperti DMN, Drools, Decisions4s, strukturnya dapat diputar ulang untuk melihat aturan mana yang dijalankan dengan input apa dan menghasilkan hasil apa
- Event sourcing adalah pendekatan sistematis untuk membuat audit trail
- Alih-alih menyimpan status saat ini dan log secara terpisah, hanya event yang disimpan lalu status diturunkan darinya
- Ledger pembukuan berpasangan adalah contoh pola ini karena balance tidak disimpan, melainkan dihitung dari entry
- Event sourcing juga memiliki banyak batasan praktis
- Tidak dibutuhkan di semua tempat; jika ledger sudah mencakup uang, domain di sekitarnya bisa cukup dengan model biasa dan change log yang tepercaya
- Demi performa, balance dan projection dapat di-cache atau dibuat snapshot
- Sumber event sulit di-query secara efisien, sehingga pekerjaan projection bisa menjadi banyak
- Karena event disimpan selama bertahun-tahun, kode hari ini juga harus dapat membaca event dari masa lalu
- Jejak audit harus append-only, karena jika dapat diubah, ia tidak menjadi bukti
- Append-only table, penghapusan
UPDATE·DELETEdari hak akses DB, pemblokiran mutating operation di lapisan aplikasi, serta tamper evidence melalui checksum atau hash chain dapat menjadi alatnya
- Append-only table, penghapusan
- Dalam sistem nyata, terkadang event log atau audit trail perlu diperbaiki karena bug
- Biasanya, setelah data dilaporkan ke pihak eksternal, data harus dibekukan; jika belum dilaporkan, perbaikan di tempat mungkin dapat dilakukan setelah masalah ditemukan sebelum keluar dari sistem
Pembatalan dan koreksi
- Kesalahan seperti posting jumlah yang salah atau posting akun yang salah memang terjadi
- Imutabilitas menuntut cara memperbaiki ke depan
- Posting compensating entry baru dan hubungkan dua arah dengan record asal
- Reversal sepenuhnya mengimbangi transaksi asal seolah-olah secara ekonomi tidak pernah terjadi, tetapi transaksi asal dan reversal tetap tersimpan dalam riwayat
- Correction atau adjustment membukukan selisih antara catatan aktual dan nilai yang benar, atau membalikkan lalu mem-posting ulang dengan nilai yang benar
- Koreksi dapat masuk ke periode pelaporan yang berbeda dari transaksi asal
- Informasi keterkaitan diperlukan agar laporan dapat mengatribusikan koreksi dengan benar dan membedakan aktivitas aktual dari cleanup
- Karena backdate ke periode pelaporan yang sudah ditutup biasanya tidak diizinkan, apakah value time masa lalu akan ditentukan saat koreksi bergantung pada jadwal pelaporan
Eksekusi aliran uang: kondisi invariant dan reservasi dana
- Invariant adalah sifat yang harus selalu benar dalam sistem
- Accounting equation adalah salah satu contohnya, dan pemangku kepentingan bisnis dapat mendefinisikan berbagai kondisi
- Cara menegakkan invariant saling melengkapi
- Mendesain agar hanya objek valid yang dibuat pada tahap pembuatan
- Memeriksa saat runtime dengan assertion, pengujian, dan property-based testing
- Menganalisis data tersimpan setelahnya dengan reconciliation job atau nightly check
- Transaksi yang berinteraksi dengan dunia luar harus menghindari race condition
- Perlu mencegah situasi ketika saldo tidak cukup baru diketahui setelah panggilan eksternal, atau uang yang sama dibelanjakan dua kali
- Funds reservation atau hold-and-release adalah pola untuk mencadangkan dana bagi transaksi tertentu sebelum interaksi eksternal
- Jika berhasil, reservation di-settle dan transaksi dilanjutkan
- Jika gagal, dana di-release dan dikembalikan ke available balance
- Pola ini membedakan total balance dan available balance
available = total - reserved- Pemeriksaan saldo dan reservation baru dilakukan berdasarkan available balance
- Jumlah akhir dapat berbeda dari estimasi awal
- Jika biaya atau kurs berubah, jumlah perkiraan dicadangkan, jumlah aktual di-settle, lalu sisanya di-release
- Reservation wajib di-settle atau di-release
- Reservation yatim mengunci dana pengguna, tetapi tidak menghilangkan atau menciptakan uang
- Expiry atau timeout dapat menjadi jaring pengaman, tetapi tidak wajib
- Pemeriksaan saldo dan pencatatan reservation harus linearizable
- Pada stale read, dua transaksi bisa sama-sama lolos pemeriksaan dan didukung oleh dana yang sama
Overdraft dan idempotensi
- Overdraft adalah situasi ketika saldo akun menjadi negatif
- Overdraft yang disengaja adalah produk kredit dengan limit dan bunga, dan biasanya dimodelkan sebagai akun overdraft terpisah
- Overdraft yang tidak disengaja dapat terjadi meskipun dilarang oleh kebijakan
- Settlement bisa lebih besar dari estimasi reservasi, atau reversal dapat masuk setelah dana sudah keluar
- Funds reservation mempersempit window, tetapi tidak menghilangkannya
- “Dilarang” dan “tidak dapat direpresentasikan” itu berbeda
- Jika saldo negatif dibuat tidak dapat direpresentasikan dengan unsigned integer atau
CHECK (balance >= 0), saat secara realistis saldo negatif harus diterima, hal itu dapat berujung pada crash, zero clamp, atau pemrosesan yang salah - Jika saldo negatif di-clamp menjadi 0, uang akan tercipta
- Jika saldo negatif dibuat tidak dapat direpresentasikan dengan unsigned integer atau
- Jika overdraft terdeteksi, perlakukan sebagai sinyal investigasi, lalu pulihkan atau tangani secara eksplisit melalui future deposit dan netting, permintaan repayment, atau write-off ke akun expense/loss
- Dalam sistem terdistribusi, exactly-once delivery tidak dapat dijamin, sehingga retry diperlukan, dan retry dapat menimbulkan pengiriman duplikat
- Idempotency adalah sifat yang membuat pemrosesan hanya berdampak sekali meskipun pesan yang sama dikirim dua kali
- Idempotency key eksplisit biasanya lebih sederhana dan aman daripada deduplication berbasis payload
- Key harus dibatasi pada operation dan cakupan client tertentu
- Perlu memutuskan apakah error akan diputar ulang atau diproses ulang; untuk error permanen, biasanya lebih sederhana untuk memutar ulang apa adanya
- Memverifikasi bahwa payload panggilan duplikat sama dengan yang asli adalah praktik yang baik, tetapi memiliki biaya kompleksitas implementasi dan fleksibilitas
- Pada skala besar, deduplication untuk miliaran request dan atomic barrier pada akses bersamaan diperlukan
- Idempotency window seperti 24 jam menyederhanakan implementasi, tetapi membawa biaya correctness yang besar
- Pengujian retry dan penanganan out-of-order retry juga diperlukan
Alur yang dapat dimulai ulang
- Aliran uang berlangsung melalui beberapa tahap dan harus diasumsikan bisa mati di mana pun di antara tahap-tahap tersebut
- Full resumability adalah desain yang memastikan alur yang setengah selesai selalu berada dalam keadaan yang dapat dipulihkan
- Status progres harus disimpan di penyimpanan persisten, bukan di memori
- Modelkan alur sebagai state machine eksplisit dan commit penyelesaian tiap tahap sebelum memulai tahap berikutnya
- Diperlukan driver independen yang mendorong kembali alur yang terhenti
- Scheduler, worker, atau poller harus memproses incomplete flow bahkan setelah orchestrator crash
- Saat dilanjutkan, tahap yang sudah terjadi sebagian mungkin dieksekusi ulang, sehingga setiap tahap harus idempotent
- Efek eksternal tidak dapat di-rollback
- Setelah memanggil dunia luar, status tidak dapat dikembalikan seolah-olah panggilan belum dilakukan
- Lakukan roll forward hingga selesai, atau jika tahap berikutnya gagal permanen, posting compensating action seperti dalam saga pattern
- Dapat menggunakan durable-execution engine seperti Temporal, Camunda, Workflows4s, AWS Step Functions, atau membangun persistent state machine sendiri
Mengonsumsi API Eksternal
- API eksternal seperti penyedia pembayaran, custodian, blockchain node, dan vendor KYC harus ditangani secara defensif karena kita tidak dapat mengontrol kode, kualitas, maupun uptime-nya
- Jangan memercayai skema
- Field bisa hilang, tipe bisa berubah, dan null yang tidak terduga bisa muncul
- Bagian penting harus divalidasi di boundary, dan data yang tidak terduga harus gagal secara jelas
- Jika memvalidasi hingga bagian yang tidak diperlukan, pelanggaran kontrak dari pihak ketiga dapat menyebabkan gangguan yang tidak perlu
- Pada API eksternal, hal-hal seperti token dikirim lewat URL, hilangnya presisi, HTTP code yang tidak sesuai makna, error body di dalam
200, pagination yang tidak konsisten, dan custom date format sangat mungkin terjadi - Semua pemanggilan bisa gagal, jadi timeout dan retry diperlukan
- Circuit breaker terutama merupakan courtesy terhadap server yang kelebihan beban, dan menambah kompleksitas di sisi klien
- Namun, ini bisa diperlukan saat melindungi sumber daya terbatas seperti latency, thread, dan connection
- Untuk rate limit dan quota, perlu memperkirakan jumlah panggilan di muka dan mencocokkannya dengan limit provider
- Menyimpan semua request dan response dalam bentuk terstruktur dan dapat di-query menjadi bahan untuk investigasi, audit trail, bukti dalam sengketa perilaku provider, dan pemrosesan ulang setelah bug
- Pada area inti, provider redundancy dapat dipertimbangkan
- Contohnya memvalidasi data dengan dua blockchain node, backup bank partner, crypto custodian, atau vendor KYC
- Biaya pengembangan, fee, dan kompleksitasnya sangat besar
- Sandbox bisa sangat berbeda dari production, jadi perlu menyiapkan production test lewat canary release atau controlled usage yang berdampak kecil
Pemrosesan Webhook
- Webhook adalah cara umum untuk menerima sinyal dari sistem eksternal, tetapi memprosesnya dengan aman tidak mudah
- Jangan mengasumsikan urutan
- Pesan bisa datang out-of-order atau memuat stale data
- Jangan menganggap webhook yang baru diterima sebagai kebenaran terbaru lalu menimpa status
- Jangan mengasumsikan validitas
- Webhook datang dari subsistem lain milik issuer dan bisa memuat data yang stale atau salah ditransformasi
- Sebaiknya gunakan body webhook hanya sebagai trigger, lalu query API untuk memeriksa authoritative state
- API juga bisa eventually consistent, sehingga query langsung dapat mengembalikan status lama; retry diperlukan
- Jangan mengasumsikan delivery
- Meskipun issuer menjanjikan redelivery policy yang kuat, webhook pada akhirnya tetap bisa hilang
- Proses independen seperti reconciliation harus melengkapi integritas data
- Jangan pula mengasumsikan single delivery
- Webhook yang sama dapat dikirim beberapa kali, dan pemrosesannya harus idempotent
- Harus acknowledge dengan cepat dan memproses secara asinkron
- Simpan raw event ke durable store, segera kembalikan 2xx, lalu lakukan pekerjaan sebenarnya secara asinkron
- Raw payload harus disimpan apa adanya
- Ini diperlukan untuk pemrosesan yang stabil, audit trail, dan pemrosesan ulang setelah bug
- Pemanggil harus diverifikasi
- Umumnya issuer menyertakan payload signature, dan penerima memverifikasi dengan HMAC berbasis shared secret atau tanda tangan asimetris berbasis public key
- Verifikasi tanda tangan harus dilakukan atas raw bytes yang diterima, bukan atas payload yang diserialisasi ulang
- Webhook harus diperlakukan bukan sebagai kebenaran tentang apa yang terjadi, melainkan sebagai hint bahwa sesuatu telah terjadi
Notifikasi Andal: Outbox dan CDC
- Saat perubahan sistem harus diberitahukan secara andal ke channel eksternal seperti Kafka event atau webhook call, transactionality menjadi masalah
- Bisa terjadi situasi publish berhasil tetapi respons tidak diterima karena masalah jaringan sehingga status sistem di-rollback, atau state change sudah di-commit tetapi publish gagal
- Jawaban textbook adalah 2-phase commit atau distributed transaction, tetapi jarang dipakai karena kompleksitas dan sulitnya standardisasi untuk reuse
- Ada beberapa pilihan praktis
- Outbox pattern: mencatat publishing intent secara transactionally di store khusus bersama perubahan status, lalu memprosesnya nanti sampai berhasil
- Change Data Capture: membaca database write-ahead atau replication log dan mengubah perubahan yang sudah di-commit menjadi event stream
- Debezium dan AWS DMS menyediakan CDC
- CDC mengeluarkan raw event dalam bentuk table row, jadi postprocessing diperlukan agar schema internal tidak bocor
- Listen-to-yourself berarti mem-publish event terlebih dahulu, lalu membangun kembali status sendiri dari event tersebut
- Event sourcing memiliki event log yang sudah ada di DB, sehingga publish dapat dilakukan dari sana
- Apa pun mekanisme yang dipilih, delivery bersifat at-least-once
- Jika relay atau connector crash setelah publish tetapi sebelum mencatatnya, event dapat dikirim lagi saat restart
- Consumer harus melakukan deduplicate dengan stable event id dan beroperasi secara idempotent
Reconciliation
- Sistem yang bergantung pada data eksternal rentan terhadap data drift, yaitu status dua sistem menjadi tidak selaras
- Webhook bisa terlewat, atau transaction sudah di-posting di ledger tetapi belum tercermin di sistem external provider
- Reconciliation adalah proses untuk menyelaraskan dua sistem
- Dalam praktiknya bisa ada tiga sistem atau lebih, seperti ledger, payment processor, dan bank
- Cadence bisa hourly, daily, monthly, atau yearly, bergantung pada konteks dan batasan
- Drift bisa berupa missing data, atau perbedaan yang lebih kompleks seperti jumlah pada transaction yang sama berbeda
- Timing juga penting
- Jika settlement adalah T+3, record bisa tetap unreconciled selama 3 hari, sehingga ini harus tercermin dalam process untuk mencegah alert yang tidak perlu
- Matching algorithm adalah kesulitan utama
- Biasanya, menyimpan external provider id di sisi internal akan membuat matching lebih sederhana
- Jika tidak ada, mungkin diperlukan heuristic berbasis amount dan time
- One-to-many reconciliation juga diperlukan
- Satu settlement transfer dapat mencakup banyak transaction
- Discrepancy tidak boleh sekadar di-overwrite agar sesuai dengan reconciliation
- Penyebabnya harus dipahami dan diperbaiki lewat dukungan first-class seperti correction record atau reprocessing webhook data
Kontrol dan Akses
- Sistem uang harus mengontrol bukan hanya data, tetapi juga siapa yang dapat melakukan tindakan apa, serta membuktikan kepatuhan prosedur setelahnya
- Segregation of duties adalah kontrol yang mencegah satu orang memiliki keseluruhan proses
- Four-eyes, maker-checker, dan dual control adalah cara yang mewajibkan orang kedua menyetujui action tertentu sebelum diterapkan
- Ini diterapkan pada tindakan yang dapat memindahkan dana atau menampilkannya secara keliru, seperti withdrawal berskala besar atau manual, manual ledger correction, perpindahan treasury dan cold-wallet, serta perubahan fee schedule atau limit
- Kontrol yang sama juga berlaku pada engineering
- Code merge, production deploy, dan infrastructure change adalah action sensitif dalam sistem uang, sehingga memerlukan review dan approval
- Approval itu sendiri juga merupakan bagian dari trail
- Untuk membuktikan control, harus dicatat siapa yang meminta, siapa yang menyetujui, dan apakah keduanya orang yang berbeda
- Untuk emergency, diperlukan jalur break-glass yang eksplisit dan diaudit secara ketat
- Access control adalah bagian dari status sistem dan berubah seiring waktu
- Baik human maupun service harus diberi hak minimum
- RBAC lebih disukai daripada per-person grant karena memudahkan review
- Capability grant dan revoke juga merupakan event sensitif, sehingga perlu dicatat apa yang berubah, siapa yang mengubah, dan mengapa
- Scheduled access review harus dilakukan untuk menemukan permission drift yang sudah usang atau tidak akurat
Pelacakan Perubahan SDLC
- Dalam lingkungan regulasi, proses bagaimana kode mencapai production harus dapat diaudit
- Source control adalah catatan perubahan
- Commit history mengatribusikan semua perubahan kepada author, dan menghubungkan alasannya melalui review serta linked ticket
- Harus dilindungi dengan signed commit, protected branch, dan larangan force-push pada shared history
- Review dan pipeline harus diwajibkan
- Required review, status check, dan larangan direct push ke main branch adalah hal penting
- Deployment harus dapat dilacak
- Agar incident dapat dihubungkan dengan perubahan penyebabnya, harus dimungkinkan untuk merekonstruksi version apa yang sedang berjalan serta siapa yang melakukan release dan kapan
Strategi Pengujian
- Dalam sistem uang, ruang operation sequence besar dan kegagalan yang menarik muncul dari kombinasi, sehingga pengujian menjadi sangat penting
- Property-based testing memverifikasi property yang harus berlaku untuk input apa pun, bukan output tertentu
- Cocok untuk invariant dan money math
- Saat membuat operation sequence, invariant harus diperiksa tidak hanya di akhir, tetapi juga setelah setiap tahap
- Karena sulit dilakukan secara manual dalam skala besar, diperlukan testing harness yang menyuntikkan assertion secara otomatis
- Generative idempotency testing memverifikasi bahwa setiap operation yang menyentuh dunia eksternal tidak memiliki dampak pada panggilan kedua
- Crash and resume injection memverifikasi apakah long flow dapat pulih meskipun mati di antara tahap mana pun
- Round-trip testing memastikan apakah setelah encode/decode, serialize/deserialize, atau convert/convert back, hasilnya kembali ke titik awal atau berada dalam tolerance yang diketahui
- Ini adalah cara cepat untuk menangkap kehilangan presisi di boundary pada money dan currency type serta serialization bug
- Golden testing membandingkan hasil perhitungan seperti fee breakdown, statement, dan report dengan hasil ekspektasi yang tersimpan untuk mengungkap diff yang tidak disengaja
- Backward-compatibility testing mempertahankan corpus payload real-format lama dan memverifikasi bahwa kode saat ini masih melakukan deserialize dan project dengan benar
- Production testing mungkin diperlukan ketika sandbox sangat berbeda dari production
- Contohnya canary release, controlled rollout dengan blast radius kecil, dan synthetic transaction yang terus mengalirkan jumlah uang nyata yang kecil
- Karena production test memindahkan uang sungguhan, ia harus melewati ledger, reconciliation, dan audit trail yang sama, serta dibereskan melalui jalur correction/reversal normal
Istilah Domain dan Referensi
- Dalam pengantar fintech, vocabulary dan concept bisa lebih sulit daripada kode, sehingga istilah inti dirangkum secara terpisah
- Area akuntansi dan ledger mencakup ledger, general ledger dan sub-ledger, debit/credit, posting, chart of accounts, receivable/payable, IOU, accrual vs cash basis, trial balance, suspense/clearing account, write-off, commingling, dan reconciliation break
- Area Money dan FX mencakup Money type, minor units, basis point, notional, fiat vs crypto, stablecoin, pegged/wrapped/bridged, bid/ask/spread, mid-market rate, reference rate, dan mark-to-market
- Area transaksi dan settlement mencakup value date, booking date, settlement date, T+X, clearing vs settlement, cut-off time, float, netting, backdating, dan reversal/correction
- Istilah pembayaran, kartu, pasar, crypto, dan compliance juga dirangkum secara terpisah
- 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
- Referensi dibagi menjadi akuntansi dan ledger, payments dan cards, markets dan trading, crypto, engineering, serta KYC dan AML
- Accounting for Computer Scientists: tulisan untuk engineer yang menjelaskan pembukuan berpasangan melalui graf dan model data
- Modern Treasury, How to Scale a Ledger: seri tulisan yang membahas production ledger dari perspektif software engineering
- Designing Data-Intensive Applications: membahas idempotency, log, consistency, dan failure mode dari perspektif sistem
Tiga contoh end-to-end
-
Penarikan kripto
- Ini adalah alur ketika pengguna menarik 0,5 ETH ke alamat eksternal
- Permintaan menyertakan idempotency key agar pengiriman duplikat hanya membuat satu withdrawal
- 0,5 ETH dan estimasi network fee direservasi dari available balance
- Compliance gate memeriksa sanctions, AML, dan destination address, serta dapat sleep selama beberapa hari karena panggilan eksternal dan review manual
- On-chain broadcast harus idempotent, dan setelah crash harus memeriksa kembali chain, bukan melakukan broadcast kedua
- Setelah confirmation yang cukup, lakukan posting di ledger untuk user account debit, external on-chain account credit, network fee expense, dan service fee revenue
- Nightly job merekonsiliasi ledger dengan realitas chain
-
Deposit kartu
- Ini adalah alur top-up kartu melalui PSP
- Pengguna mengirimkan jumlah dan informasi kartu, lalu membuka deposit transaction di PSP dengan idempotency key
- Authorization hanya membuat hold; karena uang belum menjadi milik perusahaan, jangan credit user balance
- Webhook
capturedmemverifikasi signature raw bytes, menyimpan raw payload, memberi respons 2xx cepat, lalu diproses secara asinkron - Webhook hanya trigger, sehingga authoritative state diambil dari PSP API
- Status captured but not settled diposting melalui clearing account, dan settlement dapat tiba dalam batch setelah T+X
- Chargeback ditangani sebagai linked compensating entry tanpa mengubah entri asli
-
Konversi in-app dengan cashback
- Ini adalah alur mengubah 1.000 EUR menjadi USDC dan memberikan promotional cashback
- Quote EUR→USDC bukan kebalikan dari USDC→EUR, melainkan directional rate
- EUR dan USDC tidak dijumlahkan satu sama lain; USDC diidentifikasi dengan
(network, contract address)dan tidak sama dengan pegged fiat - Perhitungan mempertahankan presisi penuh dan hanya membulatkan sekali di batas dengan strategi eksplisit
- Spread harus dibukukan secara eksplisit ke revenue account dan tidak boleh hilang sebagai rounding residual
- Cashback bukan penambahan balance gratis, melainkan uang nyata yang dipindahkan dari company promotional/expense account ke user balance
- Publish hasil menjamin reliable delivery dengan mekanisme seperti outbox, CDC, atau event log, dan downstream consumer melakukan dedupe dengan stable event id
1 komentar
Komentar Hacker News
Saya sudah membacanya sekilas, dan menurut saya handbook ini dangkal; di beberapa bagian bahkan mendekati saran yang buruk
Misalnya, kalau melihat nilai uang disimpan dalam bentuk selain integer, rasanya saya akan menjerit lalu kabur. Ini karena hal-hal seperti decimal di Rust yang direpresentasikan sebagai floating point JSON. Kecuali ada alasan yang sangat kuat, nilainya harus selalu berupa integer, sementara view yang diekspor bisa saja dalam format bitcoding aneh atau apa pun
Kurs valuta asing juga bukan masalah yang bisa diselesaikan dengan satu titik waktu tertentu. Kurs pada waktu menurut pembeli, kurs pada waktu menurut penjual, kesepakatan, toleransi kesepakatan, dan timestamp final yang disepakati semuanya berpengaruh
Karena immutability, di semua tempat yang menangani uang rasanya ingin memakai event sourcing. Stream yang sudah dirapikan pada akhirnya mungkin terlihat seperti
A -> B -> E, tetapi stream sebenarnya bisa sajaA0 -> Edit(A0, A) -> B -> C -> D -> Rollback(B) -> EPada akhirnya, Fintech juga tidak semuanya sama. Di beberapa tempat uang diperlakukan seperti barang bawaan, sementara di tempat lain uang adalah pusat dari segalanya
Tentang valuta asing juga, ini tampaknya justru memperkuat pernyataan handbook bahwa “tidak ada canonical rate yang benar”. Selain itu, tulisan tersebut membahas catatan setelah finalisasi, sedangkan komentar ini sepertinya berbicara tentang cara finalisasinya. Itu nuansa yang valid untuk tujuan terpisah, tetapi tidak terlihat seperti bukti bahwa ada yang terlewat atau salah
Bagian immutability juga tampaknya menyampaikan poin yang sama dengan tulisan tersebut. Saya tidak tahu apa bedanya
Jika Anda menghitung harga opsi Monte Carlo di atas jalur suku bunga, dan peduli pada metrik risiko seperti duration, convexity, dan vega, tidak ada yang peduli apa aturan pembulatannya. double sudah cukup. Bagaimana Anda akan memaksa
exp(-rt)cashflowatau fungsi distribusi kumulatif normal menjadi integer?Ada juga area yang memang tepat memakai integer. Namun itu bukan prinsip universal; cukup buat pilihan rekayasa yang tepat
Jika lingkungan yang digunakan mendukungnya, fixed-point juga bisa dipakai, tetapi secara teknis itu tetap integer
Untuk tampilan, mengembalikan nilai decimal juga aman
Bagus kalau Anda kabur dari sistem yang menyimpan jumlah uang sebagai integer. Dengan begitu kita mungkin tidak akan bekerja di sistem yang sama. Saat ini justru sering kali saya ingin kabur dari sistem yang memperlakukan jumlah uang sebagai integer. Jika codebase ideal yang hanya disentuh programmer finansial berpengalaman, mungkin bisa berjalan baik, tetapi sistem seperti itu biasanya berisiko menjadi terlalu eksklusif atau rapuh
Jika ingin memberi saran kepada orang yang mempertimbangkan strategi minor-unit precision untuk merepresentasikan jumlah uang: sebaiknya jangan. Setidaknya jangan gunakan sebagai format data pertukaran/API
Ini terlihat cerdik—operasi integer cepat, tidak ada masalah pembulatan pada penjumlahan dan pengurangan—tetapi begitu bekerja dengan partner lain yang punya asumsi implisit berbeda tentang jumlah digit untuk mata uang tertentu, Anda bisa benar-benar tersandung. Ini terutama penting untuk stablecoin, karena sering kali jumlah digit desimal implisitnya berbeda dari mata uang fiat yang diwakilinya
Dalam API berbasis JSON, merepresentasikan jumlah uang sebagai tipe string juga layak dipertimbangkan. JSON tidak menentukan presisi desimal, jadi Anda harus selalu memastikan bahwa parser/serializer milik Anda dan semua pengguna/vendor tidak melewati floating point secara internal lalu kehilangan presisi. Ini bisa cepat menjadi berantakan, dan string secara konseptual terlihat kurang rapi, tetapi cara ini sepenuhnya menghindari masalah tersebut. Sebagian orang akan menyebutnya antipattern [1], tetapi saya tidak ingin memperjuangkan kemurnian ideologis ini di atas pundak pengguna atau pemegang saham
[1] https://blog.json-everything.net/posts/numbers-are-numbers-n...
Di ranah high-frequency trading, jika Anda bisa menetapkan eksponen yang konsisten sebelumnya untuk suatu {slice}, Anda bisa menghemat ruang transmisi. Misalnya, dalam cakupan seperti produk/ukuran tick/kelas aset/bursa/feed/server, cukup kirim mantissa saja dan klien memakai eksponen yang di-hardcode
Namun bahkan di ranah serupa, sering kali sepadan untuk mengirim satu eksponen
uint32tambahan dalam data transmisi. Dengan begitu, Anda bisa mengubahnya nanti dan tidak terhambat oleh desain awal seperti “sekarang kita hanya butuh sen”. Misalnya, tiba-tiba Anda mungkin harus mendukung harga bitcoin dengan presisi penuh. Pengguna akan berterima kasih jika Anda tidak perlu mengoordinasikan breaking change saat ingin menyesuaikan eksponen tetapKriteria “apa pun” itu tidak masuk akal. Itu standar yang tidak bisa dicapai dan bisa menuntut anggaran engineering tanpa batas tanpa nilai yang benar-benar dapat dibuktikan
Mengidentifikasi ketiadaan standar, membicarakan bagaimana parser nyata berperilaku, serta membahas celah dan use case yang belum terpenuhi itu bagus. Mengusulkan perlunya standar yang lebih masuk akal juga bagus. Tetapi menuntut semua orang mendukung “semua kemungkinan” yang sebenarnya tidak dibutuhkan siapa pun, maknanya tidak jelas, dan tidak bisa dicapai secara nyata, bukan ide yang baik
float/double, aritmetika fixed-point dalam satuan seperseribu minor unit atau lebih kecil, desimal presisi arbitrer, atau pendekatan yang sama sekali berbeda?Sebagai programmer, ketika melihat programmer Fintech berbicara dari pengalaman dan perspektif masing-masing, saya jadi bertanya-tanya apa sebenarnya arti menjadi jago memrogram
Saat xlii mengatakan jangan menyimpan jumlah uang dalam floating point, itu adalah masalah IEEE 754 yang umum. Pelacakan keuangan memang sebaiknya dilakukan dengan log immutable atau catatan berbasis event, tetapi menurut saya tidak semua layanan di sekitarnya perlu dibuat dengan event sourcing. Cukup menerapkannya pada logika inti seperti ledger, settlement, order, dan execution. Dari tulisan xlii, teknik itu terlihat seperti hanya bisa terwujud jika pemodelannya berhasil
Pernyataan lxgr menyoroti masalah minor-unit. Jika angka JSON diparse oleh bahasa atau parser sebagai floating point, presisi bisa hilang. Biasanya nilai dikirim bersama field terpisah untuk jumlah digit desimal. Namun saya dengar dalam high-frequency trading, overhead itu sendiri terlalu mahal sehingga mereka tidak melakukannya
Pernyataan antonymoose selaras dengan apa yang dikatakan banyak buku. Karena itu, desain seperti ini umum dalam konteks valuta asing atau API. Rasanya juga seperti desain protokol
Jika dirangkum, semuanya benar dalam domain masing-masing. Saya berpikir akan bagus jika ada orang seperti xlii sebagai programmer senior, tetapi pada saat yang sama saya juga merasa mungkin tidak bisa merancang sistem serumit itu. Dalam arti itu, ucapan masing-masing valid, dan menarik melihat pendapat berbeda menurut domain. Saya bertanya-tanya apakah inilah yang disebut keahlian
Melihat hal seperti ini, kita bisa kira-kira menebak pengalaman macam apa yang dimiliki seorang programmer. Terkadang programming terasa bukan seperti mencari jawaban benar, melainkan memilih pandangan dunia
Selalu menarik melihat di HN bagaimana para programmer memodelkan domain mereka. Kadang saya mengklik profil mereka, lalu menambahkan pengetahuan domain mereka ke wiki pribadi dengan pikiran mungkin suatu hari akan berguna
Bagus. Buku ini sudah memuat banyak informasi bagus yang juga bisa ditemukan di tempat lain, tetapi sekadar mengumpulkannya saja sudah cukup praktis. Saya sangat merekomendasikan Designing Data-Intensive Applications karya Kleppmann. Edisi pertamanya juga sangat bagus, dan edisi keduanya baru-baru ini terbit
Saya pernah bekerja sebagai CTO di FinTech dan membangun seluruh stack perangkat lunak dari nol; pelajaran dalam buku ini secara umum benar. Saya mengatakan secara umum karena, seperti biasa, dalam proyek tertentu Anda harus banyak mempertimbangkan “tergantung situasinya”. Misalnya, saya tidak memakai event sourcing karena ingin menghindari masalah menghitung seluruh state. Audit trail append-only standar saja bisa sudah cukup
Exactly-once delivery tidak bisa dijamin, tetapi effectively-once processing bisa disusun, dan sebenarnya itulah yang diinginkan
Pernyataan untuk menyimpan semua request dan response benar secara mutlak. Itu harus dilakukan bukan hanya saat mengonsumsi API, tetapi juga saat mengumpulkan informasi apa pun dari dunia luar; jika memungkinkan, catat juga semua tahap transformasi perantara di dalam boundary. Kombinasi bucket berbasis content-addressing dan tabel relasional itu bagus
Selain itu, teks utama tidak mengatakan apa pun tentang data lineage. Apa yang Anda lakukan jika vendor memperbarui suatu data di tengah hari, dan Anda wajib mengetahui fakta itu? Anda harus bisa menjelaskan perubahan tersebut sambil memastikan bahwa menjalankan ulang perhitungan yang memakai nilai lama tetap menghasilkan hasil yang sama. Ini bukan masalah yang sangat sulit dipecahkan, tetapi perlu dipikirkan
Menyebutnya “saran buruk” itu sebenarnya ungkapan yang cukup sopan. Terus terang, “handbook” ini tampaknya sebagian besar ditulis oleh LLM
Misalnya, di bagian imutabilitas ada kalimat seperti ini: “Dengan memisahkan PII dari data keuangan, Anda dapat menghormati hak penghapusan tanpa kehilangan riwayat keuangan yang wajib disimpan”
Di lembaga keuangan, keduanya berjalan bersama karena alasan KYC/AML yang jelas
Jika Anda langsung menghapus nama pelanggan, alamat, dan sebagainya saat diminta sebelum periode terkait berakhir, tetapi hanya menyisakan data keuangan, seluruh organisasi akan mengalami hari yang sangat buruk ketika lembaga yang berwenang secara hukum datang meminta data untuk melacak kejahatan
Orang yang ingin bekerja di Fintech tidak boleh bergantung pada “handbook” acak yang ditulis oleh orang tak dikenal dari yurisdiksi yang tidak diketahui
Orang yang bekerja di Fintech seharusnya hanya bekerja mengikuti handbook/pedoman internal pemberi kerja mereka. Dokumen semacam itu kemungkinan disusun bersama oleh pengacara perusahaan dan petugas kepatuhan, agar memenuhi hukum dan persyaratan pelaporan di yurisdiksi tempat pemberi kerja beroperasi
Menurut saya, yang pada akhirnya disarankan adalah memisahkan PII yang harus dihapus dari data yang ingin disimpan secara praktis selamanya karena masuk ke persamaan akuntansi/invarian. Dengan begitu, setelah periode retensi catatan yang relevan lewat, yang pertama bisa dihapus
Benar bahwa kita tidak boleh bergantung pada “handbook” yang ditulis oleh orang tak dikenal dari yurisdiksi yang tidak diketahui. Namun, kita juga tidak boleh secara membabi buta mengabaikan ide dan praktik di dalamnya, atau tidak melihat ke luar organisasi sendiri. Idealnya, setelah membacanya, kita membandingkannya dengan pengetahuan sendiri dan regulasi setempat, lalu menyesuaikannya
Jika dunia hanya berisi organisasi yang sempurna dan bebas kesalahan, pendekatan hanya mengikuti panduan internal pemberi kerja tampak masuk akal. Namun tanpa percakapan seperti ini, bagaimana kita bisa mencapai tingkat itu?
Saya rasa sebagian besar isi ini berlaku bukan hanya untuk Fintech, tetapi untuk rekayasa perangkat lunak secara umum
Misalnya, bagian yang membahas retry, idempotensi, urutan event, dan sebagainya berlaku pada sistem apa pun yang membutuhkan tingkat kebenaran tertentu, meskipun uang tidak terlibat langsung. Saya sudah melihat terlalu banyak sistem yang dibuat dengan asumsi “bisa retry kapan saja”, padahal retry hanya mungkin jika kegagalan terjadi dengan bersih sejak awal, dan subsistem harus menyediakan tingkat idempotensi yang kita kira ada. Hal-hal seperti ini sering kali tidak benar-benar diverifikasi
Saya lebih ingin membaca tulisan yang membela pendekatan yang lebih radikal seperti database per akun. Maksudnya hal-hal yang punya trade-off unik di dalam Fintech
Nasihat utama yang ingin saya berikan kepada engineer atau founder Fintech adalah memperlakukan risiko dan kepatuhan secara serius sejak hari pertama
Sistem keuangan dibangun di atas kepercayaan. Jika Anda tidak dapat membuktikan bahwa risiko telah dimitigasi, Anda akan kehilangan kepercayaan, dan pada akhirnya kehilangan seluruh bisnis
Pernyataan untuk menghindari floating point tidak benar. Saya bekerja 20 tahun di Fintech dan sebagian besar memakai double. Excel juga memakai double, frontend juga akan memakai double, dan semua database mendukung double. Standard library tahu cara parsing double, dan JSON, entah teorinya bagaimana, dalam praktiknya memakai double. Banyak sistem ERP juga memakai double
Kunci saat menangani mata uang dengan double adalah mengingat bahwa ia dapat memuat total presisi 15 digit. Selama angka Anda tidak memakai digit lebih banyak dari itu, seperti
123456789.01atau123.456789, Anda bisa mendapatkan presisi desimal yang sempurna untuk perhitungan keuangan. Cukup selalu bulatkan hasil ke dalam presisi 15 digit setelah setiap perhitungan dan sebelum setiap perbandingan. Excel melakukan ituKeunggulan terbesar double adalah dukungannya luas, dan Anda bisa mencampur presisi berbeda di dalam sistem. Jika menangani keuangan internasional atau produk keuangan tingkat lanjut, hal seperti itu akan terjadi. Sebagian pembukuan membutuhkan presisi hingga seperseribu, sebagian lain harus dibulatkan ke kelipatan 0,25. Pada akhirnya Anda tidak akan memakai aritmetika dasar, melainkan library matematika akuntansi khusus, dan library itu dapat sepenuhnya memakai floating point sebagai backend
Pemeriksaan saldo Plaid bukan jaminan bahwa debit ACH yang akan segera diajukan akan berhasil
Tidak peduli saldonya satu juta dolar. Sebelum ACH diproses, semua uang bisa (a) keluar lewat wire transfer, (b) terselesaikan oleh ACH kemarin—tagihan, autodebit, dan sebagainya—serta cek, atau (c) dipakai di kartu debit/ATM
Sebaiknya saya tidak mengatakan bagaimana saya tahu sebagian Fintech tidak menangani hal ini
Bagian kunci idempotensi saja sudah membuat tulisan ini layak dibaca. Sebagian besar developer mempelajari pelajaran itu dengan cara yang sulit
Banyak di antaranya berasal dari masa sebelum pengetahuan tentang idempotensi tersebar luas, sehingga sering kali orang memaksakan pembuatan kunci idempotensi dengan menggabungkan beberapa field yang seolah-olah unik secara global. Masalahnya, itu tidak pernah benar-benar sepenuhnya unik. Kadang kita bisa melihat apa yang terjadi di balik layar, misalnya ketika bank tidak mengizinkan transfer dengan tanggal yang sama, jumlah yang sama, dan ke rekening penerima yang sama
Saya menghabiskan banyak waktu menjelaskan bagaimana idempotensi seharusnya bekerja dan mengapa itu penting. Sebagian besar tim memahami kebutuhannya, tetapi hampir tidak ada yang sudah memikirkannya sejak awal
“Fintech” sangat luas, dan sebagian besar hal yang disebut Fintech sebenarnya adalah komunikasi. Komunikasi antarperusahaan, antarpedagang, antarsistem, dan antarledger. Tidak ada cara pemrograman yang “benar” untuk seluruh industri. Pada akhirnya, cara yang benar adalah cara yang dapat dipahami oleh pihak yang berkomunikasi dengan kita
Jika pihak lain melacak mata uang dalam satuan sen, maka jika Anda melacak dengan presisi lebih tinggi, akan muncul ketidaksesuaian pembulatan. Sebaliknya juga sama jika Anda memakai satuan sen sementara pihak lain menangani hingga 0,1 sen. Semua saran lain dalam dokumen ini juga harus dilihat dengan cara seperti itu