Skip to content

Admin billing page: add pagination, search, and Stripe reconciliation tools #4451

@geneticallymodifiedfoodforthought

Description

Problem

/admin/billing currently loads all records in a single page, making it unusable at scale — it times out or takes too long to render. There is also no search, so admins cannot look up a specific org, invoice, or Stripe customer without scrolling through the full list.

This creates a hard dependency on manual Stripe Console access for routine admin tasks, and makes it impossible to resolve escalations directly from the AAO admin surface.

Specific pain points

  1. Page won't load — the billing list is too long; the page either times out or takes an unacceptably long time to render.
  2. No search — no way to find a specific organization, Stripe customer ID, or invoice without loading everything.
  3. No Stripe reconciliation tools — when a member reports a payment received but status still shows past due, there is no way for an admin to:
    • Look up the Stripe payment intent or charge by org or email
    • Force a status refresh / re-sync from Stripe
    • Manually mark an invoice as paid after out-of-band verification
    • Update a member's billing email to match their Stripe customer record

Proposed changes

/admin/billing page

  • Add server-side pagination (e.g. 25–50 rows per page)
  • Add search/filter by: org name, domain, email, Stripe customer ID, invoice status (open / past due / paid)
  • Load on demand — do not pre-fetch all records

Addie tools (or admin-only API endpoints)

  • lookup_stripe_customer(email | org_name | org_id) — find the Stripe customer record and linked invoices
  • get_stripe_invoice(invoice_id) — fetch full invoice detail including payment intent status
  • sync_stripe_status(org_id) — pull current Stripe subscription/invoice state and update AAO membership status
  • mark_invoice_paid(invoice_id, note) — admin override to mark an invoice paid after manual verification (e.g. wire transfer, bank confirmation)

Existing update_billing_email tool

Currently works when you have the org_id or customer_id. Make it also accept email as a lookup key, since admins often only have the member's email when resolving an escalation.

Why this matters

Escalations where a member confirms payment but AAO shows past due currently require a manual Stripe Console session — no audit trail, no structured workflow, and it blocks members from accessing their membership benefits until an admin gets to it. Escalations where a member needs an email update hit the same friction.

Pagination + search alone would make the billing page usable. The reconciliation tools would close the loop so admins can resolve billing escalations end-to-end without leaving AAO.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions