billing

POST /v1/subscriptions/{subscriptionId}/plan

Move a subscription onto a bigger or smaller plan.

모든 billing 엔드포인트

모든 개발자 문서

인증

Bearer 토큰으로 API 키를 전송하세요. 키는 반드시 billing.payment.manage 권한을 가지고 있어야 하며, 권한이 없는 키는 404가 아닌 403으로 거부됩니다.

이 엔드포인트는 조직 ID를 받지 않습니다. 사용자의 키가 이미 속한 조직을 식별하며, 응답은 해당 조직으로 한정됩니다.

무료 체험하기

대괄호 안에 있는 모든 내용을 사용자 지정 값으로 바꾸고, 키 플레이스홀더는 대시보드의 키로 바꾸세요.

curl -X POST https://api.zinndigital.com/v1/subscriptions/{subscriptionId}/plan \
  -H "Authorization: Bearer zdk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "plan_version_id": <Uuid> }'

로그인하셨나요? 대시보드의 API 콘솔이 실제 조직 ID와 본인의 키를 자동으로 채우고 라이브 API를 대상으로 요청을 실행하므로 실제 응답을 확인할 수 있습니다. API 콘솔에서 이 엔드포인트를 여세요

상세 정보

Charges the prorated difference for the remainder of the current period, moves every site the subscription entitles, and supersedes the subscription onto the new plan version — keeping the existing period window, so the customer's renewal date does not move and they are not handed a free extra period. ⛔ A plan change SUPERSEDES rather than mutates, because a subscription pins the exact version it was sold so that a later catalogue edit cannot rewrite what a live subscriber pays. subscription_id in the response is therefore a new id and a client holding the old one must replace it. ⭐⭐ slots_before and slots_after are read back from the subscription rows, not derived from the plan that was asked for. A plan change that answers 200 and silently does not take effect is the worst outcome on this path, and a status code cannot tell that apart from one that worked. Mid-period money. A larger plan is charged the difference now — the customer asked for more room today, and applying it at the next renewal is the buy-flow dead end in another costume. A smaller plan returns the unused difference as account credit, not a card refund: it is instant, it cannot be unavailable, it is idempotent, and it is spendable on their next order. ⛔ Account credit carries no VAT credit note; a proration credit spans the current period's invoice rather than reversing it. ⛔ expected_total_minor is a money guard, not a convenience. It is the figure the customer was actually shown, and the change is refused 422 when the freshly-computed quote differs. Every other refusal is 422 as well, with nothing charged and nothing changed: a plan on another product line, the plan they are already on, a plan that has been re-priced since the page loaded, account usage above what a smaller plan allows, a card decline. ⛔ The downgrade guard is account-wide and there is no override. The same check_downgrade the site endpoint and the staff tariff endpoint call: sites, mailboxes, mailbox storage and disk across the org's subtree. Staff have an audited override because they sometimes genuinely need to move an over-limit account; a customer overriding their own quota check is not an override, it is no check. Repeating an identical request is the recovery and it is safe. Every step is idempotent on a key anchored to the subscription being left, so an attempt that died part-way is finished rather than duplicated: one order, one charge, one credit, one supersede. 404 for a subscription in another tenant as well as for one that does not exist. 503 when the driver behind an entitled site cannot move a package between types at all — our gap, not theirs. Requires billing.payment.manage — it charges a card, so the key that gates paying is the key that gates committing to a payment.

매개변수

이름유형필수설명
subscriptionId (path)UuidThe subscription whose plan is being read or changed.

요청 본문

이름유형필수설명
plan_version_idUuidThe priced plan version to move onto, exactly as getSitePlanChoices reported it.
expected_total_minorinteger아니요A money guard, not a convenience. The figure the customer was actually shown, in minor units. The engine refuses 422 when its freshly-computed quote differs, so a price…
gatewayobject아니요The payment rail the customer picked, from getPaymentOptions. Omit it (or send null) for "no preference", which follows the payment method the organization would be charged on…

응답

이름유형필수설명
plan_codestringThe plan this subscription is now on.
plan_namestringIts catalogue name, so a receipt can name it without a second lookup.
plan_version_idstringThe priced version the new subscription carries.
subscription_idstringThe new subscription. A plan change supersedes rather than mutates, because a subscription pins the exact version it was sold — so this id differs from the one in the request…
order_idstringThe order the charge was raised against, or "" when the change resulted in a credit and no order was minted.
charged_minorintegerWhat was actually taken, in minor units.
credited_minorintegerWhat was actually returned as account balance, in minor units.
package_typestringThe vendor package type, read back after the move. "" on our own fleet and "" when the subscription entitles no site — there is no package to move.
slots_beforeintegerThe site allowance the subscription held before the change.
slots_afterintegerThe site allowance it holds now.
slots_before_unlimitedbooleanThe old plan sold unlimited sites, so slots_before is null by design.
slots_after_unlimitedbooleanThe new plan sells unlimited sites, so slots_after is null by design.
quoteSitePlanQuoteThe quote the change was performed against.

이 엔드포인트가 반환할 수 있는 오류

401 · 403 · 404 · 422 · 429 · 503