Skip to main content
View as Markdown
Version: v2

Cancelling and Resuming

ODUS gives you three ways to cancel a subscription: immediately, at the end of the current billing period, or at the end of the next one — letting the upcoming renewal charge go through first. Either scheduled option can be reversed by resuming the subscription before it takes effect.

Prerequisites​

You need the ID of an active subscription. Only active subscriptions can be cancelled or resumed.

Cancelling a Subscription​

Send a POST /v2/subscriptions/{id}/cancel request and pick the boundary with cancelAt:

cancelAtTakes effectFurther charges
immediatelyRight awayNone; open invoices are voided
end_of_current_cycleAt currentPeriodEndNone
end_of_next_cycleOne renewal laterOne more renewal charge is taken

cancelAt defaults to end_of_current_cycle.

Moving from v1: send cancelAt, not cancelImmediately

cancelImmediately is not part of v2. Where v1 sent { "cancelImmediately": true }, send { "cancelAt": "immediately" }.

If you remove cancelImmediately without adding cancelAt, the request gets the default, end_of_current_cycle. It succeeds without an error, and the subscription keeps billing until the end of the current cycle.

Immediate cancellation​

To cancel a subscription right away:

{
"cancelAt": "immediately"
}

ODUS immediately:

  1. Voids all open invoices belonging to the subscription. No further charges are attempted.
  2. Sets the subscription status to cancelled.

The customer loses access as soon as the request completes. This action cannot be undone. To re-subscribe the customer, you must create a new subscription.

End-of-period cancellation​

To let the customer keep access until their current billing period ends:

{
"cancelAt": "end_of_current_cycle"
}

ODUS sets cancelAtPeriodEnd: true on the subscription and records the booking in cancelAtCycle. The subscription status remains active, and the customer continues to have access until currentPeriodEnd. When that date arrives, ODUS cancels the subscription automatically without collecting any additional charge.

The response shows the pending cancellation state:

{
"id": "sub_2Q9fNQAs77Fhue9itgVFbUzq8NV",
"status": "active",
"cancelAtPeriodEnd": true,
"currentCycle": 4,
"cancelAtCycle": 4,
"currentPeriodEnd": "2024-03-09T00:00:00.000Z"
}

Cancellation after one more renewal​

Some cancellation policies have a notice window: a request made close to the renewal date should let that renewal complete and take effect afterwards. Send:

{
"cancelAt": "end_of_next_cycle"
}

ODUS books the cancellation against the next cycle. Because the current cycle is unaffected, cancelAtPeriodEnd stays false and the upcoming renewal is charged exactly as it would have been:

{
"id": "sub_2Q9fNQAs77Fhue9itgVFbUzq8NV",
"status": "active",
"cancelAtPeriodEnd": false,
"currentCycle": 4,
"cancelAtCycle": 5,
"currentPeriodEnd": "2024-03-09T00:00:00.000Z"
}

Once that renewal is billed and the subscription moves into cycle 5, cancelAtPeriodEnd flips to true on its own and the subscription cancels at the new currentPeriodEnd.

You do not need to run a timer against the renewal date yourself. The booking is stored as a cycle number, not a timestamp, so it stays correct even when the period boundary moves — for example when a failed renewal delays it through retries.

Plan updates while a cancellation is booked

A subscription with a pending cancellation cannot have its plan or next billing date updated; the request returns a 400. Resume it first, apply the update, then cancel again.

If the intervening charge fails

The cancellation still fires at the end of that cycle. A failed renewal that starts retries advances the subscription into the booked cycle just as a successful one does, so the booking becomes due at that cycle's currentPeriodEnd either way. If the retries are exhausted, the subscription is cancelled at that point instead — sooner than booked, never later.

If billing stops for another reason before the renewal is even attempted, the booking is brought forward onto the current period, so the cancellation still happens rather than waiting for a renewal that will never come. For the same reason, end_of_next_cycle is rejected with a 400 on a subscription whose automatic billing has already stopped — use end_of_current_cycle there.

One booking at a time

A subscription that is already scheduled for cancellation — at either boundary — cannot be scheduled again; the request returns a 400. To move a booking from one boundary to the other, resume the subscription first and then cancel it again. Cancelling immediately is always allowed, since it is terminal either way.

Cancelling from the Dashboard​

  1. Open the subscription detail page.
  2. Click Cancel Subscription.
  3. In the dialog, use the Cancel immediately toggle to choose between immediate and end-of-period cancellation.
  4. Click Cancel to confirm.

The Dashboard covers the immediate and end-of-current-period options; end_of_next_cycle is available through the API.

Resuming a Subscription​

If you have scheduled a subscription for cancellation — at either boundary — and it has not yet taken effect, you can reverse the decision.

Send a POST /v2/subscriptions/{id}/resume request — no request body is required:

POST /v2/subscriptions/sub_2Q9fNQAs77Fhue9itgVFbUzq8NV/resume

ODUS clears cancelAtCycle and sets cancelAtPeriodEnd back to false. The subscription returns to its normal billing state and will renew at currentPeriodEnd as usual.

Resuming from the Dashboard​

  1. Open the subscription detail page.
  2. Click Resume Subscription.
  3. Confirm in the dialog.

Edge case: already cancelled subscriptions​

Resume only works when a subscription is active with a pending cancellation — that is, with a non-null cancelAtCycle. A subscription whose status is already cancelled cannot be resumed. You must create a new subscription for the customer instead.

Reactivating a Subscription Whose Billing Stopped​

A subscription can stay active after its billing has stopped: autoBillingEnabled is false, and no renewal will be attempted. Once the customer can be charged again, restart billing with a POST /v2/subscriptions/{id}/reactivate request. No request body is required, and your key needs subscription:force_bill.

POST /v2/subscriptions/sub_2Q9fNQAs77Fhue9itgVFbUzq8NV/reactivate

ODUS then:

  1. Starts a new billing period now. currentPeriodEnd is set to the time of your request, and upcomingInvoice covers one billing interval from then.
  2. Sets autoBillingEnabled to true.
  3. Takes the renewal charge within a few minutes, like any other renewal. If the charge fails, the usual retry rules apply.
Missed periods are not charged

The customer is charged once, for the new period. Periods that went unpaid while billing was stopped are not charged, and the renewal date moves to the day you reactivate.

Reactivating takes a charge. Check that the customer still wants the subscription and has a payment method that can be charged before you send the request.

If a customer bought several subscriptions together and payment bundling is enabled, reactivate them one right after another so they can be charged in a single payment.

The request is refused with 400 and type invalid_state_error when the subscription:

  • is not active
  • is still billing (autoBillingEnabled is true)
  • is scheduled for cancellation. Resume it first.
  • has an open invoice that can still be paid, for example while a payment is being retried. Wait for that invoice to be paid or voided.
  • has a paid billing period that has not ended, or had its latest renewal paid by a retry. The customer has already paid, and billing resumes on its own.
  • is still processing the outcome of its latest renewal. Try again in a few minutes.
  • is in a billing period that has not started yet.

Reactivation is available in v2 only.