Skip to main content
Make sure to configure Products, Entitlements and Offerings in the Qonversion dashboard before you start handling purchases with Qonversion SDK:

1. Make a purchase

When Products and Entitlements are set, you can start making purchases with thepurchaseProduct method for iOS and cross-platform SDKs, and purchase for Android
Qonversion.shared().purchase(product) { (result) in
  if result.isSuccessful {
    if let premium: Qonversion.Entitlement = result.entitlements["premium"], premium.isActive {
      // Grant user access to premium features
    }
  } else if result.isCanceledByUser {
    // Handle canceled purchase
  } else if result.isPending {
    // Handle pending purchase
  } else {
    // Handle errors
  }
}
Where “product” is the Qonversion Product created in the Dashboard. See the previous step to display Products.

1.1. Define a specific offer (Android only)

Google Play Billing Library allows you to sell a subscription with different offers. You can get information about available offers from QProduct.storeDetails. Use one of the following options to provide the chosen offer for the purchase.
// Specify the concrete offer:
final QProductOfferDetails productOfferDetails = ...; // Choose an offer from `storeDetails`
final QPurchaseOptions purchaseOptions = new QPurchaseOptions.Builder()
        .setOffer(productOfferDetails)
        .build();

// or specify only the offer ID:
final QPurchaseOptions purchaseOptions = new QPurchaseOptions.Builder()
        .setOfferId("offer_id")
        .build();

// and then provide created `QPurchaseOptions` to the `purchase` method:
Qonversion.getSharedInstance().purchase(this, product, purchaseOftions, new QonversionPurchaseCallback() {
    ...
});
If provided, we will try to find and purchase the offer with the specified ID for the requested Qonversion product. If there is no offer with the specified ID, an error will be returned. If no offer ID is provided for the subscription purchase of Qonversion product with a specified base plan ID, then we will choose the most profitable offer for the client from all the available offers. We calculate the cheapest price for the client by comparing all the trial or intro phases and the base plan. For old Qonversion products (where the base plan ID is not specified), as well as for in-app products, the offer ID is ignored. You can also remove any intro/trial offer from the purchase (to keep only a base plan). For that purpose, you should call removeOffer method of purchase options builder:
final QPurchaseOptions purchaseOptions = new QPurchaseOptions.Builder()
        .removeOffer()
        .build();

2. Handle a purchase result

iOS, Android, React-Native, Flutter SDKs

The product purchase method returns a result object containing all the information about the purchase, including its status, user entitlements after the purchase, store transaction, or an error (if it happened). You should first check the status and then the entitlements, if the purchase was successful. See the examples above.

Other cross-platform SDKs

The product purchase method returns a dictionary with the user’s entitlements on success (either via callback/completion block or as return value depending on the platform). If something goes wrong, the method returns an error or throws an exception with the failure description. There is aisCancelled flag available, which equals true if a user cancels the purchasing process on Unity. For other platforms, there is an additional field in the thrown exception for that purpose (see the code examples above). Entitlement IDs are the keys to the entitlements dictionary. The values are the objects of the Qonversion.Entitlement class.

3. Update purchases (Android only)

Upgrading, downgrading, or changing a subscription on Google Play Store requires setting additional options through the PurchaseOptions builder. See Google Play Documentation for more details.
final QPurchaseOptions purchaseOptions = new QPurchaseOptions.Builder()
        .setOldProduct(oldProduct)
        .build();
Qonversion.getSharedInstance().purchase(this, product, purchaseOftions, new QonversionPurchaseCallback() {
    ...
});
Also, Qonversion supports providing any replacement mode for the old purchase. Just provide the necessary purchase update policy while building purchase options as follows:
final QPurchaseOptions purchaseOptions = new QPurchaseOptions.Builder()
        .setOldProduct(oldProduct)
        .setUpdatePolicy(QPurchaseUpdatePolicy.WithTimeProration)
        .build();
Purchase update policy can be one of the following values:
NameDescription
ChargeFullPriceThe new plan takes effect immediately, and the user is charged full price of new plan and is given a full billing cycle of subscription, plus remaining prorated time from the old plan.
ChargeProratedPriceThe new plan takes effect immediately, and the billing cycle remains the same.
WithTimeProrationThe new plan takes effect immediately, and the remaining time will be prorated and credited to the user.
DeferredThe new purchase takes effect immediately, the new plan will take effect when the old item expires.
WithoutProrationThe new plan takes effect immediately, and the new price will be charged on next recurrence time.
The default update policy is WithTimeProration.

4. Multi-quantity purchases (iOS only)

When buying in-app products, you have the option to choose how many items you want to purchase. On Android, you can adjust the quantity directly in the purchase pop-up. However, on iOS, you’ll need to set the quantity beforehand. You can do it while building purchase options as follows:
let purchaseOptions = Qonversion.PurchaseOptions(quantity: quantity)
Qonversion.shared().purchase(product, options: purchaseOptions) { (result) in
  ...
}

5. Check user entitlements

Use the checkEntitlements() SDK method in case you want to check users’ entitlements separately from a purchase. Learn more here.

6. Restore purchases

When users, for example, upgrade to a new phone, they need to restore purchases so they can keep access to your premium features. Call the restore() method to restore purchases:
Qonversion.shared().restore { [weak self] (entitlements, error) in
  if let error = error {
    // Handle error
  }

  if let entitlement: Qonversion.Entitlement = entitlements["plus"], entitlement.isActive {
    // Restored and entitlement is active
  }
}

7. Consumable in-app purchases

How to handle consumable in-app purchases in your application. Since consumable in-app purchases do not make sense to tie to a specific entitlement, when making a purchase, you only need to look at the purchase outcome (success/error). If there is an error, do not grant bonuses for the consumable purchase; if the purchase is successful, then grant bonuses. Let’s go through the scenario step by step:
  1. The customer initiates the consumable in-app purchase.
  2. You call the Qonversion purchase method.
  3. You receive a response after the purchase is made.
    1. Is the response successful? Grant the user bonuses.
    2. Was there an error? No bonuses should be granted.
On iOS and Android, you can also use the purchased transaction from the store.
Qonversion.shared().purchase(product) { (result) in
  if result.isSuccessful {
    // Grant coins here
    // Also check the store transaction if necessary
    if let transaction = result.transaction {

    }
  } else if result.isCanceledByUser {
    // Handle canceled purchase
  } else if result.isPending {
    // Handle pending purchase
  } else {
    // Handle errors
  }
}

Displaying Products Subscription Status