Skip to content

[eas-cli] Add eas billing:subscribe and billing:manage commands#4007

Draft
jonsamp wants to merge 2 commits into
mainfrom
jon/eng-24459-eas-subscribe-command
Draft

[eas-cli] Add eas billing:subscribe and billing:manage commands#4007
jonsamp wants to merge 2 commits into
mainfrom
jon/eng-24459-eas-subscribe-command

Conversation

@jonsamp

@jonsamp jonsamp commented Jul 12, 2026

Copy link
Copy Markdown
Member

Why

Implements the CLI half of ENG-24459: let users subscribe to an EAS plan and get a Stripe checkout link from the terminal (e.g. eas billing:subscribe starter), plus manage/cancel an existing subscription.

The www-side half is ENG-24461 (jon/eng-24461-add-stripe-link-support-to-www), which makes the stripe-auth/checkout endpoint accept plan slugs and return session.url. This PR depends on that shipping first.

How

New billing topic:

  • eas billing:subscribe <plan> (starter, agent, production-plus, enterprise) — resolves the account (-a/--account, single account, or interactive picker), POSTs stripe-auth/checkout with the plan slug, and opens/prints the returned Stripe checkout URL. If the account already has a paid subscription it does not create a second one; it points the user at billing:manage (Stripe's portal handles plan changes with proration).
  • eas billing:manage — POSTs stripe-auth/customer-portal and opens/prints the portal URL (change plan, update payment method, cancel).

Implementation notes:

  • Plan slug → server PlanType mapping lives in the CLI; the env-specific Stripe price ids stay server-side.
  • Reuses ApiV2Client; unwraps the apiv2 { data } response envelope (eas-cli's ApiV2Client returns the raw body, unlike the website client).
  • Opens URLs with open instead of better-opn: better-opn runs the URL through encodeURI, which double-encodes Stripe's already-percent-encoded checkout fragment (%2F%252F) and breaks the link. The URL is always printed as a clickable fallback.
  • Added AccountQuery.getSubscriptionAsync for the already-subscribed check.

Test Plan

  • Unit tests: billingClient (envelope unwrapping), subscribe (plan mapping, already-subscribed guard, free-plan handling, non-interactive/JSON output, missing-URL error), manage (portal open, verbatim URL). yarn test src/billing src/commands/billing → 10/10 pass.
  • yarn typecheck, yarn lint, yarn fmt:check clean.
  • Manual: ran the built CLI against a local www with the ENG-24461 changes:
    EXPO_LOCAL=true easc papeete billing:subscribe starter --account jonexpo
    
    Returns a real https://checkout.stripe.com/... URL with the fragment intact.

Note: end-to-end against staging/prod requires ENG-24461 to be deployed first; until then the endpoint returns only { id } and subscribe reports that no URL was returned.

Adds a billing topic with:
- billing:subscribe <plan> - creates a Stripe checkout session for an EAS
  plan and returns/opens the checkout URL. Guards against double-subscribing
  by routing already-subscribed accounts to billing:manage.
- billing:manage - opens the Stripe customer portal (change plan, update
  payment method, cancel).

Calls the stripe-auth apiv2 endpoints, unwrapping the { data } envelope, and
uses open (not better-opn) so the pre-encoded Stripe checkout fragment is not
double-encoded. Depends on the www-side change (ENG-24461) that makes the
checkout endpoint return session.url and accept planTypes.
@linear-code

linear-code Bot commented Jul 12, 2026

Copy link
Copy Markdown

ENG-24459

@github-actions

Copy link
Copy Markdown

✅ Thank you for adding the changelog entry!

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.74%. Comparing base (4b1f785) to head (e5c8e82).

Files with missing lines Patch % Lines
packages/eas-cli/src/billing/resolveAccount.ts 42.11% 11 Missing ⚠️
packages/eas-cli/src/commands/billing/subscribe.ts 86.80% 7 Missing ⚠️
packages/eas-cli/src/billing/openUrl.ts 73.69% 5 Missing ⚠️
...ckages/eas-cli/src/graphql/queries/AccountQuery.ts 0.00% 3 Missing ⚠️
packages/eas-cli/src/commands/billing/manage.ts 93.94% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4007      +/-   ##
==========================================
+ Coverage   59.67%   59.74%   +0.07%     
==========================================
  Files         941      947       +6     
  Lines       41319    41459     +140     
  Branches     8675     8698      +23     
==========================================
+ Hits        24654    24766     +112     
- Misses      16571    16599      +28     
  Partials       94       94              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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