---
title: "How to Migrate from Glassfy to RevenueCat"
description: "Glassfy is ceasing operations in December of 2024. This is how to migrate from Glassfy to RevenueCat"
language: "en"
publishedAt: "2024-08-01T10:23:09Z"
updatedAt: "2024-08-01T10:23:09Z"
authors:
  - name: "Charlie Chapman"
    url: "https://www.revenuecat.com/blog/author/charlie-chapman"
category: "Engineering"
categoryUrl: "https://www.revenuecat.com/blog/engineering"
readingTime: 5
canonical: "https://www.revenuecat.com/blog/engineering/how-to-migrate-from-glassfy-to-revenuecat"
---

# How to Migrate from Glassfy to RevenueCat

Glassfy is ceasing operations in December of 2024. This is how to migrate from Glassfy to RevenueCat

## Table of contents

- [What RevenueCat plan to pick when migrating from Glassfy](#what-revenuecat-plan-to-pick-when-migrating-from-glassfy)
- [Configure RevenueCat](#configure-revenuecat)
- [Setup Offerings](#setup-offerings)
- [Update your app](#update-your-app)
  - [SDK References](#sdk-references)
- [Migrate existing data](#migrate-existing-data)
- [Now the fun begins](#now-the-fun-begins)
- [Migrating from Paddle and Glassfy to RevenueCat](#migrating-from-paddle-and-glassfy-to-revenuecat)
- [A shoutout to the Glassy team](#a-shoutout-to-the-glassy-team)

[Glassfy recently announced](https://glassfy.io/blog/important-update-glassfy-services-ending-december-2024/) that they are ceasing operations by the end of 2024. This guide will show you how to migrate from Glassfy to RevenueCat without affecting your subscribers.

Note that, for now, this guide details the process for an iOS migration. We will update with details specifically for Play shortly, but most of the principles and much of the process is the same. You can also check out the full [‘migration to RevenueCat’ guide in our docs](https://www.revenuecat.com/docs/migrating-to-revenuecat/sdk-or-not#integrating-with-our-sdk), though this is less specifically geared towards migrating from Glassfy.

## What RevenueCat plan to pick when migrating from Glassfy

The first step is to [sign up for RevenueCat](https://app.revenuecat.com/signup). It’s straight-forward (name, email, password), and you should be able to get started right away.

There’s just a single plan, which unlocks access to all the same features that our biggest customers use to serve tens of millions of subscribers, regardless of how much you pay us (if you’re even paying us at all).

Pricing is simple: 1% of tracked revenue in those months that you make $2,500 USD or more. In months where you make less, we won’t charge you and you’ll still have access to the full suite of features and functionality.

## Configure RevenueCat

Now, it’s time to configure your App Store app in RevenueCat.

Start by creating a project in RevenueCat for your app, and within the project click on the **Add an App** button, then select “App Store”.

![](https://cdn.sanity.io/images/c3qnx9b0/production/5c767aa9474ace4de95f2fe71feb6889eaec58a0-938x344.png)

Add a name for your app, and then copy the values from the Glassfy App Store configuration. The descriptions of each value are fairly similar, but if you’re unsure what value goes where, simply follow this table:

| **Glassfy App Store** | **RevenueCat App Store** |
| --- | --- |
| App Bundle ID | App Bundle ID |
| Apple Shared Secret * | App Store Connect App-Specific Shared Secret |
| In-App Purchase Key p8 File | P8 key file from App Store Connect |
| In-App Purchase Key ID | Key ID |

You will also need to enter your *issuer ID* in the RevenueCat purchases key section.

![](https://cdn.sanity.io/images/c3qnx9b0/production/492c90f5c5093f0516b9e1e0ddb70ccb17446ffa-1369x559.png)

You can find your *issuer ID* at [https://appstoreconnect.apple.com/access/integrations/api/subs](https://appstoreconnect.apple.com/access/integrations/api/subs). If there’s no code there, you may need to first [create an API key](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api), or you may not have admin access to this account. In the latter case, ask your admin to copy the code for you.

![](https://cdn.sanity.io/images/c3qnx9b0/production/98148981641714c122a58fdf27d89f118a4ade65-1600x821.png)

Click *SAVE CHANGES*, and then scroll down to the **Apple Server to Server notification** section.

Copy the Apple Server Notification URL, and – in App Store Connect – add it as your new Production Server URL under App > App Information > App Store Server Notifications:

![](https://cdn.sanity.io/images/c3qnx9b0/production/8586335300b738d1150e7b3e47208d1a42a1ad9c-2500x1925.png)

Note that, in your App Store Connect, you’ll see the Glassfy Server to Server Notification URL. Copy this, before overwriting it with RevenueCat’s URL: You’ll need it in the next step.

Go back to RevenueCat’s **Apple Server to Server notification** section. In the Apple Server Notification Forwarding URL, paste Glassfy’s URL. This will ensure that, as long as Glassfy is still operational, your data will be synced there as well:

![](https://cdn.sanity.io/images/c3qnx9b0/production/98e74df6e25bc14dee12a4212ddfbe05b6a4c8da-1600x534.png)

## Setup Offerings

Next you’ll replicate your Glassfy product configuration in the RevenueCat dashboard. RevenueCat has similar concepts to Glassfy, but uses different terms:

| **Glassfy** | **RevenueCat** |
| --- | --- |
| Products | Products |
| SKU | Package |
| Offerings | Offerings |
| Permissions | Entitlement |

For a more complete understanding of RevenueCat’s production configuration model you can check out our [docs](https://www.revenuecat.com/docs/getting-started/entitlements) or this video overview:

[Video](https://www.youtube.com/watch?v=QxHeZiW4KCA)

## Update your app

### SDK References

The Glassfy and RevenueCat SDKs are relatively similar. Use this reference to map your Glassfy methods with their RevenueCat equivalents:

#### Initialize the SDK

##### Glassfy

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

##### RevenueCat

```swift
Purchases.configure(withAPIKey: "YOUR_API_KEY")
```

#### Fetch offering

##### Glassfy

```swift
Glassfy.offerings { (offers, err) in
\u00a0 \u00a0 if let offering = offers?["premium_offering"] {
\u00a0 \u00a0 \u00a0 \u00a0 \/\/ display your offering's skus
\u00a0 \u00a0 \u00a0 \u00a0 for sku in offering.skus {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ sku.extravars
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ sku.product.localizedTitle
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ sku.product.localizedDescription
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ sku.product.price
\u00a0 \u00a0 \u00a0 \u00a0 }
\u00a0 \u00a0 }
}
```

##### RevenueCat

```swift
Purchases.shared.getOfferings { (offerings, error) in
\u00a0 \u00a0 if let packages = offerings?.offering(identifier: "premium_offering")?.availablePackages {
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for package in packages {
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let product = package.storeProduct
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print("Product Title: \(product.localizedTitle)")
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print("Product Description: \(product.localizedDescription)")
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print("Product Price: \(product.price)")
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}
\u00a0\u00a0\u00a0\u00a0}
}
```

#### Purchase an SKU

##### Glassfy

```swift
Glassfy.purchase(sku: premiumSku) { (transaction, e) in
\u00a0 \u00a0 \/\/ update app status accordingly
\u00a0 \u00a0 if let p = transaction?.permissions["premium"] {
\u00a0 \u00a0 \u00a0 \u00a0 if p.isValid {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ unlock aFeature
\u00a0 \u00a0 \u00a0 \u00a0 } else {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ lock aFeature
\u00a0 \u00a0 \u00a0 \u00a0 }
\u00a0 \u00a0 }
}
```

##### RevenueCat

```swift
Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in
\u00a0 \u00a0 if customerInfo?.entitlements["premium"]?.isActive == true {
\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Unlock that great "pro" content \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0
\u00a0 \u00a0 }
}
```

#### Verify permissions

##### Glassfy

```swift
Glassfy.permissions { (permission, err) in
\u00a0 \u00a0 \/\/ update app status accondingly
\u00a0 \u00a0 if let permissions = permission?.all {
\u00a0 \u00a0 \u00a0 \u00a0 for p in permissions {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 switch p.permissionId {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 case "premium":
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if p.isValid {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ unlock aFeature
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 } else {
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ lock aFeature
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 default:
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 print("Permission not handled");
\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }
\u00a0 \u00a0 \u00a0 \u00a0 }
\u00a0 \u00a0 }
}
```

##### RevenueCat

```swift
Purchases.shared.getCustomerInfo { (customerInfo, error) in
\u00a0 \u00a0 \/\/ access latest customerInfo
\u00a0 \u00a0 if customerInfo?.entitlements["premium"]?.isActive == true {
\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Unlock that great "pro" content \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0
\u00a0 \u00a0 }
}
```

#### Test and release

After testing all of your changes, publish the updated version of your app. Subscribers will retain access across versions.

If your new release is rejected by Apple, be sure to [tag us in a Tweet or LinkedIN post](https://x.com/RevenueCat/status/1681643378742575104), and we’ll send you some sweet, sweet App Store Rejection Socks 🧦

## Migrate existing data

Reach out to support@glassfy.io and ask for an export of all receipts associated with your app and user.

Call the [POST /receipts REST API endpoint](https://www.revenuecat.com/docs/api-v1#tag/transactions/operation/receipts) to iterate through the list, and push each purchase to RevenueCat. This will create the customer in RevenueCat, which will validate the receipt and keep the subscription up-to-date.

Note that any end user that is not imported can *restore purchases* in your app which will grant access to their content, and lead to their data being synced with RevenueCat.

## Now the fun begins

Congrats! Now your app is migrated, you can take advantage of the powerful capabilities RevenueCat enables.

Discover new insights into your business with our powerful [charts](https://www.revenuecat.com/feature/charts/) or create a fully native, backend driven paywall with [RevenueCat Paywalls](https://www.revenuecat.com/feature/paywalls/). You can run A/B tests to compare different paywalls with [Experiments](https://www.revenuecat.com/feature/experiments/), or send different paywalls to different users with our flexible [Targeting](https://www.revenuecat.com/feature/targeting/) feature.
If you have any issues or questions we’re here to support you as well. You can find a lot of help on the [RevenueCat Community](https://community.revenuecat.com), or reach out to our [support](https://www.revenuecat.com/support) team directly.

## Migrating from Paddle and Glassfy to RevenueCat

RevenueCat has a [native integration with Stripe](https://www.revenuecat.com/docs/web/stripe), as well as its own (Stripe-powered) web billing solution: [RevenueCat Billing and Web SDK](https://www.revenuecat.com/docs/web/revenuecat-billing). If you’re looking to migrate from Paddle and Glassfy to RevenueCat’s web billing solution, [reach out to support](https://www.revenuecat.com/docs/revenuecat-support/support-first-steps) and we’ll see how we can help.

We are considering a more direct integration with Paddle as well (and have built custom solutions for some customers), so don’t hesitate to reach out and discuss your particular needs.

## A shoutout to the Glassy team

Last but not least, a quick shoutout from us to Marco Pifferi and the Glassfy team.

Even as competitors, we a shared a mission: Help developers make more money. Glassfy took a different approach to that challenge then we did, and – especially in terms of business model – made big and admirable bets. In the actual platform, Glassfy built some unique capabilities which – in time – you may see reflected in RevenueCat as well.

We’ll be sad to no longer run into them ‘in the arena’, but have nothing but respect for their willingness to work with us on giving their users a ‘soft landing’.

*Buona fortuna* with the acquisition and whatever comes next, Marco and team!
