Skip to content

Billing-portal plan changes take up to a day to reach a Cloud workspace #1560

Closed

Description

@helpcodeai

Problem

A plan change made in the Stripe billing portal reaches a Cloud workspace only at the next daily re-verification (licences are re-checked when lastVerifiedAt is older than 20 hours) or when an admin reloads the licence page at the right moment.

Seen on 6 Nov 2026: a customer upgraded Starter → Team in the billing portal. The licence site switched the licence to Team at once, but the Cloud workspace kept Starter's limits (3 MCP servers), so the customer had paid for limits they could not use.

Why the existing refresh did not help:

  1. The licence page calls POST /api/license/refresh on load, but the refresh is throttled to once a minute per workspace. The admin opened the licence page, upgraded and came back within the minute, so the refresh was skipped.
  2. The billing portal opened from other pages (useManagePlan) returns to that page, which does not refresh.
  3. A change made without coming back to the app (the portal link emailed from /account, a cancellation, a renewal paid or failed) waits for the daily check.

Fix

  • Cloud: POST /api/license/sync with body { licenseKey }. It accepts only the licence site's service token (x-amcp-service-token = LICENSE_SERVICE_TOKEN, the secret Cloud already presents to the site) and re-verifies that key against the licence site. The call carries no licence data: Cloud stores what /api/license/verify answers, so a forged call can at worst cause one extra check. 404 on self-hosted, without the token, or with a wrong one. Concurrent calls for the same key verify once.
  • Cloud: opening the billing portal resets the refresh throttle, so the return visit always refreshes.
  • Licence site: the Stripe webhook calls the Cloud endpoint after customer.subscription.updated/deleted, invoice.paid/payment_failed and checkout.session.async_payment_*, for Cloud licences bound to a workspace. Best-effort; the daily re-verification remains the fallback.

Deployment modes

  • Cloud: as above.
  • Self-hosted: no change. The endpoint answers 404, and the licence site only notifies Cloud licences.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions