Subscription cancellation (cancel at period end + resume) + checkin reason (#23) #24

Merged
Cordy merged 5 commits from feat/cancel into main 2026-08-24 01:09:53 +00:00
Owner

Closes #23.

  • POST /v1/licenses/{id}/cancel — org-admin gated (same chain as seats), Paddle cancel effective_from=next_billing_period; CancelAt recorded from Paddle's scheduled_change.effective_at (fallback: license expiry) and surfaced in GET /v1/licenses as cancelAt.
  • POST /v1/licenses/{id}/cancel/resume — Paddle scheduled_change: null, clears CancelAt.
  • refreshWith clears CancelAt on renewals (extend=true) only — mid-cycle seat changes leave it alone.
  • /v1/checkin 403 body now carries reason: expired|revoked|unknown (server half of Cairn#308; backwards-compatible).
  • paddleAPI gains a post helper.

Tests: full cancel→resume flow against a fake Paddle (period-end body, scheduled_change:null body, CancelAt set/cleared, list surfacing, 409 non-subscription, 401 anonymous), renewal-clears-CancelAt vs seat-change-does-not, and all four checkin reason paths.

Dashboard UI lands in cairn-site next.

Closes #23. - `POST /v1/licenses/{id}/cancel` — org-admin gated (same chain as seats), Paddle cancel `effective_from=next_billing_period`; `CancelAt` recorded from Paddle's `scheduled_change.effective_at` (fallback: license expiry) and surfaced in `GET /v1/licenses` as `cancelAt`. - `POST /v1/licenses/{id}/cancel/resume` — Paddle `scheduled_change: null`, clears `CancelAt`. - `refreshWith` clears `CancelAt` on renewals (extend=true) only — mid-cycle seat changes leave it alone. - `/v1/checkin` 403 body now carries `reason: expired|revoked|unknown` (server half of Cairn#308; backwards-compatible). - `paddleAPI` gains a `post` helper. Tests: full cancel→resume flow against a fake Paddle (period-end body, scheduled_change:null body, CancelAt set/cleared, list surfacing, 409 non-subscription, 401 anonymous), renewal-clears-CancelAt vs seat-change-does-not, and all four checkin reason paths. Dashboard UI lands in cairn-site next.
Cordy merged commit 187b3b33e8 into main 2026-08-24 01:09:53 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/cairn-license-server#24
No description provided.