Skip to content

mvp: enforce invoice expiry on verify and periodic sweep #559

Description

@CemAyyildiz

Goal

Make invoice expiry real on the MVP demo backend: past-due PENDING invoices must transition to EXPIRED, and POST /api/invoices/:id/verify must reject settlement with INVOICE_EXPIRED instead of accepting Horizon-matched payments on stale invoices.

Context

The frontend already surfaces expiry (frontend/app/pay/[id]/page.tsx countdown + EXPIRED UI; dashboard expired filter). Backend storage implements the transition but the MVP server never calls it:

  • backend/src/storage/memory-storage.tsmarkExpiredInvoices() transitions PENDINGEXPIRED when expiresAt < now
  • backend/src/services/invoice-memory.service.ts — exposes markExpiredInvoices()
  • backend/src/utils/verify-errors.ts — defines INVOICE_EXPIRED + message
  • backend/src/server-mvp.ts — verify only checks status !== 'PENDING'; never reads expiresAt and never calls markExpiredInvoices()
  • backend/tests/memory-storage.test.ts — unit coverage for expiry in isolation

The Postgres path runs a periodic sweep in payment-monitor.service.ts; the MVP demo path does not.

Acceptance criteria

  • server-mvp.ts runs invoiceService.markExpiredInvoices() on a sensible interval after startup (mirror ~60s cadence in payment-monitor.service.ts)
  • POST /api/invoices/:id/verify calls expiry check before Horizon lookup; past-due invoices return HTTP 400 with code: INVOICE_EXPIRED
  • GET /api/invoices/:id and list/stats reflect EXPIRED after sweep (no stale PENDING past expiresAt)
  • Backend tests prove: past-due invoice → EXPIRED after sweep; verify on expired → INVOICE_EXPIRED; valid pending verify still succeeds
  • Update docs/VERIFY.md error table for expiry rejection on MVP path

Out of scope

  • Pay-page UI changes (already handles EXPIRED)
  • Automatic payment detection / Horizon streaming
  • Proof PDF / quittance output changes
  • Shared TypeScript API contract types
  • Postgres payment-monitor.service.ts refactor

Conflict rule

  • Do not edit: frontend/app/pay/[id]/page.tsx, frontend/lib/export.ts, frontend/lib/mock-api.ts

Complexity

Complexity: Medium — 150 points (Stellar Wave)

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave program

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions