Quick Start

This guide outlines the 10 steps to integrate subscriptions and in app purchases in your app.

1. Store configuration

Configure the stores you use by following the relevant guide:

2. Configure SKUs

The SKU is the Glassfy unique identifier to link to a product on the app stores you use. There are two steps:

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

3. Configure permissions

Permissions control which Glassfy feature or content a user can access. It references a list of SKUs defined in Glassfy and allows app developers to check if a user has appropriate access without checking all the products or SKUs in application code. Each app can have multiple permissions that unlock different features or content.

Read the permissions guide for more detail.

4. Configure offerings

An offering allows you to add SKUs to Glassfy and list them dynamically in an app without recompiling and resubmitting it for review. It references a list of SKUs and allows customers to change the chosen SKUs or add others. Each app can have multiple offerings which can have different content.

Read the offerings guide for more detail.

5. Configure SDK

Read the following guides depending on what your application needs:

6. Install SDK

Read the SDK installation guide

7. Initialize the SDK

Copy your APIKEY from the Glassfy Setting page and use it to initialize the SDK with the following code:

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

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

}
[...]
   ContentView()
      .onAppear {
           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({ apiKey: 'YOU_API_KEY', watcherMode: 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 code example below shows how to fetch the offering 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 an SKU

When the customer makes a selection from the list of SKUs displayed from Step 8, the app uses 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 Transaction object returned contains a list of permissions (as configured in Step 3 ) that can unlock specific sections of an app.

The code above checks for the premium permission.

10. Verify permissions

The example code below uses permissions to verify the status of subscriptions or in-app purchases (IAP):

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.

Next steps

You have completed integrating 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 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.