Payment Invoice Matching
MediumSimulation ยท Stripe
Settle payments ([id, amount, memo]) in order against invoices ([id, amount, due_day]). Each invoice is settled at most once. A payment uses the first rule that applies:
- A word of
memo(split on whitespace, case-sensitive) is the id of an open invoice with exactly the payment's amount. - The open invoice with exactly that amount and the earliest
due_day. - The earliest-due open invoice whose amount exceeds the payment by
1totolerance; the shortfall is forgiven.
Ties go to the earlier memo word, then the earlier listed invoice. Return one string per payment: "<payment id> -> <invoice id>", with (forgave <shortfall>) appended when forgiven, or "<payment id> -> unmatched".
Example 1
- Input:
- invoices = [["INV-1", 500, 10], ["INV-2", 500, 5], ["INV-3", 800, 7]], payments = [["p1", 500, ""], ["p2", 500, "for INV-1"], ["p3", 795, "INV-3"]], tolerance = 10
- Output:
- ["p1 -> INV-2", "p2 -> INV-1", "p3 -> INV-3 (forgave 5)"]
- Explanation
p1has no memo, so the earlier-due 500 invoice wins.p3is 5 short ofINV-3, within the tolerance.
Example 2
- Input:
- invoices = [["A", 300, 1], ["B", 300, 2]], payments = [["x", 300, "A"], ["y", 300, "A"], ["z", 300, ""]], tolerance = 0
- Output:
- ["x -> A", "y -> B", "z -> unmatched"]
- Explanation
Ais already settled whenyarrives, so its memo no longer counts.
Example 3
- Input:
- invoices = [["I1", 990, 9], ["I2", 1000, 3]], payments = [["q", 985, ""]], tolerance = 20
- Output:
- ["q -> I2 (forgave 15)"]
Constraints
0 <= invoices.length <= 20000 <= payments.length <= 2000- Invoice ids and payment ids are unique non-empty strings without spaces
1 <= amount <= 10^9,0 <= due_day <= 10^6,0 <= tolerance <= 10^6memomay be empty