wtf( )unctionsystem design, drawn
← all problemsPaymentsHard

The refund arrived before the payment

Two notifications describe the same payment. They were sent in the right order and delivered in the wrong one, because delivery is retried per event and a retry of an earlier notification can land after a later one.

The handler applies each one as it arrives: set the status to whatever this event says. The last to arrive wins, and the last to arrive is not the last that happened.

Make the handler's outcome independent of the order the notifications arrive in.
Components — tap one, then tap a slot on the diagram
!An order was marked refunded and then, four seconds later, paid. The customer has the goods and we have no money.

Outside every boundary: Payment succeeded (sent first), Order state (one mutable row; FAILED: refunded, then paid), Payment refunded (sent second), Payment provider (at-least-once), Handler (last write wins; FAILED: applied out of order), an empty slot for the compared before applying, an empty slot for the written with the effect Connections: Payment provider publishes to Payment succeeded (step 1) Payment provider publishes to Payment refunded (step 2) Payment refunded publishes to Handler — arrives first (step 3) Payment succeeded publishes to Handler — arrives second (step 4) compared before applying controls Handler Handler calls Order state written with the effect controls Order state

Payment succeededsent first
Order stateone mutable rowrefunded, then paid
Payment refundedsent second
Payment providerat-least-once
Handlerlast write winsapplied out of order