How to integrate subscriptions and IAPs in 10 steps
This guide will help you integrating subscriptions and in app purchases in your app in 10 steps.
1. Store Configuration
Configure the stores by following our guides:
2. Configure SKUs
The SKU is the Glassfy unique identifier to link a product on the 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 you should create SKUs in Glassfy
3. Configure Permissions
The permission allows to control which feature or content the user as access to.
It references a list of SKUs and allows app developers to quickly check the 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.
4. Configure Offerings
The offering allows to purchase SKUs dynamically without recompiling and resubmitting for review. It references a list of SKUs and allows user to change the choosen SKUs or add other of them. Each app can have multiple offerings which can have different content.
5. Configure SDK
- App Store Configuration & 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 at the Step 4
The offering will contains a list of SKUs that you can use to update the UI of your app with purchasable SKUs.
In the following example we hare 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 its selection from the list of SKUs displayed at the Step 8 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 contains a list of permissions (as configured at the Step 3 ) that can be used to unlock specific sections of your app.
In the above example we are checking for the permission premium
10. Verify permissions
You can use the permission
to verify 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 wil return a Permissions object or an error
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 simply 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 13 days ago