diff --git a/content/docs/expo/sdk-reference/components/CustomPurchaseControllerProvider.mdx b/content/docs/expo/sdk-reference/components/CustomPurchaseControllerProvider.mdx index 401d47c..bb1a3a4 100644 --- a/content/docs/expo/sdk-reference/components/CustomPurchaseControllerProvider.mdx +++ b/content/docs/expo/sdk-reference/components/CustomPurchaseControllerProvider.mdx @@ -38,6 +38,29 @@ export default function App() { } ``` + +**Important:** The `onPurchase` and `onPurchaseRestore` callbacks communicate success or failure through how the Promise resolves: + +- **Promise resolves normally** → Superwall records a successful purchase (counts as a conversion) +- **Promise throws an error** → Superwall records a failed/cancelled purchase + +You **must** throw an error for any non-successful outcome (user cancelled, payment failed, etc.). If your purchase function returns a status like `'cancelled'` or `'error'`, you need to check it and throw: + +```tsx +onPurchase: async (params) => { + const result = await yourPurchaseFunction(params.productId); + + if (result !== 'success') { + throw new Error(`Purchase ${result}`); + } + + // Only reaches here on success +}, +``` + +**Why this matters:** If your callback resolves without throwing (even when the purchase failed), Superwall will incorrectly count it as a conversion. + + ## Props ### `controller` @@ -115,5 +138,4 @@ For a complete RevenueCat integration with error handling, subscription status s ## Notes - The provider must wrap your app at a level where both the Superwall SDK and your purchase logic can access it -- Purchase success/failure handling is automatic - you just need to perform the actual purchase -- **Important:** The `onPurchase` and `onPurchaseRestore` callbacks should not return any values. Success is indicated by the Promise resolving normally, and failure by throwing an error \ No newline at end of file +- Purchase success/failure handling is automatic - you just need to perform the actual purchase \ No newline at end of file diff --git a/content/docs/support/faq/can-i-pre-authenticate-users-on-subscription-management-page.mdx b/content/docs/support/faq/can-i-pre-authenticate-users-on-subscription-management-page.mdx new file mode 100644 index 0000000..bf38746 --- /dev/null +++ b/content/docs/support/faq/can-i-pre-authenticate-users-on-subscription-management-page.mdx @@ -0,0 +1,25 @@ +--- +title: "Can I pre-authenticate users on the subscription management page?" +--- + + +Short Answer +------------ + +No: for security reasons, users always need to verify their email by clicking a magic link sent to their inbox. + +Pre-filling the Email Field +--------------------------- + +While full pre-authentication isn't possible, you can pre-fill the email field by passing it as a query parameter: + +``` +https://{your-app}.superwall.app/manage?email=user@example.com +``` + +This way, when users open the subscription management page from within your app, their email will already be populated. They just need to tap "Continue" and then click the link in their inbox to access their subscription details. + +Why Magic Link Verification is Required +--------------------------------------- + +The subscription management page gives users access to sensitive account information and the ability to modify their subscription. Email verification via magic link ensures that only the actual account owner can access these controls, even if someone else has access to the device. diff --git a/content/docs/support/faq/how-do-i-migrate-my-existing-purchases-to-revenuecat.mdx b/content/docs/support/faq/how-do-i-migrate-my-existing-purchases-to-revenuecat.mdx new file mode 100644 index 0000000..cc5bd21 --- /dev/null +++ b/content/docs/support/faq/how-do-i-migrate-my-existing-purchases-to-revenuecat.mdx @@ -0,0 +1,36 @@ +--- +title: "How do I migrate my existing purchases to RevenueCat?" +--- + + +Overview +-------- + +If you're migrating to RevenueCat, Superwall can help export your existing user and purchase data to facilitate the transition. + +What We Can Export +------------------ + +* **User IDs**: Your Superwall app user identifiers + +* **Original Transaction IDs**: Apple's unique subscription identifiers + +Note: We don't have access to receipts or receipt-type metadata, but RevenueCat has historically accepted original transaction IDs for migration purposes. + +The Process +----------- + +1. **Open a support ticket with RevenueCat**: They'll provide specific requirements for the data import + +2. **Contact Superwall support**: Once RevenueCat confirms what they need, let us know and we'll coordinate the export + +3. **Receive your CSV**: We'll provide a CSV with `app_user_id` and `store_transaction_id` columns + +RevenueCat recommends excluding sandbox transactions if appropriate, as sandbox volume can be very large. + +Pricing +------- + +* **First 1,000 users:** Free + +* **Additional users:** $0.20 per exported subscription diff --git a/content/docs/support/faq/why-is-my-android-app-missing-historical-revenue-data.mdx b/content/docs/support/faq/why-is-my-android-app-missing-historical-revenue-data.mdx new file mode 100644 index 0000000..d39b755 --- /dev/null +++ b/content/docs/support/faq/why-is-my-android-app-missing-historical-revenue-data.mdx @@ -0,0 +1,31 @@ +--- +title: "Why is my Android app missing historical revenue data after setting up the Google Play integration?" +--- + + +The Issue +--------- + +After setting up the Google Play integration for your Android app, you may notice that historical subscriber data, ARR, and MRR from before the integration aren't showing up. This is different from iOS, where historical data appears after connecting App Store Connect. + +Why This Happens +---------------- + +This is due to a fundamental platform difference between Apple and Google: + +### iOS (App Store Connect) + +Apple provides a **Transaction History API** that allows Superwall to retrieve historical purchases retroactively. This is why your iOS app shows data from before the integration was set up. + +### Android (Google Play) + +Google Play **does not offer an equivalent API**. Their system only sends real-time notifications going forward from when the integration is configured. There is no way to pull historical transaction data. + +What You Can Expect +------------------- + +* This is a Google platform limitation, not something Superwall can work around + +* All new Android subscription events from the integration point forward will be tracked correctly + +* Your metrics will become more complete over time as new events come in diff --git a/content/docs/support/faq/why-is-my-transaction-failure-rate-high.mdx b/content/docs/support/faq/why-is-my-transaction-failure-rate-high.mdx new file mode 100644 index 0000000..a6504dd --- /dev/null +++ b/content/docs/support/faq/why-is-my-transaction-failure-rate-high.mdx @@ -0,0 +1,45 @@ +--- +title: "Why is my transaction failure rate high?" +--- + + +What is a "Failed Checkout"? +---------------------------- + +A failed checkout occurs when a user taps to purchase, the payment sheet appears (Apple Pay or Google Pay), but the payment system returns an error before the transaction completes. + +Common Causes +------------- + +Failed checkouts are typically caused by: + +* **Declined payment methods**: Insufficient funds, expired cards, or invalid payment details + +* **Fraud prevention**: Apple or Google's systems blocking suspicious transactions + +* **Network issues**: Connectivity problems during the payment flow + +* **User cancellation**: User dismissing the payment sheet after it appears + + +What's a Normal Failure Rate? +----------------------------- + +A transaction failure rate of **5-6%** is within industry standards. Some variance is expected depending on your audience demographics and geographic distribution. + +What You Can and Can't Control +------------------------------ + +### Can't control + +These failures happen entirely within Apple's or Google's payment infrastructure, between the user and their payment provider. Neither Superwall nor your app can influence these outcomes. + +### Can control + +While you can't prevent payment-side failures, you can optimize: + +* **Paywall UX**: Clear pricing and value proposition + +* **Audience targeting**: Showing paywalls to users more likely to convert + +* **Timing**: Presenting offers at optimal moments in the user journey diff --git a/content/docs/support/troubleshooting/troubleshooting-pending-trials-not-converting.mdx b/content/docs/support/troubleshooting/troubleshooting-pending-trials-not-converting.mdx new file mode 100644 index 0000000..b403407 --- /dev/null +++ b/content/docs/support/troubleshooting/troubleshooting-pending-trials-not-converting.mdx @@ -0,0 +1,28 @@ +--- +title: "Why are my trials still showing as pending after they should have converted?" +--- + +Understanding Pending Trials +---------------------------- + +If you're seeing trials that remain in "pending" status long after the trial period should have ended, this is usually expected behavior related to how Apple handles billing. + +Common Causes +------------- + +### Billing Retry Period + +When a user has a billing issue (e.g., expired card, insufficient funds), Apple doesn't immediately cancel the subscription. Instead, Apple will **retry billing for up to 16 days**. During this entire period, the trial remains in "pending" status in Superwall. + +### Billing Grace Period + +Your billing grace period setting in App Store Connect affects how long users stay in pending status. This is configurable and can be tuned based on your preferences. + +What You Can Do +--------------- + +* **Check App Store Connect** — Review your billing grace period settings and adjust if needed + +* **Expect some delay** — It's normal to see a significant number of pending trials due to billing retries + +* **Wait for resolution** — Most pending trials will resolve within 16 days as either converted or cancelled