Skip to main content

Set up SDK

React native
Flutter
Swift
Kotlin

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

info

If you're using Adalo, follow this guide instead.


React native UI component

If you're using React Native, we recommend using our React Native UI component.
It has been developed on top of react-native-iaphub and will make your life easier by providing React components to initialize IAPHUB and display a beautiful (customizable) paywall translated in 6 languages. If it is the right solution for you, please follow this guide instead.

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
Flutter
Swift
Kotlin

info

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.

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
Flutter
Swift
Kotlin

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
Flutter
Swift
Kotlin

info

Configuring the sandbox environment on iOS and Android is necessary to be able to test products that aren't approved yet and make test purchases for free. Otherwise the getProductsForSale method will return an empty array.

Detect when the billing system is unavailable

When the billing system is unavailable, the products for sale will be filtered and an empty array will be returned.
You can use the getBillingStatus method (after fetching the products) to detect when it is the case in order to display the appropriate error message.

On Android, we also recommend displaying an error message when the billing system is unavailable because the Google Play Store app is outdated (it can happen on old devices with an outdated software). Tell the user to open the Play Store app, go to "Settings", select "About" and click on "Update Play Store".

If the getBillingStatus method doesn't return any error but your product is missing, it is most likely a misconfiguration issue.
You should check the filteredProductIds property. If your product ID is in the array, it is an issue with GooglePlay/iTunes (we are relying on them to fetch the products details). Otherwise it is an issue with IAPHUB. Please follow this guide to walk through the different possibilities that could cause this issue.

var status = await Iaphub.getBillingStatus();

if (status.error && status.error.code == "billing_unavailable") {
  if (status.error.subcode == "play_store_outdated") {
    // Display a message on your paywall saying that the Play Store app on the user's device is out of date, it must be updated
  }
  else {
    // Display a message on your paywall saying that the in-app billing isn't available on the device
  }
}

if (status.filteredProductIds.length) {
  // Some products have been filtered because they were not returned by GooglePlay/iTunes
}
React Native
Flutter
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.

info

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', () => {
  // Refresh your data and UI here
});
React Native
Flutter
Swift
Kotlin

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
Flutter
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.

Detect deferred purchases

It is possible for a purchase to be processed outside of the buy method, for instance:

  • After a purchase is made outside the app (by redeeming a promo code on the store by example)
  • After a deferred payment (when the error code 'deferred_payment' is returned by the buy method)
  • After a payment fails because it couldn't be validated by IAPHUB (and succeeds later)

An event is available if you need to detect these purchases:

var listener = Iaphub.addEventListener('onDeferredPurchase', (transaction) => {
  // Process deferred transaction
});
React Native
Flutter
Swift
Kotlin

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
Flutter
Swift
Kotlin

info

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).

info

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', () => {
  // Refresh your data and UI here
});
React Native
Flutter
Swift
Kotlin

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
Flutter
Swift
Kotlin

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

await Iaphub.logout();
React Native
Flutter
Swift
Kotlin

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
Flutter
Swift
Kotlin

info

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.

info

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).

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.

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].