From bb71ea144f4935c633a8abefa79cc086fa321119 Mon Sep 17 00:00:00 2001 From: Armin Dervisagic Date: Mon, 15 Dec 2025 10:07:19 +0100 Subject: [PATCH] Added support/troubleshooting and support/faq articles --- ...ate-from-another-provider-to-superwall.mdx | 50 ++++++ ...on-status-active-but-no-dashboard-data.mdx | 67 ++++++++ ...-paywall-not-updating-after-publishing.mdx | 156 ++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 content/docs/support/faq/how-to-migrate-from-another-provider-to-superwall.mdx create mode 100644 content/docs/support/troubleshooting/subscription-status-active-but-no-dashboard-data.mdx create mode 100644 content/docs/support/troubleshooting/why-is-my-paywall-not-updating-after-publishing.mdx diff --git a/content/docs/support/faq/how-to-migrate-from-another-provider-to-superwall.mdx b/content/docs/support/faq/how-to-migrate-from-another-provider-to-superwall.mdx new file mode 100644 index 0000000..f4b50c0 --- /dev/null +++ b/content/docs/support/faq/how-to-migrate-from-another-provider-to-superwall.mdx @@ -0,0 +1,50 @@ +--- +title: "How do I migrate to Superwall from another provider?" +description: "Guide for migrating from Adapty, Qonversion, Glassfy, or other subscription SDKs to Superwall" +--- + +# How do I migrate to Superwall from another subscription provider? + +If you're currently using a subscription management provider like Adapty, Qonversion, Glassfy, or another SDK and want to migrate to Superwall, here's what you need to know. + +## Will My Existing Subscribers Keep Their Access? + +**Yes.** Superwall reads subscription status directly from the device's App Store (iOS) or Google Play (Android) records. This means: + +- Existing subscribers are automatically recognized when you switch SDKs +- No manual migration of subscription data is required +- Users won't experience any interruption to their access + +When a user opens your app with the new Superwall SDK, their active subscriptions are detected automatically, regardless of which SDK was used to originally make the purchase. + +## What Gets Migrated Automatically + +| Data | Migrated? | +|------|-----------| +| Active subscription status | ✅ Yes - read directly from the device | +| Entitlement access | ✅ Yes - based on active subscriptions | +| Cross-device sync (same Apple ID/Google account) | ✅ Yes | + +## What Does NOT Migrate + +| Data | Migrated? | +|------|-----------| +| Historical analytics and metrics | ❌ No | +| Paywall designs and configurations | ❌ No - must be recreated in Superwall | +| A/B test history and experiment data | ❌ No | +| Custom user attributes from previous SDK | ❌ No - must be re-set via Superwall SDK | + +## Migration Steps + +1. Remove your current subscription SDK from your project +2. Follow the [Superwall installation guide](/docs/getting-started-with-our-sdks) for your platform + +## Troubleshooting + +### Subscription status not detected + +If an existing subscriber isn't being recognized: + +1. Have them tap "Restore Purchases" on any paywall +2. Ensure they're signed into the same App Store/Google Play account used for the original purchase +3. Check that the subscription hasn't expired diff --git a/content/docs/support/troubleshooting/subscription-status-active-but-no-dashboard-data.mdx b/content/docs/support/troubleshooting/subscription-status-active-but-no-dashboard-data.mdx new file mode 100644 index 0000000..31d5c71 --- /dev/null +++ b/content/docs/support/troubleshooting/subscription-status-active-but-no-dashboard-data.mdx @@ -0,0 +1,67 @@ +--- +title: "Why does my user show active subscription but no data in the dashboard?" +description: "Understanding why a user may have an active subscription on device but no entitlements, Apple events, or webhooks in the Superwall dashboard" +--- + +## Understanding How Superwall Tracks Subscriptions + +Superwall uses two different sources of truth for subscription data: + +### 1. On-Device Subscription Status (SDK) + +The SDK determines subscription status by reading the **local Apple receipt** directly from StoreKit. This receipt is tied to the user's **Apple ID**, not their Superwall user ID. + +If there's a valid subscription receipt on the device, the SDK will report `subscriptionStatus = active`, regardless of which Superwall user ID is currently active. + +### 2. Dashboard Attribution (Server-Side) + +The dashboard displays subscription data (entitlements, Apple server events, webhooks, receipts) that is attributed to a specific **Superwall user ID**. This attribution happens at the time of purchase. Whichever user ID was active when the transaction occurred is the one that gets linked to the subscription data. + +## The Most Common Cause + +When you see an active subscription on device but nothing in the dashboard, it almost always means: + +**The subscription was purchased under a different Superwall user ID than the one you're currently looking at.** + +This can happen when a user: + +- Reinstalls the app (generates a new anonymous user ID) +- Logs out and back in (may generate a new user ID depending on your implementation) +- Switches accounts +- Had their identity reset for any reason + +The subscription remains valid because Apple validates it against the user's Apple ID. But all the purchase events, webhooks, and server notifications are attributed to the **original** user ID that was active at purchase time. + +## Example Scenario + +1. User installs your app and gets assigned anonymous user ID `abc-123` +2. User purchases a subscription. All events are attributed to `abc-123` +3. User deletes and reinstalls the app +4. User gets assigned a new anonymous user ID `xyz-789` +5. The subscription is still valid (same Apple ID), so the SDK shows `active` +6. But the dashboard shows nothing for `xyz-789` because the subscription belongs to `abc-123` + +## How to Verify This + +If you suspect this is happening: + +1. Check the "Customer Info" section in the dashboard for the user. If it shows subscription status as active but no entitlements, this confirms the SDK is reading a valid receipt +2. The subscription data exists, it's just linked to a different user ID +3. If you have access to your server logs or Apple's App Store Connect, you can try to find the original transaction and trace it back to the original user ID + +## How to Prevent This + +To maintain consistent attribution across user sessions: + +- Call `Superwall.shared.identify(userId:)` with a stable user ID from your own authentication system as early as possible, ideally before any purchases occur +- Use the same user ID consistently across reinstalls and devices +- If your app supports account creation, identify users immediately after they sign up or log in + +## Key Takeaways + +- **Active subscription + no dashboard data = purchased under a different user ID** +- The subscription is valid and working correctly +- This is expected behavior, not a Superwall bug +- The SDK uses the Apple receipt (tied to Apple ID) for access control +- The dashboard uses attribution data (tied to Superwall user ID) for reporting +- These are intentionally separate to ensure users never lose access to their purchases diff --git a/content/docs/support/troubleshooting/why-is-my-paywall-not-updating-after-publishing.mdx b/content/docs/support/troubleshooting/why-is-my-paywall-not-updating-after-publishing.mdx new file mode 100644 index 0000000..8fadeb6 --- /dev/null +++ b/content/docs/support/troubleshooting/why-is-my-paywall-not-updating-after-publishing.mdx @@ -0,0 +1,156 @@ +--- +title: "Why is my paywall not updating after publishing?" +description: "Troubleshoot why users may still see an outdated paywall after you've made and published updates in the Superwall dashboard" +--- + +## Quick Checklist + +Before diving into detailed troubleshooting, verify these common causes: + +- [ ] Have you **published** the paywall after making changes? +- [ ] Is the user **assigned to a different paywall** in an A/B test? +- [ ] Are you using **conditional visibility** (e.g., `hasIntroductoryOffer`) that shows different content? +- [ ] Has the user's **trial eligibility** changed, showing a different UI state? + +--- + +## Step 1: Verify the Paywall is Published + +Changes made in the paywall editor are saved locally but not live until published. + +**To check:** +1. Open the paywall in the editor +2. Look for the **Publish** button in the top-right +3. If it's clickable, your changes haven't been published yet + +**Note:** Publishing a paywall doesn't automatically update users who have already been assigned to it in an experiment. + +--- + +## Step 2: Check Campaign and Experiment Setup + +### Multiple Paywalls in a Campaign + +If your campaign has multiple paywalls (an A/B test), users are randomly assigned to one variant. The user seeing an "outdated" paywall may simply be assigned to a different variant than the one you updated. + +**To check:** +1. Go to **Campaigns** → Select your campaign +2. Look at the **Paywalls** tab for the relevant audience +3. Verify which paywalls are active and their distribution percentages + +### Sticky Assignments + +**Important:** Superwall assignments are "sticky." Once a user is assigned to a paywall variant, they continue seeing that same paywall regardless of: +- Changes you make to presentation percentages +- Updates you publish to other paywalls +- App reinstalls or calling `Superwall.reset()` + +This is by design. It ensures experiment integrity and allows you to keep existing users on an old pricing while testing new pricing with new users. + +--- + +## Step 3: Check Conditional Visibility and Dynamic Values + +Paywalls often use **dynamic values** to show different content based on conditions. The most common scenario is **trial eligibility**. + +### Trial Eligibility (`products.hasIntroductoryOffer`) + +If your paywall has components with visibility controlled by `products.hasIntroductoryOffer`: +- **True:** User is eligible for a free trial/intro offer +- **False:** User has already used their trial (or the product has no trial) + +**Common issue:** Apple App Store reviewers often test with accounts that have already used trials, so `hasIntroductoryOffer` is `false` for them, showing different UI than you expect. + +**To check in the editor:** +1. Open your paywall in the editor +2. Click **Variables** in the floating toolbar +3. Toggle `products.hasIntroductoryOffer` between true/false +4. Observe which components appear/disappear + +### Other Dynamic Conditions + +Check if any components have visibility rules based on: +- Selected product index +- Device type +- User attributes +- Custom parameters + +Look for components that have the **gear icon** indicating dynamic values are set. + +--- + +## Step 4: Verify Products Are Correctly Configured + +### Product Approval Status + +Products must be approved in App Store Connect before they can be properly displayed: +- Products in "Waiting for Review" may not load correctly +- Sandbox testing uses different product states than production + +**To check:** +1. Go to App Store Connect → Your App → Subscriptions +2. Verify all products show "Ready to Submit" or "Approved" + +### Product Assignment on Paywall + +Ensure the correct products are assigned to your paywall: +1. Open the paywall in the editor +2. Check the **Products** section on the left sidebar +3. Verify the intended products are selected as Primary, Secondary, etc. + +--- + +## Step 5: Understand Caching Behavior + +### Server-Side Caching + +Superwall's static configuration is cached by CDN for up to **1 hour**. After publishing changes: +- New users get the update immediately (fresh cache) +- Existing users may see cached content for up to 1 hour + +### Device-Side Caching + +If your paywall has **Cache on Device** enabled in settings: +- The SDK stores the paywall locally for faster presentation +- Reinstalling the app clears this cache +- `Superwall.reset()` clears on-device data but NOT server-side assignments + +--- + +## Step 6: Testing Checklist + +When testing paywall updates, follow this process: + +### For Fresh Testing +1. Wait a few minutes for cache propagation +2. Use a **new user ID** or test account +3. Delete and reinstall the app +4. Trigger the placement that shows the paywall + +### For App Store Review +1. Remember reviewers may not be eligible for trials (trial already used) +2. Test your paywall with `hasIntroductoryOffer = false` in the editor +3. Ensure all UI states look correct for non-trial-eligible users + +--- + +## Common Scenarios and Solutions + +| Scenario | Likely Cause | Solution | +|----------|--------------|----------| +| User sees old paywall copy | Sticky assignment to old variant | Wait for new users or use new test account | +| User sees different products | Assigned to different A/B variant | Check which variant user is assigned to | +| Trial text showing when user isn't eligible | `hasIntroductoryOffer` conditional visibility | Check dynamic values on text components | +| Non-trial text showing for trial-eligible user | Same as above, inverted | Verify conditional logic in editor | +| Changes not visible after publishing | CDN cache or device cache | Wait up to 1 hour, or reinstall app | +| App Store reviewer sees wrong content | Reviewer's trial eligibility differs | Design for both trial/non-trial states | + +--- + +## Related Documentation + +- [Publishing Paywalls](https://superwall.com/docs/dashboard/dashboard-creating-paywalls/paywall-editor-publishing) +- [A/B Testing and Experiments](https://superwall.com/docs/campaigns/campaigns-starting-an-experiment) +- [Dynamic Values](https://superwall.com/docs/dashboard/dashboard-creating-paywalls/paywall-editor-dynamic-values) +- [Variables Reference](https://superwall.com/docs/dashboard/dashboard-creating-paywalls/paywall-editor-variables) +- [Campaign Audiences](https://superwall.com/docs/campaigns/campaigns-audience)