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.
- Create and configure your in-app purchases and subscriptions in App Store Connect, Play Store or Paddle Store
- 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
- App Store Configuration and App Store Server To Server Notifications
- Play Store Configuration
- Paddle Configuration
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.
Updated almost 2 years ago