Onboarding Plan Pick #
Classification: Internal-Only
The monthly volume, plan and interval an onboarding organization picked before paying, so a reload does not lose them. Code: apps/bonsapi/src/service/onboarding/plan_choice.rs. Everything here is behind ONBOARDING_V2_DOCUMENTS (bonsapi Doppler secret, default false).
Storing #
PUT /api/v1/onboarding/plan with volume_range, plan and interval (month or year). volume_range is the picked range’s up_to_per_month from the onboarding plans list, null for the open-ended range; plan is a plan’s id or plan_key from the same list. Both must be offered to the organization, else 400.
- Written to the Clerk organization’s public metadata (
onboarding_volume_range,onboarding_chosen_plan,onboarding_chosen_interval) in one merge of those keys, then mirrored into bonsapi’s copy straight away. - Runs under the organization onboarding lock, so it cannot interleave with another pick or with
POST /onboarding/complete. - 403 once onboarding has ended, 409 once the organization has a plan (the same check as the login
paid; a Stripe error lets the pick through), 404 while the flag is off. POST /onboarding/completeclears the three keys. After payment the plan comes from the Stripe subscription.
Reading #
The login answer (GET /api/v1/me/organization, onboarding) carries the three fields: absent until picked, null when the metadata cannot be read. The open-ended volume range is stored as no key, so it reads null once a plan is picked.
After checkout #
With the flag on, checkout.session.completed for an onboarding checkout drops the cached plan before and after settling, so paid is current at once even when the claim is retried. Onboarding sessions carry the onboarding_checkout metadata marker; sessions from before it count when the organization is still onboarding. POST /billings/refresh is the client’s backstop.
Logs #
| Event | When | Fields |
|---|---|---|
onboarding_plan_chosen (audit) |
A pick is stored | changes per key, from and to |
onboarding_plan_store_failed (ERROR) |
The Clerk write failed | error |