In every system that holds money the same moment eventually arrives: a customer says their balance is wrong, you look at the screen, and you cannot show how the number got there. If the balance lives in a single column, all you have is the result — there is no history.
Not a column, a movement
The right approach is not to store the balance but to derive it. Every movement of money — a top-up, a deduction, a refund, a correction — is written as its own row, and the balance is the sum of those rows. The answer to "where did this number come from" is then always a list you can query.
This approach has a real cost: every read requires a summation. But that cost is manageable with summarised balance fields or appropriate indexing. What is not manageable is the loss of trust caused by a number whose source cannot be shown.
The deduction is written in the event's own transaction
The second critical point is timing. If you write the deduction in a separate transaction after the delivery completes, a failure in between separates the two: the delivery is finished but the money was never taken. The deduction must be written in the same database transaction as the status change. The transaction either succeeds whole or not at all.
A negative limit is a business rule, not an accident
What happens when a business runs out of balance must also be defined explicitly. Left undefined, the system either accepts orders and accumulates debt, or cuts off service at an unexpected moment. Defining a separate negative limit per business hands that decision to management instead of burying it in code.
