Billing notifications — frontend integration
Billing notifications — frontend integration
Two new notification types now reach the client when a workspace's subscription
changes state. Additive only — no existing payload changed, but an unknown
type will fall through your notification renderer if you switch on it.
New notification types
type | When |
|---|---|
subscription_canceled | The user canceled via POST /user/billing/cancel, or the gateway terminated the subscription (external cancel, dunning exhausted, term expired) |
subscription_renewed | A recurring charge succeeded and advanced the billing period. The first charge (activation) does not notify. |
Both are delivered on two channels:
- In-app — a row in
GET /api/v1/notifications, exactly like assignment and mention notifications. - FCM push — a visible notification with a
clickActionpointing at the billing settings page.
Recipients
Every super-admin of the workspace (super_admin = true, is_active = true). Regular members are not notified — billing is the owner's concern.
In-app shape
{
"id": 812,
"type": "subscription_renewed",
"title": "Subscription renewed",
"message": "Your Advanced plan renewed. Next charge on 2026-03-10.",
"action_url": "/en/settings/billing",
"is_read": false,
"data": {
"type": "subscription_renewed",
"plan_name": "Advanced",
"workspace_name": "Acme",
"period_end": "2026-03-10", // key omitted when the sub carries no period
"frontend_url": "https://acme.corteksa.net/en/settings/billing",
"notification_type": "subscription_renewed",
"timestamp": "2026-02-10T00:00:00.000Z"
}
}performed_by is null on these — nobody in the workspace performed the
action. object_slug / record_slug are present but empty, as on any
non-record notification.
Copy for the canceled case:
title:Subscription canceledmessage:Your {plan} plan was canceled. {workspace} keeps access until {period_end}.— the date clause is dropped whenperiod_endis empty.
period_end means access end for a cancellation (the workspace keeps working
until then, per the existing lapse ladder) and next charge date for a
renewal. Format is YYYY-MM-DD.
Push shape
Same data keys as above, plus the standard title / body. The FCM
collapseKey is subscription_subscription_canceled /
subscription_subscription_renewed, so a newer lifecycle notification replaces
an unread older one on the device instead of stacking.
Filtering
GET /notifications?type= still accepts only all | assign | comment.
Billing notifications are returned under all; there is no dedicated filter
value yet. Unread counts include them.