Skip to content

feat(autumn): plan catalog, eligibility, and hosted checkout flow#7

Merged
RhysSullivan merged 2 commits into
mainfrom
autumn-checkout-trial
Jun 29, 2026
Merged

feat(autumn): plan catalog, eligibility, and hosted checkout flow#7
RhysSullivan merged 2 commits into
mainfrom
autumn-checkout-trial

Conversation

@RhysSullivan

Copy link
Copy Markdown

Extends the Autumn emulator beyond customers + usage so it can drive a real billing UI (plans page, trial checkout). Motivated by reproducing an executor bug where the billing page stayed stale after completing a Stripe free-trial checkout.

What's new

  • Seedable plan catalog returned by plans.list, with per-customer customer_eligibility (status, attach_action, trialing, trial_available) computed from the customer's subscriptions. Seed via { "plans": [...] }.
  • billing.attach and billing.open_customer_portal. A paid plan, or a card-required free_trial, routes attach through a hosted checkout page (returns payment_url).
  • Hosted checkout (uses the shared renderCheckoutPage): GET /checkout/:id renders the page, POST /checkout/:id/complete redirects to success_url without activating, and /checkout/settle (or /checkout/:id/settle) activates the subscription. This mirrors Stripe: the browser is redirected back before checkout.session.completed reaches Autumn, so activation is deferred to settle. A card-required trial activates as trialing.
  • customers.get_or_create now returns SDK-shaped subscriptions and per-feature balances derived from the active plan.

Why deferred activation matters

Completing checkout intentionally does not activate the plan until settle is called. That is what lets a consumer reproduce the real "page is stale until reload" race, where the redirect back lands before the webhook.

Validation

New autumn-trial.test.ts drives attach → hosted checkout → complete → settle through the real autumn-js SDK (zod-validated responses) and asserts eligibility transitions (upgrade + trial available, to none + active + trialing after settle). Existing tests still pass; typecheck and lint clean. Response shapes verified against autumn-js 1.2.8 (executor) and 1.2.28.

Docs: updated skills/autumn/SKILL.md (seed shape + checkout flow). README/apps/web only list autumn generically, no per-feature section to touch. Consumed by executor UsefulSoftwareCo/executor#1215; needs a release for executor to pick it up.

Extends the Autumn emulator beyond customers and usage so it can drive the
billing UI:

- Seedable plan catalog returned by plans.list, with per-customer
  customer_eligibility (status, attach_action, trialing, trial_available)
  computed from the customer's subscriptions.
- billing.attach and billing.open_customer_portal. A paid plan or a
  card-required free trial routes attach through a hosted checkout page.
- Hosted checkout: GET /checkout/:id renders via the shared renderCheckoutPage,
  POST /checkout/:id/complete redirects to success_url WITHOUT activating, and
  /checkout/settle (or /checkout/:id/settle) activates the subscription. This
  mirrors Stripe: completing checkout redirects back before the
  checkout.session.completed webhook lands, so activation is deferred to settle.
  A card-required trial activates as trialing.
- customers.get_or_create now returns SDK-shaped subscriptions and per-feature
  balances derived from the active plan.

Validated against the real autumn-js SDK in a new test.
@RhysSullivan RhysSullivan merged commit 2d9c273 into main Jun 29, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant