From ace1fcebc4c353ba8c1930fa750dcaf59a7b92dd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Nov 2025 19:44:49 +0000 Subject: [PATCH 1/2] docs(flutter): update for 2.4.5 --- content/docs/flutter/index.mdx | 2 +- content/docs/flutter/meta.json | 4 + .../sdk-reference/PresentationResult.mdx | 108 ++++++++++++++++++ .../docs/flutter/sdk-reference/consume.mdx | 59 ++++++++++ .../sdk-reference/getPresentationResult.mdx | 78 +++++++++++++ content/docs/flutter/sdk-reference/index.mdx | 2 +- .../sdk-reference/overrideProductsByName.mdx | 104 +++++++++++++++++ 7 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 content/docs/flutter/sdk-reference/PresentationResult.mdx create mode 100644 content/docs/flutter/sdk-reference/consume.mdx create mode 100644 content/docs/flutter/sdk-reference/getPresentationResult.mdx create mode 100644 content/docs/flutter/sdk-reference/overrideProductsByName.mdx diff --git a/content/docs/flutter/index.mdx b/content/docs/flutter/index.mdx index 4f62f2b..b7ba729 100644 --- a/content/docs/flutter/index.mdx +++ b/content/docs/flutter/index.mdx @@ -34,4 +34,4 @@ If you have feedback on any of our docs, please leave a rating and message at th If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-flutter/issues). - \ No newline at end of file + \ No newline at end of file diff --git a/content/docs/flutter/meta.json b/content/docs/flutter/meta.json index b5c1690..9ac2571 100644 --- a/content/docs/flutter/meta.json +++ b/content/docs/flutter/meta.json @@ -26,15 +26,19 @@ "sdk-reference/configure", "sdk-reference/Superwall", "sdk-reference/register", + "sdk-reference/getPresentationResult", "sdk-reference/identify", "sdk-reference/setUserAttributes", "sdk-reference/getUserId", "sdk-reference/subscriptionStatus", + "sdk-reference/consume", + "sdk-reference/overrideProductsByName", "sdk-reference/SuperwallDelegate", "sdk-reference/PaywallPresentationHandler", "sdk-reference/SuperwallOptions", "sdk-reference/PaywallOptions", "sdk-reference/PurchaseController", + "sdk-reference/PresentationResult", "sdk-reference/handleDeepLink", "sdk-reference/advanced", diff --git a/content/docs/flutter/sdk-reference/PresentationResult.mdx b/content/docs/flutter/sdk-reference/PresentationResult.mdx new file mode 100644 index 0000000..06761ae --- /dev/null +++ b/content/docs/flutter/sdk-reference/PresentationResult.mdx @@ -0,0 +1,108 @@ +--- +title: "PresentationResult" +description: "The result of a paywall presentation attempt." +--- + +## Purpose +Represents the possible outcomes when checking or presenting a paywall. Used by [`getPresentationResult()`](/flutter/sdk-reference/getPresentationResult) and paywall presentation handlers. + +## Signature +```dart +sealed class PresentationResult { + factory PresentationResult.placementNotFound() = PlacementNotFoundPresentationResult; + factory PresentationResult.noAudienceMatch() = NoAudienceMatchPresentationResult; + factory PresentationResult.paywall(Experiment experiment) = PaywallPresentationResult; + factory PresentationResult.holdout(Experiment experiment) = HoldoutPresentationResult; + factory PresentationResult.paywallNotAvailable() = PaywallNotAvailablePresentationResult; +} + +class PlacementNotFoundPresentationResult extends PresentationResult; +class NoAudienceMatchPresentationResult extends PresentationResult; +class PaywallPresentationResult extends PresentationResult { + final Experiment experiment; +} +class HoldoutPresentationResult extends PresentationResult { + final Experiment experiment; +} +class PaywallNotAvailablePresentationResult extends PresentationResult; +``` + +## Cases + + +| Case | Description | +|------|-------------| +| `PlacementNotFoundPresentationResult` | The placement was not found or doesn't exist. | +| `NoAudienceMatchPresentationResult` | No audience match for the placement based on the current user attributes. | +| `PaywallPresentationResult` | A paywall would be or was presented. Contains experiment information. | +| `HoldoutPresentationResult` | The user is in a holdout group. Contains experiment information. | +| `PaywallNotAvailablePresentationResult` | The paywall is not available (e.g., network error, configuration issue). | + + +## Experiment Information + +When a paywall is presented or the user is in a holdout group, the result includes an `Experiment` object: + +```dart +class Experiment { + final String id; + final String groupId; +} +``` + +- `id` - The unique identifier for the experiment +- `groupId` - The identifier for the experiment group the user is in + +## Usage + +Handling different presentation results: +```dart +final result = await Superwall.shared.getPresentationResult('premium_feature'); + +if (result is PaywallPresentationResult) { + // Paywall would be shown + final experimentId = result.experiment.id; + final groupId = result.experiment.groupId; + print('Experiment: $experimentId, Group: $groupId'); +} else if (result is HoldoutPresentationResult) { + // User is in holdout + print('User in holdout for experiment ${result.experiment.id}'); +} else if (result is NoAudienceMatchPresentationResult) { + // No audience match + print('No audience match for placement'); +} else if (result is PlacementNotFoundPresentationResult) { + // Placement not found + print('Placement not found'); +} else if (result is PaywallNotAvailablePresentationResult) { + // Paywall not available + print('Paywall not available'); +} +``` + +Using pattern matching: +```dart +final result = await Superwall.shared.getPresentationResult('premium_feature'); + +switch (result) { + case PaywallPresentationResult(experiment: final exp): + // Handle paywall presentation + print('Paywall for experiment ${exp.id}'); + case HoldoutPresentationResult(experiment: final exp): + // Handle holdout + print('Holdout for experiment ${exp.id}'); + case NoAudienceMatchPresentationResult(): + // Handle no match + print('No audience match'); + case PlacementNotFoundPresentationResult(): + // Handle not found + print('Placement not found'); + case PaywallNotAvailablePresentationResult(): + // Handle not available + print('Paywall not available'); +} +``` + +## Related +- [`getPresentationResult()`](/flutter/sdk-reference/getPresentationResult) - Gets presentation result without showing paywall +- [`registerPlacement()`](/flutter/sdk-reference/register) - Registers and presents a paywall +- [`PaywallPresentationHandler`](/flutter/sdk-reference/PaywallPresentationHandler) - Handles paywall presentation lifecycle diff --git a/content/docs/flutter/sdk-reference/consume.mdx b/content/docs/flutter/sdk-reference/consume.mdx new file mode 100644 index 0000000..b520b37 --- /dev/null +++ b/content/docs/flutter/sdk-reference/consume.mdx @@ -0,0 +1,59 @@ +--- +title: "consume()" +description: "Consumes an in-app purchase by its purchase token." +--- + +## Purpose +Consumes a consumable in-app purchase using its purchase token. This is typically used for Google Play Store purchases that need to be consumed before they can be purchased again. + +## Signature +```dart +Future consume(String purchaseToken) +``` + +## Parameters + +| Name | Type | Description | +|------|------|-------------| +| `purchaseToken` | `String` | The purchase token of the in-app purchase to consume. | + + +## Returns / State +Returns a `Future` that resolves to the purchase token of the consumed purchase. + +## Usage + +Consuming a purchase after successful purchase: +```dart +try { + final purchaseToken = await Superwall.shared.consume('purchase_token_123'); + print('Purchase consumed: $purchaseToken'); +} catch (e) { + print('Failed to consume purchase: $e'); +} +``` + +Using with a PurchaseController: +```dart +class MyPurchaseController extends PurchaseController { + @override + Future purchase(Product product) async { + // Handle purchase + final transaction = await _processPurchase(product); + + // If this is a consumable product, consume it + if (product.type == ProductType.consumable) { + try { + await Superwall.shared.consume(transaction.purchaseToken); + print('Consumable purchase consumed'); + } catch (e) { + print('Failed to consume purchase: $e'); + } + } + } +} +``` + +## Related +- [`PurchaseController`](/flutter/sdk-reference/PurchaseController) - Handles purchase logic +- [`Product`](/flutter/sdk-reference/Product) - Product information diff --git a/content/docs/flutter/sdk-reference/getPresentationResult.mdx b/content/docs/flutter/sdk-reference/getPresentationResult.mdx new file mode 100644 index 0000000..e980415 --- /dev/null +++ b/content/docs/flutter/sdk-reference/getPresentationResult.mdx @@ -0,0 +1,78 @@ +--- +title: "getPresentationResult()" +description: "Gets the result of a paywall presentation without actually showing the paywall." +--- + +## Purpose +Retrieves the presentation result for a placement without presenting the paywall. This is useful for checking whether a paywall would be shown, determining if the user is in a holdout group, or getting experiment information without triggering a paywall presentation. + +## Signature +```dart +Future getPresentationResult( + String placement, { + Map? params, +}) +``` + +## Parameters + +| Name | Type | Description | +|------|------|-------------| +| `placement` | `String` | The name of the placement to check. | +| `params` | `Map?` | Optional parameters to pass with the placement. These can be referenced within campaign rules. Keys beginning with `$` are reserved for Superwall and will be dropped. Nested maps and lists are currently unsupported and will be ignored. Defaults to `null`. | + + +## Returns / State +Returns a `Future` that resolves to one of the following: +- `PlacementNotFoundPresentationResult` - The placement was not found +- `NoAudienceMatchPresentationResult` - No audience match for the placement +- `PaywallPresentationResult` - A paywall would be presented (contains experiment information) +- `HoldoutPresentationResult` - User is in a holdout group (contains experiment information) +- `PaywallNotAvailablePresentationResult` - Paywall is not available + +## Usage + +Checking if a paywall would be shown: +```dart +final result = await Superwall.shared.getPresentationResult( + 'premium_feature', + params: {'source': 'onboarding'}, +); + +if (result is PaywallPresentationResult) { + print('Paywall would be shown'); + print('Experiment ID: ${result.experiment.id}'); + print('Group ID: ${result.experiment.groupId}'); +} else if (result is HoldoutPresentationResult) { + print('User is in holdout group'); + print('Experiment ID: ${result.experiment.id}'); +} else if (result is NoAudienceMatchPresentationResult) { + print('No audience match'); +} else if (result is PlacementNotFoundPresentationResult) { + print('Placement not found'); +} else if (result is PaywallNotAvailablePresentationResult) { + print('Paywall not available'); +} +``` + +Using with switch expressions: +```dart +final result = await Superwall.shared.getPresentationResult('premium_feature'); + +switch (result) { + case PaywallPresentationResult(experiment: final exp): + print('Paywall would show for experiment ${exp.id}'); + case HoldoutPresentationResult(experiment: final exp): + print('User in holdout for experiment ${exp.id}'); + case NoAudienceMatchPresentationResult(): + print('No audience match'); + case PlacementNotFoundPresentationResult(): + print('Placement not found'); + case PaywallNotAvailablePresentationResult(): + print('Paywall not available'); +} +``` + +## Related +- [`registerPlacement()`](/flutter/sdk-reference/register) - Registers and presents a paywall +- [`PresentationResult`](/flutter/sdk-reference/PresentationResult) - The result type returned by this method diff --git a/content/docs/flutter/sdk-reference/index.mdx b/content/docs/flutter/sdk-reference/index.mdx index 130f1f2..78bef29 100644 --- a/content/docs/flutter/sdk-reference/index.mdx +++ b/content/docs/flutter/sdk-reference/index.mdx @@ -15,4 +15,4 @@ If you have feedback on any of our docs, please leave a rating and message at th If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-flutter/issues). - \ No newline at end of file + \ No newline at end of file diff --git a/content/docs/flutter/sdk-reference/overrideProductsByName.mdx b/content/docs/flutter/sdk-reference/overrideProductsByName.mdx new file mode 100644 index 0000000..d5a6e22 --- /dev/null +++ b/content/docs/flutter/sdk-reference/overrideProductsByName.mdx @@ -0,0 +1,104 @@ +--- +title: "overrideProductsByName" +description: "Globally override products on any paywall by product name." +--- + +## Purpose +Allows you to globally override products on any paywall that have a given name. The key is the product name in the paywall, and the value is the product identifier to replace it with. This is useful for A/B testing different products or dynamically changing products based on user segments. + +## Signature +```dart +// Setter +set overrideProductsByName(Map? overrideProducts) + +// Getter +Future?> getOverrideProductsByName() +``` + +## Parameters + +| Name | Type | Description | +|------|------|-------------| +| `overrideProducts` | `Map?` | A map where keys are product names in paywalls (e.g., `"primary"`, `"secondary"`) and values are the product identifiers to replace them with (e.g., `"com.example.premium_monthly"`). Pass `null` to clear all overrides. | + + +## Returns / State +- **Setter**: Sets the global product overrides. Changes take effect immediately for all future paywall presentations. +- **Getter**: Returns a `Future?>` containing the current override mapping, or `null` if no overrides are set. + +## Usage + +Setting product overrides: +```dart +// Override products globally +Superwall.shared.overrideProductsByName = { + 'primary': 'com.example.premium_monthly', + 'secondary': 'com.example.premium_annual', + 'tertiary': 'com.example.premium_lifetime', +}; + +// All paywalls will now use these product identifiers +// instead of the ones configured in the dashboard +``` + +Clearing overrides: +```dart +// Clear all overrides +Superwall.shared.overrideProductsByName = null; +``` + +Getting current overrides: +```dart +final overrides = await Superwall.shared.getOverrideProductsByName(); +if (overrides != null) { + print('Current overrides: $overrides'); +} else { + print('No overrides set'); +} +``` + +Dynamic overrides based on user segment: +```dart +void _setProductOverridesForUser(User user) { + if (user.isPremium) { + // Premium users get annual products + Superwall.shared.overrideProductsByName = { + 'primary': 'com.example.premium_annual', + }; + } else { + // Regular users get monthly products + Superwall.shared.overrideProductsByName = { + 'primary': 'com.example.premium_monthly', + }; + } +} +``` + +A/B testing different products: +```dart +void _setupProductABTest() { + final random = Random(); + if (random.nextBool()) { + // Variant A: Monthly product + Superwall.shared.overrideProductsByName = { + 'primary': 'com.example.premium_monthly', + }; + } else { + // Variant B: Annual product + Superwall.shared.overrideProductsByName = { + 'primary': 'com.example.premium_annual', + }; + } +} +``` + +## Notes + +- Overrides apply globally to all paywalls that use the specified product names +- Overrides take effect immediately for all future paywall presentations +- You can also set overrides per-paywall using [`PaywallOptions.overrideProductsByName`](/flutter/sdk-reference/PaywallOptions#overrideproductsbyname) +- Per-paywall overrides take precedence over global overrides + +## Related +- [`PaywallOptions.overrideProductsByName`](/flutter/sdk-reference/PaywallOptions) - Override products for a specific paywall +- [`PaywallOptions`](/flutter/sdk-reference/PaywallOptions) - Paywall configuration options From 2addcdd2ee2c96b1665648d3f704a0252ac9a75e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Nov 2025 21:27:58 +0000 Subject: [PATCH 2/2] docs(flutter): add missing APIs from 2.3.0-2.4.5 - Add CustomerInfo class and getCustomerInfo() method - Add IntegrationAttribute enum and setIntegrationAttribute/setIntegrationAttributes methods - Add Entitlements class and getEntitlements() method with byProductIds() - Update SuperwallDelegate with handleSuperwallDeepLink and customerInfoDidChange methods --- content/docs/flutter/meta.json | 7 ++ .../flutter/sdk-reference/CustomerInfo.mdx | 83 ++++++++++++++ .../flutter/sdk-reference/Entitlements.mdx | 100 ++++++++++++++++ .../sdk-reference/IntegrationAttribute.mdx | 107 ++++++++++++++++++ .../sdk-reference/SuperwallDelegate.mdx | 16 +++ .../flutter/sdk-reference/getCustomerInfo.mdx | 62 ++++++++++ .../flutter/sdk-reference/getEntitlements.mdx | 75 ++++++++++++ .../sdk-reference/setIntegrationAttribute.mdx | 69 +++++++++++ .../setIntegrationAttributes.mdx | 64 +++++++++++ 9 files changed, 583 insertions(+) create mode 100644 content/docs/flutter/sdk-reference/CustomerInfo.mdx create mode 100644 content/docs/flutter/sdk-reference/Entitlements.mdx create mode 100644 content/docs/flutter/sdk-reference/IntegrationAttribute.mdx create mode 100644 content/docs/flutter/sdk-reference/getCustomerInfo.mdx create mode 100644 content/docs/flutter/sdk-reference/getEntitlements.mdx create mode 100644 content/docs/flutter/sdk-reference/setIntegrationAttribute.mdx create mode 100644 content/docs/flutter/sdk-reference/setIntegrationAttributes.mdx diff --git a/content/docs/flutter/meta.json b/content/docs/flutter/meta.json index 9ac2571..071e606 100644 --- a/content/docs/flutter/meta.json +++ b/content/docs/flutter/meta.json @@ -31,14 +31,21 @@ "sdk-reference/setUserAttributes", "sdk-reference/getUserId", "sdk-reference/subscriptionStatus", + "sdk-reference/getCustomerInfo", + "sdk-reference/getEntitlements", "sdk-reference/consume", "sdk-reference/overrideProductsByName", + "sdk-reference/setIntegrationAttribute", + "sdk-reference/setIntegrationAttributes", "sdk-reference/SuperwallDelegate", "sdk-reference/PaywallPresentationHandler", "sdk-reference/SuperwallOptions", "sdk-reference/PaywallOptions", "sdk-reference/PurchaseController", "sdk-reference/PresentationResult", + "sdk-reference/CustomerInfo", + "sdk-reference/Entitlements", + "sdk-reference/IntegrationAttribute", "sdk-reference/handleDeepLink", "sdk-reference/advanced", diff --git a/content/docs/flutter/sdk-reference/CustomerInfo.mdx b/content/docs/flutter/sdk-reference/CustomerInfo.mdx new file mode 100644 index 0000000..1d97ae2 --- /dev/null +++ b/content/docs/flutter/sdk-reference/CustomerInfo.mdx @@ -0,0 +1,83 @@ +--- +title: "CustomerInfo" +description: "Contains the latest subscription and entitlement information about the customer." +--- + +## Purpose +Represents the complete customer information including all subscription transactions, non-subscription transactions, entitlements, and user identification. + +## Signature +```dart +class CustomerInfo { + final List subscriptions; + final List nonSubscriptions; + final List entitlements; + final String userId; +} +``` + +## Properties + + +| Property | Type | Description | +|----------|------|-------------| +| `subscriptions` | `List` | All subscription transactions the user has made. | +| `nonSubscriptions` | `List` | All non-subscription transactions (consumables and non-consumables) the user has made. | +| `entitlements` | `List` | All entitlements available to the user. | +| `userId` | `String` | The ID of the user. | + + +## Usage + +Getting customer info: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +// Access user ID +print('User ID: ${customerInfo.userId}'); + +// Check entitlements +final activeEntitlements = customerInfo.entitlements + .where((e) => e.isActive) + .toList(); + +// Access subscriptions +for (final subscription in customerInfo.subscriptions) { + if (subscription.isActive) { + print('Active subscription: ${subscription.productId}'); + } +} +``` + +Checking for specific entitlements: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +final hasPremium = customerInfo.entitlements.any( + (entitlement) => + entitlement.id == 'premium' && + entitlement.isActive, +); + +if (hasPremium) { + // User has premium access + showPremiumContent(); +} +``` + +Filtering active subscriptions: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +final activeSubscriptions = customerInfo.subscriptions + .where((sub) => sub.isActive && !sub.isRevoked) + .toList(); + +print('User has ${activeSubscriptions.length} active subscriptions'); +``` + +## Related +- [`getCustomerInfo()`](/flutter/sdk-reference/getCustomerInfo) - Method to retrieve customer info +- [`SubscriptionTransaction`](/flutter/sdk-reference/SubscriptionTransaction) - Subscription transaction details +- [`NonSubscriptionTransaction`](/flutter/sdk-reference/NonSubscriptionTransaction) - Non-subscription transaction details +- [`Entitlement`](/flutter/sdk-reference/Entitlement) - Entitlement information diff --git a/content/docs/flutter/sdk-reference/Entitlements.mdx b/content/docs/flutter/sdk-reference/Entitlements.mdx new file mode 100644 index 0000000..3638906 --- /dev/null +++ b/content/docs/flutter/sdk-reference/Entitlements.mdx @@ -0,0 +1,100 @@ +--- +title: "Entitlements" +description: "Container for all entitlements available to the user, organized by status." +--- + +## Purpose +Provides organized access to user entitlements with methods to filter and query them. Returned by [`getEntitlements()`](/flutter/sdk-reference/getEntitlements). + +## Signature +```dart +class Entitlements { + final Set active; + final Set inactive; + final Set all; + final Set web; + + Future> byProductIds(Set productIds); +} +``` + +## Properties + + +| Property | Type | Description | +|----------|------|-------------| +| `active` | `Set` | All active entitlements available to the user. | +| `inactive` | `Set` | All inactive entitlements. | +| `all` | `Set` | All entitlements (both active and inactive). | +| `web` | `Set` | Entitlements from web checkout. | + + +## Methods + +### byProductIds() + +Filters entitlements by product IDs. Returns all entitlements that contain any of the specified product IDs. + +**Signature:** +```dart +Future> byProductIds(Set productIds) +``` + +**Parameters:** +- `productIds` - A set of product identifiers to search for + +**Returns:** A future that resolves to a set of entitlements that contain any of the specified product IDs. + +## Usage + +Accessing different entitlement sets: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +// Check active entitlements +if (entitlements.active.isNotEmpty) { + print('User has ${entitlements.active.length} active entitlements'); +} + +// Check web checkout entitlements +if (entitlements.web.isNotEmpty) { + print('User has web checkout entitlements'); +} +``` + +Filtering by product IDs: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +// Find entitlements for specific products +final premiumEntitlements = await entitlements.byProductIds({ + 'premium_monthly', + 'premium_yearly', + 'premium_lifetime', +}); + +if (premiumEntitlements.isNotEmpty) { + print('User has premium access'); + for (final entitlement in premiumEntitlements) { + print('Premium entitlement: ${entitlement.id}'); + } +} +``` + +Checking for specific entitlement: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +final hasPro = entitlements.all.any( + (entitlement) => entitlement.id == 'pro' && entitlement.isActive, +); + +if (hasPro) { + // User has pro access + showProFeatures(); +} +``` + +## Related +- [`getEntitlements()`](/flutter/sdk-reference/getEntitlements) - Method to retrieve entitlements +- [`Entitlement`](/flutter/sdk-reference/Entitlement) - Individual entitlement information diff --git a/content/docs/flutter/sdk-reference/IntegrationAttribute.mdx b/content/docs/flutter/sdk-reference/IntegrationAttribute.mdx new file mode 100644 index 0000000..21bce6f --- /dev/null +++ b/content/docs/flutter/sdk-reference/IntegrationAttribute.mdx @@ -0,0 +1,107 @@ +--- +title: "IntegrationAttribute" +description: "Attributes for third-party integrations with Superwall." +--- + +## Purpose +Enumeration of integration attributes that allow you to sync user identifiers from your analytics and attribution providers with Superwall. This enables better user tracking and attribution across platforms. + +## Signature +```dart +enum IntegrationAttribute { + adjustId, + amplitudeDeviceId, + amplitudeUserId, + appsflyerId, + brazeAliasName, + brazeAliasLabel, + onesignalId, + fbAnonId, + firebaseAppInstanceId, + iterableUserId, + iterableCampaignId, + iterableTemplateId, + mixpanelDistinctId, + mparticleId, + clevertapId, + airshipChannelId, + kochavaDeviceId, + tenjinId, + posthogUserId, + customerioId; +} +``` + +## Values + + +| Value | Description | +|-------|-------------| +| `adjustId` | The unique Adjust identifier for the user. | +| `amplitudeDeviceId` | The Amplitude device identifier. | +| `amplitudeUserId` | The Amplitude user identifier. | +| `appsflyerId` | The unique Appsflyer identifier for the user. | +| `brazeAliasName` | The Braze `alias_name` in User Alias Object. | +| `brazeAliasLabel` | The Braze `alias_label` in User Alias Object. | +| `onesignalId` | The OneSignal Player identifier for the user. | +| `fbAnonId` | The Facebook Anonymous identifier for the user. | +| `firebaseAppInstanceId` | The Firebase instance identifier. | +| `iterableUserId` | The Iterable identifier for the user. | +| `iterableCampaignId` | The Iterable campaign identifier. | +| `iterableTemplateId` | The Iterable template identifier. | +| `mixpanelDistinctId` | The Mixpanel user identifier. | +| `mparticleId` | The unique mParticle user identifier (mpid). | +| `clevertapId` | The CleverTap user identifier. | +| `airshipChannelId` | The Airship channel identifier for the user. | +| `kochavaDeviceId` | The unique Kochava device identifier. | +| `tenjinId` | The Tenjin identifier. | +| `posthogUserId` | The PostHog User identifier. | +| `customerioId` | The Customer.io person's identifier (`id`). | + + +## Usage + +Setting a single integration attribute: +```dart +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.mixpanelDistinctId, + 'user_123', +); +``` + +Setting multiple integration attributes: +```dart +await Superwall.shared.setIntegrationAttributes({ + IntegrationAttribute.mixpanelDistinctId: 'user_123', + IntegrationAttribute.amplitudeUserId: 'amp_456', + IntegrationAttribute.adjustId: 'adjust_789', +}); +``` + +Removing an integration attribute: +```dart +// Set to null to remove +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.mixpanelDistinctId, + null, +); +``` + +Syncing with analytics providers: +```dart +void _syncAnalyticsIds() async { + // Get IDs from your analytics SDKs + final mixpanelId = await MixpanelSDK.getDistinctId(); + final amplitudeId = await AmplitudeSDK.getUserId(); + + // Sync with Superwall + await Superwall.shared.setIntegrationAttributes({ + IntegrationAttribute.mixpanelDistinctId: mixpanelId, + IntegrationAttribute.amplitudeUserId: amplitudeId, + }); +} +``` + +## Related +- [`setIntegrationAttribute()`](/flutter/sdk-reference/setIntegrationAttribute) - Set a single integration attribute +- [`setIntegrationAttributes()`](/flutter/sdk-reference/setIntegrationAttributes) - Set multiple integration attributes at once diff --git a/content/docs/flutter/sdk-reference/SuperwallDelegate.mdx b/content/docs/flutter/sdk-reference/SuperwallDelegate.mdx index 0c09746..9f1a0da 100644 --- a/content/docs/flutter/sdk-reference/SuperwallDelegate.mdx +++ b/content/docs/flutter/sdk-reference/SuperwallDelegate.mdx @@ -22,6 +22,8 @@ abstract class SuperwallDelegate { void didPresentPaywall(PaywallInfo paywallInfo); void paywallWillOpenURL(Uri url); void paywallWillOpenDeepLink(Uri url); + void handleSuperwallDeepLink(Uri fullURL, List pathComponents, Map queryParameters); + void customerInfoDidChange(CustomerInfo from, CustomerInfo to); } ``` @@ -68,6 +70,20 @@ class MySuperwallDelegate extends SuperwallDelegate { break; } } + + @override + void handleSuperwallDeepLink(Uri fullURL, List pathComponents, Map queryParameters) { + print('Superwall deep link: $fullURL'); + print('Path: $pathComponents'); + print('Query: $queryParameters'); + // Handle deep link navigation + } + + @override + void customerInfoDidChange(CustomerInfo from, CustomerInfo to) { + print('Customer info changed'); + // Sync with your backend, update UI, etc. + } } ``` diff --git a/content/docs/flutter/sdk-reference/getCustomerInfo.mdx b/content/docs/flutter/sdk-reference/getCustomerInfo.mdx new file mode 100644 index 0000000..157f176 --- /dev/null +++ b/content/docs/flutter/sdk-reference/getCustomerInfo.mdx @@ -0,0 +1,62 @@ +--- +title: "getCustomerInfo()" +description: "Gets the latest customer information including subscriptions, transactions, and entitlements." +--- + +## Purpose +Retrieves the most up-to-date customer information including subscription transactions, non-subscription transactions, entitlements, and user ID. This is useful for displaying subscription status, checking entitlements, or syncing with other services. + +## Signature +```dart +Future getCustomerInfo() +``` + +## Returns / State +Returns a `Future` containing: +- `subscriptions` - List of subscription transactions +- `nonSubscriptions` - List of non-subscription transactions (consumables, non-consumables) +- `entitlements` - List of all entitlements available to the user +- `userId` - The ID of the user + +## Usage + +Getting customer info: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +print('User ID: ${customerInfo.userId}'); +print('Active subscriptions: ${customerInfo.subscriptions.length}'); +print('Entitlements: ${customerInfo.entitlements.length}'); +``` + +Checking for specific entitlements: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +final hasPremium = customerInfo.entitlements.any( + (entitlement) => entitlement.id == 'premium' && entitlement.isActive, +); + +if (hasPremium) { + print('User has premium access'); +} +``` + +Accessing subscription transactions: +```dart +final customerInfo = await Superwall.shared.getCustomerInfo(); + +for (final subscription in customerInfo.subscriptions) { + print('Product: ${subscription.productId}'); + print('Active: ${subscription.isActive}'); + print('Will renew: ${subscription.willRenew}'); + if (subscription.expirationDate != null) { + print('Expires: ${subscription.expirationDate}'); + } +} +``` + +## Related +- [`CustomerInfo`](/flutter/sdk-reference/CustomerInfo) - The customer information class +- [`getEntitlements()`](/flutter/sdk-reference/getEntitlements) - Gets entitlements directly +- [`subscriptionStatus`](/flutter/sdk-reference/subscriptionStatus) - Stream of subscription status changes diff --git a/content/docs/flutter/sdk-reference/getEntitlements.mdx b/content/docs/flutter/sdk-reference/getEntitlements.mdx new file mode 100644 index 0000000..fd5edae --- /dev/null +++ b/content/docs/flutter/sdk-reference/getEntitlements.mdx @@ -0,0 +1,75 @@ +--- +title: "getEntitlements()" +description: "Gets all entitlements available to the user, organized by status." +--- + +## Purpose +Retrieves all entitlements available to the user, organized into active, inactive, all, and web entitlements. Also provides a method to filter entitlements by product IDs. + +## Signature +```dart +Future getEntitlements() +``` + +## Returns / State +Returns a `Future` containing: +- `active` - Set of active entitlements +- `inactive` - Set of inactive entitlements +- `all` - Set of all entitlements (active and inactive) +- `web` - Set of entitlements from web checkout +- `byProductIds(productIds)` - Method to filter entitlements by product IDs + +## Usage + +Getting all entitlements: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +print('Active: ${entitlements.active.length}'); +print('Inactive: ${entitlements.inactive.length}'); +print('Total: ${entitlements.all.length}'); +print('Web: ${entitlements.web.length}'); +``` + +Checking for specific entitlements: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +final hasPremium = entitlements.active.any( + (entitlement) => entitlement.id == 'premium', +); + +if (hasPremium) { + print('User has premium access'); +} +``` + +Filtering entitlements by product IDs: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +// Get entitlements that contain any of these product IDs +final filtered = await entitlements.byProductIds({ + 'premium_monthly', + 'premium_yearly', +}); + +print('Found ${filtered.length} entitlements for those products'); +``` + +Checking web checkout entitlements: +```dart +final entitlements = await Superwall.shared.getEntitlements(); + +if (entitlements.web.isNotEmpty) { + print('User has ${entitlements.web.length} web checkout entitlements'); + for (final entitlement in entitlements.web) { + print('Web entitlement: ${entitlement.id}'); + } +} +``` + +## Related +- [`Entitlements`](/flutter/sdk-reference/Entitlements) - The entitlements container class +- [`Entitlement`](/flutter/sdk-reference/Entitlement) - Individual entitlement information +- [`getCustomerInfo()`](/flutter/sdk-reference/getCustomerInfo) - Get customer info including entitlements diff --git a/content/docs/flutter/sdk-reference/setIntegrationAttribute.mdx b/content/docs/flutter/sdk-reference/setIntegrationAttribute.mdx new file mode 100644 index 0000000..f5ae99a --- /dev/null +++ b/content/docs/flutter/sdk-reference/setIntegrationAttribute.mdx @@ -0,0 +1,69 @@ +--- +title: "setIntegrationAttribute()" +description: "Sets a single attribute for third-party integrations." +--- + +## Purpose +Syncs a user identifier from an analytics or attribution provider with Superwall. This enables better user tracking and attribution across platforms. + +## Signature +```dart +Future setIntegrationAttribute( + IntegrationAttribute attribute, + String? value, +) +``` + +## Parameters + +| Name | Type | Description | +|------|------|-------------| +| `attribute` | `IntegrationAttribute` | The integration attribute key specifying the integration provider. | +| `value` | `String?` | The value to associate with the attribute. Pass `null` to remove the attribute. | + + +## Returns / State +Returns a `Future` that completes when the attribute is set. + +## Usage + +Setting an integration attribute: +```dart +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.mixpanelDistinctId, + 'user_123', +); +``` + +Removing an integration attribute: +```dart +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.mixpanelDistinctId, + null, +); +``` + +Syncing with multiple providers: +```dart +// Mixpanel +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.mixpanelDistinctId, + mixpanelUserId, +); + +// Amplitude +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.amplitudeUserId, + amplitudeUserId, +); + +// Adjust +await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.adjustId, + adjustId, +); +``` + +## Related +- [`setIntegrationAttributes()`](/flutter/sdk-reference/setIntegrationAttributes) - Set multiple attributes at once +- [`IntegrationAttribute`](/flutter/sdk-reference/IntegrationAttribute) - Available integration attribute types diff --git a/content/docs/flutter/sdk-reference/setIntegrationAttributes.mdx b/content/docs/flutter/sdk-reference/setIntegrationAttributes.mdx new file mode 100644 index 0000000..4778745 --- /dev/null +++ b/content/docs/flutter/sdk-reference/setIntegrationAttributes.mdx @@ -0,0 +1,64 @@ +--- +title: "setIntegrationAttributes()" +description: "Sets multiple attributes for third-party integrations at once." +--- + +## Purpose +Syncs multiple user identifiers from analytics and attribution providers with Superwall in a single call. This is more efficient than calling `setIntegrationAttribute()` multiple times. + +## Signature +```dart +Future setIntegrationAttributes( + Map attributes, +) +``` + +## Parameters + +| Name | Type | Description | +|------|------|-------------| +| `attributes` | `Map` | A map of integration attribute keys to their values. Pass `null` as a value to remove that attribute. | + + +## Returns / State +Returns a `Future` that completes when all attributes are set. + +## Usage + +Setting multiple integration attributes: +```dart +await Superwall.shared.setIntegrationAttributes({ + IntegrationAttribute.mixpanelDistinctId: 'user_123', + IntegrationAttribute.amplitudeUserId: 'amp_456', + IntegrationAttribute.adjustId: 'adjust_789', +}); +``` + +Setting and removing attributes in one call: +```dart +await Superwall.shared.setIntegrationAttributes({ + IntegrationAttribute.mixpanelDistinctId: 'user_123', + IntegrationAttribute.amplitudeUserId: 'amp_456', + IntegrationAttribute.adjustId: null, // Remove this attribute +}); +``` + +Syncing with all analytics providers: +```dart +void _syncAllAnalyticsIds() async { + // Collect IDs from all analytics SDKs + final analyticsIds = { + IntegrationAttribute.mixpanelDistinctId: await _getMixpanelId(), + IntegrationAttribute.amplitudeUserId: await _getAmplitudeId(), + IntegrationAttribute.adjustId: await _getAdjustId(), + IntegrationAttribute.appsflyerId: await _getAppsflyerId(), + }; + + // Sync all at once + await Superwall.shared.setIntegrationAttributes(analyticsIds); +} +``` + +## Related +- [`setIntegrationAttribute()`](/flutter/sdk-reference/setIntegrationAttribute) - Set a single integration attribute +- [`IntegrationAttribute`](/flutter/sdk-reference/IntegrationAttribute) - Available integration attribute types