Integrating subscriptions and IAPs in 10 steps

This guide shows how to integrate subscriptions and in-app purchases in to an app in 10 steps.

1. Store Configuration

Configure the stores you use by following our guides:

2. Configure SKUs

The SKU is the Glassfy unique identifier to link a product to an App Store.

  1. Create and configure your in-app purchases and subscriptions in App Store Connect, Play Store or Paddle Store
  2. Once your products are created create SKUs in Glassfy

3. Configure Permissions

The permission allows to control which feature or content the user has access to.

It references a list of SKUs and allows app developers to quickly check if the user has appropriate access without having to check for all the products/SKUs in the application code. Each app can have multiple permissions that can unlock different content.

Read the create permissions guide for more details.

4. Configure Offerings

The offering allows to purchase SKUs dynamically without recompiling and resubmitting an app for review. It references a list of SKUs and allows a user to change the chosen SKUs or add others. Each app can have multiple offerings which can have different content.

Read the create offerings guide for more details.

5. Configure SDK

6. Install SDK

7. Initialize the SDK

Copy your APIKEY from Glassfy Setting page and use it to initialize the SDK.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  Glassfy.initialize(apiKey: "YOUR_API_KEY", watcherMode: false)

}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  [Glassfy initializeWithAPIKey:@"YOU_API_KEY" watcherMode:NO];
}
class App : Application() {
  override fun onCreate() {
    super.onCreate()
    
    Glassfy.initialize(this, "YOUR_API_KEY", false, null)
  }
}
public class App extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    Glassfy.initialize(this, "YOUR_API_KEY", false, null);
  }
}
try {

  await Glassfy.initialize('YOU_API_KEY',watcherMode: false);

} catch (e) {
  // error
  [...]
}
try {

  await Glassfy.initialize('YOU_API_KEY', false);

} catch (e) {
  // initialization error
}
try {

  await Glassfy.initialize('YOU_API_KEY', false);

} catch (e) {
  // initialization error
}

8. Fetch offering

You can now fetch the offering configured in Step 4.

The offering contains a list of SKUs that you can use to update the UI of your app with purchasable SKUs.

The following example shows fetching the permission called premium_offering:

Glassfy.offerings { (offers, err) in
    if let offering = offers?["premium_offering"] {
        // display your offering's skus
        for sku in offering.skus {
            // sku.extravars
            // sku.product.localizedTitle
            // sku.product.localizedDescription
            // sku.product.price
        }
    }
}
[Glassfy offeringsWithCompletion:^(GYOfferings *offers, NSError *err) {
    GYOffering *offering = offers[@"premium_offering"];
    if (offering) {
        // display your offering's skus
        for (GYSku *sku in offering.skus) {
            // sku.extravars
            // sku.product.localizedTitle
            // sku.product.localizedDescription
            // sku.product.price
        }
    }
}];
Glassfy.offerings() { offers, err ->
    offers?.all
        ?.firstOrNull { it.offeringId == "premium_offering" }
        ?.also {
            // display your offering's skus
            for (sku in it.skus) {
                // sku.extravars
                // sku.product.title
                // sku.product.description
                // sku.product.price
            }
        }
}
Glassfy.offerings(new OfferingsCallback() {
    @Override
    public void onResult(@Nullable Offerings offers, @Nullable GlassfyError err) {
        Offering offering = null;
        if (offers != null) {
            for (Offering o : offers.getAll()) {
                if (o.getOfferingId().equals("premium_offering")) {
                    offering = o;
                }
            }
        }
        if (offering != null) {
            // display your offering's skus
            for (Sku sku : offering.getSkus()) {
                // sku.getExtravars();
                // sku.getProduct().getTitle();
                // sku.getProduct().getDescription();
                // sku.getProduct().getPrice();
            }
        }
    }
});
try {
    var offerings = await Glassfy.offerings();
    var offering = offerings.all
        ?.singleWhere((offering) => offering.offeringId == 'premium_offering');

    offering?.skus?.forEach((sku) {
        // sku.product.description
        // sku.product.price
    });
} catch (e) {
  // initialization error
  [...]
}
try {
    let offering = offerings.all.find((o) => o.identifier === 'premium_offering');

    offering?.skus.forEach((sku) => {
      // sku.extravars
      // sku.product.description;
      // sku.product.price
    });
} catch (e) {
  [...]
}
try {
    let offering = offerings.all.find((o) => o.identifier === 'premium_offering');

    offering?.skus.forEach((sku) => {
      // sku.extravars
      // sku.product.description;
      // sku.product.price
    });
} catch (e) {
  [...]
}

9. Purchase a SKU

When the user make a selection from the list of SKUs displayed in Step 8, and you can use the selected SKU to purchase from the store.

Glassfy.purchase(sku: premiumSku) { (transaction, e) in
    // update app status accondingly
    if let p = transaction?.permissions["premium"] {
        if p.isValid {
            // unlock aFeature
        } else {
            // lock aFeature
        }
    }
}
[Glassfy purchaseSku:premiumSku completion:^(GYTransaction *transaction, NSError *err) {
    GYPermissions *permissions = transaction.permissions;
    if (permissions) {
        GYPermission *p = permissions[@"premium"];
        if (p.isValid) {
            // unlock aFeature
        }
        else {
            // lock aFeature
        }
    }
}];
Glassfy.purchase(activity, sku) { transaction, err ->
    // update app status accordingly
    transaction?.permissions
        ?.all
        ?.firstOrNull { it.permissionId == "premium" }
        ?.also {
            if (it.isValid) {
                // unlock aFeature
            } else {
                // lock aFeature
            }
        }
}
Glassfy.purchase(activity, sku, new PurchaseCallback() {
    @Override
    public void onResult(@Nullable Transaction t, @Nullable GlassfyError err) {
        // update app status accordingly
        Permission permission = null;
        if (t != null) {
            for (Permission p : t.getPermissions().getAll()) {
                if (p.getPermissionId().equals("premium")) {
                    permission = p;
                }
            }
        }
        if (permission != null) {
            if (permission.isValid()) {
              // unlock aFeature
            } else {
              // lock aFeature
            }
        }
    }
});
try {
    var transaction = await Glassfy.purchaseSku(sku);

    var p = transaction.permissions?.all?.singleWhere((permission) => permission.permissionId == 'premium');
    if (p?.isValid==true) {
        // unlock aFeature
    }
    else {
        // lock aFeature
    }
} catch (e) {
  // initialization error
  [...]
}
try {
    const transaction = await Glassfy.purchaseSku(premiumSku );
    const permission = transaction.permissions.all.find((p) => p.permissionId === "premium");
    if (permission && permission.isValid) {
        // unlock aFeature
    }
} catch (e) {
  // initialization error
  [...]
}
try {
    const transaction = await Glassfy.purchaseSku({ sku: premiumSku });
    const permission = transaction.permissions.all.find((p) => p.permissionId === "premium");
    if (permission && permission.isValid) {
        // unlock aFeature
    }

} catch (e) {
  // initialization error
  [...]
}

The returned Transaction object contains a list of permissions (as configured in Step 3) that you can use to unlock specific sections of the app.

The example above checks for the premium permission.

10. Verify permissions

Use the permission to verify the status of subscriptions or IAPs.

Glassfy.permissions { (permission, err) in
    // update app status accondingly
    if let permissions = permission?.all {
        for p in permissions {
            switch p.permissionId {
            case "premium":
                if p.isValid {
                    // unlock aFeature
                } else {
                    // lock aFeature
                }
            default:
                print("Permission not handled");
            }
        }
    }
}
[Glassfy permissionsWithCompletion:^(GYPermissions *permission, NSError *err) {
    NSArray<GYPermission*> *permissions = permission.all;
    if (permissions) {
        for (GYPermission *p in permissions) {
            switch (p.permissionId) {
            case @"premium":
                if (p.isValid) {
                    // unlock aFeature
                }
                else {
                    // lock aFeature
                }
                break;
            default:
                NSLog(@"Permission not handled");
                break;
            }
        }
    }
}];
Glassfy.permissions { permission, err ->
    // update app status accordingly
    permission?.all?.forEach {
        when (it.permissionId) {
            "premium" ->
                if (it.isValid) {
                    // unlock aFeature
                } else {
                    // lock aFeature
                }
            else -> println("Permission not handled");
        }
    }
}
Glassfy.permissions(new PermissionsCallback() {
    @Override
    public void onResult(@Nullable Permissions permission, @Nullable GlassfyError error) {
        // update app status accondingly
        if (permission != null) {
            for (Permission p: permission.getAll()) {
                switch (p.getPermissionId()) {
                case "premium":
                    if (p.isValid()) {
                        // unlock aFeature
                    } else {
                        // lock aFeature
                    }
                    break;
                default:
                    Log.d(TAG, "Permission not handled");
                }
            }
        }
    }
});
try {
var permission = await Glassfy.permissions();
      permission.all?.forEach((p)=> {
        if (p.permissionId == "premium") {
          // unlock aFeature
        }
      });
} catch (e) {
  // initialization error
  [...]
}
try {
    const permissions = Glassfy.permissions();
    const permission = transaction.permissions.all.find((p) => p.permissionId === "premium");

    if (permission && permission.isValid) {
        // unlock aFeature
    }
} catch (e) {
  // initialization error
  [...]
}
try {
    const permissions = Glassfy.permissions();
    const permission = transaction.permissions.all.find((p) => p.permissionId === "premium");
    if (permission && permission.isValid) {
        // unlock aFeature
    }

} catch (e) {
  // initialization error
  [...]
}

The permissions completion block returns a Permissions object or an error.

Integration complete

You have completed the integration of Glassfy in your app and you can start testing your application in sandbox mode.

To release the app on the App Store or Play Store upload it to the app on AppStoreConnect or Google Play.

🚧

App Store

To test the purchases in sandbox mode and to release the app you must be sure to have accepted all the contracts on AppStoreConnect.