Setting Up the Paywall SDK
What you'll learn
- Generating the Paywall SDK with pricing UI and subscription management
- Understanding the mock purchase flow for development
- Customizing pricing tiers and paywall presentation
- Connecting to real payment providers in production
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
- Auth SDK already generated (see Auth SDK Setup)
Step 1: Generate the Paywall SDK
bash
archipelago generate paywall_sdkYou will be prompted for:
- appName —
MyApp(must match your monorepo app name) - isForMonorepo —
true(uses workspace path resolution)
Or use a config file:
json
{
"appName": "MyApp",
"isForMonorepo": true
}bash
archipelago generate paywall_sdk --config paywall_config.jsonStep 2: Understand the Generated Structure
features/
└── paywall_sdk/
└── lib/src/
├── paywall_sdk.dart # FeatureSDK entry point
├── data/
│ ├── datasources/ # Mock and remote purchase sources
│ ├── models/ # Subscription, pricing models
│ └── repositories/ # Purchase repository impl
├── di/ # Scoped DI registration
├── domain/
│ ├── entities/ # Subscription, plan entities
│ ├── repositories/ # Purchase repository contract
│ └── usecases/ # Purchase, restore, check status
├── presentation/
│ └── ui/pages/
│ ├── paywall_page.dart # Pricing comparison UI
│ └── subscription_page.dart # Active subscription details
└── router/ # Paywall route definitionsStep 3: Register the Paywall Feature
dart
import 'package:paywall_sdk/paywall_sdk.dart';
FeatureRegistry.register(PaywallSdk());Step 4: Use the Mock Purchase Flow
During development, the SDK uses a mock purchase datasource that simulates purchases without real transactions:
dart
// The mock datasource auto-completes purchases
// No real payment provider needed during development
final result = await purchaseUseCase.execute(selectedPlan);
// result.isSuccess == true (always, in mock mode)Step 5: Connect a Real Payment Provider
Replace the mock datasource with your payment provider:
dart
// paywall_sdk/lib/src/data/datasources/remote/purchase_remote_datasource.dart
class PurchaseRemoteDatasource {
Future<PurchaseResult> purchase(Plan plan) async {
// Integrate RevenueCat, Stripe, or in-app purchases
final result = await Purchases.purchasePackage(plan.package);
return PurchaseResult.fromRevenueCat(result);
}
Future<SubscriptionStatus> checkStatus() async {
final info = await Purchases.getCustomerInfo();
return SubscriptionStatus.fromCustomerInfo(info);
}
}Common Customizations
| Customization | Where to Change |
|---|---|
| Pricing tiers | domain/entities/ — define plans |
| Paywall UI layout | presentation/ui/pages/paywall_page.dart |
| Trial periods | data/models/ — add trial fields |
| Restore purchases | domain/usecases/ — RestorePurchaseUseCase |
| Gate features | Check subscription status in feature guards |
Next Steps
- Set up the Home SDK with subscription-gated content
- Configure Monitoring to track purchase failures