My idea is that a reusable ledger, as a service or library, would be too distant from actual needs to provide much value.
Consider the example database state in the article:
Transfer ID Description ┃ user receivables available
1 order created ┃ -$10 $10
2 payment received ┃ -$10 $10
3 partial refund ┃ $5 -$5
A real application cannot go very far with this kind of "description": every type of transaction needs specific data, whose complexity dwarfs the double-entry ledger mechanism.
For example "order created" transactions need a reference to an order with details of what has been ordered, "payments" need a reference to a collections of debts that they are meant to pay and details of how they have been paid, "refunds" are actually many types and need a reference to what they are refunding.
Real accounts are also much more complex than a history of changes and a computed balance: for example, some of them need to be included in accounting calculations and reports in various roles, with largely arbitrary relationships and accounting criteria, while some are linked to real-world persons.
Comparing the two ledger implementations that the article references is instructive: Pgledger has simple ID columns for accounts and transfers, and it is up to the application to use them as foreign keys from the interesting tables, while TigerBeetle also offers some generic "user data" and "code" columns with arbitrary data and suggests having a separate "control plane" database.
My idea for for this to add metadata to the transfers, likely with a jsonb column. But I agree that the ledger won't encompass everything. You would still have other database tables and then you'd store domain identifiers in the ledger and/or ledger identifiers in your other tables.
> how do we efficiently get the balance of a certain account at a certain date time?
This depends on how you implement the ledger. For pgledger, I store the balance in every entry, so to find a historical balance, you just need to find the most recent entry before that time:
That makes sense and is an elegant solution. This way one can check the balance at any time without recalculating, but we still have an audit log to find discrepancies when the balance is expected to be zero but is not.
I think that's a fair point. Unnesting arrays in SQL can be annoying. Here is your first example with duckdb:
duckdb -c \
"select * from ( \
select unnest(assets)->>'browser_download_url' as url \
from read_json('https://api.github.com/repos/go-gitea/gitea/releases/latest') \
) \
where url like '%linux-amd64'"
> And it is bizarre to me that you could run a payments system without high-availability or immutability at its core.
I’m not sure what you’re referring to here as my post didn’t really go into these topics.
> Also putting logs in a database alongside your core data is such a bad idea.
I’m not suggesting putting all logs into the database. I’m suggesting that for a certain type of info (that is often logged), I find it more useful to put it in the database instead.
Unfortunately, I think Braintree in the UK is probably doomed at this point.
They looked good a year or two ago, and we did consider using them. They were certainly a better prospect than old school card payments where you had to apply for multiple services, make back room deals to get good fees, and all that nonsense. However, to start the application process with Braintree, it seemed you would still be faced with a lot of form-filling, followed by multi-week delays to get approval (or not), and on top of that the fees were unclear but didn't look competitive in most cases.
More recently, the likes of GoCardless and Stripe have become serious players on the UK scene, and both seem to be working on expansions further into Europe as well. They have all the same obvious benefits that Braintree offered: a single company to deal with, staffed by human beings rather than robots, reasonable APIs. But they also offer much faster sign-up and reasonable, transparent fees.
At this point, to be brutally honest, the likes of Braintree are simply outclassed. Unless anything very surprising happens, I expect the payments market for UK and probably European small businesses and start-ups to be completely dominated by GoCardless and Stripe within 2-3 years. Unless you're big enough to approach the old school players with enough leverage to get favourable terms, it's hard to see why you'd look any further if these are options, and I think both GoCardless and Stripe will do well because they're different enough not to be in direct competition but similar enough to keep each other honest.
I looked at Braintree but I found the fee's not worth it at this stage, I've looked at NoChex and a few other providers but there is a worry about giving people too much choice, at moment we have PayPal, Google Checkout and GoCardless, I'd be looking to replace GC with either Stripe or NoChex
We actually have much the same functionality. We can dynamically route/rate-limit requests on a per-marketplace (or anything else, really) basis, using Nginx's Lua integration capabilities. We may end up writing another post on this, if there's any interest from the community.
Thanks, didn't know about that. 15% of first purchase, eh? Since most people transferring will only buy a year for ~$10, a $1.50 one-time payment doesn't really do the trick! An ongoing 15% would be more like it.