Subscription Status

Check subscription status and manage user access

You can check a subscription status and manage user access to the premium content on your app by checking user entitlements (permissions) with the checkPermissions() method.

Permission is access to the premium features of your application.
→ Read more about creating and using permissions here.

You need to call the checkPermissions() method at the start of your app to check if a user has the required permission. This method will check the user receipt and will return the current permissions. If Apple or Google servers are not responding at the time of the request, Qonversion provides the latest permissions data from its database.

📘

Qonversion SDK caches all required data on products, offerings, and permissions. The data is still immediately available in cases the internet connection is lost or any server-side delays.

🚧

Note please that the permission object will be available only in case the user made any purchase. In case there were no purchases you will receive an empty result.

Qonversion.checkPermissions { (permissions, error) in
  if let error = error {
    // handle error
    return
  }
  
  if let premium: Qonversion.Permission = permissions["premium"], premium.isActive {
    switch premium.renewState {
       case .willRenew, .nonRenewable:
         // .willRenew is the state of an auto-renewable subscription 
         // .nonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
         break
       case .billingIssue:
         // Grace period: permission is active, but there was some billing issue.
         // Prompt the user to update the payment method.
         break
       case .cancelled:
         // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
         // Prompt the user to resubscribe with a special offer.
         break
       default: break
    }
  }
}
[Qonversion checkPermissions:^(NSDictionary<NSString *,QNPermission *> * _Nonnull permissions,
                               NSError * _Nullable error) {
  
  QNPermission *premiumPermission = permissions[@"premium"];
  if (premiumPermission && premiumPermission.isActive) {
    switch (premiumPermission.renewState) {
      case QNPermissionRenewStateWillRenew:
      case QNPermissionRenewStateNonRenewable:
        // QNPermissionRenewStateWillRenew is state for auto-renewable purchases
        // QNPermissionRenewStateNonRenewable is state for in-app purchases that unlock the permission lifetime
        break;
      case QNPermissionRenewStateBillingIssue:
        // Grace period: permission is active, but there was some billing issue.
        // Prompt the user to update the payment method.
        break;
      case QNPermissionRenewStateCancelled:
        // The user canceled the subscription, but the subscription has not expired yet.
        // Prompt the user to resubscribe with some special offer.
        break;
      default:
        break;
    }
  }
}];
Qonversion.checkPermissions(new QonversionPermissionsCallback() {
            @Override
            public void onSuccess(@NotNull Map<String, QPermission> permissions) {
                QPermission premiumPermission = permissions.get("premium");

                if (premiumPermission != null && premiumPermission.isActive()) {
                    switch (premiumPermission.getRenewState()) {
                        case NonRenewable:
                        case WillRenew:
                            // WillRenew is the state of an auto-renewable subscription
                            // NonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
                            break;
                        case BillingIssue:
                            // Prompt the user to update the payment method.
                            break;
                        case Canceled:
                            // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
                            // Prompt the user to resubscribe with a special offer.
                            break;
                        default: break;
                }
            }

            @Override
            public void onError(@NotNull QonversionError error) {
                // handle error here
            }
});
Qonversion.checkPermissions(object: QonversionPermissionsCallback {
            override fun onSuccess(permissions: Map<String, QPermission>) {
                val premiumPermission = permissions["premium"]
                if (premiumPermission != null && premiumPermission.isActive()) {
                    // handle active permission here

                    // also you can check renew state if needed
                    // for example to check if user has canceled subscription and offer him a discount
                    when (premiumPermission.renewState) {
                        QProductRenewState.NonRenewable,
                        QProductRenewState.WillRenew ->
                            // WillRenew is the state of an auto-renewable subscription
                            // NonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
                        QProductRenewState.BillingIssue ->
                        // Prompt the user to update the payment method.
                        QProductRenewState.Canceled ->
                        // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
                        // Prompt the user to resubscribe with a special offer.
                    }
                }
            }

            override fun onError(error: QonversionError) {
                // handle error here
            }
})
try {
  final Map<String, QPermission> permissions = await Qonversion.checkPermissions();
  final main = permissions['main'];
  if (main != null && main.isActive) {
    switch (main.renewState) {
      case QProductRenewState.willRenew:
      case QProductRenewState.nonRenewable:
        // .willRenew is the state of an auto-renewable subscription
        // .nonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
        break;
      case QProductRenewState.billingIssue:
        // Grace period: permission is active, but there was some billing issue.
        // Prompt the user to update the payment method.
        break;
      case QProductRenewState.canceled:
        // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
        // Prompt the user to resubscribe with a special offer.
        break;
      default:
        break;
    }
  }
} catch (e) {
  print(e);
}
const permissions: Map<string, Permission> = await Qonversion.checkPermissions();
    
const premiumPermission = permissions.get('premium');
if (mainPermission != null) {
  switch (premiumPermission.renewState) {
    case RenewState.NON_RENEWABLE:
      // NON_RENEWABLE is the state of consumable/non-consumable IAPs that could unlock lifetime access
      break;
    case RenewState.WILL_RENEW:
      // WILL_RENEW is the state of an auto-renewable subscription 
      break;
    case RenewState.CANCELED:
      // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
      // Prompt the user to resubscribe with a special offer.
      break;
    case RenewState.BILLING_ISSUE:
      // Grace period: permission is active, but there was some billing issue.
      // Prompt the user to update the payment method.
      break;
  }
}
Qonversion.CheckPermissions((permissions, error) =>
{
      if (error == null)
      {
           if (permissions.TryGetValue("plus", out Permission plus) && plus.IsActive)
            {
                switch(plus.RenewState)
                {
                    case QProductRenewState.WillRenew:
                    case QProductRenewState.NonRenewable:
                        // .willRenew is the state of an auto-renewable subscription 
                        // .nonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
                        break;
                    case QProductRenewState.BillingIssue:
                        // Grace period: permission is active, but there was some billing issue.
                        // Prompt the user to update the payment method.
                        break;
                    case QProductRenewState.Canceled:
                        // The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
                        // Prompt the user to resubscribe with a special offer.
                        break;
                    default:
                        break;
                }
            }
      }
      else
      {
        // Handle the error  
        Debug.Log("Error" + error.ToString());
      }
});

The Permission Object

Var name

Description

permissionID

Qonversion Permission ID. For example, premium

productID

Product ID created in Qonversion Dashboard

isActive

Boolean. true means a user has active permission.
Please note, isActive = true does not mean that a subscription will be renewed. A user can have active permission, while auto-renewal for the subscription was switched off.

renewState

A renewal state of the product that unlocked the permission. It can have the following values:
nonRenewable – consumable or non-consumable in-app purchase
willRenew – Subscription is active, and auto-renew status is on
billingIssue – There was some billing issue.
cancelled –  Subscription auto-renew status is off, but the subscription may still be active. Check isActive to be sure that the subscription has not expired yet.

startedDate

Initial transaction date. For a subscription with a trial period, the date will be when the trial starts.

expirationDate

The expiration date for a subscription.
null for a consumable/non-consumable in-app purchase or a lifetime subscription

Trial and introductory offer eligibility

You can check if a user is eligible for an introductory offer, including a free trial. Users who have not previously used an introductory offer for any products in the same subscription group are eligible for an introductory offer.
You can show only a regular price for users who are not eligible for an introductory offer.
Use the following function to determine eligibility:

Qonversion.checkTrialIntroEligibility(forProductIds: ["main", "secondary"]) { (result, error) in
  if let mainProductIntroEligibility = result["main"],
     mainProductIntroEligibility.status == .eligible {
     // handle available trial
  }
}
[Qonversion checkTrialIntroEligibilityForProductIds:@[@"main", @"secondary"] completion:^(NSDictionary<NSString *,QNIntroEligibility *> * _Nonnull result, NSError * _Nullable error) {
  QNIntroEligibility *mainProductEligibility = result[@"main"];
  if (mainProductEligibility && mainProductEligibility.status == QNIntroEligibilityStatusEligible) {
    // handle available trial
  }
}];
List<String> productIds = Arrays.asList("main", "secondary");
Qonversion.checkTrialIntroEligibilityForProductIds(productIds, new QonversionEligibilityCallback() {
    @Override
    public void onSuccess(@NotNull Map<String, QEligibility> eligibilities) {
        QEligibility mainProductEligibility = eligibilities.get("main");
        if (mainProductEligibility != null && mainProductEligibility.getStatus() == QIntroEligibilityStatus.Eligible) {
            // handle available trial
        }
    }

    @Override
    public void onError(@NotNull QonversionError error) {
        // handle error here
    }
});
Qonversion.checkTrialIntroEligibilityForProductIds(listOf("main", "secondary"), object : QonversionEligibilityCallback {
    override fun onSuccess(eligibilities: Map<String, QEligibility>) {
        val mainProductEligibility = eligibilities["main"];
        if (mainProductEligibility != null && mainProductEligibility.status == QIntroEligibilityStatus.Eligible) {
            // handle result here
        }
    }

    override fun onError(error: QonversionError) {
        // handle error here
    }
})
try {
    const eligibilityStatuses = await Qonversion.checkTrialIntroEligibilityForProductIds(['main', 'secondary']);
    const mainProductEligibility = eligibilityStatuses.get('main');
    if (mainProductEligibility && mainProductEligibility === IntroEligibilityStatus.ELIGIBLE) {
        // handle result here
    }
} catch (error) {
    // handle error here
}
try {
  final Map<String, QEligibility> eligibility = await Qonversion.checkTrialIntroEligibility(['main', 'premium']);
  final QEligibility mainProductStatus = eligibility['main'];
  if (mainProductStatus.status == QEligibilityStatus.eligible) {
      // handle available trial
  }
} catch (e) {
  print(e);
}
string[] productIds = {"premium"};

Qonversion.CheckTrialIntroEligibilityForProductIds(productIds, (eligibility, error) =>
{
    if (error == null)
    {
        if (eligibility.TryGetValue("premium", out Eligibility premiumEligibility) && premiumEligibility.Status == EligibilityStatus.Eligible)
        {
            // handle available eligibility
        }
    }
});

Did this page help you?