HANDOFF: target project invoice

Scope
Only invoice requirements are authoritative. Ignore all archived records for other projects. Apply future invoice updates only to the keys they explicitly replace; retain other current choices. No later updates or questions are available yet.

CURRENT choices
{
  "currency": "USD",
  "rounding": "invoice",
  "duplicate_event": "last",
  "inclusive_limit": false,
  "max_refund_age_days": 45,
  "refunds_first": false,
  "refund_overflow": "reject",
  "void_is_tombstone": false,
  "order": "created",
  "fee_refundable": true,
  "min_invoice_cents": 25,
  "status_case": "upper"
}

Fixed interface
Implement evaluate(payload) returning:
{invoices:[{id,charge,refunded,balance,status}]}

Input contract
Invoices have unique id, integer created day, currency, lines containing nonnegative decimal-dollar strings, nonnegative fee_cents, and ordered events.
Each event has eid, kind (refund/void/restore), day, and nonnegative cents.
Do not mutate payload. Empty input returns {invoices:[]}.

Processing with current choices
1. Exclude invoices whose currency is not USD.
2. Sum line dollar amounts exactly, then convert that sum to integer cents using decimal ROUND_HALF_UP. Do not round individual lines first or use inexact floating-point arithmetic.
3. Principal is the rounded line total. Charge is principal + fee_cents.
4. Skip invoices with charge < 25 cents. Charge equal to 25 is included.
5. Deduplicate each invoice’s events by eid. Last occurrence supplies the retained value, but the eid stays in its first insertion position.
6. Preserve the resulting event order; do not move refunds ahead or sort events by day.
7. Begin active with refunded = 0.
   - void makes the invoice inactive and disables subsequent refunds.
   - restore re-enables refunds, including after a void, because void_is_tombstone is false.
   - Previously accepted refunds are never undone.
8. Accept a refund only when active and 0 <= event.day - invoice.created < 45. Day 45 is excluded; negative ages are excluded.
9. Refund ceiling includes both principal and fee, so it equals charge. If a refund exceeds the remaining unrefunded ceiling, reject that entire event; do not partially cap it. A refund equal to the remaining ceiling is allowed.
10. balance = charge - refunded.
11. Final status, in priority order:
    - VOID if inactive, even if fully refunded.
    - REFUNDED if active and refunded == charge.
    - OPEN otherwise.
12. Sort retained invoices ascending by (created, id). Return only id, charge, refunded, balance, status; monetary output values are cents.

Unresolved / unspecified
No unresolved choice values remain among the listed settings.
The exact payload container schema, malformed-input handling, and id type/comparison conventions have not been specified beyond the stated contract. Do not invent additional requirements; clarify if needed.
No implementation language has been requested. This note is a requirements handoff, not code.