Skip to main content

Chapter billing & dues

GreekManage bills dues at the chapter level: one invoice per chapter per billing period, computed from the head count by member type times the per-type rate. Officers don't configure rates, don't generate invoices, and don't issue refunds — those are national-admin actions. What officers can do is see the chapter's invoices, pay the chapter total through the org's configured payment processor, and explain the state to any member who comes asking. This page covers each of those, and the long list of things you can't do.

What you see

In your sidebar: Operations → Billing. The page renders:

  • Billing header — page title and a description.
  • Invoices card — a table listing every invoice for your chapter (across all billing periods).
  • Status filter at the top right of the table — All / Unpaid / Partial / Paid / Overdue.

Each row shows:

  • Period — the human label, e.g. "Spring 2026" or "2026-2027 Annual".
  • Issued — date the invoice was generated.
  • Due Date — when payment is due.
  • Total — full invoice amount in USD.
  • Balance — outstanding amount (Total minus payments received).
  • Status — Unpaid / Partial / Paid / Overdue badge.
  • Actions — a View button that opens invoice detail.

chapter billing list with mixed statuses and the View action hover chapter billing list with mixed statuses and the View action hover

Rows are sorted with overdue invoices first, then by issued_at descending. Newest activity at the top, problems above everything else.

The Dues Balance card on the dashboard

In addition to the dedicated page, your chapter dashboard renders a Dues Balance card surfacing the most recent invoice. It shows:

  • The period label.
  • The balance due in USD.
  • The due date.
  • The status badge.
  • A View Invoice button linking to invoice detail.

The card uses React Query's refetchInterval: 60000, so it polls every 60 seconds. When your treasurer triggers a payment that the processor's webhook confirms, the card flips to Paid within roughly a minute without a page reload. (Caveat: if the webhook doesn't fire — see troubleshooting — the card stays stale until reconciled.)

Members can also see this Dues Balance card (it lives on the dashboard, not behind officer auth), but its View Invoice button leads to officer-only detail. If a regular member clicks through, they get a permission-denied error.

Open an invoice

Click any View button or the View Invoice link on the dashboard card. The detail page (ChapterBillingDetailPage) renders:

  • A header with the period label and overall status badge.
  • Metadata grid: chapter designation, issued date, due date, balance due (highlighted card).
  • Line Items table — one row per member type that was billed:
    • Member type (Undergraduate / Associate / Officer).
    • Count — how many members of that type at invoice generation time. This count is snapshot at generation; it doesn't change if the chapter adds or loses members later.
    • Rate — the per-member rate at the time, in USD.
    • Subtotal — count × rate.
  • Payment History table — every payment the webhook has recorded against this invoice:
    • Date.
    • Method (Card / ACH / PayPal).
    • Amount.
    • Last-four of the card or account (where the processor returns it).
    • Status (Succeeded / Failed / Pending).
  • A Pay Now button (only if status != paid and balance_due_cents > 0).

The member-type counts are pulled from member_snapshot (a JSON field on ChapterInvoice) and the actual line items are immutable after invoice issuance — InvoiceLineItem.save() raises ValueError if you try to update an existing row.

What members see that you don't

Members don't see this detail page at all — they see only the Dues Balance card on their dashboard. Specifically, members cannot:

  • Open the invoice list.
  • Open invoice detail.
  • See line items by member type.
  • See payment history.
  • See the Pay Now button.

If a member asks "what was my share?", the answer is to ask the treasurer. The platform doesn't itemise per-member.

Initiate a payment

Officers (and presidents) initiate payment for the chapter total — not for individual members. The chapter is the customer; the chapter pays one invoice per period; the chapter's officers handle the transaction inside the platform.

The flow:

  1. Open the invoice detail.
  2. Click Pay Now.
  3. The Payment Modal opens and fetches PaymentConfigView to learn which processor is configured (stripe, braintree, square, paypal). It renders the corresponding hosted form:
ProcessorForm rendered
StripeStripe Elements card field with Apple Pay / Google Pay where supported
BraintreeBraintree drop-in UI (card + PayPal + Venmo where enabled)
SquareSquare Web Payments SDK
PayPalPayPal Smart Buttons
  1. The modal calls PaymentInitiateView which creates a payment intent on the processor and writes a PaymentAttempt row with status = pending.
  2. Member of the chapter enters card / account details into the embedded form.
  3. Submit. The processor handles authorisation; the modal shows a processing spinner.
  4. On success: green checkmark and "Payment Successful". Closing triggers invalidation of chapter-invoice, chapter-invoices, and chapter-balance queries, refetching all three.
  5. The processor calls back via webhook to /api/payments/webhook/<org_id>/<processor>/. The webhook handler verifies the cryptographic signature, creates a PaymentRecord row (idempotent on processor_payment_id), and updates the invoice's balance_due_cents and status.

A few mechanics that matter:

  • PaymentInitiateView is officer-and-up only. The previous version of this doc said the endpoint was "shared with members on their own invoices" — that's wrong. IsChapterOfficer is the permission, and it requires role to be officer or president. Regular members cannot trigger payment through the platform.
  • Officers can initiate payment for a member who needs help in the sense that the chapter total is being paid, not in the sense that you're paying one member's share. There is no "pay on behalf of member X" endpoint; chapter dues aren't tracked per-member at all.
  • Partial payments are supported. PaymentInitiateView accepts an optional amount_cents; if omitted, it defaults to the full balance_due_cents. Anything more than the balance is rejected (400 "Amount exceeds balance due.").
  • Already-paid rejects. If balance_due_cents <= 0, both PaymentConfigView and PaymentInitiateView return 400.
  • The processor's config is read-only to you. Officers see PaymentConfigView returning the hosted-config dict the gateway needs to render its form. You cannot change which processor the org uses; that's ProcessorConfigView, gated to IsNationalAdmin.

What if the chapter wants to pay outside the platform?

A chapter can absolutely pay via paper check or external bank transfer; the platform just won't know about it until your national admin records the payment manually via Django admin (no officer-accessible "record manual payment" endpoint exists). For most chapters using GreekManage in production, the embedded processor flow is the path of least friction.

Filter and sort

The list supports the four InvoiceStatus values plus an "All" pseudo-filter. Sort is fixed: overdue first, then by issued_at desc. You cannot:

  • Sort by amount.
  • Sort by due date ascending.
  • Filter by billing period at officer scope (the org admin can, you can't).
  • Export to XLSX at officer scope (the export endpoint, OrgInvoiceExportView, is IsNationalAdmin only).

If you need an export for accounting, ask your national admin to run the org-wide export and filter it for your chapter rows.

Read the configured processor

PaymentConfigView returns a hosted-form configuration object that includes the processor type, a tokenisation key for the embedded form, and a tax / fee summary if the processor returns one. Officers can read it (via the Pay Now modal) but cannot change it. The org-admin-facing ProcessorConfigView and ProcessorStatusView (/api/hq/billing/{org_id}/processor/) are both IsNationalAdmin-gated; officers get 403.

If you want to know which processor is in use without opening the modal, click any invoice's Pay Now and read the modal header — it tells you whether you're looking at Stripe Elements, Braintree drop-in, Square SDK, or PayPal buttons.

Common billing-question scenarios

A member walks up to you with a billing question. Here's the playbook for the most common ones.

"I think I overpaid my share. Can you refund me?"

What you can do: confirm whether the chapter invoice is paid (open invoice detail, look at Payment History), screenshot the relevant payment for them, document the conversation.

What you can't do: issue a refund. There is no officer-accessible refund endpoint in v0.62.1 — no full refund, no partial refund, no credit memo. Refunds happen through the processor's own dashboard (Stripe / Braintree / Square / PayPal) and are processed by your national admin or treasurer with processor credentials.

What to do next: forward the request to your national admin with the invoice ID and the member's information. The refund will appear in GreekManage when the processor's refund webhook fires; the invoice's balance_due_cents will go up and status may flip from Paid back to Partial.

"I want to pay my share through the app."

What you can do: explain that GreekManage tracks dues at the chapter level, not per-member. Their share is collected by the chapter's treasurer outside the platform (Venmo, Zelle, check, cash, payment plan).

What you can't do: invoice them individually. There is no per-member invoice surface, no per-member payment flow.

What to do next: point them at the treasurer's preferred channel.

"I see the invoice says Unpaid but I paid my treasurer last week."

What you can do: open invoice detail; check Payment History; see whether the chapter's payment to the processor has cleared.

What you can't do: mark the invoice paid manually. No officer endpoint records manual payments — Cash / check / Zelle / Venmo transfers between the member and the treasurer don't show up on PaymentRecord. Only processor-webhook-confirmed payments do.

What to do next: confirm with your treasurer that the chapter has paid its invoice to the org. If it has, and the webhook didn't fire, escalate to your national admin.

"I think this invoice was generated with the wrong head count."

What you can do: open invoice detail and read the Line Items table. Each row shows count × rate. If the count looks wrong (you have 24 actives, the line item says 27), document it.

What you can't do: edit the invoice. Line items are immutable after issuance (InvoiceLineItem.save() raises if you try). There is no "Adjust invoice" or "Issue credit" endpoint.

What to do next: send the invoice ID and the discrepancy to your national admin. They can either issue a credit through OrgInvoiceDetailView workflows or void and re-issue depending on how your org handles corrections.

"When will dues be late?"

What you can do: open invoice detail, read the Due Date field, and pass it on. After the due date passes with balance remaining, the daily Celery overdue task flips status from Unpaid (or Partial) to Overdue and notifications fire to admins.

What you can't do: change the due date. That's set at invoice generation by the national admin in BillingPeriod.due_date.

"Can you send a reminder to the members who haven't paid their share?"

What you can do: the chapter has one invoice. The chapter pays one invoice. Members don't have individual invoices on the platform, so "members who haven't paid" isn't a record GreekManage knows. If your treasurer maintains a spreadsheet of who's paid their share, that's the source of truth; you'd remind them out-of-band (Engage post, email, group chat).

What you can't do: trigger a per-member reminder from the billing surface. There is no officer-side send_reminder endpoint. Even the org-admin side doesn't have a "send dues reminder" button as of v0.62.1; overdue notifications go to org admins via the standard notification pipeline.

What officers cannot do

These actions don't have an officer-facing endpoint in v0.62.1:

  • Record a manual payment (cash, check, or anything outside the configured processor). Reconcile those through your org admin.
  • Refund a payment, in part or in full. Refunds happen out of band through the payment processor's own dashboard; the GreekManage ledger does not represent a refunded invoice as a distinct status.
  • Adjust an invoice, add a credit, add a fee, or waive an amount. Line items are immutable after issuance — even your org admin would generate a corrective invoice rather than editing the original.
  • Send a dues reminder to a single member or in bulk. Overdue notifications run on a scheduled task targeted at admins, not officers.
  • Delete an invoice.
  • Generate a financial summary or XLSX export at officer scope.
  • Configure dues rates or billing periods. Those settings are owned by your org admin.
  • No payment-processor config at officer scope.
  • No per-member invoice surface — chapter dues are tracked at the chapter, not per-member.
  • No "pay on behalf of member X" flow — see above; there is no per-member invoice to pay.

If you need any of these actions, your national admin is the entry point. They can configure rates, process refunds in the processor's dashboard, and adjust invoices via the org-level admin tools.

Errors and edge cases

SymptomCauseWhat to do
"No payment processor configured." on Pay NowOrg admin hasn't set up processor credentialsAsk national admin to configure in Settings → Billing → Processor.
"Invoice is already paid."balance_due_cents <= 0Refresh; you may have a stale view.
"Amount exceeds balance due."Partial payment value > balanceLower the amount or pay full balance.
Pay Now button missingInvoice status is paidExpected.
Dues Balance card stale after paymentWebhook hasn't fired yetWait — card polls every 60 sec. If still stale after 5–10 minutes, escalate.
403 Access Denied on BillingYour role isn't Officer or President on this chapterAsk your national admin to update your role. See Officer transition.
403 Access Denied on invoice detailYou're a member, not an officerExpected; ask treasurer for a summary.
Status stuck on "Unpaid" though processor shows charge clearedWebhook misfireNational admin must manually reconcile via processor's dashboard.

Tips

  • Use this page for visibility only. Pair it with a conversation with the member or treasurer when something needs action.
  • Don't promise refunds in DMs. Until your national admin processes one through the processor, it hasn't happened.
  • Take screenshots when escalating to your national admin. Invoice detail screenshots are the fastest way to communicate what you're looking at.
  • The 60-second auto-refresh on the dashboard card is your friend. Don't reload the whole page after the treasurer pays — just wait a moment.
  • Don't try to mark an invoice paid via Django admin yourself even if you have access. Manual ChapterInvoice edits bypass the audit chain and the line-item snapshot invariants.

Last verified against v0.62.1 (2026-05-11).