Billing

From HEWIKI
Jump to: navigation, search

Contents

Overview

HeroEngine’s in-game billing system is designed to facilitate the purchase of items from a game’s HeroEngine Store. Comprised of three distinct modules (client, server and web), the in-game billing architecture provides a complete set of tools to add microtransaction capabilities to any HeroEngine game.

How In-Game Purchases Work

A successful store transaction is carried out by the player as follows:

  1. The player navigates - using the in-game browser - to the game's HeroEngine Store and makes a purchase of a store item.
  2. The game server receives confirmation of an item purchase and begins the process of fulfillment by querying an internal billing webservice for details of the completed transaction.
  3. Once informed, the game server fulfills the purchase in-game by instantiating any purchased items and giving them to the player.

Billing Architecture 1.png

Organization

Areas of Responsibility

From a development perspective, the in-game billing system is split into three parts:

Billing Architecture 2.png

The Web Store is managed via the "Microtransaction Stores" administrative interface accessed from your HeroEngine web portal. This is where stores and items may be created and managed, and it’s where customizations to a store’s state and appearance are made. The items created here - separate from their in-game counterparts - are used to visually represent a set of items within the web-based store view. They also serve as the basis for in-game item fulfillment and act as the ‘authoritative source’ of purchasable items for your game. In-engine, these item definitions are synced to establish a link between the web-based item description and your in-game fulfillment logic.

Item Definitions exist in pairs: one in the web store and one in-engine. Each is required in order for successful purchases to be made, and each has a reference to the other in order to bridge web purchases with in-game items. After an item is created via the "Microtransaction Stores" administrative interface, a sync may be performed in-engine; this creates the in-game version of the item definition and will allow item fulfillment logic to instantiate items to give to players who make a purchase.

Fulfillment Logic links the in-game item definitions created via a web-store sync with the logic required to instantiate, initialize and deliver items to a player in-game. This logic exists as part of the spec system and can be extended to produce items of any custom type with any desired custom logic.

Sequence

Billing Sequence 1.png The basic sequence of events when setting up microtransaction capabilities for your game are as follows:

Once these steps have been completed, players may then use the in-game web browser to view the game's HeroEngine Store, make purchases, and receive in-game versions of those items as a result. This is the foundation for HeroEngine Stores.

Entities

Billing Entities 1.png

Billing System Area

All communication between the in-game servers and the billing webservices is performed from the Billing System Area. This area is responsible for querying for transaction information, performing item store syncs, and initiating item fulfillment after a successful transaction.

Billing System Node

On the client, this is where the point of access to launching the in-game browser to view the game's HeroEngine Store lives. On the server, all interaction with the billing webservices and the external shop item spec oracle is carried out here.

External Shop Item Spec Oracle

In order to fulfill items in-game, item definitions must exist in this oracle. These definitions are brought in from the web via a synchronization operation. Once finished, the sync will have created one spec per defined item and populated it with identifying information. These specs are then used to perform logic to fulfill item purchases.

External Shop Item Spec

All logic required to fulfill an in-game purchase is associated with an external shop item spec. This can include instantiating a persisted node representing the item, manipulating a player's account or character data, or interacting with other game systems to unlock features and functionality. Logic related to fulfilling purchased items can be arbitrarily extended to produce unique, game-specific behavior.

External Shop Item

As part of fulfillment, the default behavior of the system is to factory a persisted external shop item instance. This instance can represent a physical item (like a piece of armor) or it can be extended to represent any custom game-specific concept.

Communication

Billing Communication 1.png

Most communication in the billing system - such as requests for purchase details or item definitions - occurs between the billing system area and the internal webservices. These operations are generally carried out autonomously on behalf of the player and are restricted to being run at specific times and only in the designated system area. All other communication is focused on directing the appropriate commands and instructions toward the billing system area (in the case of user-initiated commands) or toward the player (in the case of informational feedback).

Instances of inter-process or client/server communication:

Security

Due to the sensitive nature of performing real money purchases, great care is taken to make sure there are no breaches of security. Specifically:

Though the billing system is highly extensible and custom logic can be inserted to perform custom fulfillment, the act of carrying out a purchase is tightly regulated inside a small number of methods on the billing system node. It is not possible for a developer to compromise this functionality.

Integrity

It's possible for a player to purchase an item and then have fulfillment fail in-game. This could be due to the player no longer qualifying for the item at the time of fulfillment, or it could be due to errors in the implementation of game-specific systems involved in fulfillment. Either way, there are safeguards in place to prevent loss of currency or unintended consequences of failed fulfillments:

Usage

Support for in-game microtransactions requires the following to be true:

At this point, any client can invoke an in-game browser to view the web store and - if they have the access and the currency - can purchase and receive items.

Creating a Microtransaction Store

To use the Microtransaction User Interface from the Account website, login using your active HeroCloud account at https://account.heroengine.com. Your account must be setup as an “Administrator”, “Developer”, or “Tester” on a valid Group, which must in turn have the Microtransactions feature enabled. If you do not see the “Microtransaction Stores” menu on the sidebar of the Dashboard (below), please contact your Group Owner or HeroEngine Support. Please reference the User Interface section (later) step-by-step details on creating a Microtransaction Store.

Billing Usage 1.png

Note that in order to be able to view a new store from within the Heroengine client, a separate update must be made, which currently requires action from the HeroEngine Team. Please contact Idea Fabrik to enable this store to be accessible from the game client.


Performing an Item Sync

Billing Usage 2.png

To perform a sync of the items defined in the HeroEngine Store:

External shop item specs will only be created once for each item defined in the HeroEngine Store. Subsequent syncs will update the data associated with the items based off of a hash value calculated upon edits. In order to keep your in-game items up-to-date, make sure you perform syncs periodically.

External shop item specs will never be deleted, even if your HeroEngine Store items are. This is necessary in order to keep an accurate history of previously-fulfilled items. If you want to disable a spec's ability to fulfill items (causing purchases of that item to fail), simply mark it as 'deleted' in the spec editor.

Adding Custom Fulfillment Logic

Billing Usage 3.png

Fulfillment of individual items is performed exclusively by the spec to which the item definition belongs. Extending or customizing a spec's fulfillment logic can be accomplished by glomming one or more decorators onto a spec or by creating a new spec class to be used alongside item syncs.

Opening an In-game Browser to the Store

Billing Usage 4.png

Browsing to the HeroEngine Store is as simple as calling the following method from the client, specifying the name of your store:

 $_BILLING._OpenExternalBillingShop(request_id, store_name, browser_width_in_pixels, browser_height_in_pixels)

The player can then navigate the store and make purchases.

Receiving Fulfilled Items After a Purchase

Billing Usage 5.png

Items begin fulfilling immediately after a purchase is made via the web-store. By default, fulfillment will generate a persisted _ExternalShopItem node from the appropriate _ExternalShopItemSpec and will then issue a pop-up message suggesting that custom fulfillment logic be implemented. It is recommended that developers replace this functionality with custom fulfillment logic of their own by following the steps outlined in the section titled ‘Extending The Billing System’.

A Closer Look

The following is a closer look at the sequence of events that occurs during an item purchase: A client script opens an in-game browser to the HeroEngine Store:

 $_BILLING._OpenExternalBillingShop(new_request_id, "My Item Store", 1280, 768)

The browser receives confirmation that a purchase was successful and passes that confirmation back to the client in the form of an HSL callback:

 $_BILLING._OpenExternalBillingShopCallback(902286018600914, "success", "BMS_HEROENGINE_STORE[14329]")

The client then performs a call to the area server the player is connected to, passing the confirmation along:

 call server %_BILLING._OnClientCompleteTransaction(accountID, federatedTransactionID, additionalData)

The area server forwards the notification to the billing system area:

 call area $_BILLING._GetBillingSystemAreaID() instance 0 $_BILLING._OnClientCompleteTransaction(accountID, federatedTransactionID, additionalData)

Which then constructs a _BillingTransactionFulfillmentAnchor to maintain the state of the transaction's fulfillment from initiation to completion:

 transactionFulfillmentAnchor as NodeRef of Class _BillingTransactionFulfillmentAnchor = $_BILLING._BillingGetOrCreateTransactionFulfillmentAnchor(federatedTransactionID)

The system area then invokes two calls to the billing webservices: the 'order update' webservice (to notify web which player we want to fulfill items for) and then the 'query' webservice (to obtain the pertinent information related to the transaction):

 $_BILLING._BillingDoMakeWebServiceRequest(requestID, "transaction/update:BillingOrderUpdateRequest", $_BILLING, parms)
 $_BILLING._BillingDoMakeWebServiceRequest(newRequestID, "transaction/query:BillingOrderQueryRequest", $_BILLING, parms)

Upon receiving the go-ahead response from the webservice, the system area replicates the fulfillment anchor to the area the player is in:

 areaInstance as Class _AreaInstance = $WORLD._WhereIsPlayer(me._BillingTransactionFulfillmentAnchorAccountID)
 repGroup._AddServerDestination(areaInstance._currentArea, areaInstance._currentAreaInstance)

And when the node arrives at its destination, the local billing system instructs each spec involved in the order to begin fulfilling its items:

 foreach externalShopItemSpekKey in me._BillingTransactionItemPurchaseMap
   fulfillmentSpec as NodeRef of Class _ExternalShopItemSpec = shopItemSpecOracle.GetSpecByKey(externalShopItemSpekKey)
   fulfillmentSpec._ExternalShopItemSpecFulfillTransaction(me, me._BillingTransactionFulfillmentAnchorAccountID, me._BillingTransactionItemPurchaseMap[externalShopItemSpekKey], me._BillingTransactionOptionalData)

The spec first checks whether it can successfully fulfill the item:

 foreach s in scriptRefs
   if not s:CanExternalShopItemSpecFulfillTransaction(me, fulfillmentAnchorID, accountID, quantity, additionalData)
     canFulfill = false
     break
   .
 . 

If it can fulfill the item, we give the spec's decorators the opportunity to create a node to act as the in-game item:

 foreach s in scriptRefs
   instantiatedNode = s:OnExternalShopItemSpecDoCreateFromSpec(me)
   break // We only create from the first decorator; allowing additional decorators to process the request would result in duplicate items.
 . 

Then, we let decorators respond to the item's creation (by glomming classes, modifying data, adding inventory associations, etc):

 scriptRefsTwo as List of ScriptRef = QueryPrototypeScriptsWithFunction(me, "OnExternalShopItemSpecCreateFulfillmentItem")
 foreach s in scriptRefsTwo
   s:OnExternalShopItemSpecCreateFulfillmentItem(me, createdThing, accountID, additionalData)
 . 

Once all specs have successfully fulfilled their items, the fulfillment anchor will notify the billing system that it may now finalize the transaction. It does so by first calling the 'order status update' webservice and then de-replicating the fulfillment anchor:

 parms["OrderStatus"] = "fulfilled"
 $_BILLING._BillingDoMakeWebServiceRequest(newRequestID , "transaction/statusupdate:BillingOrderStatusUpdateRequest", $_BILLING, parms)
 transactionAnchor._BillingTransactionFulfillmentAnchorDereplicate()

System Node Interface

The following methods act as the public interface to the $_BILLING system. Note that most functionality operates behind-the-scenes and does not support overrides in order to maintain the security and integrity of microtransaction purchases. Extending the system should be done via specs and spec decorators, as outlined below.

 unique method _BillingGetDefaultExternalShopItemSpecName() as String
 untrusted remote unique method _SyncExternalShopItemSpecOracleFromWeb(fromClient as ID)
 untrusted remote unique method _OnClientCompleteTransaction(accountID as ID, federatedTransactionID as String, additionalData copies Class _BillingTransactionAdditionalData)
 unique method _OpenExternalBillingShop(request_id as ID, shop_name as String, width as Integer, height as Integer) as Boolean

External Shop Item Spec Interface

 method _ExternalShopitemSpecGetDefaultSpecClass() as String
 method _ExternalShopItemSpecFulfillTransaction(fulfillmentAnchorID as ID, accountID as ID, quantity as Integer, additionalData as Class _BillingTransactionAdditionalData)
 method _ExternalShopItemSpecRollBackTransaction(fulfillmentAnchorID as ID, accountID as ID, quantity as Integer, additionalData as Class _BillingTransactionAdditionalData)

External Shop Item Spec Decorator Interface

 shared function CanExternalShopItemSpecFulfillTransaction(spec as NodeRef of Class _ExternalShopItemSpec, fulfillmentAnchorID as ID, accountID as ID, quantity as Integer, additionalData as Class _BillingTransactionAdditionalData) as Boolean
 shared function CanExternalShopItemSpecRollbackTransaction(spec as NodeRef of Class _ExternalShopItemSpec, fulfillmentAnchorID as ID, accountID as ID, quantity as Integer, additionalData as Class _BillingTransactionAdditionalData) as Boolean
 shared function OnExternalShopItemSpecCreateFulfillmentItem(spec as NodeRef of Class _ExternalShopItemSpec, createdItem as NodeRef, forAccountID as ID, additionalData as Class _BillingTransactionAdditionalData)
 shared function OnExternalShopItemSpecRollbackFulfillmentItem(spec as NodeRef of Class _ExternalShopItemSpec, createdItem as NodeRef, forAccountID as ID, additionalData as Class _BillingTransactionAdditionalData)
 shared function OnExternalShopItemSpecDoCreateFromSpec(spec as NodeRef of Class _ExternalShopItemSpec) as NodeRef

External Functions

 external function _BillingIsEnabled(enabled references Boolean) as Boolean
 external function _BillingGetWebServiceStatus(isUp references Boolean) as Boolean
 external function _BillingMakeWebServiceRequest( requestID as ID, APICall as String, callback_node as NodeRef, parms as LookupList indexed by String of String ) as Boolean
 external function _BillingEnumerateExternalItemStores(webStoreNames references List of String) as Boolean
 external function OpenExternalBillingShop(request_id as ID, callback_node as NodeRef, shop_name as String, windowWidth as Integer, windowHeight as Integer) as Boolean
 external function EnumerateExternalBillingShops() as List of String

Extending the Billing System

Customizing the behavior of item fulfillment within the billing system involves modifying (or creating new) external shop item specs and spec decorators. The default spec - _ExternalShopItemSpec - factories a single persisted _ExternalShopItem node during fulfillment before allowing any glommed decorators to modify the factoried node. It is recommended that - if you need to introduce additional functionality to your fulfillment specs - you do so either 1) via decorators, or 2) by extending the default spec. It is almost never a good idea to abandon the default spec hierarchy in favor of creating a completely new spec.

Below, we explore the creation of a new spec, MY_ExternalShopItemSpec. We'll also create the spec decorator MY_ExternalShopItemDebugFulfillmentSpecDecorator, which will trigger an $ALERT popup on the player's client when an item is purchased or rolled back. (note: The _ExternalShopItemDebugFulfillmentSpecDecorator decorator is glommed - by default - onto each newly created _ExternalShopItemSpec (but not on any derived spec class, such as our MY_ExternalShopItemSpec class)).

Procedure

First, we'll create the DOM entities to support our spec and spec decorator by using the DOM Editor:

Next, we'll instruct the billing system node to use our new class to create item fulfillment specs when syncing from the web store:

 method HE_BillingGetDefaultExternalShopItemSpecName(specName references String) as Boolean
   specName = "MY_ExternalShopItemSpec"
   return true
 .
 method HE_BillingGetValidExternalShopItemSpecNames(validSpecs references List of String) as Boolean
   add back "MY_ExternalShopItemSpec" to validSpecs
   return false
 .
 method HE_BillingGetValidExternalShopItemSpecDecoratorNames(validDecorators references List of String) as Boolean
   add back "MY_ExternalShopItemDebugFulfillmentSpecDecorator" to validDecorators
   return false
 .

Next, we'll add the item fulfillment logic we want to activate when our decorator is glommed onto one of our custom specs:

 shared function CanExternalShopItemSpecFulfillTransaction(spec as NodeRef of Class _ExternalShopItemSpec, fulfillmentAnchorID as ID, accountID as ID, quantity as Integer, additionalData as Class _BillingTransactionAdditionalData) as Boolean
   return true
 .
 shared function OnExternalShopItemSpecCreateFulfillmentItem(spec as NodeRef of Class _ExternalShopItemSpec, createdItem as NodeRef, forAccountID as ID, additionalData as Class _BillingTransactionAdditionalData)
   $ALERT._FadeAlert(forAccountID, "Success! You got " + spec.displayName + "!$R$R  Please implement your own fulfillment logic by either extending the default spec or creating one of your own.", 00:00:10.00)
 .
 shared function OnExternalShopItemSpecRollbackFulfillmentItem(spec as NodeRef of Class _ExternalShopItemSpec, createdItem as NodeRef, forAccountID as ID, additionalData as Class _BillingTransactionAdditionalData)
   $ALERT._FadeAlert(forAccountID, "Whoops! Rolled back " + spec.displayName + "!$R$R  Please implement your own rollback logic by either extending the default spec or creating one of your own.", 00:00:10.00)
 .

Now, we'll instruct our custom spec to GLOM this decorator on each time a new spec is created (making this decorator our 'default behavior' for newly synced item definitions):

 method NotifyOnNewSpecCreation()
   if me is exactly MY_ExternalShopItemSpec
     $GLOM._GlomClassToPrototype("MY_ExternalShopItemDebugFulfillmentSpecDecorator", me)
   .
   $_BILLING._BillingTryFinalizeExternalShopItemSpecOracleSync()
 .

Now, whenever you sync new items from your web store, the sync operation will use your custom MY_ExternalShopItemSpecOracle class and GLOM on your custom MY_ExternalShopItemDebugFulfillmentSpecDecorator class. This decorator can also be manually glommed onto your items using the spec oracle's GLOM GUI.

Script and Class References

The following classes comprise the billing system:

The following scripts are all either integral to the operation of - or contain references to - the billing system:

Internal Configuration References

Universe Parameters

Account Management System Store Interface

To use the Microtransaction User Interface from the Account website, login using your active HeroCloud account at https://account.heroengine.com. Your account must be setup as an “Administrator”, “Developer”, or “Tester” on a valid Group, which must in turn have the Microtransactions feature enabled. If you do not see the “Microtransaction Stores” menu on the sidebar of the Dashboard (below), please contact your Group Owner or HeroEngine Support.

Billing Web Interface 1.png

Microtransaction Store List

When you initially click on the “Microtransaction Stores” link from the Dashboard, you see the Store List. Initially, since no stores are created for the group yet, the list will be empty.

Billing Web Interface 2.png

Create Microtransaction Store

New Microtransaction Stores are created by clicking on the “Create Store” button, which will bring you to the Create Store interface (below).

Billing Web Interface 3.png

For this interface, you will need to enter the following:

Along with the store, a default view will also be created. A view is a collection of items within a store and which can be seen in the store preview (later).

After creating the store, the Microtransaction Store List will now display the store, along with any associated views underneath it.

Billing Web Interface 4.png

Note that in order to be able to view a new store from within the Heroengine client, a separate update must be made, which currently requires action from HeroEngine. Please contact Idea Fabrik to enable this store to be accessible from the game client.

Edit Microtransaction Store

Existing Store can be edited by clicking on the dropdown menu icon to the far right of the store, and clicking “Edit Store” in the dropdown menu.

Billing Web Interface 5.png

This will bring up the Store Edit dialog box.

Billing Web Interface 6.png

The Name, Description, and Default View can be changed. The Store can also be deleted completely by clicking the “Remove” button. Note: Deleting a Store will also delete any Items, Views, and Store Banners associated with it. Currently, functionality to undelete a store is not supported.

Create Store View

Additional Views may be created by clicking on the “Create View” button.

Billing Web Interface 7.png

For this interface, the following fields are needed:

After clicking “Create”, a new view will be created and added under the list of views under the store.

Billing Web Interface 8.png

Each of the published views in the store, including the default view, will be displayed as a separate tab in the store.

Create Store Item

New Microtransaction Store items can be created by clicking on the “Create Item” button from the main Store List page.

Billing Web Interface 9.png

In this interface, you will need to provide the following fields:

Publish Store View

In the Store View Listing, each view is shown with it’s associated version. As previously stated, Test versions of a particular View will not be visible to the end user, until it is published. A Store View can be moved to the Published State by clicking on the “Publish” link to the right of the View. The following dialog box will appear, prompting the user to confirm.

Billing Web Interface 10.png

When the user clicks on the “Publish” button, the View will be transferred to the Published State.

Billing Web Interface 11.png

Each of the published views in the store, including the default view, will be displayed as a separate tab in the store.

Edit Store View

Existing views can be edited by clicking on the “Edit” link next to the store view.

Billing Web Interface 12.png

Note that Editing a Store View will create a new version of the Store View, marked “Test”. In order for end-users to see this, you must Publish the view (later).

Microtransaction Store View

A store view can be directly accessed by clicking on the “View” link next to the “Edit” link mentioned above. This will bring up a page which displays all the items in the view.

Billing Web Interface 13.png

From this interface, new items can be added to the view, and Existing Items can be edited.

Store Banners Management

Store Banners are marquee images which are displayed in the default theme as part of a slideshow marquee in the store view (below). The Store Banner management page can be entered by click on “Store Banner” from the store dropdown menu on the main Microtransaction Store List.

Billing Web Interface 14.png

Initially, since no Store Banners are created yet, the page will be empty.

Billing Web Interface 15.png

Create Store Banner

To create a new Store Banner, click on the “Create Banner” button.

Billing Web Interface 16.png

In this interface, you will have to fill the following fields:

Billing Web Interface 17.png

After clicking on the “Save” button, the new Store Banner will be created, and will be visible in the main page.

Billing Web Interface 18.png

Edit Store Banner

Existing Store Banners can be edited by clicking on the “Edit” link.

Billing Web Interface 19.png

The Store Banner name, description, sort order, action, and image can be modified and saved. The Store Banner can also be removed completely by clicking on the “Remove” button.

Microtransaction Item List

A complete list of Microtransaction Items can be found by clicking on the “Manage Store Items” dropdown menu item from the Store List, or the “Manage Items” button from the view interface.

Billing Web Interface 20.png

This will bring up a list of all the Items in the Store.

Billing Web Interface 21.png

From this interface, new Items can be created, and existing Items can be Edited. By clicking on the checkbox below any of the Store Items, or by clicking the Select All checkbox, a dropdown list of all views can be triggered.

Billing Web Interface 22.png

The dropdown allows items to be bulk added or removed to and from any views belonging to the store.

Bulk Grant Currencies

For testing purposes, Administrator accounts of the group have the ability to grant currencies to any or all of the users in the group. Please note that this action grants money only to a special Test Wallet to each account. This is a different Wallet with a different balance than what will be seen in the in-game store.

Billing Web Interface 23.png

This interface can be invoked by clicking on the “Grant Currencies” dropdown menu item from the main Store List.

Billing Web Interface 24.png

Each user can be selected by clicking on the checkbox next to the corresponding currency next to their account name. All of the currencies for the users can be bulk-checked by clicking on the top checkbox corresponding to the currency. In addition, the amount of the currency to be granted must be entered for “Add Amount”.

Store Preview

A preview of the store can be triggered by clicking on the “Preview” dropdown menu item from the main Store List page.

Billing Web Interface 25.png

A preview of the in-game store page will be displayed. The first tab (displayed by default) will contain the store banner images (if any) as well as any featured items.

Billing Web Interface 26.png

Each of the published views in the store, including the default view, will be displayed as a separate tab in the store.

Billing Web Interface 27.png Billing Web Interface 28.png

By clicking on the “Buy” button under each Item, the item can be purchased. The following confirmation dialog box will appear.

Billing Web Interface 29.png

Upon clicking “OK”, the item will either be purchased successfully, or failed (possibly due to insufficient funds).

References

Spec System System Area

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox