Description
Long-running invoice payments with multiple tranches or async recipient claims have no unified progress representation in the SDK. Callers poll individual operations independently, producing inconsistent UX. A progress tracker should aggregate all per-recipient payment states into a single InvoicePaymentProgress object that can be subscribed to and rendered progressively.
Technical Context
Add src/paymentProgressTracker.ts. Aggregates RecipientPaymentState[] from src/types.ts. Uses src/poller.ts per recipient to fetch operation status. Emits invoiceProgressUpdated events via src/events.ts with { invoiceId, percentComplete, recipientStates } payloads. Integrates with src/trancheProgress.ts for tranche-based invoices. Exposes a subscribe(invoiceId, callback) API.
Acceptance Criteria
Description
Long-running invoice payments with multiple tranches or async recipient claims have no unified progress representation in the SDK. Callers poll individual operations independently, producing inconsistent UX. A progress tracker should aggregate all per-recipient payment states into a single
InvoicePaymentProgressobject that can be subscribed to and rendered progressively.Technical Context
Add
src/paymentProgressTracker.ts. AggregatesRecipientPaymentState[]fromsrc/types.ts. Usessrc/poller.tsper recipient to fetch operation status. EmitsinvoiceProgressUpdatedevents viasrc/events.tswith{ invoiceId, percentComplete, recipientStates }payloads. Integrates withsrc/trancheProgress.tsfor tranche-based invoices. Exposes asubscribe(invoiceId, callback)API.Acceptance Criteria
PaymentProgressTracker.subscribe(invoiceId, onProgress)starts polling all recipient payment legs and callsonProgresson each status changeInvoicePaymentProgress.percentCompleteis computed as the number of settled legs divided by total legs × 100RecipientPaymentStateincludesaccountId,status,settledAmount, andlastUpdatedAtunsubscribe(invoiceId)cancels all underlying pollers for that invoicepercentCompleteincrements correctly as legs settle