Skip to main content
When a customer switches plan mid-cycle, we work out the unused portion of their current plan and credit it against the new plan’s charge. The maths is per-second — no rounding to days.

Always preview first

Before committing a plan change, call the preview endpoint. It tells you exactly what will happen: what the customer owes (or gets credited), whether it’s immediate or deferred, and a line-item breakdown.
curl -X POST https://api.useplinth.com/v1/subscriptions/sub_01JABC.../preview-change \
  -H "Authorization: Bearer sk_test_DOCS_SHARED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"new_plan_id": "plan_max_01..."}'
Response
{
  "direction": "upgrade",
  "current_plan": "Pro",
  "new_plan": "Max",
  "due_now_minor": 443300,
  "credit_minor": 316700,
  "new_plan_charge_minor": 760000,
  "scheduled_for": null,
  "line_items": [
    {
      "description": "Unused Pro (19 days remaining)",
      "amount_minor": -316700,
      "type": "credit"
    },
    {
      "description": "Max plan (19 days remaining)",
      "amount_minor": 760000,
      "type": "charge"
    }
  ]
}
  • directionupgrade, downgrade, or lateral (same price, different plan)
  • due_now_minor — kobo to charge now (upgrades only)
  • credit_minor — kobo credited (downgrades return credit to customer balance)
  • scheduled_for — null if immediate, ISO date if deferred to period end

Commit the change

Once the customer confirms, commit:
curl -X POST https://api.useplinth.com/v1/subscriptions/sub_01JABC.../change-plan \
  -H "Authorization: Bearer sk_test_DOCS_SHARED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"new_plan_id": "plan_max_01..."}'

Strategies

Immediate prorated (default for upgrades): Charge or credit now based on the remaining period. The new plan takes effect immediately. At period end (default for downgrades): No charge or credit now. The new plan activates at the next renewal. The current plan runs until then. A subscription.plan_change_scheduled event fires. You can override the strategy:
{
  "new_plan_id": "plan_pro_01...",
  "strategy": "immediate"
}
Options: "immediate" or "period_end".

Upgrades without a card on file

/change collects an immediate upgrade by charging a stored card token. If the customer has no card (e.g. they pay by bank transfer), that charge can’t happen — /change returns no_payment_method. Instead of dead-ending, collect the prorated difference via a checkout:
curl -X POST https://api.useplinth.com/v1/subscriptions/sub_01JABC.../change-checkout \
  -H "Authorization: Bearer sk_test_DOCS_SHARED_KEY" \
  -d '{ "plan_id": "pln_01STANDARD..." }'
Redirect the customer to the returned checkoutLink. The plan stays unchanged until the payment settles — Plinth records the intended change as pending and applies the swap (plus a paid proration invoice) when the webhook confirms payment, emitting subscription.upgraded. See Checkout-funded plan change.

Cancel a scheduled change

If the customer changes their mind before the scheduled change fires:
curl -X DELETE https://api.useplinth.com/v1/subscriptions/sub_01JABC.../scheduled-change \
  -H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
The subscription continues on the current plan. A subscription.plan_change_canceled event fires.

Worked example

Priya is on Pro (₦5,000/month) on day 11 of a 30-day cycle. She upgrades to Max (₦12,000/month). Unused Pro credit:
  • Remaining days: 30 − 11 = 19 days
  • ₦5,000 × (19/30) = ₦3,166.67 → ₦3,167 (rounded half-up)
New Max charge for remaining period:
  • ₦12,000 × (19/30) = ₦7,600
Net due now:
  • ₦7,600 − ₦3,167 = ₦4,433 (443300 kobo)
Rounding uses half-up on kobo values. We never issue negative invoices — if a credit exceeds the new charge (e.g., downgrading to a much cheaper plan mid-cycle), the surplus goes to the customer’s balance and offsets their next invoice.