Payments
Connect Stripe, read the ledger that records every money movement on an order, and keep track of disputes.
Litestore takes payments through Stripe and records every money movement in a ledger. When totals don't match, the ledger is the figure to use.
Payment records
Litestore writes every capture, refund, dispute and adjustment to a payment ledger. The database rejects any edit or deletion in it.
The ledger is the main subject here. Order totals are a summary, and a summary can be wrong. The ledger is the list of what actually happened to the money, and Litestore builds it so that nobody can quietly turn it into a different list later.
Stripe is the only payment provider Litestore is wired to.
Litestore uses two records for all of this:
PaymentTransaction
PaymentDisputePaymentTransaction is a row in the ledger. PaymentDispute stores a chargeback.
Ledger entries
Every ledger row has one of five types:
authorization
capture
refund
dispute
adjustmentTogether they cover every way money can move on an order. It can be held, taken, given back, reversed by a bank or corrected.
Append-only ledger
The database rejects any attempt to change or delete a ledger row.
To correct a mistake, Litestore adds a new row. It never edits an old one.
Because rows are never changed, the ledger reconciles against the payment provider's records. An editable ledger would only hold the values someone last entered, so it couldn't show the payments, refunds and corrections that actually happened to an order.
The ledger therefore keeps the mistakes as well as the money. A wrong amount and the adjustment that corrected it both stay visible, in order, with the time each was written.
An order's financial history stays complete, and it doesn't depend on anyone being careful.
Duplicate protection
The database only allows one row for each combination of provider, provider reference and type. If Stripe sends the same payment confirmation twice, Litestore counts it once.
This isn't a rare case. Payment providers resend confirmations when they don't get an acknowledgement, which is the right thing for them to do. The ledger therefore has to receive the same event twice and record it once.
The type is part of the combination on purpose. A capture and a refund can share a provider reference, and Litestore won't mistake one for a duplicate of the other.
Order currency
The database rejects a ledger row whose currency doesn't match the order's currency.
A ledger that mixes currencies is worse than one with missing rows. Its totals still add up, but to a meaningless number. By refusing the row, Litestore makes sure every sum on an order is in one currency.
Refund ceiling
Refunds are capped at the order total
As Litestore writes each refund row, it adds up every refund already on the order. If the running total would go past the order total, it rejects the write. A second protection blocks edits and deletes on ledger rows and enforces the currency match.
The recount is what makes this work. Litestore doesn't just check whether this one refund is smaller than the order total. It checks whether all the refunds on the order together would come to more than the customer was billed.
Even when different people issue refunds days apart, through different routes, the refunds can't add up to more than the customer paid.
Base-currency totals
Each order also stores its total converted to the store's base currency at the time of purchase.
Revenue figures use that stored value. They don't fall back to the total in the order's currency.
Because Litestore stores the converted figure at the moment of sale, the store's reports stay consistent as exchange rates move. A quarter's revenue doesn't change because a currency moved afterwards, and last year's numbers stay the numbers you reported last year.
Drift views
Orders and customers both keep cached totals. These should always match what the database calculates from the underlying records.
If they ever differ, the database views OrderMoneyDrift and CustomerMoneyDrift list the order or customer. Litestore never corrects a difference on its own.
Cached totals keep lists fast, and the views keep them honest. The views aren't shown in the admin, so whoever runs the store queries them. You can also ask the assistant whether the store's order revenue matches the Stripe payment ledger.
Dispute records
For each chargeback, Litestore stores these details.
| Field | What it records |
|---|---|
| Reason | Why the customer disputed the charge. |
| Status | Where the dispute stands at the provider. |
| Amount | How much money is in dispute. |
| Evidence deadline | When the evidence is due. |
| Evidence submitted | Whether evidence was submitted. |
| Handler | The staff member handling it. |
The queue shows which disputes still need a response, so you work through them without leaving the admin. You still file the evidence itself with the payment provider.
Setup
Stripe keys
Set your Stripe secret key and webhook secret. When you open Settings → Payments, Litestore checks the connection and shows the response it receives from Stripe.
Incoming payments
Captures, refunds and disputes write ledger rows as they happen.
Reconciliation
Ask the assistant from time to time to check that order revenue matches the payment ledger, and have whoever runs the store watch the drift views.
You do the day-to-day money work in the Refunds and Disputes queues.
Authoritative totals
Litestore can always recalculate a summary from the ledger rows, which is why the rows themselves can't be edited.
Related
Checkout
A shopper's cart goes through several steps before it becomes a paid order, and a short list of checks helps when checkout fails.
Orders
Orders go from payment to shipment, ship in parts when needed, and are created by hand for phone and in-person sales.
Returns
Returns come back in, only resellable items are restocked, the refund follows, and chargebacks stay on record.