Scout

wiki/decisions/2026-07-03-beta-specific-stripe-return-urls.md

ADR: Beta Stripe Checkout Uses Beta Return URLs

Date: 2026-07-03 Status: Accepted

Context

Scout has two hosted checkout surfaces:

  • /beta for $0 card-backed beta setup.
  • /pricing for paid credit-package checkout.

The earlier Stripe configuration used one generic success URL and one generic cancel URL for both flows. That made beta checkout return to the pricing page, which is confusing for beta testers and weakens the self-service onboarding experience.

Decision

Scout now supports beta-specific Stripe return URL configuration:

STRIPE_BETA_SUCCESS_URL=https://scout.chowmes.com/beta?checkout=success
STRIPE_BETA_CANCEL_URL=https://scout.chowmes.com/beta?checkout=cancelled

Paid checkout keeps using:

STRIPE_SUCCESS_URL=https://scout.chowmes.com/pricing?checkout=success
STRIPE_CANCEL_URL=https://scout.chowmes.com/pricing?checkout=cancelled

If beta-specific URLs are not configured, Scout falls back to the generic success/cancel URLs. This keeps old deployments compatible while giving the hosted ChowMes deployment a cleaner beta flow.

Implementation Notes

  • StripeCheckoutConfig resolves return URLs per package.
  • beta_trial uses beta-specific return URLs when present.
  • Paid packages continue using pricing return URLs.
  • VPS hosted-env configuration scripts allowlist the beta URL keys.
  • Hosted config validation treats beta URLs as optional but validates them as HTTPS when present.
  • Public docs and env templates include both paid and beta return URLs.

Verification

Focused verification on 2026-07-03:

  • tests/unit/scripts/test_vps_admin_scripts.py tests/unit/test_hosted_pricing_docs.py: 27 passed.
  • tests/unit/core/platform/test_stripe_checkout.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/scripts/test_hosted_readiness_check.py tests/unit/test_stripe_test_mode_smoke.py: 38 passed.
  • python3 -m pyright scout/core/platform/stripe_checkout.py scout/api/config.py scout/api/main.py scout/api/routers/billing.py: 0 errors.
  • ruff check on changed Python/test files: passed.
  • ruff format --check on changed Python/test files: passed.

Remaining Work

This does not configure Stripe or SMTP in production. Hosted SaaS still needs real Stripe keys, price IDs, webhook secret, SMTP delivery credentials, and live test-mode smoke before the beta and paid checkout flows can be called complete.