Purchase Subscription

User selects the yearly subscription plan and completes payment through the platform's native store flow.

Status: partially-live. Backend subscription infrastructure is in place. Frontend paywall UI exists but RevenueCat entitlement integration is not yet wired up.

Who Can Do This

Any user with type: free and status: active or status: onboarding. Users with status: banned, status: banned_final, or status: to_be_deleted are shown a blocking screen and cannot reach the purchase flow. A user with an active subscriber entitlement cannot purchase a duplicate subscription.

Steps

  1. User opens the subscription screen in the app.
  2. App checks slot availability with 95octane's backend and presents the applicable yearly plan — Introductory Price if slots remain, Premium Price otherwise. The actual price is fetched dynamically from RevenueCat.
  3. App redirects to the App Store (iOS) or Google Play (Android) native payment sheet.
  4. User completes payment in the store.
  5. RevenueCat confirms the purchase; 95octane increments the slot counter and updates the user's type to subscriber.

Rules

  • Only a yearly subscription is offered — there is no monthly option.
  • Every subscribe event — including a lapsed user re-subscribing — increments the global early-adopter slot counter. Automatic renewals do not increment the counter.
  • The slot limit is a soft limit — concurrent purchases when one slot remains may both receive the Introductory Price.
  • A user shown the Introductory Price at step 2 is guaranteed that price even if slots are exhausted by others before their payment clears.
  • While slots remain (counter ≤ operator-configured limit, default 1,000): the user is placed on the Introductory Price plan. This price is locked for all future automatic renewals.
  • Once slots are exhausted: only the Premium Price plan is offered. A lapsed early adopter re-subscribing after slots are full is placed on the Premium Price plan and loses their early-adopter status permanently.
  • A subscriber who renews without lapsing always pays their locked-in price; renewals do not check slot availability.
  • Actual prices are fetched dynamically from RevenueCat and reflect current App Store and Google Play pricing for the user's region.
  • Payment and billing are managed entirely by App Store / Google Play; the app does not handle payment details directly.
  • Subscription renews automatically until cancelled.

What Happens Next

The user's type changes to subscriber and they gain immediate access to unlimited Premium Rides: full navigation with traffic data, other rider positions, intercom, and the option to opt out of location sharing.

Any unused Premium Ride quota has no effect while subscribed — Premium access is unlimited. Unused quota slots are preserved and become available again if the subscription later lapses.

If the user is still in onboarding (status: onboarding): the type change to subscriber takes effect immediately on purchase. Subscriber features become available as soon as the user completes onboarding — the subscription does not wait for onboarding to complete before being recorded.

Restore Purchases

See Restore Purchases.

Auth Provider and Store Account

The auth provider used to purchase (Google or Apple sign-in) cannot be unlinked or replaced while a subscription is active. The app blocks provider removal for subscribers. This protects against losing access if the auth provider were changed.

Subscriptions are tied to the store account (Apple ID or Google account) used at the time of payment — this is separate from the Firebase Auth provider. A user who changes their device's store account at the OS level (iOS Settings or Android Settings) may lose access to their subscription, as RevenueCat validates entitlements against the current store account. Restoring purchases from the new store account will not recover the entitlement. Users in this situation must contact support for a manual entitlement transfer.

Failure Cases

  • Payment declined — handled by the store; user remains free.
  • Already subscribed — the purchase option is not shown to active subscribers.
  • User abandons the store payment sheet — user is returned to the subscription screen with a retry option. No charge is made; user remains free.
  • Network failure before store sheet loads — user sees an error with a retry option. No purchase is initiated; user remains free.
  • Slot availability check fails (step 2 backend call fails) — the purchase flow is blocked. User sees an error with a retry option; no plan is shown until the check succeeds. No purchase is initiated; user remains free.
  • Entitlement sync delayed — payment succeeded at the store but RevenueCat sync has not yet completed. User should tap Restore Purchases to re-check entitlements and regain access immediately.
  • Counter increment fails after purchase — if RevenueCat confirms the purchase but 95octane's slot counter increment fails, the user's type is still updated to subscriber immediately (entitlement is primary). The counter is corrected asynchronously on the next sync. No action is required from the user.