Switch or upgrade a plan

Guide

Move a customer to a different recurring price without canceling and re-creating their subscription. One call to change_price keeps the same subscription, the same billing date, and the same payment method - CHING figures out whether it is an upgrade or a downgrade and bills accordingly. The current period is never refunded.

How CHING routes the change

By default the change is auto-routed by comparing the per-day cost of the new price against the current one:

  • Upgrade (new price costs more per day): applied immediately. The customer is charged the new price prorated for the days left in the current period, the line item swaps right away, and current_period_end stays put - the full new price is billed at the unchanged renewal.
  • Downgrade (new price costs less per day): scheduled. Nothing is charged now; the subscription keeps running on the current plan until current_period_end, and the renewal cron applies the cheaper price on the next bill.
  • Same per-day price: a no-op that also clears any change you previously scheduled.

1. Upgrade now (prorated)

Send just the target price id. If it is an upgrade, CHING charges the prorated amount immediately and switches the plan:

curl -X POST https://api.ching.co.il/ching/v1/subscriptions/sub_hXUPYOnvxp-q/change_price \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "price": "price_QA8qF3B3VIqE" }'
{
  "success": true,
  "data": {
    "kind": "upgrade",
    "applied": true,
    "scheduled_for": null,
    "charge_amount": 15000,
    "charge_currency": "ils",
    "subscription": { "id": "sub_hXUPYOnvxp-q", "status": "active", ... }
  }
}

charge_amount is the prorated charge taken now (agorot), not the full plan price. The immediate charge issues a tax document, so you receive a charge.succeeded webhook alongside subscription.updated.

2. Downgrade (applies at renewal)

The same call with a cheaper price schedules the switch. The response reports it as not yet applied and tells you when it lands:

{
  "success": true,
  "data": {
    "kind": "downgrade",
    "applied": false,
    "scheduled_for": "2026-05-19T09:16:40.000Z",
    "charge_amount": null,
    "charge_currency": null,
    "subscription": { "id": "sub_hXUPYOnvxp-q", "pending_price": "price_basic", ... }
  }
}

Until it lands, the subscription shows the upcoming change on pending_price and pending_effective_at. Call change_price again with the original price to cancel a scheduled downgrade.

3. Control the timing

Pass change_timing to override the default routing:

  • at_period_end - defer an upgrade to the next renewal instead of charging now (no prorated charge; the new price takes effect at current_period_end).
  • immediately - force an upgrade to apply right away (the default for upgrades). It is rejected for a downgrade with DOWNGRADE_IMMEDIATE_NOT_SUPPORTED, because CHING never refunds the current period - downgrades always wait for renewal.
curl -X POST https://api.ching.co.il/ching/v1/subscriptions/sub_hXUPYOnvxp-q/change_price \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "price": "price_QA8qF3B3VIqE", "change_timing": "at_period_end" }'
Tip: Prefer letting your customers self-serve? The hosted Billing Portal runs this exact logic from a page CHING hosts, so you do not have to build the plan-switch UI yourself.

Reference

Full parameters and response fields are on the Subscriptions endpoint reference (Change a subscription's price).