Funds in flight
Model funds in flight on your ledger to enable deferred payouts and fund pending processing
You hold balances on behalf of your customers: Maybe a customer redeemed a gift card, or received a payment in your marketplace, or wants to wire money internationally. Those balances are meant to be used. But of course such transactions don't happen instantly: There is a period of time in which that money is considered "in flight". Money in flight needs to be marked as spent, even though it hasn't yet left the account. Formance Ledger can help you keep track of money in flight simply and transparently.
Using this pattern
Let's suppose you are a marketplace, bringing together buyers and sellers. You hold balances on behalf of the sellers, who periodically withdraw those balances into their business bank accounts. Of course, processing withdrawals takes time. So there is a period of time during which the money being withdrawn remains in the seller's marketplace account, yet needs to be marked as unavailable—after all, you don't want our seller to be able to withdraw the same balance twice!
The flow typically looks like this: A seller accrues a balance to their account with you. At the end of the month, the seller requests a withdrawal of their balance. You (or rather, your automated remittance systems) mark the money as "in flight", and send a request to a payment processor such as Stripe, Wise, or maybe your bank directly to transfer the amount. Once the processor confirms that the transfer is complete, you can mark the funds as removed from the seller's account, and close the transaction.
Why is marking these funds as in-flight important? Doing so has two benefits:
Processing the withdrawal might take seconds, or it might take days, but it certainly isn't instant. Unless you mark the funds as in-flight, there is nothing preventing the seller from maliciously requesting them to be withdrawn a second time. The in-flight status lets your systems know the money is unavailable for withdrawal.
It lets you cleanly separate concerns. You can have one system that receives withdrawal requests from the sellers, and a completely different system for processing withdrawal requests with your payments processor. The in-flight status serves as a signaling mechanism between those two services to hand off the processing at different stages.
But what does it mean to mark money as in flight? With Formance Ledger, this typically means transferring the funds from the seller's balance and into a temporary account used for just this purpose. Let's see what this looks like in Numscript. Suppose seller with ID
U1234 has requested to withdraw €1,050.42.
This Numscript snippet takes advantage of namespaces to name the accounts in a readable, hierarchical way. The account
@user:U1234:main represents the primary account held by user
U1234. Likewise, suppose you assign the withdrawal request a unique transfer ID
T5678. Then the account
@user:U1234:inflight:T5678 is a temporary account that marks the transferred funds as in flight as part of transfer
Now, whatever balance might remain in
@user:U1234:main is still available for other purposes, but the funds that are part of the withdrawal transaction
T5678 are unavailable.
Now, you've marked the funds as in flight. The actual money still needs to be moved. The creation of the temporary account kicks off the request with Stripe to initiate the actual movement of money. Once Stripe confirms that the funds have in fact been moved, you need to mark this in our ledger—you need to mark the money as transferred out.
@world account represents the world outside of our enterprise, and Formance Ledger uses it as a sink to indicate in your ledger that the money is no longer in your hands, but in the seller's own business account, and that therefore the transaction is complete.
In addition to the security benefits and the separation of concerns mentioned above, the use of temporary accounts like this is also useful in building your user experience. By using temporary accounts, you can use the Formance Ledger API to discover and calculate the available balance in the seller's various accounts, as well as displaying to the seller in a granular way money that is currently moving from one account to another (and hence unavailable).