Set up app

This guide will walk you through the differents steps to create and set up your app on IAPHUB.

1/ Create a IAPHUB account & create an app

If did not create an IAPHUB account yet, you can easily do so here, it'll only take a few seconds.
When logging in for the first time you'll be asked to create an app by providing the following informations:

Name
The name of your app
Currency
The main currency of your app, all your purchases will be converted to that currency and your metrics will be displayed in that currency as well
note

You won't be able to edit your currency after your app is created

Timezone
The timezone of your app that will be used for all the analytics and dates displayed on your dashboard
note

You won't be able to edit your timezone after your app is created

2/ Configure app

You should see a small widget that will guide you to the different steps to configure your app, we recommend using it.



Here is what you have to do before installing the SDK:

note

Do not forget to create a subscription group if you're looking to offer the possibility to upgrade/downgrade a subscription. For instance it is common to offer the possibility to buy a subscription for 1 month, 6 months or 1 year, in order to do this you would have to create a subscription group.

3/ Install SDK

You should install the IAPHUB SDK in your app.
All of our SDKs are open source and available on Github with the documentation in the README:

// Install react-native-iaphub
npm install react-native-iaphub --save
// Update dependency on xcode (in the ios folder)
pod install
React Native
Swift
Kotlin

note

Our code snippets below are using the latest SDK version available. If you installed the SDK a while ago, make sure you're up to date.

4/ Start SDK

You should call the start method as soon as possible when starting your app in order to initialize IAPHUB.

The appId/apiKey properties are available on the IAPHUB dashboard (Settings page).
The allowAnonymousPurchase property will allow you to purchase products without being logged in (using the login method we're talking about below).

await Iaphub.start({
 appId: "5e4890f6c61fc971cf46db4d",
 apiKey: "SDp7aY220RtzZrsvRpp4BGFm6qZqNkrt",
 allowAnonymousPurchase: true
});
React Native
Swift
Kotlin

5/ Get the products for sale

You should now try to get your products for sale. The method getProductsForSale will return the products you've configured in your listing. You can use the products returned to display your paywall.

var productsForSale = await Iaphub.getProductsForSale();
React Native
Swift
Kotlin

Detect when the products for sale are updated

You can also listen to the onUserUpdate event in order to know when your products for sale are updated.
If the products for sale are updated, the event will be triggered and you'll be able to refresh your data (and UI) by calling the getProductsForSale method again.

note

If the cache is outdated, the SDK checks automatically if the products for sale are updated everytime the app goes the foreground. So when updating your products for sale, keep in mind it won't be instant, the cache can last for up to 24 hours.

var listener = Iaphub.addEventListener('onUserUpdate', (err) => {
  // Refresh your data and UI here
});
React Native
Swift
Kotlin

My product isn't returned

Now if a product isn't returned, you have an issue. But don't worry we'll walk through the different possibilities that could cause this issue.

Check the products are configured correctly

First let's double check your products are configured correctly:

  • You've created your product on the Products page (of the IAPHUB dashboard) and on Google Play Console & iTunes connect.
  • The product sku is correct (it is the same on the IAPHUB dashboard, the Google Play Console & iTunes Connect).
  • The product type is correct.
    • On the Google Play Console, a auto-renewable subscription must be created in Subscriptions, a consumable or non-renewing subscription in In-app products.
    • On iTunes Connect, a auto-renewable subscription must be created in Subscriptions, a consumable in In-app purchases, a non-renewing subscription in Non-Renewing Subscriptions
  • The product status is valid.
    • It should be displayed as Active on the Google Play Console.
    • It should be displayed as Ready to submit or Approved on iTunes Connect (no need to submit it yet).
  • The product is available in your country.
  • You've published a listing with the products you want to sell and all the previous listings are offline (grey bubble icon).

Check if the product isn't returned by GooglePlay/iTunes

If everything listed above is correct we can assume it is an issue with GooglePlay/iTunes not returning the product (which is the most common issue).

When a product is returned by IAPHUB but not by GooglePlay/iTunes, the product is filtered. The getProductsForSale method doesn't return an error but you can use the error listener to catch the error.

note

If you're using React Native, you should have an error message '...did not return the product, the product has been filtered...' in the debug console without the need to use the error listener.

var listener = Iaphub.addEventListener('onError', (err) => {
  // This is how to catch when a product is filtered from the products for sale
  if (err.code == "unexpected" && err.subcode == "product_missing_from_store") {
    console.log("Error: My product isn't returned by GooglePlay/iTunes, sku: " + err.params.sku);
  }
  // You can also check any other error you might have
  else {
    console.log("Error: ", err.message);
  }
});
React Native
Swift
Kotlin

Check if it is a caching issue

The first thing to assume is that it is a caching issue, it can take a while for the product to be available right after you create it on GooglePlay/iTunes. So wait a little.

But it is posible to speed up things on Android by clearing the cache of the Google Play App!
Go to Settings -> Apps -> Google Play Store -> Store & cache and click on Clear cache.
The navigation might be a little different depending on your Android version but you should be able to find it.

Check if it is an issue with your phone or the configuration of your project

Check your project configuration is correct, a few things you should check:

  • Check your bundle ID match the one of the app you've created on GooglePlay/iTunes.
  • For iOS, check you've enabled the In-App purchases capability in XCode.

Also make sure your phone has no issue:

Check if it is an issue with your configuration of the Google Play Console / iTunes Connect account

The last thing to check and the most common issue.

If anything is missing or incorrect on your account or your sandbox environment isn't configured properly, GooglePlay/iTunes will simply not return any product. And unfortunately they also do not return an error that would allow us to tell you exactly what's going wrong.

So double check you've done correctly all the steps we list on our guides to configure your sandbox environment for iOS and Android.

note

Configuring the sandbox environment is necessary to be able to test products that aren't approved yet and make test purchases for free. You should test your implementation is working in sandbox before submitting your app to production.

6/ Make a sandbox purchase

If you're able to retrieve your products for sale, it's finally time to make your first sandbox purchase!
When the user click on a product for sale, simply pass the product sku to the buy method.

try {
  var transaction = await Iaphub.buy(productCliked.sku);
  console.log("Transaction successful: ", transaction);
}
catch (err) {
  console.log(`Error: Transaction failed, message: ${err.message}, code: ${err.code}, subcode: ${err.subcode}`);
}
React Native
Swift
Kotlin

Webhooks (optional)

If needed you can receive notifications on your server when an event occurs by using webhooks.
If you do, you can check the property transaction.webhookStatus that will tell you if the purchase webhook has been delivered to your server successfully.
The property webhookStatus should equal success if your server returned a HTTP response status code 200.

Errors

If you receive an error, taking a look at the error code and subcode properties will help you figuring out what's going wrong.

Please find below a list of all the errors you might encounter with a description and the message you might want to display to the user (you can of course customize the message, it is just to give you an idea).

Errors that are totally normal:

CodeDescription
user_cancelledThe payment has been cancelled.
No need to display any message
deferred_paymentThe payment has been deferred.
Message to display: Please wait, the payment is pending.

Errors caused by a configuration issue with IAPHUB:

CodeDescription
receipt_failedWe couldn't validate the receipt, double check you've configured your Google Play API credentials and iTunes shared secret correctly.
Message to display: We're having trouble validating your transaction, give us some time, we'll retry to validate your transaction ASAP.
server_errorCheck the subcode, it can be for different reasons but it is caused by something not configured correctly on the IAPHUB dashboard.
Message to display: We were not able to process your purchase, please try again later or contact the support.
product_not_availableThe product sku doesn't exist, make sure your product configuration is correct.
Message to display: The product is currently not available for purchase.
anonymous_purchase_not_allowedThe purchase failed because the user isn't logged in. Enable the allowAnonymousPurchase option to allow anonymous purchases.
Message to display: Please log in to your account before making any purchase.

Errors not caused by you:

CodeDescription
transaction_not_foundThe purchase failed.
Message to display: We were not able to process your purchase, please try again later.
network_errorA network error has happened.
Message to display: Network error, please try again later.
billing_unavailableThe Apple/Google billing system isn't available.
Message to display: In-app purchase unavailable on your device, please try again later.
cross_platform_conflictThe user already has an active subscription on a different platform.
Message to display: It seems like you already have a subscription on a different platform, please use the same platform to change your subscription or wait for your current subscription to expire.
product_already_purchasedThe user already own the product.
Message to display: Product already owned, if you do not have access to the product please restore your purchases.
product_change_next_renewalThe user tried to purchase a product that is already going to be active on next renewal.
Message to display: Subscription change already effective, your subscription will be updated on the next renewal date.
user_conflictThe product is currently owned by a different user id.
Message to display: Product owned by a different user, please use the account with which you originally bought the product or restore your purchases.
buy_processingA purchase is currently processing.
Message to display: Please wait, a purchase is currently processing.

Other errors:

If you receive the error code unexpected or any other error not on the lists above, simply display a basic error message: We were not able to process your purchase, please try again later or contact the support.

The subcode property might help you figuring out what's going wrong.

Smart assistant

If our smart assistant detect an error caused by a configuration issue, it'll send you an email with all the information needed to fix the issue. A widget Smart assistant will appear on the IAPHUB dashboard, simply click on the link (see screenshot below).



If you cannot find the cause of an error, send us an email at [email protected], we'll be happy to help.

7/ Get the active products

The getActiveProducts method will return all the subscriptions or non-consumables owned by the user.
If you're selling subscriptions in your app, you're most likely going to need this method to check if the user has an active subscription.

You won't need this method if you synchronize your server with IAPHUB using webhooks, since you'll be able to check directly with your server.

var activeProducts = await Iaphub.getActiveProducts({
  // To include subscriptions having a retry_period or paused state
  // includeSubscriptionStates: ['retry_period', 'paused']
});
React Native
Swift
Kotlin

note

If the request fails because of a network issue, the method returns the latest data in cache (if available with no expired subscription, otherwise an error is thrown).

note

If an active product is returned by the IAPHUB API but the product sku cannot be loaded (iTunes/Google doesn't return it), the product will be returned but only with the properties coming from the API (The localizedTitle, localizedDescription, localizedPrice, price, currency... properties won't be returned).

Subscription states

By default the getActiveProducts method only returns the subscriptions having a active or grace_period state.
If the includeSubscriptionStates option is specified, you could also get the subscriptions on a paused or retry_period state. (It can be useful if you would like to display a message)

See below the different subscription states (subscriptionState property):

ValueDescription
activeThe subscription is active
grace_periodThe subscription is in the grace period, the user should still access the features offered by your subscription
retry_periodThe subscription is in the retry period, you must restrict the access to the features offered by your subscription and display a message asking for the user to update its payment informations.
pausedThe subscription is paused (Android only) and will automatically resume at a later date (autoResumeDate property), you must restrict the access to the features offered by your subscription.

Detect when the active products are updated

You'll also need to use our onUserUpdate event in order to know when your active products are updated.

If any change occurs (subscription cancelled, expired, renewed...), the event will be triggered and you'll be able to refresh your data (and UI) by calling the getActiveProducts method again.

var listener = Iaphub.addEventListener('onUserUpdate', (err) => {
  // Refresh your data and UI here
});
React Native
Swift
Kotlin

8/ Authenticate the user (optional)

If your app has an authentication system, you can authenticate the user with IAPHUB by using the login method.
You can also make sure the option allowAnonymousPurchase of the start method is disabled, to prevent any purchase if the user isn't logged in.

By authenticating your users with IAPHUB you'll be able to search a user on the IAPHUB dashboard by using your own user id (and by using the IAPHUB API as well). The user will also be able to access his subscription from any device if he's logged on the same account.

If you do not authenticate the user with IAPHUB we're generating an anonymous device ID on the device to identify the user. The user will still be able to access his subscription on a different device but he'll have to call the restore method.
A subscription can be shared on up to 5 devices maximum (after a successful restore using the same iTunes/Google account).

Regarding the id, you should provide an id that is non-guessable and isn't public. (Email not allowed)

Also when calling the login or logout method, the current user is reset, you won't receive any onUserUpdate event until after you call getProductsForSale or getActiveProducts.

await Iaphub.login("1e5494930c48ed07aa275fd2");
React Native
Swift
Kotlin

And we also have a method to log the user out.

Iaphub.logout();
React Native
Swift
Kotlin

9/ Add button to restore the purchases

You should add a button somewhere visible in your app in order to allow the user to restore its purchases.
It'll re-sync the purchased transaction from the store account of the user (iTunes/GooglePlay).

It is also recommended to tell the user to restore its purchases to potentially resolve any issue/bug (for instance if the user has been charged but can't access his subscription for some reason).

await Iaphub.restore();
React Native
Swift
Kotlin

note

If you're authenticating the user (with the login method) and we detect that the transactions are already on IAPHUB with a different user ID, they will be transferred to the new user id.
It can be disabled in the settings of your app but it isn't recommended.

note

If you're not authenticating your users, restoring the purchases will allow them to restore a subscription (from a same iTunes/Google account) on a different device of the same platform (iOS/Android) (up to 5 devices allowed).

10/ Test your implementation

You should of course always test properly your implementation to make sure everything is working.
Sandbox testing is critical for testing your implementation and will allow you to purchase products without being charged.
Also sandbox subscriptions renew more quickly than normal to aid in testing.

11/ Release app

With everything we talked about above you should be able to release your app with In-App purchases pretty easily! Believe me if you were not using IAPHUB and you had to develop a custom implementation with StoreKit and the Google Play Billing library, everything you need wouldn't fit on one page... we would need a book ๐Ÿ˜….

If you're out of luck and your iOS app is rejected by the Apple Review Team, you should read this.

Upgrade your plan to production

Before submitting your app, do not forget to upgrade your IAPHUB plan to production (see screenshot below) in order to be able to process real transactions.


Display production data

If you want to display real transactions (instead of sandbox transactions), do not forget to switch the select to production data. It is located in the topbar of IAPHUB dashboard.


Need help?

If you cannot use the IAPHUB SDK because of an issue or if you have any questions, do not hesitate to contact us at [email protected].