Renewal refreshes the existing license — no re-issue #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Today every
transaction.completedmints a NEW license (new id, new key) — so a subscription renewal would create a second key the customer must re-paste into Cairn. Terrible UX; blocks monthly billing.Design
subscription_idagainst existing records (paddleSub). Match found → refresh in place: extendexpiresAtto max(now, old expiry) + billing period, re-sign the payload with the same license id, replace the stored key. No match (first purchase) → issue as today.seatsin the refreshed payload./v1/checkinresponse gains the current signed key:{status: "ok", key: "CAIRN1…"}. Since >50-seat instances check in monthly, a renewed key propagates to the instance automatically within one check-in cycle — zero manual re-pasting for exactly the instances that need a license.keydiffers from the installed one, verify offline and install it.paddleTxn) so Paddle retries don't double-extend.Acceptance: replay a renewal simulation for an existing subscription → same license id, later expiry, updated stored key; check-in returns the new key; cairnd (companion issue) picks it up; a fresh purchase still creates a new license.
Shipped and deployed (PR #7).
subscription_idagainst existing records: match →refresh()extends expiry one billing period past max(now, current expiry), updates seats, re-signs the same license id, replaces the stored key, records the new txn. No match → new license as before. Idempotency by PaddleTxn intact./v1/checkinnow returns{status: "ok", key: <current>}, and Cairn v0.3.13 installs it automatically on the monthly check-in (same-license-id guard; Cairn#58). Customers on subscriptions never re-paste keys.Covered by
TestRefreshOnRenewalandTestCheckinReturnsCurrentKey.