Post-Checkout Redirecting
Learn how to handle users redirecting back to your app after a web purchase.
After a user completes a web purchase, Superwall needs to redirect them back to your app. You can configure this behavior in two ways:
Post-Purchase Behavior Modes
You can configure how users are redirected after checkout in your Application Settings:
Redeem Mode (Default)
Superwall manages the entire redemption experience:
- Users are automatically deep linked to your app with a redemption code
- Fallback to App Store/Play Store if the app isn't installed
- Redemption emails are sent automatically
- The SDK handles redemption via delegate methods (detailed below)
This is the recommended mode for most apps.
Redirect Mode
Redirect users to your own custom URL with purchase information:
- When to use: You want to show a custom success page, perform additional actions before redemption, or have your own deep linking infrastructure
- What you receive: Purchase data is passed as query parameters to your URL
Query Parameters Included:
app_user_id- The user's identifier from your appemail- User's email addressstripe_subscription_id- The Stripe subscription ID- Any custom placement parameters you set
Example:
https://yourapp.com/success?
app_user_id=user_123&
email=user@example.com&
stripe_subscription_id=sub_1234567890&
campaign_id=summer_saleYou'll need to implement your own logic to handle the redirect and deep link users into your app.
Setting Up Deep Links
Whether you're showing a checkout page in Safari or using the In-App Browser, the Superwall SDK relies on deep links to redirect back to your app.
Prerequisites
If you're not using Superwall to handle purchases, then you'll need to follow extra steps to redeem the web purchase in your app.
Handling Redemption (Redeem Mode)
When using Redeem mode (the default), handle the user experience when they're redirected back to your app using SuperwallDelegate methods:
willRedeemLink
When your app opens via the deep link, we will call the delegate method willRedeemLink() before making a network call to redeem the code.
At this point, you might wish to display a loading indicator in your app so the user knows that the purchase is being redeemed.
func willRedeemLink() {
ToastView.show(message: "Activating...", showActivityIndicator: true)
}To present your own loading UI on top of the paywall, you can access the view controller of the paywall via Superwall.shared.presentedViewController. You can manually dismiss the paywall here, but note that the completion block of the original register call won't be triggered. The paywall will be dismissed automatically when the didRedeemLink method is called.
didRedeemLink
After receiving a response from the network, we will call didRedeemLink(result:) with the result of redeeming the code. This is an enum that has the following cases:
success(code: String, redemptionInfo: RedemptionInfo): The redemption succeeded andredemptionInfocontains information about the redeemed code.error(code: String, error: ErrorInfo): An error occurred while redeeming. You can check the error message via theerrorparameter.expiredCode(code: String, expired: ExpiredCodeInfo): The code expired andExpiredCodeInfocontains information about whether a redemption email has been resent and an optional obfuscated email address that the redemption email was sent to.invalidCode(code: String): The code that was redeemed was invalid.expiredSubscription(code: String, redemptionInfo: RedemptionInfo): The subscription that the code redeemed has expired.
On network failure, the SDK will retry up to 6 times before returning an error RedemptionResult in didRedeemLink(result:).
Here, you should remove any loading UI you added in willRedeemLink and show a message to the user based on the result. If a paywall is presented, it will be dismissed automatically.
func didRedeemLink(result: RedemptionResult) {
switch result {
case .expiredCode(let code, let expiredInfo):
ToastView.show(message: "Expired Link", systemImageName: "exclamationmark.square.fill")
print("[!] code expired", code, expiredInfo)
break
case .error(let code, let error):
ToastView.show(message: error.message, systemImageName: "exclamationmark.square.fill")
print("[!] error", code, error)
break
case .expiredSubscription(let code, let redemptionInfo):
ToastView.show(message: "Expired Subscription", systemImageName: "exclamationmark.square.fill")
print("[!] expired subscription", code, redemptionInfo)
break
case .invalidCode(let code):
ToastView.show(message: "Invalid Link", systemImageName: "exclamationmark.square.fill")
print("[!] invalid code", code)
break
case .success(_, let redemptionInfo):
if let email = redemptionInfo.purchaserInfo.email {
Superwall.shared.setUserAttributes(["email": email])
ToastView.show(message: email, systemImageName: "person.circle.fill")
}
else {
ToastView.show(message: "Welcome!", systemImageName: "person.circle.fill")
}
break
}
}How is this guide?