Skip to main content

Make purchases in mobile app

Displaying paywalls within your mobile app is an essential step in offering users access to premium content or services. However, simply presenting these paywalls is enough to support purchases only if you use Paywall Builder to customize your paywalls.

If you don't use the Paywall Builder, you must use a separate method called .makePurchase() to complete a purchase and unlock the desired content. This method serves as the gateway for users to engage with the paywalls and proceed with their desired transactions.

If your paywall has an active promotional offer for the product a user is trying to buy, Adapty will automatically apply it at the time of purchase.

warning

Keep in mind that the introductory offer will be applied automatically only if you use the paywalls set up using the Paywall Builder.

In other cases, you'll need to verify the user's eligibility for an introductory offer on iOS. Skipping this step may result in your app being rejected during release. Moreover, it could lead to charging the full price to users who are eligible for an introductory offer.

Make sure you've done the initial configuration without skipping a single step. Without it, we can't validate purchases.

Make purchase

note

In paywalls built with Paywall Builder purchases are processed automatically with no additional code. If that's your case — you can skip this step.

do {
let purchaseResult = try await Adapty.makePurchase(product: product)

switch purchaseResult {
case .userCancelled:
// Handle the case where the user canceled the purchase
case .pending:
// Handle deferred purchases (e.g., the user will pay offline with cash)
case let .success(profile, transaction):
if profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive ?? false {
// Grant access to the paid features
}
}
} catch {
// Handle the error
}

Request parameters:

ParameterPresenceDescription
ProductrequiredAn AdaptyPaywallProduct object retrieved from the paywall.

Response parameters:

ParameterDescription
Profile

An AdaptyProfile object provides comprehensive information about a user's access levels, subscriptions, and non-subscription purchases within the app.

Check the access level status to ascertain whether the user has the required access to the app.

warning

Note: if you're still on Apple's StoreKit version lower than v2.0 and Adapty SDK version lowers than v.2.9.0, you need to provide Apple App Store shared secret instead. This method is currently deprecated by Apple.

Change subscription when making a purchase

When a user opts for a new subscription instead of renewing the current one, the way it works depends on the app store:

  • For the App Store, the subscription is automatically updated within the subscription group. If a user purchases a subscription from one group while already having a subscription from another, both subscriptions will be active at the same time.
  • For Google Play, the subscription isn't automatically updated. You'll need to manage the switch in your mobile app code as described below.

To replace the subscription with another one in Android, call .makePurchase() method with the additional parameter:

Adapty.makePurchase(activity, product, subscriptionUpdateParams) { result ->
when (result) {
is AdaptyResult.Success -> {
when (val purchaseResult = result.value) {
is AdaptyPurchaseResult.Success -> {
val profile = purchaseResult.profile

// successful cross-grade
}

is AdaptyPurchaseResult.UserCanceled -> {
// user canceled the purchase flow
}

is AdaptyPurchaseResult.Pending -> {
// the purchase has not been finished yet, e.g. user will pay offline by cash
}
}
}
is AdaptyResult.Error -> {
val error = result.error
// Handle the error
}
}
}

Additional request parameter:

ParameterPresenceDescription
subscriptionUpdateParamsrequiredan AdaptySubscriptionUpdateParameters object.

You can read more about subscriptions and proration modes in the Google Developer documentation:

In-app purchases from the App Store

When a user initiates a purchase in the App Store and the transaction carries over to your app, you have two options:

  • Process the transaction immediately: Return true in shouldAddStorePayment. This will trigger the Apple purchase system screen right away.
  • Store the product object for later processing: Return false in shouldAddStorePayment, then call makePurchase with the stored product later. This may be useful if you need to show something custom to your user before triggering a purchase.

Here’s the complete snippet:

Swift
final class YourAdaptyDelegateImplementation: AdaptyDelegate {
nonisolated func shouldAddStorePayment(for product: AdaptyDeferredProduct) -> Bool {
// 1a.
// Return `true` to continue the transaction in your app. The Apple purchase system screen will show automatically.

// 1b.
// Store the product object and return `false` to defer or cancel the transaction.
false
}

// 2. Continue the deferred purchase later on by passing the product to `makePurchase` when the timing is appropriate
func continueDeferredPurchase() async {
let storedProduct: AdaptyDeferredProduct = // get the product object from 1b.
do {
try await Adapty.makePurchase(product: storedProduct)
} catch {
// handle the error
}
}
}

Redeem Offer Code in iOS

Since iOS 14.0, your users can redeem Offer Codes. Code redemption means using a special code, like a promotional or gift card code, to get free access to content or features in an app or on the App Store. To enable users to redeem offer codes, you can display the offer code redemption sheet by using the appropriate SDK method:

Adapty.presentCodeRedemptionSheet()
danger

Based on our observations, the Offer Code Redemption sheet in some apps may not work reliably. We recommend redirecting the user directly to the App Store.

In order to do this, you need to open the url of the following format: https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}