- Add Apple Sign-In backend (JWKS verification, account linking, session management) - Implement push notification deep linking with NotificationDeepLinkRouter - Add jailbreak detection, runtime integrity monitoring, secure enclave service - Implement OAuth social login, token refresh, and secure logout flows - Add image caching (memory/disk), optimizer, upload queue, async semaphore - Implement notification analytics, type preferences, and category setup - Expand UI test suite with UITestBase, accessibility, auth flow, performance tests - Add CI pipeline for iOS UI tests (3 device sizes) and performance benchmarks - Restructure Xcode project to manual groups with KordantWidgets target - Add SwiftLint, Swift Collections/Algorithms/GoogleSignIn dependencies - Update project.yml for XcodeGen with new targets and configurations
119 lines
4.4 KiB
Markdown
119 lines
4.4 KiB
Markdown
# Subscription Model Documentation
|
|
|
|
> Kordant iOS App — Billing Architecture
|
|
> Last updated: 2026-06-02
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Kordant uses **web billing via Stripe Customer Portal** for subscription management. This is **not** an In-App Purchase (IAP) model using StoreKit.
|
|
|
|
## Rationale
|
|
|
|
Apple App Store Guidelines distinguish between:
|
|
|
|
1. **Digital content** consumed within the app (magazines, music, games, e-books) → **Must use IAP**
|
|
2. **Service access** where the primary value is server-side processing → **Web billing acceptable**
|
|
|
|
Kordant falls into category 2 because:
|
|
|
|
- **Dark web monitoring** runs on Kordant's servers, scanning data breaches and dark web forums
|
|
- **Data broker removal** involves automated web forms and requests to third-party data brokers
|
|
- **VoicePrint analysis** processes audio on Kordant's servers using ML models
|
|
- **SpamShield directory** is maintained and updated server-side
|
|
- **HomeTitle monitoring** involves checking public property records online
|
|
|
|
The app is a **client interface** to these server-side services. The subscription grants access to the service tier, not digital content consumed within the app.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
|
|
│ iOS App │────────▶│ API Server │────────▶│ Stripe Billing │
|
|
│ (Client) │ │ (Backend) │ │ (Customer Portal)│
|
|
└─────────────┘ └──────────────┘ └──────────────────┘
|
|
```
|
|
|
|
### Flow
|
|
|
|
1. User taps "Upgrade Plan" in Settings
|
|
2. App opens Safari to `https://app.kordant.ai/billing`
|
|
3. User selects/changes plan on Stripe Customer Portal
|
|
4. Stripe processes payment and updates subscription
|
|
5. Backend webhook updates user's subscription tier
|
|
6. App sees updated tier on next API call / refresh
|
|
|
|
### URLs
|
|
|
|
| Environment | Billing Portal URL |
|
|
|-------------|-------------------|
|
|
| Development | `http://localhost:3000/billing` |
|
|
| Staging | `https://staging.kordant.ai/billing` |
|
|
| Production | `https://app.kordant.ai/billing` |
|
|
|
|
## Plans
|
|
|
|
| Plan | Price | Features |
|
|
|------|-------|----------|
|
|
| **Free** | $0/mo | Email monitoring, 5 alerts/month, basic support |
|
|
| **Basic** | $12/mo | Email & phone monitoring, unlimited alerts, priority support, dark web scanning |
|
|
| **Premium** | $29/mo | Full identity monitoring, unlimited alerts, 24/7 support, dark web scanning, family coverage (5), identity theft insurance |
|
|
|
|
## Implementation
|
|
|
|
### API Configuration
|
|
|
|
```swift
|
|
// APIConfig.swift
|
|
struct APIConfig {
|
|
let billingPortalURL: URL // Environment-specific billing URL
|
|
}
|
|
```
|
|
|
|
### Settings ViewModel
|
|
|
|
```swift
|
|
// SettingsViewModel.swift
|
|
func manageSubscription() {
|
|
UIApplication.shared.open(APIConfig.shared.billingPortalURL)
|
|
}
|
|
```
|
|
|
|
### Settings View
|
|
|
|
```swift
|
|
// SettingsView.swift — subscriptionSection
|
|
ShieldButton(
|
|
title: "Upgrade Plan",
|
|
style: .primary,
|
|
icon: (leading: "arrow.up.right.square", trailing: ""),
|
|
action: { viewModel.manageSubscription() }
|
|
)
|
|
```
|
|
|
|
## App Store Compliance
|
|
|
|
This model complies with App Store Guidelines because:
|
|
|
|
1. **Guideline 3.1.1** — Subscriptions are for service access, not digital content
|
|
2. **Guideline 3.1.2** — No unlocking of features that are available for free
|
|
3. **Guideline 3.1.3** — No ranking manipulation
|
|
4. **Guideline 3.1.4** — No misleading pricing
|
|
|
|
The free tier provides genuine value (limited monitoring), and paid tiers unlock additional service capacity, not features that are artificially restricted.
|
|
|
|
## Alternatives Considered
|
|
|
|
| Approach | Rejected Because |
|
|
|----------|-----------------|
|
|
| StoreKit IAP | Complex subscription management, server-side entitlement sync, family sharing complications |
|
|
| Hybrid (IAP + web) | Unnecessary complexity, Apple takes 15-30% cut for service billing |
|
|
| Web-only billing | ✅ Selected — clean separation, full control, lower fees |
|
|
|
|
## References
|
|
|
|
- Apple Developer Documentation: [In-App Purchase Overview](https://developer.apple.com/in-app-purchase/)
|
|
- Apple Guidelines: [3.1 In-App Purchase](https://developer.apple.com/app-store/review/guidelines/)
|
|
- Stripe Documentation: [Customer Portal](https://stripe.com/docs/billing/payment-pages/customer-portal)
|