Files
ops-docs/membership-allowances.md
T
inference-bot c432edbae2 membership: record the allowance renewal and lapse policy (2026-11-04)
Renewal asks Open Collective for a live recurring contribution on the
sweep's schedule, anchored to the member's join day rather than the payment
date (OC aligns charges onto a common billing day). One reminder, then a
grace window, then deactivate by removing group access while keeping the
account. Member-facing summary: co-op/support#44.
2026-11-04 05:20:45 +00:00

2.8 KiB

Membership allowance renewal and lapse

Operator-facing record of the decision taken 2026-11-04 on how a member's monthly allowance renews, and how a lapse is handled. The member-facing summary is co-op/support#44; the code lives in co-op/member-portal.

The rule

  • Renewal is decided by asking Open Collective, on our own schedule. A scheduled reconciliation asks whether the member has a live recurring contribution (order status ACTIVE or PROCESSING — a payment in flight is not a missed payment). Renewal is a decision of the sweep, not a side effect of webhook delivery, so a lost webhook costs a delayed renewal, never a silently skipped month.
  • Anchor to the member's join day, never the payment date. Open Collective aligns a whole collective's charges onto one common billing day, so anchoring to a charge lets an early charge move the boundary and skip a cycle. The member's join day is stored (members.anchor_day) and the reset is pinned to its next occurrence.
  • Grace before deactivation. One reminder email per cycle; deactivate only after PAYMENT_GRACE_DAYS unpaid.
  • Deactivate by removing group access and stopping renewal, keeping the account, so a returning payer resumes cleanly at the next cycle.
  • Log every decision (allowance_log) with the Open Collective evidence — renewed / reminded / deactivated, plus the payment date or its absence — so a dispute is answered from a record, not reconstructed.

Scope: monthly only

Verified 2026-11-04 that there are no annual contributors: 104 orders on Open Collective, 87 MONTHLY and 17 ONETIME, zero annual, and no order has a charge gap over 45 days. Only the monthly case is implemented. One-time contributions are not an allowance cycle — they top up the non-expiring credit balance and stay in the existing credits model.

Operating it

  • ALLOWANCE_POLICY = report (default) | on. report computes every decision and changes nothing; on performs renewals and sends the reminder.
  • ALLOWANCE_DEACTIVATE = off (default) | on. Gated separately so renewals and reminders can run before anyone loses access.
  • PAYMENT_GRACE_DAYS (default 7).
  • Manual check: POST /admin/allowance?mode=report (X-Admin-Token) is a no-op report; mode=test&to=<addr> emails one sample reminder; mode=send requires ALLOWANCE_POLICY=on.

The bug that prompted it

A member who joined on the 15th was charged on the 2nd (Open Collective's common billing day). The reset rule re-anchored his allowance to the new payment date and pushed his renewal from the 14th to the 2nd of the next month — skipping the reset he was owed while he had already paid. The fix is both changes above: anchor to the join day, and decide renewal on a schedule rather than on the payment.