Note not found.
Architecture: App Store Billing
Architecture: App Store Billing
Overview
Apple App Store subscription billing for westside-basketball. iOS-only subscriptions — Apple handles recurring billing, Stripe continues for one-off payments. Both coexist.
Core Concept: Apple Delinquency Gate
Apple enforces an account-wide download block ("Verification Required") when any unpaid balance exists on an Apple ID. This is free platform behavior — not developer-configured. It replaces manual payment tracking.
Components
1. Rails Webhook Endpoint (westside-basketball)
- App Store Server Notifications v2 endpoint
- JWS signature verification via
app_store_server_librarygem - Receives subscription lifecycle events (subscribe, renew, grace period, expire, revoke)
- Updates
apple_subscription_statuson Player model - Ticket: #65
2. Subscription UI (westside-basketball)
- Admin detail page shows Apple subscription status badges
- Player-facing page shows own subscription status
- Apple fields are additive — existing Stripe fields untouched
- Ticket: #66 (depends on #58 for admin detail page)
3. iOS StoreKit Purchase Flow (westside-basketball-ios)
- Turbo Native app with native StoreKit 2 purchase sheet
- Fastlane IaC manages all App Store Connect config
- Auto-renewable subscription product with 16-day billing grace period
- Builds via SSH to MacBook (no cloud CI for iOS)
- Ticket: #78
Data Model
Player model fields (additive alongside existing Stripe fields):
apple_subscription_statusenum: subscribed, grace_period, billing_retry, expired, revoked, noneoriginal_transaction_id(string) — Apple's transaction identifierexpires_at(datetime)grace_period_expires_at(datetime)
Dependency Chain
#65 (webhook) → #66 (UI needs webhook data) and #78 (iOS needs webhook endpoint). #58 (admin detail page) → #66 (subscription UI lives on detail page).
Key Decision (2026-06-27)
iOS-only subscriptions. No web or Android subscription flow. Apple delinquency gate is the enforcement mechanism. Stripe stays for one-off payments.
Related
project-westside-basketball— project page- User stories: WS-S34, WS-S35, WS-S36, WS-S37