Skip to content

Commit fd597af

Browse files
authored
New doc: Paddle app-to-web guide (#1021)
* Initial guide doc for paddle app-to-web * Initial pages for paddle app-to-web guide * Most of the initial draft for paddle app-to-web * Further updates to the Paddle doc * Full initial draft of paddle app-to-web doc * Add content to RC Web Guides page * Fix: broken link * Add user flow illustration to doc * Fix image crop issue
1 parent 0cf12b4 commit fd597af

File tree

4 files changed

+369
-0
lines changed

4 files changed

+369
-0
lines changed

docs/web/guides.mdx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: RevenueCat Web guides
3+
slug: guides
4+
excerpt:
5+
hidden: false
6+
---
7+
8+
### Paddle app-to-web purchases
9+
10+
Learn how to configure a web purchase flow linked from an iOS paywall, using web purchase links and Paddle Billing for subscriptions.
11+
12+
<Button href="./guides/paddle-app-to-web">View guide →</Button>
13+
14+
<hr />

docs/web/guides/paddle-app-to-web.mdx

Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
---
2+
title: Paddle app-to-web purchases
3+
slug: paddle-app-to-web
4+
excerpt: Configure a web purchase flow linked from an iOS paywall, using web purchase links and Paddle Billing
5+
hidden: false
6+
---
7+
8+
:::info April 2025 U.S. District Court Ruling on External Payment Options
9+
A recent U.S. District Court ruling found Apple in violation of a 2021 injunction meant to allow developers to direct users to external payment options, like Paddle. As a result, iOS developers are now permitted to guide users to web-based payment flows without additional Apple fees or restrictive design requirements. You can [find more details on the RevenueCat blog](https://revenuecat.com/blog/growth/introducing-web-paywall-buttons).
10+
:::
11+
12+
## Overview
13+
14+
![](/docs_images/web/web-billing/rc_web_paddle_flow.png)
15+
16+
This guide walks you through the setup for adding web purchases to your iOS app with RevenueCat Web and Paddle Billing. The flow consists of the following steps:
17+
18+
1. User views RevenueCat paywall (in-app)
19+
1. User clicks a web purchase button on the pwayall, and lands on a web purchase link in the device browser
20+
1. User completes their purchase in the Paddle Billing checkout (presented within the web purchase link)
21+
1. User is redirected back into the mobile app, using a custom URL scheme
22+
1. User is granted access to the premium entitlements associated with the product they purchased
23+
24+
## Current limitations
25+
26+
1. **Free trials** will not be displayed in the package selection page, or summarized in the checkout
27+
1. **Product quantity:** Products purchased with a quantity of more than one (via the quantity adjustment in the Paddle checkout) will be reflected as a single product purchase in RevenueCat.
28+
1. **Customization:** The Paddle overlay checkout only supports a single accent color customization.
29+
1. **Product descriptions:** The "show product descriptions" setting in web purchase links currently has no effect with Paddle purchases.
30+
31+
## Before you begin (prerequisites)
32+
33+
Before you start to configure this flow, you'll need the following:
34+
35+
- A RevenueCat account (sign up [here](https://www.revenuecat.com/))
36+
- A iOS mobile app with the RevenueCat SDK configured (see [getting started](../../welcome/overview))
37+
- iOS products configured in RevenueCat (see [product configuration](../../getting-started/quickstart#2-product-configuration))
38+
- A Paddle Sandbox account (sign up [here](https://sandbox-login.paddle.com/signup))
39+
- (Optional) A Paddle Production account (in order to ship a production version, sign up [here](https://login.paddle.com/signup))
40+
41+
:::info This guide can be followed for both sandbox & production setup
42+
Some steps only need to be configured once, and are marked accordingly. Others require dedicated setup in both sandbox and production environments.
43+
:::
44+
45+
## 1. Configure your Paddle account
46+
47+
:::info Do this in Paddle, for:
48+
49+
- Sandbox ([https://sandbox-vendors.paddle.com/](https://sandbox-vendors.paddle.com/))
50+
- Production ([https://login.paddle.com/](https://login.paddle.com/))
51+
:::
52+
53+
### Add a registered payment domain
54+
55+
1. Go to the **Website approval** page under Checkout
56+
1. Click **Add a new domain**
57+
1. Enter `pay.rev.cat`
58+
1. Click **Submit for Approval**
59+
60+
The `pay.rev.cat` domain has been pre-approved by Paddle, should display as approved in your account within a short period of time.
61+
62+
### Set a default payment link
63+
64+
Go to the [Checkout settings](https://sandbox-vendors.paddle.com/checkout-settings) page under Checkout.
65+
66+
If your Paddle account does not already have a default payment link set, enter `https://pay.rev.cat`.
67+
68+
If a default payment link is already configured (because you're using the account for other purposes) you can leave this unchanged. It will not affect your app-to-web purchases.
69+
70+
### Disable abandoned cart emails
71+
72+
The RevenueCat Paddle Billing integration doesn't currently support Paddle's abandoned cart emails. You should disable them [here](https://developer.paddle.com/build/checkout/checkout-recovery#configure-checkout-recovery)
73+
74+
### Add a new API key and define permissions
75+
76+
1. Navigate to the [Authentication](https://sandbox-vendors.paddle.com/authentication-v2) page under Developer Tools
77+
1. Click the **+ New API key** button
78+
1. Give the new key a suitable name and description
79+
1. **Important:** Set the key to NOT expire (differs from default)
80+
1. Set the permissions according to the list below
81+
1. Save the new key
82+
1. Copy the key to your clipboard
83+
84+
<details>
85+
<summary> <b>Minimum required API key permissions</b></summary>
86+
87+
| Permission | Read | Write |
88+
| ------------------------------ | :--: | :---: |
89+
| Addresses |||
90+
| Adjustments |||
91+
| Businesses |||
92+
| Client-side tokens |||
93+
| Customer portal sessions |||
94+
| Customer authentication tokens |||
95+
| Customers |||
96+
| Discounts |||
97+
| Notification settings |||
98+
| Notifications |||
99+
| Notification simulations |||
100+
| Payment methods |||
101+
| Prices |||
102+
| Products |||
103+
| Reports |||
104+
| Subscriptions |||
105+
| Transactions |||
106+
107+
</details>
108+
109+
:::warning leave key window open
110+
If you close the modal showing the full API key, you will no longer be able to copy it — we recommend you leave this window open until you've saved the key in the RevenueCat config.
111+
:::
112+
113+
## 2. Create Paddle config in RevenueCat dashboard
114+
115+
:::info Do this in RevenueCat, for:
116+
117+
- Sandbox
118+
- Production (separate config required)
119+
120+
:::
121+
122+
1. Log in to your RevenueCat account
123+
1. Go to your project
124+
1. Go to **Apps & providers**
125+
1. Add a new web configuration
126+
1. Select the Paddle provider
127+
1. Click **Set secret**, paste your Paddle API key and click **Set**
128+
129+
For this use case, we recommend selecting:
130+
131+
**Automatic purchase tracking** — this tracks all purchases from the Paddle account using webhooks, with no additional setup required.
132+
**Autogenerated user IDs** — because we're sending users directly from the mobile app, an app user ID will already be provided and associated to the purchase.
133+
134+
Finally, click **Connect to Paddle** to initiate and test the connection.
135+
136+
## 3. Create products and prices in Paddle
137+
138+
:::info Do this in Paddle, for:
139+
140+
- Sandbox ([https://sandbox-vendors.paddle.com/](https://sandbox-vendors.paddle.com/))
141+
- Production ([https://login.paddle.com/](https://login.paddle.com/))
142+
:::
143+
144+
:::info Product Mapping between RevenueCat and Paddle
145+
A Price in Paddle maps to a Product in the RevenueCat system. So for example, if you create two prices under the same Paddle product, when you import or manually create the products in the RevenueCat dashboard, you'll notice two separate products.
146+
147+
![](/docs_images/web/paddle/paddle_dashboard_prices.png)
148+
![](/docs_images/web/paddle/revenuecat_paddle_product_mapping.png)
149+
150+
:::
151+
152+
1. Log in to the Paddle Dashboard
153+
1. To create a new product, expand the **Catalog** section in the sidebar and click **Products**.
154+
1. On the top right corner of the page, click **New Product**.
155+
1. Enter the product name and any other optional details like a description then click **Save**.
156+
157+
![](/docs_images/web/paddle/create-product.png)
158+
159+
Then on the prices section, click **New Price**.
160+
Enter details like the base price, the type of pricing (recurring or one-time), the billing period, and any trial periods you are offering and click **Save**.
161+
162+
:::info "price name" is customer-facing label
163+
The "price name" field defines to what is shown to users in the checkout, as a representation of what they're purchasing.
164+
:::
165+
166+
![](/docs_images/web/paddle/create-price.png)
167+
168+
You can read more about **products and prices** in [Paddle's official documentation](https://developer.paddle.com/build/products/create-products-prices).
169+
170+
## 4. Import products to RevenueCat
171+
172+
:::info Do this in RevenueCat, for:
173+
174+
- Sandbox
175+
- Production
176+
:::
177+
178+
1. Go to the **Product catalog** in your RevenueCat dashboard, and select the **Products** tab
179+
1. Find your previously added Paddle provider, and click **Import**
180+
1. Check the products you want to use for your web purchases, and click **Import**
181+
182+
The imported products should now be displayed under your Paddle provider on the Products page.
183+
184+
## 5. Create entitlements in RevenueCat
185+
186+
:::info Do this in RevenueCat, for:
187+
188+
- Sandbox
189+
- Production
190+
:::
191+
192+
### What is an entitlement?
193+
194+
RevenueCat Entitlements represent a level of access, features, or content that a user is "entitled" to, and are typically unlocked after a user purchases a product.
195+
196+
Entitlements are used to ensure a user has appropriate access to content based on their purchases, without having to manage all of the product identifiers in your app code. For example, you can use entitlements to unlock "pro" features after a user purchases a subscription.
197+
198+
Most apps only have one entitlement, unlocking all premium features. However, if you had two tiers of content such as Gold and Platinum, you would have 2 entitlements.
199+
200+
[Read more about entitlements](../../getting-started/entitlements)
201+
202+
### Adding an entitlement
203+
204+
1. Go to the **Product catalog** in your RevenueCat dashboard, and select the **Entitlements** tab
205+
1. Click **+ New entitlement**
206+
1. Enter an identifier and description for the entitlement, and click **Add**
207+
208+
### Attaching a product to your entitlement
209+
210+
1. Go to your previously created entitlenment and click **Attach** under associated products
211+
1. In the table, check the product from your Paddle provider, and click **Attach**
212+
213+
## 6. Create an offering & packages in RevenueCat
214+
215+
:::info Do this in RevenueCat, for:
216+
217+
- Sandbox
218+
- Production
219+
:::
220+
221+
1. Go to the **Product catalog** in your RevenueCat dashboard, and select the **Offerings** tab
222+
1. Click **New offering** to create a new offering
223+
1. Enter a suitable identifier and display name
224+
1. Under **Packages**, click **+ New Package**
225+
1. Select an identifier that corresponds to the billing cycle of your subscription
226+
1. Enter a description
227+
1. In the products list, find your previously-created Paddle provider and select the corresponding Paddle product (this should correspond with the billing cycle you chose in the identifier)
228+
1. Click **Save**
229+
230+
## 7. Create and configure a web purchase link to enable web purchases
231+
232+
:::info Do this in RevenueCat, for:
233+
234+
- Sandbox
235+
- Production
236+
:::
237+
238+
### Web Purchase Link basics
239+
240+
1. Go to the **Product catalog** in your RevenueCat dashboard, and select your previously created offering in the **Offerings** tab
241+
1. Go to the **Web Purchase Link** tab and select **Create a Web Purchase Link for this offering**
242+
1. For the **Web config**, choose the Paddle config you created earlier
243+
1. Enter a suitable header and subheader for the package selection page, along with a link to terms & conditions
244+
245+
:::info Package selection skipped by default for web-to-app purchases
246+
When linking to a web purchase from a RevenueCat paywall, by default the package selection page will be skipped and subscribers will land directly on the checkout with the package selected.
247+
:::
248+
249+
### Configure the success redirect
250+
251+
To redirect the subscriber back into to your app after the purchase, you can use a custom URL scheme (see instructions below). You could alternatively redirect the subscriber to a [Universal Link](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app), or your own custom page.
252+
253+
**To add a custom URL scheme in iOS:**
254+
255+
1. In Xcode, find your xcodeproj file — Info tab — **URL Types** section.
256+
1. Then add your custom scheme in the **URL Schemes** field.
257+
258+
**Adding your custom URL scheme in the web purchase link redirect:**
259+
260+
Select the **Redirect to a custom success page** option, and enter your URL scheme in the format `YOUR_CUSTOM_SCHEME://`.
261+
262+
:::warning Important: URL schemes on production can require app updates
263+
In order to use a URL scheme on production, your users must be using a version of your app that has the URL scheme configured. Distribute app updates before enabling this feature.
264+
:::
265+
266+
### Choose the repeat purchase behavior
267+
268+
Define what happens when customers to purchase a product while they already have an active subscription or entitlement. For the app-to-web use case, it's recommended to choose **Show the success page**.
269+
270+
:::info Re-purchasing same product not possible
271+
Note that customers can't have more than one active subscription to the same product, or re-purchase a non-consumable product.
272+
:::
273+
274+
## 8. Create a mobile paywall
275+
276+
:::info Do this in RevenueCat, for:
277+
278+
- Sandbox
279+
- Production
280+
:::
281+
282+
**If you have an existing mobile paywall configured:**
283+
284+
1. Make sure your existing paywall is attached to the same offering you've configured for web purchases
285+
1. Add a web purchase button to your paywall ([Read more](https://www.revenuecat.com/docs/tools/paywalls/creating-paywalls/web-purchase-button))
286+
287+
**If you don't have a mobile paywall configured:**
288+
289+
1. Go to **Paywalls** in the RevenueCat dashboard
290+
1. Select **+ New paywall**
291+
1. Choose the offering you created earlier in this guide and click **Add**
292+
1. [follow this detailed guide](../../tools/paywalls/creating-paywalls) on creating a paywall, and add the mobile packages you want to present.
293+
1. Add a web purchase button to your paywall ([Read more](https://www.revenuecat.com/docs/tools/paywalls/creating-paywalls/web-purchase-button))
294+
295+
### Configure the web purchase button
296+
297+
Once you've added a suitable web purchase button to your paywall:
298+
299+
1. Set the **Open** behavior to **Web purchase**
300+
1. Publish the changes
301+
302+
## 9. Test the purchase flow in sandbox
303+
304+
:::info Do this in RevenueCat, for:
305+
306+
- Sandbox only
307+
:::
308+
309+
### Testing the paywall
310+
311+
If you've completed this flow for a sandbox setup, you have several options for testing it:
312+
313+
- Use the RevenueCat iOS app to preview ([see how](../../tools/paywalls/testing-paywalls#1-preview-in-the-revenuecat-app))
314+
- Override a customer's default offering ([see how](../../tools/paywalls/testing-paywalls#2-override-a-customers-default-offering))
315+
- Create a Targeting Rule for an internal app version ([see how](../../tools/paywalls/testing-paywalls#3-create-a-targeting-rule-for-an-internal-app-version))
316+
- Test through Xcode ([see how](../../tools/paywalls/testing-paywalls#4-testing-through-xcode-and-android-studio))
317+
318+
### Testing web purchases
319+
320+
To test the web checkout in sandbox mode, make sure that you:
321+
322+
- Have a paddle config created connected to a Paddle sandbox account
323+
- Have products and entitlements from that sandbox account
324+
- Have configured an offering and web purchase link to present those products/packages
325+
326+
You can find the sandbox purchase URL by
327+
328+
1. Going to **Product catalog - Offerings** and selecting the offering you created earlier.
329+
1. Selecting the **Web Purchase Link** tab
330+
1. Copying the Sandbox URL template and appending an app user ID to it
331+
332+
:::warning App user ID must be appended to URL template
333+
334+
The sandbox URL template will only function if you append an app user ID to it (can be a random ID for testing purposes).
335+
336+
:::
337+
338+
To test web purchases on sandbox, you can use [Paddle's test cards](https://developer.paddle.com/v1/concepts/payment-methods/credit-debit-card#test-payment-method) to simulate a real transaction.
339+
340+
## 10. Repeat this walkthrough to configure production purchases
341+
342+
If you've successfully configured and tested a purchase flow using sandbox environments, you can now restart this guide to do the same for a production environment.
343+
344+
In production, you'll need:
345+
346+
- A different Paddle account, from the production domain ([https://login.paddle.com/](https://login.paddle.com/))
347+
- A new Paddle config in RevenueCat, connected to the production Paddle account
348+
- Newly imported products from the production paddle account
349+
- A new offering in RevenueCat, connected to a paywall to present those products

sidebars.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ const webSDKCategory = Category({
218218
itemsPathPrefix: "integrations/",
219219
items: [Page({ slug: "stripe" }), Page({ slug: "paddle" })],
220220
}),
221+
SubCategory({
222+
label: "Guides",
223+
slug: "guides",
224+
itemsPathPrefix: "guides/",
225+
items: [Page({ slug: "paddle-app-to-web" })],
226+
}),
221227
Page({ slug: "faq" }),
222228
],
223229
});
654 KB
Loading

0 commit comments

Comments
 (0)