Skip to content

Part 5 of 7 · Purchase order approver series ~6 min read

How the money gets committed

Somebody taps approve. What happens in the next two seconds is the only part of this system that can lose money, and it is worth slowing down for. There are two writes — one to your budget ledger, one to the outside world — and the order they happen in is the difference between a budget that holds and a budget that occasionally, quietly, does not.

Key takeaways

  • Reserve the money first, send the purchase order second. Never the other way round.
  • The ledger write is conditional on the room still being there, so two approvals in the same second cannot both win.
  • The purchase order is sent from a queue, so a mail failure retries without re-reserving.
  • If the send permanently fails, the reservation is released and a person is told.
  • Every commitment carries the request id, so the ledger can be replayed against the requests.

The two writes, in order

The obvious order is: send the purchase order, then update the budget. It reads naturally and it is wrong. It means there is a window — short, but real — where the vendor has an order and your budget does not know about it. Do that on two requests that land in the same second against a line with room for one, and you have committed twice and reserved once.

The sequence from approve tapped to purchase order committedA vertical chain of five steps entered by a box labelled Approve tapped, signed and single-use. Step one asks whether the request is still pending, using a conditional status write against a DynamoDB requests table; a second tap exits to Already decided, which shows the existing decision. Step two reserves the money by adding the amount to the committed column, conditional on room still being left in the DynamoDB ledger; if two approvals raced it exits to No room now, which tells both people and re-asks. Step three queues the order as exactly one message. Step four sends the order through Amazon SES with the purchase order PDF attached; if delivery permanently fails after retries it exits to Release and tell, which gives the money back. Step five is Committed, with both the requester and the approver told. A note says the money is reserved before the outside world hears anything, and released if it never does.AWS ACCOUNTApprove tappedsigned, single-useStill pending?conditional status writeDynamoDB requestsstatus = pendingAlready decidedshow the decisionsecond tapReserve the moneycommitted += amountDynamoDB ledgercondition: room leftNo room nowtell both, re-askracedQueue the orderone message, one POSend the orderSES, with the PDFRelease and tellafter retries failundeliverableCommittedrequester and approver toldThe money is reserved before the outside world hears anything, and released if it never does.
Fig 1. What happens between the tap and the purchase order. The money is reserved with a conditional write before the order is queued, and the reservation is released if the order can never be delivered.
  • Database
  • App integration
  • Machine learning
  • Security & identity
  • People

Why the reservation is conditional

The ledger write is not “add 640 to committed”. It is “add 640 to committed, but only if committed is still what I read a moment ago and the result stays under the limit”. If two approvals land against the same line at once, one of those conditions fails and one write is rejected. The rejected one does not retry blindly — it re-reads, discovers there is no longer room, and goes back to the approver with the new numbers.

This is the whole reason the budget position lives in DynamoDB rather than in the sheet. A spreadsheet cannot refuse a write on a condition. It will happily let two people set the same cell to two different values, last one wins, and the number that survives is whichever request happened to be slower.

Why the order goes out from a queue

Sending mail fails for boring reasons: a vendor’s mail server is down for ten minutes, a DNS lookup times out, SES throttles. None of those should undo an approval, and none of them should cause a second reservation when the retry succeeds. So the reservation is done, and then exactly one message goes on a queue. The sender reads it, builds the PDF, sends it. If that fails, the message returns to the queue and is tried again, and the money stays reserved the entire time because it was never the sender’s job to reserve it.

After the retries are exhausted the message lands in a dead-letter queue, and that is the one case where the reservation is undone: the money goes back to the line, and both the requester and the approver are told the order could not be delivered, with the vendor address that failed.

What a commitment record holds

The ledger is the thing you will be reading in nine months when somebody asks why a budget line looks the way it does. It is worth it holding enough to answer that without opening anything else.

FieldExampleWhy it is there
lineworkshop-consumablesWhich budget the money came out of
request_idreq_2026_07_08_4f1aLinks back to the ask, the email and the attachment
amount640.00What was reserved, in your currency
vendorMedline IndustriesAs matched, not as typed
approved_bydana@ / autoA person’s address, or the word auto
approved_at2026-07-08T09:14:02ZWhen, to the second
basislimit 4,000, committed 2,850The numbers the decision was made against
po_numberPO-2026-0412What the vendor sees on the order
statecommittedcommitted, released, or invoiced

The basis field is the unusual one and the most useful. It records what the budget looked like at the moment of the decision, not what it looks like now. Six months later, when the line is over and somebody is working out how, the ledger can say exactly which approval was the one that should not have been made — and it will usually turn out that every single one was reasonable given what was known at the time, which is a much more useful finding than a total.

Committed, then invoiced

A commitment is not a payment. When the invoice arrives — which this system does not handle, because your accounting software already does — somebody marks the commitment invoiced, and the ledger row moves state. Until then the money is reserved: not spendable by the next request, not yet paid, and visible as such.

The five states of a purchase, from asked to invoicedA horizontal row of five boxes. Asked: the request is recorded. Approved: either by a person or automatically under the line. Committed: the money is reserved in the ledger. Ordered: the purchase order is with the vendor. Invoiced: the record is handed to accounts. A note says this system owns the first four states and the fifth belongs to the existing accounting software.THE FIVE STATES OF ONE PURCHASEAskedrequest recordedApprovedby a person or the lineCommittedmoney reservedOrderedPO with the vendorInvoicedhanded to accountsThis system owns the first four. The fifth belongs to your accounting software.
Fig 2. The five states a purchase moves through, and where this system’s responsibility ends. It reserves and orders; it does not pay, and it does not try to.

Next: what all of this costs to run.

All posts