Skip to main content

PlayFab integration V2

This guide explains how to configure PlayFab services for UniPay, specifically cloud save and receipt validation. Additionally, methods are being explained for keeping local user inventory in sync with PlayFab.

danger

This guide integrates PlayFab Economy V2, which is not backwards compatible with V1. V2 required several major changes in UniPay. Because of that, you cannot just import V2 in an older version of UniPay.

Compared to Economy V1 (legacy), Economy V2 changed the following things:

  • PayPal was removed as a payment option. If you would like to continue using PayPal payments, please consider using the native PayPal option in UniPay, or in combination with IAPGUARD for securing and server-validating PayPal payments
  • The Validation Only option was removed that allowed creating an anonymous user only when making a purchase, instead of requiring the user already being logged in with PlayFab before that
  • Subscriptions that charge real money are still not supported, however now virtual subscriptions are now supported (e.g. in exchange for spending virtual currency that was previously bought with real money)
  • Products offered on an App Store need to be of type Bundle and need to include another product of type Item, even if this is a single product purchase like 'no Ads'. PlayFab is working to resolve this inconvenience
  • There is no button in the dashboard to mass-upload products using a JSON file anymore, instead this needs to be done via their backend API
info

Please see the first chapter below for limitations and restrictions that apply when using PlayFab.

Prerequisites

What else can you do to avoid cheating? To put it simple – don’t do everything on the client, but verify each user action on external servers.

The PlayFab integration is a great starting point for that by keeping everything in sync with cloud save and doing critical transactions (like purchase validation) on their servers only.

If you're using PlayFab, this means that no data is saved on the device. Since that requires an online connection throughout the whole play session, it is the most secure solution by far, although better suited for online games and devices supporting a reliable internet connection (desktop pc's via ethernet or mobile devices using wi-fi). Please keep that in mind when making use of this. Basically you have two options with online-only games when there is no internet connection available:

  • logging into PlayFab is not possible - it would be best to disallow entering the game at this state
  • or, only permit offline mode without earning & spending (such as a training mode with local scores)

Also note that with the various different native plugins supporting mobile login via PlayFab (i.e. Play Game Services by Google), I am not able to write a separate integration guide for each of them. The default login method is via registered email addresses, or automatic login on platform where a user is already authenticated (like Steam), which are the most common techniques for desktop applications. Please refer to the PlayFab documentation for implementing other login methods.

With that out of the way, let's continue by creating your PlayFab developer account.

Creating a PlayFab account

Creating a PlayFab developer account is easy and free. Sign up here: PlayFab Website

Once you're logged in, you will be greeted by a somewhat empty screen, where you can define your company and game name. In PlayFab, when speaking about games, they are usually referred to as Titles. Each game must have its own title (or dashboard), which is used to independently track users, purchases, cloud scripts and all the other stuff PlayFab provides.

After you've created your first title, it should be shown under your games page along with its generated title identifier.

PlayFab-Integration010

Creating your store catalog

Now with the title created in PlayFab, we need a way to transfer all the different in-app purchase products from Unity to PlayFab. Unfortunately with Economy V2, PlayFab removed its dashboard button to upload a JSON configuration directly from UniPay. At the moment, you will have to create your products manually, or use their backend API.

Navigate to the Economy > Catalogs (V2) section. If your game uses a virtual currency, start with that and create your other products later. There are a few specific configurations that need to be done for each product type, which will be explained below. Since fullscreen images would clutter this guide too much, each of the catalog screenshots are linked rather than shown here: open them to see them in their original size.

Virtual Currency

For your products to be purchased with virtual currency, you have to define a currency in PlayFab first. This is similar to the Project Settings > UniPay In-App Purchasing > Currencies section in Unity. The Friendly ID in PlayFab should be set to your currency identifier in UniPay. In this case, coins.

PlayFab-Integration020

Products for Real Money

Products for real money need to be defined in the Bundles tab on PlayFab, since only this type of products support App Store identifier mapping. As an example, we are going to add a currency bundle and a no ads product.

In the currency bundle, there are 3 important settings:

  • Friendly ID: this needs match your product identifier entered in Project Settings > UniPay In-App Purchasing > Products
  • ITEMS: here you add how much currency should be granted to the user, matching what is defined in UniPay
  • MARKETPLACE MAPPING: these are your App Store product identifiers. Add them, even if they are the same as the Friendly ID

PlayFab-Integration030

Now for the no ads bundle, there is a workaround we have to take due to PlayFab requiring each bundle granting an item. So the no ads bundle needs to grant a separate no ads product, basically. And if the bundle grants an item, we have to create the item before the bundle. Navigate to the Items tab and create the no ads product. As always, the Friendly ID needs to match your product identifier in UniPay.

PlayFab-Integration040

Note that all other product categories are left empty and there is no marketplace mapping that we could populate. So, navigate to the Bundles tab and create your no ads bundle. The most important part is the Friendly ID: it is kept empty! This is because we do not want this bundle to be a separate product, but only have it grant one no ads item when purchased via the marketplace mapping identifier.

PlayFab-Integration050

Products for Virtual Currency

After you've created a virtual currency, creating virtual products is very easy. Just make sure that the currency price and item grants match what is defined in UniPay, otherwise PlayFab will report that it cannot find that product constellation.

PlayFab-Integration060

Subscriptions

PlayFab only supports virtual subscriptions, in exchange for virtual currency, not real money. And since a subscription needs to grant an item too, like a bundle, we have to define that item first, then the subscription. Here comes the special thing: the virtual subscription and the item it grants when active are actually two distinct products. So while the player purchases the subscription, you have to check the item to determine whether they currently own the subscription. However while that item needs to be defined in UniPay as well, it should not be displayed in a shop anywhere (only the subscription product).

PlayFab-Integration070

PlayFab-Integration080

Importing the PlayFab Unity SDK

First of all, download the PlayFab Unity SDK from the official Microsoft Landing page. The Editor Extensions package is not necessary.

PlayFab-Integration090

After downloading, import the PlayFab SDK into your Unity project. For establishing the relation between the SDK and your title on PlayFab's servers, you will have to enter its title ID in the SDK settings. Locate the PlayFabSharedSettings file in your project as shown below, then enter the title ID that has been generated for you in PlayFab's dashboard (see first screenshot in this guide). The Developer Secret Key is located at Title Settings > Secret Keys > Default Key.

PlayFab-Integration100 PlayFab-Integration110

Next, open Project Settings > UniPay In-App Purchasing and import the PlayFab (External SDK) package by pressing the corresponding button.

PlayFab-Integration120

Marketplace Setup

Your in-app purchase receipts will get sent to PlayFab for validation and approval, so only verified transactions are granted the correct amount of products or currency. For this, PlayFab needs some of your App Store secret keys to validate their authenticity for you. Head over to the Add-ons section, where you'll have to activate one or many of the platforms you would like to use.

PlayFab-Integration130

For a list of platforms supported by Economy V2's receipt validation, please see this page. UniPay has been tested with Google Play, Apple App Store and Steam.

PlayFab-Integration140

  • Google App Package ID: Google Play Developer Console, App > Dashboard, below your app name
  • Google App License Key: Google Play Developer Console, App > Monetisation setup > License, Base64-encoded RSA public key
  • Service account key: Key ID after following the official documentation

PlayFab-Integration150

  • iOS App Bundle ID: App Store Connect, Apps > App Information, Bundle ID
  • iOS App Shared Secret: App Store Connect, Apps > App Information, App-Specific Shared Secret

PlayFab-Integration160

  • Steam Application ID: Steamworks dashboard, the number after your app name
  • Steam Web API Key: Steamworks dashboard, Users & Permissions > Manage Groups > Everyone (WebAPI), create key on right side

Logging in the user in Unity

With PlayFab integrated, our DBManager will not save any data locally on the device. This is also reflected by the DBManager's Storage Target = Memory mode, which is activated automatically for this, and means that players need to download their own data from the PlayFab servers each time your app is launched. This complies with a high-security app environment, as there is no local data or any save games regarding in-app purchases that could be tampered with.

This also means that players need a way to get their purchase data, and only their data, by logging in to PlayFab servers. UniPay provides a very basic example login scene that you can learn from, use or customize.

PlayFab-Integration170

The login example scene offers registration and login via email & password. On platforms where players are already authenticated when launching the game, like on Steam, you would want to skip any manual authentication flow. This is why when running on Steam, the example login scene authenticates the user automatically with PlayFab using their Steam session token so they do not need to enter anything.

note

If you are creating your own login scene, note that the important configuration in this scene is having the PlayFabManager prefab present. Additionally, it needs to contain the IAPManager prefab with the Auto Initialize toggle disabled. After logging in, the PlayFabManager will then make a call to initialize the IAPManager automatically.

Feature Overview

Now that we've implemented PlayFab, in this chapter we're going to take a look at everything the integration does for us.

Receipt Validation

Receipt validation happens whenever users purchase any product in the shop. Both real money and virtual purchases, as well as the result (e.g. inventory and virtual currency balances) are synchronized with PlayFab - nothing exists locally on the device.

On the PlayFab dashboard, this allows you to go into great detail about monetization, track purchase amounts across platforms and even inspecting single users on what they bought in your game. For a more aggregated summary on what your users are buying in your game, along with how often they do it, you can set up a query in the Analytics section for a bar chart analysis.

PlayFab-Integration180

PlayFab-Integration190

Cloud Save

Since all transaction related actions are acknowledged by the PlayFab servers, they are registered on the user's PlayFab account. In the user's perspective this means that, combined with a login system described in the last chapter, users can switch devices, uninstall & reinstall the app, still retrieve their data and continue playing without any loss of data (more on synchronization in the next chapter). In an administrator's perspective (yours), having everything flowing over PlayFab's servers allows you to control virtual currency economies, modifying currency balances or inventory of hacking users, banning their accounts, giving out product keys as promotions or just looking at what your players are doing.

PlayFab-Integration200

Introducing Sales

Temporary sales for products could be a way to make specific items or purchases in general more appealing - the big benefit here is that you can introduce IAP sales without updating your app. If you know you would like to run sales in the future, just check the Fetch checkbox for both real money and virtual products in the IAP Project Settings.

PlayFab-Integration210

What this does is not only fetching and displaying localized prices of real money products from the App Stores, but also downloading current virtual product prices from your title's economy catalog in PlayFab. So in order to run a sale for a specific virtual product, just open it in PlayFab's catalog and edit its price. The new price will be effective when users relaunch your app.

PlayFab-Integration220

In-game Synchronization

Many game actions are automatically synchronized with PlayFab at the time they happen in your app. This applies to everything that requires an interaction with PlayFab's servers, basically. For example, these are the actions which get auto-synced:

  • user purchases real money product (product is assigned to inventory)
  • user purchases virtual currency (currency amount is updated)
  • user purchases virtual product (currency amount is updated, product is assigned to inventory)
  • user purchases virtual product with usage count (currency amount is updated, product usage is updated in inventory)
  • user selects/unselects product (selection value is updated in Player Data (Title))

PlayFab-Integration230

As you can see, most of the shop synchronization is handled for you already. What UniPay cannot know though, is what you are doing with these items in your game. This means that everything dependent on your own game-specific use case also has to be handled and synchronized by you. The PlayFabManager (link to Scripting Reference) provides several methods, described below, for syncing your data back to PlayFab. Each method is explained with a sample use case and the point when it's best to call it.

SetPurchase

Use case: the player finds a new weapon in-game and you would like to give it to them for free. Note that this method is best suited for non-consumable products, as for consumable products you should call the other methods directly to minimize web requests. When: at any point during the game.

Use case: the player previously bought some power-ups with usage count. They then activate them in-game, which you are tracking via DBManager.ConsumePurchase (to substract the power-up usage count). You then want to synchronize the remaining usage count with PlayFab by calling this method. When: only at the end of a round or level, to minimize web requests.

SetPlayerData

Use case: the player reached a certain level or you want to save a progress value for each level (1, 2, 3 stars). You have tracked this via DBManager.Set/AddPlayerData. You then want to synchronize these custom values with PlayFab by calling this method. When: only at the end of a round or level, to minimize web requests.

SetCurrency

Use case: the player collects coins during the game, which you are tracking via DBManager.IncreaseFunds. You then want to synchronize the current currency amount with PlayFab by calling this method. When: only at the end of a round or level, to minimize web requests.

SetSelected

Use case: you have an in-game inventory display where players can select and deselect e.g. weapons. Note that the selection in the shop scene is synced for you already. When: at any point during the game.

Adding Cloud Scripts

Some of the methods listed in the previous chapters are calling custom code on PlayFab's servers, referred to as cloud scripts. Each title on PlayFab has its own server code section hosted on Microsoft Azure using Functions, where you can execute actions which should not be in the hands of users (to prevent hacking), such as granting products or virtual currency, or just to add another security measure by checking the values it receives for feasibility. You have to setup some Azure functions with the code mentioned below, so that UniPay is able to properly call them for your title. Note that the Microsoft Azure subscription includes a generous free tier for calling and executing functions.

In the (Azure Portal), create a new Functions application with an unique URL. When created, it should look similar to this:

PlayFab-Integration241

Under the Configuration section, add a PLAYFAB_DEV_SECRET_KEY variable with the value found in your PlayFab's title, under Title settings > Secret Keys > Secret Key. If there is no Default Key yet, create one first. This key serves as an authorization mechanism for allowing your Azure functions to call the PlayFab API.

PlayFab-Integration250

Next, set up a Visual Studio or Visual Studio Code project for Functions deployment. For more information on how to create a project for this, please see (the official quickstart documentation). In this project, add a PlayFabFunctions.cs file and copy-paste the code included in UniPay, located at UniPay > Extensions > PlayFab > Scripts > CloudScript.txt. Note that there are a few NuGet packages required as described in the quickstart guide, namely the PlayFabAllSDK and PlayFabCloudScriptPlugin packages. Additionally, add a CS2AFHelperClasses.cs file with the code found (on this respository).

With the function code deployed to Azure, you should see a setItems and addItems function in your application dashboard. For each function, open it and copy the function URL.

PlayFab-Integration260

In PlayFab, register these functions with a HTTP trigger and insert the URL copied from Azure before.

PlayFab-Integration270

Congratulations, you've made it to the end!