Charge each request only once
The payment webhook is delivered at least once, sometimes more. Each delivery carries an idempotency key, and a replay must not charge the customer twice.
- Sum the amounts, but only the first event carrying a given key counts.
- A later event with a key already seen is a replay, whatever amount it claims.
apply_once(events: list<Event>) → int
Where you start
def apply_once(events: list[Event]) -> int:
Worked examples
| Call | Result |
|---|---|
apply_once([Event(key="a", amount=100), Event(key="b", amount=50), Event(key="a", amount=100)]) | 150 |
apply_once([Event(key="a", amount=100), Event(key="a", amount=-100)]) | 100 |
apply_once([Event(key="x", amount=7)]) | 7 |
apply_once([]) | 0 |
Hint
Remember the keys you have already honoured.
Reference solution in Python
def apply_once(events: list[Event]) -> int:
seen = set()
total = 0
for e in events:
if e.key in seen:
continue
seen.add(e.key)
total += e.amount
return total