subscription.renewed

Fires when a subscription successfully renews to its next billing cycle. The renewal charge has succeeded, currentPeriodStart / currentPeriodEnd have rolled forward, and failedPaymentCount is reset to 0.

You'll usually receive subscription.payment_succeeded at the same moment — that event carries the charge details; this event carries the lifecycle signal.

When it fires

In the renewal cron, after the charge succeeds and the cycle has advanced:

  1. Cron tick lands on a subscription whose currentPeriodEnd is in the past.
  2. The renewal charge fires against the customer's default payment method.
  3. On success: currentPeriodStart = old currentPeriodEnd, new currentPeriodEnd = +interval, then this event fires.

A successful retry after a failed renewal also emits subscription.renewed (treat it the same way).

Payload

{
  "id": "evt_01HX...",
  "type": "subscription.renewed",
  "createdAt": "2026-06-01T00:00:15Z",
  "accountId": "acc_01HX...",
  "data": {
    "subscriptionId": "sub_01HX..."
  }
}

Slim by design — the event is a notification. Fetch the subscription via GET /v1/payment/subscriptions/:id for the full state, or read it from the sibling subscription.payment_succeeded payload.

Handler examples

// Node
if (event.type === 'subscription.renewed') {
  const { subscriptionId } = event.data;
  const sub = await client.subscriptions.retrieve(subscriptionId);
  await access.extend(sub.customerId, sub.planId, sub.currentPeriodEnd);
}
# Python
if event["type"] == "subscription.renewed":
    sub = client.subscriptions.retrieve(event["data"]["subscriptionId"])
    access.extend(sub["customerId"], sub["planId"], sub["currentPeriodEnd"])
// Go
if event.Type == "subscription.renewed" {
    var d struct{ SubscriptionID string `json:"subscriptionId"` }
    _ = json.Unmarshal(event.Data, &d)
    sub, _ := client.Subscriptions.Retrieve(ctx, d.SubscriptionID)
    access.Extend(ctx, sub.CustomerID, sub.PlanID, sub.CurrentPeriodEnd)
}

What to do

  • Extend the entitlement to the new currentPeriodEnd.
  • Log the recurring-revenue event.
  • Send a renewal receipt if you handle receipts yourself (Storlaunch sends one by default).

Common pitfalls

  • Treating it as the only renewal signal. If you also subscribe to subscription.payment_succeeded, watch out for double-handling. The Plugipay flow fires both for renewals; pick one as your renewal trigger and dedupe the other.
  • Forgetting the retry-success path. A successful retry after dunning emits this event too — you should restore access from any past-due downgrade, not just extend it.

Related events

Next