Skip to content

phzfi/ApprienUnitySDK

Repository files navigation

ApprienUnitySDK

Apprien Unity SDK is a lightweight client for Apprien Automatic Pricing API for mobile game companies using Unity. Apprien increases your In-App Purchases revenue by 20-40% by optimizing the prices by country, time of the day and customer segment.

It typically takes 2-4h to integrate Apprien Unity SDK with your game.

The minimal compiled footprint of ApprienUnitySDK is roughly 16KB.

Apprien.cs contains the main programming interface with the SDK, the ApprienManager class. The SDK contains code files for Unity Editor integration and unit tests. An example store showing the way Apprien IAPs can be handled is available in ExampleStoreUIController.cs

In case of any network or backend failure, ApprienUnitySDK will always revert to the base IAP ID and show the fixed prices.

Prerequisites

You need to setup app store integrations by providing Apprien the credentials to access the platforms to perform price optimization and automatically create the Apprien-generated products for your game.

Currently Apprien supports the following platforms

  • Google Play Store

Upcoming support on our roadmap

  • Apple App Store

Please contact sales@apprien.com to get the integration instructions for other stores.

Apprien provides your Quality Assurance team generic Apprien Game Testing Documentation and Test Cases on how to detect typical issues with your game and Apprien integration. By incorporating the Test Cases to your game's testing plan, you can ensure that Apprien integration works smoothly for your players.

Compatibility Notes

The SDK sends a web request to fetch a variant IAP ID that has the current optimal price set in the supported stores. The SDK uses UnityWebRequest for maximal platform support, and thus Unity 4.x and below are not currently supported in the SDK. Unity 4.x users can still access Apprien Game API for optimal prices, but the SDK does not offer a web request interface for 4.x (yet).

Officially supported Unity versions:

  • Unity 2019.x
  • Unity 2020.x
  • Unity 2021.x
  • Unity 2022.x

Using the latest available unityPackage might work just fine in newer Unity releases. We aim to support all LTS versions and a mid-year release for the current newest version. Older Unity versions might work just fine with the 2019.x package, but some elbow grease can be required. The SDK code is provided in full so that modifications can be made to ensure high compatibility with old and new Unity versions, and custom purchasing logic.

Using the SDK requires the official In-App Purchasing package by Unity in the Package Manager. All versions of the package for the supported Unity versions should work. See the SDK API documentation below for using the SDK with your product model.

The provided .unityPackage files in Releases are exported for each major Unity version, with latest available releases.

Setup

1) Open your project in a supported Unity version (see Compatibility Notes above)

2) Install the In-App Purchasing package in the Unity Package Manager

3) Import Apprien Import the correct version of the .unityPackage archive available in Releases containing everything required with an optional example store implementation.

4) Add integration to your Store controller

(For an example on how Apprien can be integrated with your Store controller, see ExampleStoreUIController.cs.)

Before your game with Apprien integration goes live, Apprien will generate IAP id variants for your IAP products. These variants will contain the same reward, description and other product details, only the price will be different. When the integration is live for your players, Apprien will then map your IAP id to the variant that corresponds with the optimum price.

You need to integrate ApprienUnitySDK to your current Store controller. The general overview of the end result is as follows:

  • When the store is initialized, you have the IAP ids of the products for your game.
  • You initialize an instance of ApprienManager class and wrap your products inside the ApprienProduct instances. See the relevant part of the API documentation.
  • Before you fetch the prices from the store, the IAP ids are passed to the Apprien Game API in a web request, which will respond with one IAP id variant for each product, with optimal pricing. The ApprienProduct instances that were passed to the relevant API method have been populated with optimized product variants.
  • You fetch the prices from Google and Apple using the UnityEngine.Purchasing.IStoreListener interface (or by other means). It is important to fetch prices for all products, both default and those returned from Apprien. If using the ConfigurationBuilder in Unity, it is safer to first add all defaults products to the builder, in case connection issues with Apprien, and only then fetch optimum prices, and initialize the IStoreListener (see code samples below in SDK API documentation).
  • You display the same product / reward on the in-game store, and the IAP id is the variant IAP id received from Apprien.
  • When a user purchases the product, the sale and transaction will be for the Apprien IAP id variant, instead of the fixed price product. The SDK has a failsafe, where any errors or connection problems will return the base IAP id instead, so that the players will be able to purchase products, only with the fixed price.
  • Your Store controller should refresh the optimal prices every now and then. Apprien updates the price points every 15 minutes. If you only fetch the Apprien-optimized prices during game load, players might not get served the most optimal price.

System Overview

Apprien SDK process overview

See the SDK API documentation below for code examples on how to use the SDK to fetch the optimal prices. Additionally, ExampleStoreUIController.cs shows a minimal example of enabling Apprien dynamic pricing in an abstract store.

Typically the product IAP IDs have been hard-coded somewhere in your game (ScriptableObjects, Unity IAP Catalog, JSON resources, fetched from your backend etc.). The SDK contains an intermediary model for products, ApprienProduct, which can be easily generated using the SDK from Unity IAP Catalog or the ConfigurationBuilder that is normally used to initialize products via UnityEngine.Purchasing

The player should be delivered the same amount of 'goods' (e.g. gems, gold) for the variants as for the base product. You can achieve this by passing the purchased variant IAP id through the static method ApprienUtility.GetBaseIAPId(...) that converts the variant back to the base IAP id for the delivery of goods.

5) Receipts (Optional, but recommended)

Apprien requires the data of the purchased transactions to perform the optimal price analysis. Apprien can obtain the transaction history also from Google Play and Apple iTunes, but it takes 24h or more to get the data. A faster way is to send the data straight away to Apprien from the client. This enables the pricing to be updated in real time (or by every 15 mins). For a code sample, see SDK API documentation below.

Also, if you are using a Store (e.g. Chinese) where Apprien doesn't yet have backend-to-backend integration, you can use client side integration to enable dynamic pricing.

6) Fraud Management backend (Optional)

A few gaming companies are using fraud management backends to verify real purchases from fraudulent ones (sent by hackers). Often the fraud management backends are written in various programming languages such as C#, Java, Node.js, Go, Python or PHP.

The problem is that the fraud management backend typically refuses the purchases of Apprien variant IAP ids because their names don't match to the expected ones. However, you can overcome this issue by passing the IAP id through the static ApprienUtility.GetBaseIAPId(...) method, which returns the default, base IAP id. For example if the customer purchased a variant by name z_base_product_name.apprien_599_dfa3, the method returns the expected base_product_name.

While we are working to implement adaptations for all commonly used programming languages, you can convert the GetBaseIAPId() method from Apprien.cs to your preferred language, since it works by using simple string manipulation available for all languages.

7) Testing

Please test the integration by following the generic Apprien game test cases.

The provided .unityPackages contain an editor script for testing the connection to Apprien.

Provided is also a set of unit tests for the SDK.

SDK API documentation

The SDK uses C# IEnumerator objects in many of it's classes and methods for asynchronous operation. There are two ways to execute the asynchronous methods correctly:

  1. Using any MonoBehaviour's StartCoroutine() method, e.g. this.StartCoroutine(_apprienManager.FetchApprienPrices(...));
  2. Advancing the IEnumerator manually using MoveNext() once per frame:
_pricesFetch = _apprienManager.FetchApprienPrices(products, () => { });

...
// In an update method, or from inside a recurring coroutine
if (_pricesFetch != null && !_pricesFetch.MoveNext())
{
    _pricesFetch = null;
}

Unity's StartCoroutine is the easier method, if your Store Manager is a MonoBehaviour. Otherwise, a MonoBehaviour instance may have to be passed to Store Manager from outside (during initialization).

Apprien.cs

Main file for integrating the SDK:

class ApprienManager

Main class for Apprien integration. Can be instantiated and kept in the Store Manager.

Method ApprienManager(string gamePackageName, ApprienIntegrationType integrationType)
Description Constructor for the class.

Usage:

_apprienManager = new ApprienManager(
    Application.identifier,
    ApprienIntegrationType.GooglePlayStore,
);

Method IEnumerator<ApprienFetchPricesResponse> FetchApprienPrices(ApprienProduct[] products)
IEnumerator<ApprienFetchPriceResponse> FetchApprienPrice(ApprienProduct product)
Description Main method for fetching IAP ids with optimal prices from Apprien. The first overload fetches all Apprien products using one HTTP request, while the second overload can be used to fetch single products. The former method is recommended if you have multiple products, to keep resource usage and loading times at minimum. The response objects have a Success property that can be used to control situations where the fetch failed. The method updates the given products in-place, so you don't need to handle the JSON data returned in the response object.

Usage:

/// <summary>
/// Fetch Apprien variant IAP ids and re-initialize UnityPurchasing
/// </summary>
private void FetchPrices()
{
    // Update the products with Apprien IAP ids
    StartCoroutine(FetchPricesCoroutine());
}

private IEnumerator FetchPricesCoroutine()
{
    yield return _apprienManager.FetchApprienPrices(_apprienProducts);

    // The products will now contain updated IAP ids. Add them to the product builder
    // If the connection failed or the variants were not fetched for some reason
    // this will add duplicates to the builder, which will ignore them safely.
    foreach (var product in _apprienProducts)
    {
        // Apprien variant IAP id. If connection failed, the variant IAP id
        // defaults to the base IAP id
        _builder.AddProduct(product.ApprienVariantIAPId, product.ProductType);
    }

    // Initialize UnityPurchasing with the fetched IAP ids
    UnityPurchasing.Initialize(this, _builder);
}

Method IEnumerator<ApprienPostReceiptResponse> PostReceipt(MonoBehaviour unityComponent, string receiptJson)
Description Optional. Sends a receipt of a completed purchase to Apprien for better pricing optimization. The transactions are normally fetched daily from the stores for analysis, but using this expedites the process. The response object can be used to determine if the operation was successful, but handling it is optional.

Usage:

public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
{
    var receipt = e.purchasedProduct.receipt;
    StartCoroutine(_apprienManager.PostReceipt(receipt));

    // Handle giving the reward to the player

    return PurchaseProcessingResult.Complete;
}

ApprienProduct.cs

class ApprienProduct

Intermediate model for products. Used to ensure that in case of connection errors or other failure, the base IAP id is used.

Method ApprienProduct(string baseIapId, ProductType productType)
ApprienProduct(Product product)
Description Constructor for the class. The second overload accepts a UnityEngine.Purchasing.Product. See below for more preferred initialization methods.

Method static ApprienProduct[] FromConfigurationBuilder(ConfigurationBuilder builder)
Description Create an array of ApprienProducts from the given ConfigurationBuilder that has already been filled with default products.

Usage:

_builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
foreach (var product in Products)
{
    _builder.AddProduct(product.id, product.type);
}

_apprienProducts = ApprienProduct.FromConfigurationBuilder(ConfigurationBuilder builder);

// Fetch the apprien prices and add them to the builder before initializing UnityPurchasing

Method static ApprienProduct[] FromIAPCatalog(ProductCatalog catalog)
Description Create an array of ApprienProducts from the given Unity IAP Catalog.

Usage:

var catalog = ProductCatalog.LoadDefaultCatalog();
_apprienProducts = ApprienProduct.FromIAPCatalog(catalog);

_builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
foreach (var product in catalog.allValidProducts)
{
    _builder.AddProduct(product.id, product.type);
}

// Fetch the apprien prices and add them to the builder before initizling UnityPurchasing

ApprienUtility.cs

enum ApprienIntegrationType

A helper enum for defining which store Apprien should connect to. Values:

  • GooglePlayStore
  • AppleAppStore (WIP)

Method public static string GetBaseIAPId(string storeIAPId)
Description Optional. Converts an Apprien-formatted IAP id variant to the base IAP id. Doesnt't affect non-Apprien IAP ids.

Usage:

var baseIapId = ApprienUtility.GetBaseIAPId(apprienProduct.ApprienVariantIAPId);

Method public static string GetIntegrationUri(ApprienIntegrationType type)
Description Convert the ApprienIntegrationType enum into a resource URI string that gets passed to the Apprien backend.

Usage:

var uri = ApprienUtility.GetIntegrationUri(ApprienIntegrationType.GooglePlayStore);

ApprienConnectionTester.cs

(optional)

Currently empty ScriptableObject only used for the ApprienConnectionTesterEditor.cs editor script.

ApprienConnectionTesterEditor.cs

(optional)

Editor script for ScriptableObject instanced assets of ApprienConnectionTester.cs. Can be used to test the connection to Apprien.

ApprienManagerTests.cs

ApprienBackendConnectionTests.cs

(optional)

Unit tests for the SDK and the internal backend operations. The tests can be easily run using Unity Test Runner. If the tests fail to compile, make sure you are targeting .NET Standard 2.0 or later.

Troubleshooting

Apprien prices won't show up in game. Only default fixed prices are visible.

See Apprien Unity SDK Test Plan to check for typical errors.

Links

See https://www.apprien.com for more information

See https://game.apprien.com for Game API documentation

Special thanks to

  • Daniel Liljeqvist @ Nitro Games
  • Jari Pauna @ Tunnelground

Support

Please contact support@apprien.com or open a ticket on https://support.phz.fi/

License

Apprien is a SaaS service with a separate end user agreement. However, Apprien Unity SDK (this project) is open source, see LICENSE for more information and feel free to contribute! This source contains third-party licensed content, see appropriate license files included with such content.

Trademark® Apprien

Copyright© Apprien Ltd 2015-2024

About

Apprien Unity SDK

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 15

Languages