Accept payments for digital goods on iOS using Payment Links
Link out to a Stripe-hosted payment page from your app to sell digital goods or subscriptions.
In some countries, you can link to an external website to accept payments on iOS. This guide shows you how you can create low-code payment links from the Stripe Dashboard and use those to redirect customers from your app to a Stripe-hosted payment page. You can dynamically update the link with URL parameters to pre-fill a customer’s email or use the client_
to pass through a user’s app ID or unique identifier.
Payment Links are a great option if you have a limited number of products and prices, because you don’t need to stand up a server. If you want to offer a more dynamic cart or attach a Customer to the session, we recommend using Stripe Checkout instead.
Note
This guide only describes the process for selling in-app digital goods. If you sell any of the following use the native iOS payment guide instead:
- Physical items
- Goods and services intended for consumption outside your app
- Real-time person-to-person services between two individuals
What you’ll build 
This guide shows you how to:
- Model your digital goods or subscriptions with Products and Prices.
- Create payment links from the Dashboard.
- Use universal links to redirect directly to your app from the payment link.
- Monitor webhooks to update your customer’s in-app subscriptions.
What isn’t covered 
This guide demonstrates how to add payment links alongside your existing in-app purchase system. It doesn’t cover:
- User authentication. If you don’t have an existing authentication provider, you can use a third-party provider, such as Sign in with Apple or Firebase Authentication.
- Native in-app purchases. To implement in-app purchases using StoreKit, visit Apple’s in-app purchase guide.
Set up universal linksClient-sideServer-side
Universal links allow payment links to deep link into your app after a successful payment. To configure a universal link:
- Add an
apple-app-site-association
file to your domain. - Add an Associated Domains entitlement to your app.
- Add a fallback page for your Checkout redirect URLs.
Define the associated domains
Add a file to your domain at .
to define the URLs your app handles. Prepend your App ID with your Team ID, which you can find on the Membership page of the Apple Developer Portal.
{ "applinks": { "apps": [], "details": [ { "appIDs": [ "A28BC3DEF9.com.example.MyApp1", "A28BC3DEF9.com.example.MyApp1-Debug" ], "components": [ { "/": "/checkout_redirect*", "comment": "Matches any URL whose path starts with /checkout_redirect" } ] } ] } }
Warning
You must serve the file with MIME type application/json
. Use curl -I
to confirm the content type.
curl -I https://example.com/.well-known/apple-app-site-association
See Apple’s page on supporting associated domains for more details.
Add an Associated Domains entitlement to your app
- Open the Signing & Capabilities pane of your app’s target.
- Click + Capability, then select Associated Domains.
- Add an entry for
applinks:yourdomain.
to the Associated Domains list.com
For more information on universal links, see Apple’s universal links documentation.
Although iOS intercepts links to the URLs defined in your apple-app-site-association
file, you might encounter situations where the redirect fails to open your app.
Create a payment link for your product or subscription
Payment Links support card payments and Apple Pay by default. You can enable additional payment methods from the Dashboard.
Use URL parameters to attach relevant information
URL parameters allow you to add additional context to your payment page and streamline checkout. You can use URL parameters to adjust the language of the payment page, prefill an email or promotion code, or attach relevant metadata to help with reconciliation.
We recommend using prefilled_
and client_
to help streamline checkout and help with your reconciliation.
Parameter | Description | Syntax |
---|---|---|
| Use |
We recommend encoding email addresses that you attach as URL parameters to reduce the risk of them not being passed through to your payment page. |
client_ | Use client_ to attach a unique string of your choice to the Checkout Session. This can be an App ID or a cart ID (or similar), and you can use it to reconcile the Session with your internal systems. This value isn’t shown to the customer during checkout, but is sent in the checkout.session.completed webhook after payment completion. | client_ can be composed of alphanumeric characters, dashes, or underscores, and be any value up to 200 characters. Invalid values are silently dropped, but your payment page continues to work as expected. |
The following is an example link with prefilled_
and client_
:
https://buy.
Add the link to your app
Add a checkout button to your app. This button:
- Prefills your payment link with prefilled_email and client_reference_id.
- Opens the Stripe-hosted payment page in Safari.
Handle order fulfillmentServer-side
After the purchase succeeds, Stripe sends you a checkout.
webhook. In the payload of the webhook event, you will find the client_
under the checkout.
, which you can use for your business logic, such as associating the payment with a specific order or user in your system.
To test your integration, you can monitor events in the Dashboard or using the Stripe CLI. For production, set up a webhook endpoint and subscribe to appropriate event types. If you don’t know your STRIPE_
key, click the webhook in the Dashboard to view it.
Testing 
To test your that your checkout button works, do the following:
- Click the checkout button, which redirects you to the Stripe Checkout payment form.
- Enter the test number , a three-digit CVC, a future expiration date, and any valid postal code.
- Tap Pay.
- The
checkout.
webhook fires, and Stripe notifies your server about the transaction. You’re redirected back to your app.session. completed