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. |
renewState | A renewal state of the product that unlocked the permission. It can have the following values: |
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. |
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
}
}
});
Updated 5 months ago