Overview

Inventory Service provides endpoints to create/modify/update inventory.

It integrates with 3rd party stores such as Google PlayStore and Apple AppStore to validate receipts and listen for notification from store.

There are four major concepts in this service: item definition, product definition, user records and inventory.

The basic flow is:

  1. Developer creates item definition and product definition
  2. User purchase product and receives the items defined in the product in user's inventory.

Item Definition

Item definition is template for an item.

Game developers create an item definition, which makes the developer the owner of the definition.

By default, the owner can create items from item definition that goes into a user's inventory. Developer can grant other game/user permission to create items.

Item definition is not tied to a game. This means any game can choose to implement any item created by anyone. For example, a streamer can create an item definition, then several game developers can implement this item in their games.

Item definition's ID is unique globaly. To avoid collision, the ID is prefix with owner's user ID, ie. <owner ID>:<item ID>

Product Definition

A product defines a list of items that user obtains upon purchase. It also defines a list of cost that will be consumed from user inventory during purchase.

Product is tied to a game, similar to how 3rd party store defines products under an app. Product ID is scope under the license and will not conflict with products from other games.

Real Product Type

Real product are tied to 3rd party store such as Google PlayStore or Apple AppStore. The product ID must match the ID on the stores.

Real money transaction is handled by the store. Inventory service validates the receipt with the store and grants the items in the product. Cost for real product is only for reference.

Virtual Product Type

Virtual product are transaction that exchange a set of in-game items or another set. Cost is a list of item definitions and quantities to be consumed from user inventory.

Reward Product Type

Rewards are essentially free give away with no cost. Only game owner can process a reward product.

User Records

Records are entries from any changes in user's inventory, range from purchase, consume, refund, share claim, share revoke, and store notification.

This provides a history of what occur in the inventory.

User Inventory

A list of items that user owns. Items are created from item definition. Each item has quantity, such as 100 gold. Most items of same ID are aggreagated into a single entry but some are separated into its own entry due it having unique properties, such as expiry date for subscription.

Aggregated item

Most common items are aggregated, meaning a single entry for an item. For example, if user have an entry of 100 gold and makes a purchase for 10 gold, the additional gold is added to the same entry, resulting in the entry with 110 gold.

Non-aggregated item

Items have their own unique entry when they have unique properties such as expiry date. A ticket that will expires next month cannot be aggregated with another ticket. In general, any product that defines expiry for its items will result in a unique entry in the inventory.

Share item

Share item are separate from regular user inventory. They are available for another user to claim and adds to that user's regular inventory by using a share code. The purchaser of the share item can also revoke the share item, at which point the other user lose the item. The purchaser cannot use share item in any way such as paying for a purchase.

Permission

Inventory service use the Authorization Bearer token in the request header to identify the caller's identify.

Caller's user_id claim refers to the field in this token.

Owner of game

For the caller to own a game, the caller must have the game's license ID in the licenses claim.

Owner of item definition

For the caller to own an item definition, the caller's user_id claim must match to item definition's owner field.

Creator of item definition

For the caller to be a creator of an item definition, caller's user_id claim must exist in creator_user field in the item definition.

Alternatively, one of caller's licenses claim must match an entry in creator_license in the item definition.

Guest user

While guest user can have an inventory, it is advised not to make purchase or give items to guest user. The guest user ID is lost when the app is reinstalled. It also does not carry over to another device.

Caller's claim refers to the fields in the HTTP request's OAuth bearer token. For example, for the caller to own a game, the caller must have the game's license ID in the licenses claim.

Purchasing workflow:

See reference image from https://docs.unity3d.com/2018.4/Documentation/Manual/UnityIAPProcessingPurchases.html

  1. App's server is the Inventory Service
  2. Step 6 could fail if connection to Inventory Service is not available. In this case the App should cache the receipt and re-send the receipt to Inventory Service until successful
  3. Between Step 6 and 7, Inventory Service needs to validate the receipt with Partner store and update the inventory
  4. After Step 7, App can pull the updated inventory

Changes to user inventory:

Any changes to user inventory such as consuming an item, purchasing with virtual currency involves the App sending request to Inventory Service.

Other part of the platform can also modify user inventory (such as giving reward) by talking directly to Inventory Service.

The App should regularly query user inventory to get the most up-to-date data.

Persistent Layer

Inventory Service is designed to use DynamoDB to achieve flexible data attributes and fast response to request, prioritized by access patterns.

Receipt Validation

Each 3rd party store requires a credential in order to validate receipt. In order for Inventory Service to process real purchase, it needs to have this credential. See below on how to create this credential in each store, then upload it through Dev Portal.

Google PlayStore

You should create a service account for your project at https://console.developers.google.com and download a JSON key file. Copy content of the JSON file to Dev Portal.

Setup subscription Pub/Sub in your Google Developer Console and set the Push endpoint to https://sagames-api.streamsix.com/store-broadcaster/playstore/sub/<your-license-id>

Apple Store

Follow instruction here to create a shared secret: https://help.apple.com/app-store-connect/#/devf341c0f01 then copy it to Dev Portal.

Setup App Store Server Notifications by setting both production and sandbox url to https://sagames-api.streamsix.com/store-broadcaster/appstore/sub/<your-license-id>