feat(admin): subscription webhooks promote the entitlement and reissue; cancel and past-due take no licence action

created/updated/activated fold into 'make the world match current state', so
out-of-order delivery is correct by construction. A confirmed subscription
promotes desired->granted and signs from granted only. Cancel and past-due touch
only status; the licence runs to expiry. IssueForInstance backstops a
self-hosted placeholder that is linked after payment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 10:40:06 +01:00
co-authored by Claude Opus 5
parent 6832bfd7bb
commit 2e8114c41e
4 changed files with 327 additions and 5 deletions
+26
View File
@@ -164,6 +164,32 @@ func SendLicense(to, instanceName, blob string) error {
instanceName, blob))
}
// SendCancelled confirms a cancellation and states what stays true: the licence
// keeps working until it expires, then the instance degrades to read-only.
func SendCancelled(to, instanceName string) error {
return send(to, "Your Vantage subscription is cancelled",
fmt.Sprintf("Your subscription for %s is cancelled.\n\n"+
"Your instance keeps working until the current licence expires. After "+
"that, monitors keep running but changes are disabled.\n", instanceName))
}
// SendPastDue notifies of a failed charge without alarming: the licence is
// untouched while Paddle retries the card.
func SendPastDue(to, instanceName string) error {
return send(to, "Payment failed for your Vantage subscription",
fmt.Sprintf("A payment for %s failed.\n\n"+
"Your instance is unaffected while the card is retried. Update your "+
"payment method from the billing portal.\n", instanceName))
}
// SendLinkReminder chases a self-hosted customer who paid but never linked.
func SendLinkReminder(to, instanceName string) error {
return send(to, "Finish setting up "+instanceName,
fmt.Sprintf("Your subscription for %s is active, but the instance is not "+
"linked yet.\n\nPaste your install's ID in the portal to receive your "+
"licence.\n", instanceName))
}
// SendInstanceReady tells a customer their cloud instance exists, where it is,
// and when its licence runs out.
//