Custom Payments Platform Development: Ledgers, Payouts and Reconciliation That Actually Tie Out
Build it when the money movement itself is your product or your margin, not when you just need to accept cards. If you are running gateways, a ledger, payouts and reconciliation across more than one processor and your finance team is closing the month in spreadsheets, a custom payments platform pays for itself fast. Across 2,000+ Digital Heroes projects, a focused first release covering one ledger, one processor integration and automated reconciliation typically lands at $60,000 to $130,000 in 12 to 16 weeks. A full platform with multi-processor routing, split payouts, chargeback handling, KYC onboarding and a merchant-facing dashboard runs $150,000 to $400,000 phased over 6 to 12 months. If you process under roughly $2M a year through a single processor and never split a payment, stay on Stripe and spend the money elsewhere.
Why your payments stack makes or breaks a high-volume operator
We walk into this one about twice a year. A marketplace doing $40M a year in gross volume. Stripe Connect handles card acquiring for the US, Adyen handles the EU because Stripe's local method coverage was not good enough, and there is a legacy Authorize.Net account still alive because one enterprise client refuses to re-sign a payment mandate. Payouts go out through Stripe for most sellers, through Wise for the international ones, and through a bank file for the eleven sellers who are big enough to have negotiated wire terms. The ledger, the actual authoritative record of who is owed what, lives in a Google Sheet maintained by a controller named Dana, and every line in it is typed by hand or pasted from a CSV export.
Month end takes Dana and one analyst nine working days. They pull the Stripe balance transaction export, the Adyen settlement detail report, the Wise statement, and the bank's BAI2 file, and they try to make four different definitions of "settled" agree with each other. Stripe reports the fee net of the transaction. Adyen reports it as a separate line in a separate batch. The bank reports a lump sum with no reference to any individual payment. Somewhere in there is a $3,400 gap that has been carried forward for four months because nobody has nine more days to find it. Meanwhile a seller emails support asking why their payout was $180 short, and the only honest answer is "give us a week."
A broken payments platform does not fail loudly. It bills you every month: two full time finance headcount doing work nobody would hire for on purpose, a close that lands too late to be useful, chargebacks fought manually or not at all, and an inability to answer "what is our take rate by seller cohort" without a two day data pull. We have rebuilt this exact stack more times than any other category, and the pattern is always the same. The processors are fine. The ledger is missing.
Problem 1: your ledger is your processor's balance, and that is not a ledger
Stripe's balance is Stripe's opinion of your money. It is not double entry, it does not know about the Adyen leg, it does not know about the $12,000 you owe a seller for a January order that refunded in March, and it has no concept of a liability you have accrued but not paid. Operators discover this the first time they try to answer a simple question: as of last Tuesday at 4pm, how much of the cash in our bank account was actually ours versus held on behalf of sellers? Stripe cannot answer it. QuickBooks cannot answer it because it only sees the daily deposit. So the answer gets estimated, and estimates get audited.
Stripe Treasury and Adyen for Platforms both give you balance accounts, and they are real products, but they are per-processor. The moment you have two acquirers, or one acquirer plus a bank plus a payout rail, no vendor ledger is the source of truth because none of them can see the others. This is not a gap you close with a better plan tier.
What a custom build does: a real double entry ledger as the system of record, with immutable append-only entries and a strict account tree. Every event that touches money writes a balanced journal entry. Authorization creates a pending entry, capture moves it, the processor fee debits an expense account, the seller share credits a liability account named for that seller, the payout debits the liability and credits cash. Nothing is ever updated, only reversed and re-entered, so you have a full audit trail with no destructive edits. Processors become sources of events, not sources of truth. When Stripe and your ledger disagree, your ledger wins and the disagreement becomes a reconciliation exception with a ticket attached, not a mystery. We build these with a transactions table, an entries table with a hard database constraint that debits equal credits per transaction, and account balances derived by summing entries rather than stored as a mutable number. That single design decision eliminates the entire category of "the balance drifted" bugs.
Problem 2: reconciliation is nine days of human pattern matching
The specific pain: Adyen settles in batches with a batch number, Stripe settles per payout with a payout id, and the bank shows a single credit for $412,880.19 with the memo "ACH CREDIT ADYEN". Nothing in any of those three records shares a key. Dana matches them by amount and date, which works until two payouts land on the same day for similar amounts, and then it silently does not work.
Off-the-shelf tools try hard here. Modern Treasury, Ledge, and Numeral all sell reconciliation, and if your flows are simple they are worth the list price. Where they break for a real multi-processor operator: they reconcile bank to processor, but they do not know your business rules. They cannot tell you that a $180 short payout was correct because the seller had a $180 chargeback in a prior period that your terms say gets netted from the next cycle. That rule lives in your head, or in a Slack thread, and no vendor will model it for you.
What a custom build does: an ingestion layer that pulls every source on a schedule, Stripe balance transactions via API, Adyen settlement detail reports via SFTP, the bank via BAI2 or an Open Banking feed, and normalizes them into a single canonical movement record with a source, an external id, an amount in minor units, a currency, and a value date. Then a matching engine runs in tiers: exact match on external reference first, then deterministic rules you write for known patterns like "Adyen batch N corresponds to bank credit with memo containing batch N," then amount-and-date-window fuzzy matching. Anything unmatched becomes an exception in a queue with the candidate matches ranked next to it, and a human clicks accept or investigate. AI does one job here and does it well: an LLM reads unstructured bank memos and free-text remittance advice, extracts invoice numbers and seller references that no regex handles reliably, and proposes a match with a confidence score. It suggests, a human confirms above a threshold, and the confirmations become training signal for the deterministic rules. Nine days becomes a two hour exception review. That is one and a half headcount back, permanently.
Problem 3: payouts are correct in aggregate and wrong per seller
Split payments are where off-the-shelf quietly gives up. Stripe Connect does application fees and transfers well when the split is a simple percentage decided at charge time. Real operators do not have simple splits. You have a seller share that depends on the seller's tier, a referral partner who gets 2% on their sourced volume for the first twelve months, a fee that is negative on promotional orders because you are subsidizing, a fuel surcharge that goes to the driver not the shop, tax withholding for certain jurisdictions, and a reserve you hold on new sellers for their first 90 days. Encoding that in Connect means either a wall of application fee math in your charge creation code or, more commonly, doing the split correctly in a spreadsheet afterward and paying out manually.
The failure mode is specific and expensive: a seller disputes their payout, you cannot reconstruct how the number was produced because the logic was three code deploys ago and the spreadsheet was overwritten, so you refund the difference to keep the relationship. We have seen operators eat $20,000 a year in "just make it right" credits because they cannot defend their own math.
What a custom build does: payout calculation as a versioned, replayable rule engine. Each seller has an effective-dated fee schedule. Each payout run snapshots the exact rule version it used and stores the full calculation trace, every input line and every rule applied, attached to the payout record. When the seller asks why it was $180 short, support opens the payout and sees a line item breakdown they can send in one click, including the January chargeback that netted out. Payout runs are idempotent and dry-runnable: finance previews the batch, sees the totals and the exceptions, and approves. The actual disbursement then fans out across rails, Stripe for domestic ACH, Wise for cross border, a NACHA file for the wire clients, with each leg tracked to a terminal state and each failure automatically returning the liability to the seller's account rather than silently vanishing.
Problem 4: one processor is one point of failure and one negotiating position
At $40M of volume, 30 basis points is $120,000 a year. You cannot negotiate that down if you cannot credibly move volume, and you cannot move volume if your entire codebase calls stripe.charges.create directly in forty places. We have watched an operator stay on a bad rate for two years purely because migration was estimated at nine months.
There is also the availability side. Processors have incidents. If yours is your only path, an incident is a revenue outage measured in the tens of thousands per hour, and your only response is a status page refresh.
What a custom build does: a processor abstraction layer with a single internal payment intent model, and adapters per processor that translate to and from Stripe, Adyen, Braintree, whatever comes next. Above it, a routing engine that picks the processor per transaction based on rules you control: card BIN country, amount band, method, seller, or a straight percentage split for A/B rate testing. Below it, a health checker that fails over automatically when authorization rates drop below a threshold for a rolling window. The commercial value is bigger than the technical one. Once volume can move with a config change, your next processor conversation is a different conversation. The build cost of the abstraction is roughly 15% of the platform, and it has paid for itself in rate renegotiation on every engagement where we shipped it.
What this costs and how long it takes
Digital Heroes numbers, from our own delivery across 2,000+ projects. A focused first release is $60,000 to $130,000 over 12 to 16 weeks. That scope is: the double entry ledger with the account tree modeled for your business, one processor integration behind the abstraction layer, automated ingestion and matching for your two or three highest volume reconciliation sources, and a finance-facing exception queue. That release is where the headcount savings live, so it goes first.
A full platform is $150,000 to $400,000 phased across 6 to 12 months: multi-processor routing and failover, the payout rule engine with multi-rail disbursement, chargeback and dispute workflow with evidence assembly, KYC and onboarding, a merchant-facing dashboard, and the reporting layer.
What drives price up in payments specifically, in rough order of impact. Money transmission posture: if you are taking custody of funds rather than riding a processor's licenses, you are in a different world of legal review and controls, and it adds meaningfully to both cost and calendar. Number of currencies, because multi-currency is not a formatting problem, it is an FX rate sourcing, spread accounting, and rounding-policy problem that touches every ledger entry. Number of payout rails, each rail is its own file format, its own return codes, its own reconciliation shape. PCI scope: staying at SAQ A with tokenized fields is cheap, touching a raw PAN anywhere puts you into SAQ D and adds audit, segmentation and scanning cost. Historical data migration, because backfilling three years of transactions into a new ledger and making the closing balances tie out is often 3 to 5 weeks on its own. And the volume of bespoke fee rules, which is the single most underestimated line: every operator swears they have "a few," and every operator has thirty.
Build or buy: where we would draw it
Buy, and do not let anyone talk you out of it, if payments are a cost center rather than a product. If you charge a card, you keep the money, and one processor handles it, Stripe plus a bookkeeper is correct and a custom platform is a vanity project. Same if you are a marketplace under roughly $2M of annual volume with straight percentage splits: Stripe Connect does that natively and does it well. Buy Modern Treasury or Ledge if your only real pain is bank-to-processor reconciliation and your fee rules are simple. That is a good product solving a narrow problem, and building it yourself to save the subscription is bad math.
Build when these signals show up, and they tend to show up together. Two or more processors or acquirers live in production. Your ledger of record is a spreadsheet or a set of database tables nobody would call double entry. Finance close takes more than three days. Payout disputes are resolved by refunding rather than by explaining. You have fee logic that no processor's fee model can express, so it lives in a manual step. Or the strategic one: your take rate is your business model, and you are currently unable to measure it by cohort without an analyst spending two days.
The ledger is the thing you build, and everything else is negotiable. We have shipped platforms where the client kept Stripe as the only processor for another year and that was the right call, but the ledger came in-house immediately and the close went from nine days to one. If your budget only covers one phase, buy the acquiring and build the ledger. Building a slick checkout on top of a spreadsheet ledger is how operators end up with a $3,400 gap they carry for four months.
How to choose a developer for payments platform work
Ask them to whiteboard the double entry model for a marketplace order with a partial refund and a chargeback in a later period. This takes ten minutes and it is the whole interview. A team that has done this reaches for accounts and journal entries immediately and asks you about your account tree. A team that has not will reach for a status column on an orders table. There is no faking it.
Ask which settlement report formats they have parsed in production, by name. You want to hear specifics: Adyen settlement detail, Stripe balance transactions and the difference between the API and the reports API, BAI2 or MT940 from the bank, NACHA return codes. Anyone who has actually shipped reconciliation has strong opinions and a war story about a file format. Generalists will talk about webhooks, which is the easy 10%.
Ask them to state your PCI scope back to you and tell you what they will do to keep it there. The right answer is a plan to never let a card number touch your infrastructure, tokenization at the client via the processor's elements or hosted fields, and a clear statement of which SAQ level that leaves you at. If they are relaxed about handling raw card data on your servers, that is disqualifying, not a preference difference.
Ask what happens when the same webhook arrives twice, and what happens when it never arrives at all. You want to hear idempotency keys, an inbound event log written before processing, and a reconciliation job that catches missed events by polling rather than trusting delivery. Payments teams that have been burned answer this instantly. It is the cheapest signal of production experience in the entire category.
The evidence behind this guide
Independent findings on why this investment pays off. Every link goes to the primary source.
- Retailers improving Core Web Vitals saw measurable gains: Vodafone improved LCP by 31% for 8% more sales, Lazada saw a 16.9% mobile conversion increase, and Cdiscount saw a 6% Black Friday revenue uplift. Source: web.dev (Google Chrome team) (2021) →
- Standish's 2015 CHAOS research found roughly a third of software projects (about 36% by the Modern definition) fully succeed on time, on budget, and on scope, with top success drivers including executive support, user involvement, and clear requirements/business objectives. Source: Standish Group (CHAOS Report) (2015) →
- 88% of customers say good customer service makes them more likely to purchase from a brand again in the future, quantifying the direct revenue link between support quality and retention. Source: HubSpot (2024) →
- Digital Champions expect to achieve about 16% in cost savings and around 15% in revenue gains from digital operations over five years; the study surveyed 1,155 manufacturing executives across 26 countries. Source: PwC / Strategy& (2018) →
Rohan advises mid-market and enterprise teams on ERP, CRM and custom software, and has led delivery on dozens of business-software builds.
Writes for Digital Heroes, shipping business software for 2,000+ brands across 55+ countries since 2017.