mysuperwall_sdk 1.1.3
mysuperwall_sdk: ^1.1.3 copied to clipboard
Remotely configure and present mobile app paywalls with audience targeting, A/B experiments, offline caching, and your existing billing integration.
MySuperWall Flutter SDK #
Show remotely configured paywalls in your Flutter app. Design the paywall and choose when it appears in the MySuperWall dashboard; the SDK fetches it by trigger key and presents it. Purchases stay with your own IAP code (RevenueCat, in_app_purchase, ...).
Full documentation: https://mysuperwall.com/docs/
Install #
Requires Flutter >=3.35.0 / Dart >=3.9.0, matching the minimum required by the SDK’s current dependencies. Supports Android and iOS.
dependencies:
mysuperwall_sdk: ^1.1.3
Quick start #
import 'package:mysuperwall_sdk/mysuperwall_sdk.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await MySuperWallClient.initialize(appKey: 'YOUR_APP_KEY'); // Dashboard > Settings
runApp(const MyApp());
}
// Recommended: pre-loads paywalls so they open instantly.
MaterialApp(
builder: (context, child) => MySuperWallHost(child: child!),
home: const HomePage(),
);
// Show a paywall at the right moment.
final result = await MySuperWallClient.instance.handleTrigger(
context,
triggerKey: 'onboarding_finish',
onPurchase: (productId) async {
// Run the purchase with your IAP library, then report it:
await MySuperWallClient.instance.trackPurchaseSuccess(productId: productId);
},
onRestore: () {/* restore with your IAP library */},
onDismiss: () {},
);
if (!result.show) {
// No paywall for this user/trigger (disabled, holdout, offline). Continue normally.
}
Product prices #
Pass the localized prices you read from the store, keyed by product ID, before showing a paywall:
await MySuperWallClient.instance.setProductPrices({
'weekly_sku': '\$6.99',
'monthly_sku': '\$19.99',
});
For intro offers and per-day/week/month text use setStructuredProductData with MySuperWallProductDataEntry:
await MySuperWallClient.instance.setStructuredProductData({
'weekly_sku': const MySuperWallProductDataEntry(
displayPrice: '\$6.99',
pricePerWeekText: '\$6.99',
introDisplayPrice: '\$1.99',
introEligible: true,
introUsed: false,
),
});
If the user is intro-eligible, price placeholders show the intro price; otherwise the regular price.
Features #
- Remote paywall HTML delivered by trigger key, with A/B variants and audience rules configured in the dashboard
- Disk cache, prefetching and a warm pool of ready paywalls (
MySuperWallHost) - Built-in lifecycle triggers:
mysuperwall.install,.update,.session,.session_3/5/10/20/50,.day_1/3/7/14/30 - Locale and user identity (
setLocale,setUserId; anonymous ID generated if omitted) - Purchase and dismiss analytics (
trackPurchase*,trackDismiss) - Fails open on network errors: your app is never blocked by a paywall
Example #
See example/ for a runnable app.
Verify completed purchases without RevenueCat #
Your billing integration still handles purchase, acknowledgment/consumption and entitlements. After it reports a completed purchase, pass the store-issued proof:
Future<void> reportCompletedApplePurchase({
required String productId,
required String transactionId,
}) async {
await MySuperWallClient.instance.trackPurchaseSuccess(
productId: productId,
proof: StorePurchaseProof.apple(transactionId: transactionId),
onVerification: (result) {
// A transaction proof is not authorization to grant a user entitlement.
// result.retryable identifies transport/server/rate-limit failures.
},
);
}
Use StorePurchaseProof.googleProduct(purchaseToken: token) for Google one-time
products or StorePurchaseProof.googleSubscription(purchaseToken: token) for
subscriptions. Supply the purchase token, not the Google order ID or full
JSON receipt. Apple needs the transaction ID, not its base64 app receipt.
Extract these values from your own billing provider's completed-purchase result;
the SDK does not depend on RevenueCat or any particular billing package.
Existing trackPurchaseSuccess calls remain compatible and send unverified
analytics when no proof is supplied. onVerification is optional and receives
verification separately from the billing outcome. The original Future<void>
return type is preserved. A verification failure never marks a successful store
payment as a billing failure.
To retry only verification without another reported analytics event:
Future<PurchaseVerificationResult> retryAppleVerification({
required String productId,
required String transactionId,
}) => MySuperWallClient.instance.verifyPurchase(
productId: productId,
proof: StorePurchaseProof.apple(transactionId: transactionId),
);
Initialize with the dashboard appKey; verification requires an explicit key.
Configure the matching app's encrypted Apple/Google store connection first.
Requests use the existing HTTP client and timeout. Network/timeouts/server errors
get at most three attempts with bounded backoff; 4xx responses (including 429)
are returned without an immediate retry. No proof is persisted or logged by the
verification service. There is no durable offline retry queue; retry from the
billing integration when connectivity returns. Never put proofs in analytics
metadata or logs.
PurchaseVerificationResult includes verified, duplicate, environment,
amountUsd, reason, statusCode and retryable. Sandbox is determined by the
store. A null amount is unknown, not zero; Google amounts remain unknown when the
purchase API does not provide an actual charge. Do not combine direct-store and
RevenueCat totals for the same transactions. Backend contract:
backend/docs/purchase-verification-api.md in the MySuperWall backend repository.
Recovery and cache update (1.1.1) #
Paywall language defaults to the device locale. setLocale('tr') switches the
manifest cache and refreshes in the background. setCountry('TR') independently
sets the audience region; the device region is used otherwise. Regional language
requests fall back to the base translation on compatible backends.
handleTrigger automatically runs configured recovery rules with cooldown,
once-per-session, bounded depth and repeat protection. The legacy dismiss second
screen is supported when present in the current manifest. Call
setSubscriptionStatus(bool) from real entitlement state for skipIfPremium.
Purchase success rules only follow host-confirmed completion calls, never taps.
After a confirmed restore, call trackRestoreSuccess(paywallId: displayedPaywallId).
Existing setAutomationActionHandler integrations remain authoritative and disable
the new default runner to avoid double presentation. Identity and locale changes
cancel pending default recovery and invalidate the active manifest scope. Legacy
second-screen recovery uses the current manifest and retries manifest synchronization
when it is unavailable; offline recovery requires a cached target.
The setup panel provides immutable source snapshots. To update a vendored SDK, use the checksum-pinned installer described in the backend SDK setup guide; it preserves the old source folder as a backup and does not build or edit your app.
Host dependency compatibility (1.1.2) #
The SDK accepts package_info_plus >=9.0.0 <11.0.0 and
device_info_plus >=11.5.0 <14.0.0. Your application can retain compatible
existing constraints such as ^9.0.0 and ^11.5.0; no dependency_overrides
is needed for these two conflicts. Pub resolves one version of each package
that satisfies both the host and SDK. Other dependencies and platform/toolchain
requirements must also remain compatible. Future major versions require API
review before extending the upper bound.
For Git installations, pin the v1.1.2 tag to receive this change. Previously
published tags are immutable and retain their original dependency constraints.