Product

Ledger-only or full integration: how to choose for each bank

Two modes, one data model. When to keep calling your bank yourself, when to hand it to PanoQore, and how to switch without moving a single balance.

EOEmmanuel Onyo, Founder
, 9 minute read
More posts
Product

Why two modes

Every team we talk to already has a bank integration. Some of them are good. Asking a team to throw that away on day one, before they trust the ledger, is asking them to take two risks at once.

So PanoQore lets each tenant choose, per partner bank, who makes the bank calls. The ledger underneath is identical either way: the same accounts, the same bindings from account number to wallet, the same nightly reconciliation and the same console for operations and compliance.

Ledger-only
Your app→Bank→Your app→PanoQore
Full integration
Your app→PanoQore→Bank
Same accounts, same bindings, same reconciliation. Only the caller changes.

Ledger-only: you call the bank

In ledger-only mode your code talks to the bank exactly as it does today. When something happens, you post the result to PanoQore as a balanced entry, using the bank’s reference as the idempotency key. If you issue virtual account numbers yourself, you tell us about each binding so we can route credits to the right wallet.

Reconciliation still needs the bank’s side of the story. You can upload the daily statement as CSV, MT940 or camt.053, or grant a read-only credential and we pull it every night at 02:00. Either way, the same control equation runs, and every unmatched line becomes a break with an owner.

Ledger-only is not a lesser mode. It is the same ledger, with you holding the pen for the bank calls.

Full integration: we call the bank

In full integration you store the bank credentials with PanoQore, per tenant, in a secrets store nobody can read back, not even you. Then you send us intents instead of results: open this named account, pay this supplier.

A payment order runs as a state machine. We check the beneficiary’s name, hold the money in the wallet so it can’t be spent twice, submit to the bank and post the entry when the bank confirms. If the bank fails it, the pending entry is voided and the hold is released. Every step is an event your product can listen to.

StateWhat just happened
NAME_CHECKEDThe account name from the bank matches the beneficiary
HELDThe amount is reserved in the wallet
SUBMITTEDThe bank has it; a pending entry is in the ledger
POSTEDThe bank confirmed; the hold is captured
VOIDEDThe bank failed it; nothing moved

How to choose

  • Choose ledger-only if your bank integration is stable, your bank hasn’t approved API access for a third party yet, or your compliance team wants credentials to stay inside your systems.
  • Choose full integration if you’re adding a new bank, you don’t want to maintain name enquiry, retries and status polling yourself, or you want payment orders as one call.
  • Mix them. Many teams run their oldest bank ledger-only and connect the newest one fully. The console shows the mode next to each bank.

Switching later

A tenant admin can switch any bank with one change in the console. They give a reason, which is saved on an audit event, and moving to full integration asks for credentials first. Orders already at the bank finish before anything changes. No balance moves and no account is re-issued, because the books never depended on who called the bank.

Try it on your own books.