Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Redirect users to your own custom URL with purchase information:
**Query Parameters Included**:
- `app_user_id` - The user's identifier from your app
- `email` - User's email address
- `stripe_subscription_id` - The Stripe subscription ID
- `stripe_subscription_id` - The Stripe subscription ID, or the Stripe Checkout session ID for one-time purchases
- Any custom placement parameters you set

**Example**:
Expand Down
4 changes: 4 additions & 0 deletions content/docs/android/guides/web-checkout/using-revenuecat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ If you're using RevenueCat, you'll need to follow [steps 1 to 4 in their guide](
associate the RevenueCat customer with the Stripe subscription IDs returned from redeeming the code. You can do this by extracting the ids from the `RedemptionResult` and sending them to RevenueCat's API
by using the `didRedeemLink(result:)` delegate method:

<Warning>
This flow is for Stripe subscriptions. Stripe one-time purchases can return Stripe Checkout session IDs through the same legacy `stripeSubscriptionIds` field, but those IDs are not Stripe subscription IDs. Handle one-time purchases with Superwall entitlements or your own backend instead of sending those IDs to RevenueCat's Stripe subscription endpoint.
</Warning>

```kotlin
import com.revenuecat.purchases.Purchases
import com.superwall.sdk.Superwall
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Redirect users to your own custom URL with purchase information:
},
stripe_subscription_id: {
type: "string",
description: "Stripe subscription ID.",
description: "Stripe subscription ID, or Stripe Checkout session ID for one-time purchases.",
},
custom_parameters: {
type: "Record<string, string>",
Expand Down
4 changes: 4 additions & 0 deletions content/docs/expo/guides/web-checkout/using-revenuecat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ If you're using RevenueCat, you'll need to follow [steps 1 to 4 in their guide](
associate the RevenueCat customer with the Stripe subscription IDs returned from redeeming the code. You can do this by extracting the ids from the `RedemptionResult` and sending them to RevenueCat's API
by using the `didRedeemLink(result)` delegate method:

<Warning>
This flow is for Stripe subscriptions. Stripe one-time purchases can return Stripe Checkout session IDs through the same legacy `stripeSubscriptionIds` field, but those IDs are not Stripe subscription IDs. Handle one-time purchases with Superwall entitlements or your own backend instead of sending those IDs to RevenueCat's Stripe subscription endpoint.
</Warning>

```typescript
import { SuperwallDelegate, RedemptionResult } from 'expo-superwall/compat';
import Purchases from 'react-native-purchases';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Redirect users to your own custom URL with purchase information:
**Query Parameters Included**:
- `app_user_id` - The user's identifier from your app
- `email` - User's email address
- `stripe_subscription_id` - The Stripe subscription ID
- `stripe_subscription_id` - The Stripe subscription ID, or the Stripe Checkout session ID for one-time purchases
- Any custom placement parameters you set

**Example**:
Expand Down
4 changes: 4 additions & 0 deletions content/docs/flutter/guides/web-checkout/using-revenuecat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ If you're using RevenueCat, you'll need to follow [steps 1 to 4 in their guide](
associate the RevenueCat customer with the Stripe subscription IDs returned from redeeming the code. You can do this by extracting the ids from the `RedemptionResult` and sending them to RevenueCat's API
by using the `didRedeemLink()` delegate method:

<Warning>
This flow is for Stripe subscriptions. Stripe one-time purchases can return Stripe Checkout session IDs through the same legacy `stripeSubscriptionIds` field, but those IDs are not Stripe subscription IDs. Handle one-time purchases with Superwall entitlements or your own backend instead of sending those IDs to RevenueCat's Stripe subscription endpoint.
</Warning>

```dart
import 'package:superwallkit_flutter/superwallkit_flutter.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
Expand Down
Binary file added content/docs/images/stripe_otp_import.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/docs/images/stripe_otp_product.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ func didRedeemLink(result: RedemptionResult) {
// Get the customer's email
let email = redemptionInfo.purchaserInfo.email

// Get the Stripe customer ID and subscription IDs
// Get the Stripe customer ID and Stripe purchase identifiers
if case let .stripe(customerId, subscriptionIds) = redemptionInfo.purchaserInfo.storeIdentifiers {
print("Stripe Customer ID: \(customerId)")
print("Subscription IDs: \(subscriptionIds)")
print("Stripe purchase IDs: \(subscriptionIds)")

// Send to your backend or analytics
sendToBackend(
Expand All @@ -37,6 +37,10 @@ func didRedeemLink(result: RedemptionResult) {
}
```

<Note>
The `subscriptionIds` value keeps its legacy name for compatibility. For Stripe subscriptions, it contains `sub_` IDs. For Stripe one-time purchases, it can contain Stripe Checkout session IDs.
</Note>

### What happens if the user kills the app during checkout?

If a user completes the Stripe checkout but terminates the app before returning, the `didRedeemLink(result:)` callback will not fire. However, their purchase is not lost.
Expand All @@ -47,20 +51,21 @@ If a user completes the Stripe checkout but terminates the app before returning,

2. **Plan management page**: Users can visit `https://{yoursubdomain}.superwall.app/manage`, enter their email, and receive a new redemption link.

3. **Automatic entitlement sync**: The SDK polls for web entitlements when the app enters foreground, so subscription status updates automatically. However, this sync only updates entitlements and does not trigger `didRedeemLink`, meaning you will not receive the Stripe customer ID or email through this path.
3. **Automatic entitlement sync**: The SDK polls for web entitlements when the app enters foreground, so subscription and entitlement status updates automatically. However, this sync only updates access and does not trigger `didRedeemLink`, meaning you will not receive the Stripe customer ID or email through this path.

<Warning>
To programmatically receive the Stripe customer ID and email, the user must tap a redemption link (either from the automatic email or the manage page).
</Warning>

### Stripe metadata

Superwall automatically includes your app user ID in the Stripe checkout session and subscription metadata. The key `_sw_app_user_id` contains the user ID you set via `Superwall.shared.identify(userId:)`.
Superwall automatically includes your app user ID in Stripe checkout metadata. For subscriptions, it is also included in subscription metadata. The key `_sw_app_user_id` contains the user ID you set via `Superwall.shared.identify(userId:)`.

This allows you to correlate Stripe subscriptions with your users directly in Stripe or through webhooks.
This allows you to correlate Stripe purchases with your users directly in Stripe or through webhooks.

## Related

- [Post-Checkout Redirecting](/sdk/guides/web-checkout/post-checkout-redirecting)
- [Stripe One-Time Purchases](/web-checkout/web-checkout-stripe-one-time-purchases)
- [How do I disable the activation link email for web checkout?](/support/web-checkout/3969573187-how-do-i-disable-the-activation-link-email-for-web-checkout)
- [Web Checkout FAQ](/web-checkout/web-checkout-faq)
17 changes: 9 additions & 8 deletions content/docs/web-checkout/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Overview"
description: "Let customers purchase products online via Stripe, then link them to your iOS app with one seamless flow. No authentication required."
---

Superwall's web checkout integration makes it easy to set up purchasing funnels for your app via the web. Web checkout is powered by Stripe. Once an online purchase is complete, the customer will be redirected back to your app with a deep link that can be used to unlock content or features in your app via any associated [entitlement](/dashboard/products#entitlements).
Superwall's web checkout integration makes it easy to set up purchasing funnels for your app via the web. Web checkout is powered by Stripe. Once an online purchase is complete, the customer will be redirected back to your app with a deep link that can be used to unlock content or features in your app via any associated [entitlement](/dashboard/products#entitlements). Web checkout supports subscriptions and Stripe one-time purchases.

Web checkout requires the Superwall iOS SDK 4.2.0 or later.

Expand Down Expand Up @@ -35,7 +35,7 @@ Refer to the individual pages below to get started, but for a quick, high-level
8. For Redeem mode: _On the device that they downloaded the app_, they click the redemption link.
9. Your iOS app is opened via a deep link (which means it must be set up with Superwall deep links, [docs here](/sdk/quickstart/in-app-paywall-previews)).
10. In the `SuperwallDelegate`, `willRedeemLink()` is called, and then once it's fetched - `didRedeemLink(result:)` is called with the result of the redemption.
11. Finally, this user's account and details are managed via a link they find in their [email receipt or by visiting a URL manually](/web-checkout/web-checkout-managing-memberships).
11. Finally, this user's account and purchase details are managed via a link they find in their [email receipt or by visiting a URL manually](/web-checkout/web-checkout-managing-memberships).

## Getting setup

Expand All @@ -44,23 +44,24 @@ Before you start, you'll need to have a Superwall account and a Stripe account.
1. **[Creating an app](/web-checkout/web-checkout-creating-an-app):** First, you'll add a Web Checkout app to an existing project within Superwall.
2. **[Stripe setup](/web-checkout/web-checkout-configuring-stripe-keys-and-settings):** Install the [Superwall Stripe app](https://marketplace.stripe.com/apps/superwall) for automatic configuration.
3. **[Managing products](/web-checkout/web-checkout-adding-a-stripe-product):** Create or import products to add to your web paywalls.
4. **[Stripe one-time purchases](/web-checkout/web-checkout-stripe-one-time-purchases):** Sell lifetime access, credit packs or other one-time products with Stripe.

### Creating paywalls and campaigns

4. **[Presenting paywalls](/web-checkout/web-checkout-creating-campaigns-to-show-paywalls):** Set up a campaign, create some placements and add paywalls to begin showing them to customers.
5. **[Presenting paywalls](/web-checkout/web-checkout-creating-campaigns-to-show-paywalls):** Set up a campaign, create some placements and add paywalls to begin showing them to customers.

### Associating entitlements to your iOS apps

5. **[Linking purchases to your iOS app](/sdk/guides/web-checkout/linking-membership-to-iOS-app):** Once a purchase occurs, the user will be prompted to download your app and click on a redemption link.
6. **[Managing memberships](/web-checkout/web-checkout-managing-memberships):** Users can cancel, update or manage their memberships via Stripe.
6. **[Linking purchases to your iOS app](/sdk/guides/web-checkout/linking-membership-to-iOS-app):** Once a purchase occurs, the user will be prompted to download your app and click on a redemption link.
7. **[Managing purchases](/web-checkout/web-checkout-managing-memberships):** Users can restore purchases, manage subscriptions, update payment methods and view billing history.

### Testing purchases

7. **[Testing purchases](/web-checkout/web-checkout-testing-purchases):** Test your web checkout flow with test purchases.
8. **[Testing purchases](/web-checkout/web-checkout-testing-purchases):** Test your web checkout flow with test purchases.

### App to Web

8. **[App to Web Checkout](/web-checkout/web-checkout-direct-stripe-checkout):** For customers in the United States, you can offer Stripe products directly from your iOS paywalls.
9. **[App to Web Checkout](/web-checkout/web-checkout-direct-stripe-checkout):** For customers in the United States, you can offer Stripe products directly from your iOS paywalls.

## Troubleshooting
If a user has issues accessing their subscription in your app after paying via web checkout, direct them to your plan management page to retrieve their subscription link or manage billing. For example: `http://yourapp.superwall.app/manage`
If a user has issues accessing their purchase in your app after paying via web checkout, direct them to your plan management page to retrieve their redemption link or manage billing. For example: `http://yourapp.superwall.app/manage`
1 change: 1 addition & 0 deletions content/docs/web-checkout/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"web-checkout-creating-an-app",
"web-checkout-configuring-stripe-keys-and-settings",
"web-checkout-adding-a-stripe-product",
"web-checkout-stripe-one-time-purchases",
"web-checkout-creating-campaigns-to-show-paywalls",

"---Implementation---",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ From there, fill in all of the fields presented to you in Stripe:
2. **Description:** A description of the product, this will show up in checkout.
3. **Image:** An image representing the product, this will show up in checkout. Optional.
4. **Product tax code:** The tax code classification for the product. Refer to your territories tax codes for more information.
5. **Recurring vs One-off:** For subscriptions, choose "Recurring", whereas one time purchases or consumables should be "one-off" products.
5. **Recurring vs One-off:** For subscriptions, choose "Recurring". For lifetime access, credit packs or other consumables, choose "One-off".
6. **Amount:** The price of your product, and what it will renew at if it's recurring.
7. **Billing period:** The billing period for the product, i.e. "Monthly", "Yearly", etc.

Expand All @@ -65,6 +65,10 @@ Now, when you return to Superwall, select your product from the **Products** dro

Be sure to associate the correct entitlement to the product as well.

<Tip>
For Stripe one-time prices, Superwall shows the period as **None (Lifetime / Consumable)**. Link lifetime products to an entitlement, and usually leave consumable products without one. Learn more in [Stripe One-Time Purchases](/web-checkout/web-checkout-stripe-one-time-purchases).
</Tip>

### Adding products to paywalls

Adding Stripe products to web paywalls works the exact same way as it does for mobile paywalls. Check out the docs [here](/dashboard/dashboard-creating-paywalls/paywall-editor-products). For a quick overview:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Configure what happens after a user completes a purchase on the web:
When using Redirect mode, you'll need to provide a **Redirect URL** (must start with `https://`). Purchase data will be appended as query parameters:
- `app_user_id` - User's app identifier
- `email` - User's email address
- `stripe_subscription_id` - Stripe subscription ID
- `stripe_subscription_id` - Stripe subscription ID, or Stripe Checkout session ID for one-time purchases
- Any custom placement parameters you've set

Learn more about [post-checkout redirecting](/sdk/guides/web-checkout/post-checkout-redirecting).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ For customers in the United States, you can offer Stripe products directly from
<Note>
**App Store Review Tip:** If you choose the in-app sheet option, we strongly suggest showing your Stripe purchase experience to Apple during an App Review before testing with users. We recommend adding the following to your App Review notes:

> US users will be able to purchase a subscription using Stripe. These users are filtered using their registered App Store country. All other countries will only be able to purchase a subscription using Apple IAPs. You can test this by switching your device's registered App Store country.
> US users will be able to purchase subscriptions or one-time products using Stripe. These users are filtered using their registered App Store country. All other countries will only be able to purchase using Apple IAPs. You can test this by switching your device's registered App Store country.
</Note>
</Step>
<Step title="Create a campaign for U.S. customers">
Expand All @@ -35,7 +35,7 @@ For customers in the United States, you can offer Stripe products directly from
<Step title="Respond to Checkout">
From there, the flow works the same way as it would for web checkout. Once the payment succeeds, the [Superwall delegate](/sdk/guides/using-superwall-delegate) functions `willRedeemLink()` and `didRedeemLink(result:)` will be called. You can use these functions to handle the deep link in your app if you need to show any specific UI as described in our [Post-Checkout Redirecting](/sdk/guides/web-checkout/post-checkout-redirecting) docs.

Additionally, the subscription status will be updated automatically and the delegate callback `func subscriptionStatusDidChange(from oldValue: SubscriptionStatus, to newValue: SubscriptionStatus)` will be called. If you're using a `PurchaseController`, refer to [the docs here](/sdk/guides/web-checkout/linking-membership-to-iOS-app#using-a-purchasecontroller).
Additionally, entitlement and subscription status will update automatically. For lifetime one-time products, the linked entitlement becomes active without an expiration. For consumables, inspect `CustomerInfo.nonSubscriptions` and grant the purchased quantity in your own system. If you're using a `PurchaseController`, refer to [the docs here](/sdk/guides/web-checkout/linking-membership-to-iOS-app#using-a-purchasecontroller).
</Step>
</Steps>

Expand Down
Loading
Loading