Start a Stripe Checkout session for a self-serve plan
Start a Stripe Checkout session for a self-serve plan: CustomDomain™ API reference in the billing group. Covers parameters, request body and responses.
Starts a subscription Checkout for the caller's workspace. Requires billing:manage (owners and admins); a widget token is refused. The session collects the card up front, and carries the customer's promotion_code as its discount when one is sent (below). A new workspace's first subscription starts with a 14 day trial; a workspace inside its grace period (the retired Free plan) gets a trial that ends when its grace ends, so subscribing early never costs a day; anyone else is charged today. A workspace that already has a running subscription gets 409 (change the plan with /billing/change-plan instead). Nothing is granted until Stripe confirms the checkout.
Supply EITHER return_url (embedded Checkout, the response carries client_secret) OR both success_url and cancel_url (hosted Checkout, the response carries url).
promotion_code is optional: the text a customer typed, at most 64 characters (never a Stripe promo_ id). It is checked here, before Stripe is asked for a session, and only CustomDomain's own codes are taken (made through the operator console, or limited to this deployment's Stripe products), because a Stripe account can be shared with other products. A code that is not CustomDomain's, does not exist or is no longer active is a 404, the same for all three, and no session is created; a CustomDomain code that Stripe will not give this order (a first order only code, a minimum amount) is a 400. The code becomes the session's one discount, and Stripe's own code field on its checkout page is never switched on, so a code of another product cannot be typed there either. A Checkout Session cannot be given a discount after it is created: to add, change or remove a code, start a new checkout (with the new code, or without one) and mount its client_secret in place of the old one.
ui_mode is optional and picks how the session is shown. Leave it out (a null or an empty string counts as leaving it out), or send embedded, for the behavior from before it existed: Stripe Embedded Checkout when return_url is set, and the hosted redirect when only success_url and cancel_url are. elements is Elements with the Checkout Sessions API: the caller renders the whole page (the plan, the price, the trial, the promotion code box, the totals) and mounts only Stripe's Payment Element with the returned client_secret, so the page can wear its own theme. It needs return_url, which is where redirect based payment methods and the finished payment land, and the session is created on a Stripe API version of the dahlia release train (the billing guide names the exact version), so mount it with a Stripe.js of that train. The trial, the promotion codes and the card up front are the same in every mode. The response's ui_mode says what was really created (embedded, elements or hosted): an elements request answers embedded when Stripe could not create an Elements session, so read it before mounting anything. hosted is only ever an answer, never a request value: a client that keeps the response's ui_mode must not send it back (the redirect flow is chosen by sending success_url and cancel_url without return_url). Any other value is a 400.
Authorization
apiKey Long-lived tenant API key, cd_live_… (production) or cd_test_… (staging, development), stored hashed. Keys created before the switch to cd_ start with sk_live_… / sk_test_… and are still accepted. Scoped to the owning application's tenant.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/billing/checkout" \ -H "Content-Type: application/json" \ -d '{ "plan": "starter" }'{ "id": "string", "url": "string", "client_secret": "string", "ui_mode": "embedded", "trial_days": 0, "trial_end": "2019-08-24T14:15:22Z", "first_charge_at": "2019-08-24T14:15:22Z"}{ "code": "string", "title": "string", "details": "string"}{ "code": "string", "title": "string", "details": "string"}{ "code": "string", "title": "string", "details": "string"}{ "code": "string", "title": "string", "details": "string"}{ "code": "string", "title": "string", "details": "string"}{ "code": "string", "title": "string", "details": "string"}