Dealer In App Purchase Module
Overview
Dealer module is for managing IAP Products easily. It allows you to create, edit and delete products
from editor GUIs and provides a simple API to initiate purchases, or restore previous purchases. Also, if Sherlock
module is present, Dealer will handle analytics events.
Installing
- Import Dealer proxy module from Package Manager UI.
- By default, the proxy module comes bundled with the Unity IAP service as a sample that can be imported from the
Package Manager UI.
-
If you are going to use Unity IAP, you need to first prepare it. Follow Unity's documentation for setting up Unity Purchasing.
-
After Unity IAP is set up correctly, import the Unity IAP sample from the Package Manager UI.
-
[!CAUTION] You need to update this sample code everytime you update the dealer package. Not doing so might result in malfunction and/or compile errors.
How to use
-
Go to
Matchingham > In App Purchases > Config
-
To add a new product, either click
Add Product
in Dealer Iap Config editor, or navigate toMatchingham > In App Purchases > Add Product
. -
From the
Add Product
window, enter product details (id, store specific id for android and ios app stores)- Make sure product ids follow the format: com.[company].[game].[productid]. For example: com.matchingham.braindom.subs.
- This is important because analytics integration uses this format to detect which item is purchased.
- Different ids can be set for different stores. Set them in the
Store Specific Ids
dictionary inIapProduct
. By default, each store uses the product id, but it can be overwritten. Examples- App Store: com.matchingham.braindom.appstore.subs
- Play Store: com.matchingham.braindom.playstore.subs
- By default, the product id is set as store specific id for each store when creating a new product.
- You can delete unused ones
- Deleted stores will return empty string by default. This can be changed to return product id
by setting the
UseProductIdForNonOverriddenStores
flag.GetStoreSpecificId(IapStore)
returns "" whenUseProductIdForNonOverriddenStores
isfalse
GetStoreSpecificId(IapStore)
returnsId
whenUseProductIdForNonOverriddenStores
istrue
- Deleted stores will return empty string by default. This can be changed to return product id
by setting the
- You can delete unused ones
- Different ids can be set for different stores. Set them in the
-
Press
Create
to create the product. It will be listed in product list, and an item that will represent the iap product will automatically be created and added to item database.- You can use this item to check if the user has a certain in-app product purchased.
-
Make sure to call
Dealer.Instance.Initialize()
at the appropriate place to initialize module.- Dealer uses
Backpack
module for storing iap products. Thus, you need to initializeBackpack
before Dealer.
- Dealer uses
How To Enable Deferred Purchase Debug Events
These events are sent to Firebase, Admost, Game Analytics and Unity Analytics.
- Each analytics service call can be separately marked for compilation using the menu:
Matchingham > In App Purchases > Unity IAP Service
- Note that if none of the calls are compiled by toggling via the menu, even if you enable this feature, you will NOT see any events on the dashboards.
- Toggle the feature programmatically by toggling
SendDeferredEvents
. This is by default turned off. (SendDeferredEvents = false
)- From the editor, you can toggle this feature on/off by setting
SendDeferredEvents
totrue
/false
from the dealer config window. - From code, you can set
Dealer.Config.SendDeferredEvents
totrue
/false
. - From remote config, you can set it
true
/false
, the remote setting key issendDeferredEvents
.
- From the editor, you can toggle this feature on/off by setting
How does this work?
Dealer is a proxy module. It provides a static API, that will be used for all IAP operations, regardless of
what IAP framework/service is being used. By default, it comes with a Unity Purchasing service integration
ready to import as a sample. It is a sample because Unity Purchasing generates some code inside the Assets
folder. Because of this, Unity Iap Service needs to be inside the Assets
folder, otherwise there would be
compile errors, as unity first compiles the package assemblies, then the project assembly.
You can create custom IAP service implementations by implementing IPurchasingService
interface.
public interface IPurchasingService : IAsyncInitialize
{
event BusyStateDelegate BusyStateChanged;
event PurchaseSuccessDelegate Purchased;
event PurchaseFailDelegate Failed;
event Action RestoreSuccess;
event Action RestoreFailed;
event ProductExpireDelegate Expired;
void Initialize();
void RequestRestore();
void RequestPurchase(string productId, params string[] tags);
IEnumerable<IapProduct> GetProducts(Func<IapProduct, bool> filter);
IapProduct GetProduct(string productId);
}
Product Definition
An IAP Product needs an in-game product id. Dealer uses this id to initiate purchases, track them and also send analytics data. Store specific ids are provided separately for android and ios. The sample product definition in the below image is a subscription item.
- Subscription type is selected in the
Type
dropdown - It has 3 rewards defined:
- 200 coins that are rewarded at purchase. These coins are not deduced from the inventory when subscription
expires. (
Give And Forget
is checked) - No Ads item is also rewarded to the player. This item is deduced from player inventory when the subscription
expires. (
Give And Forget
is NOT checked) - Subscription Skin is a cosmetic item that the player is allowed to own as long as they have a subscription.
So it is deduced from player inventory when subscription expires. (
Give And Forget
is NOT checked)
- 200 coins that are rewarded at purchase. These coins are not deduced from the inventory when subscription
expires. (
- By default, this product is listed with following metadata. This data is overwritten with metadata from the
store:
- Title is
Subscription
, and product description isSubscription
. - It is listed with
$9.99
(9.99 USD) price tag. - For analytics info, price and currency code is also provided separately.
- Title is
Configuration
Go to > Matchingham > In App Purchases > Config
Variable | Description |
---|---|
Enabled | Enabling/disabling the module |
AutoInitialize | If enabled, you don't need to call Initialize method manually. |
UseProductIdForNonOverriddenStores | Enable to use the product id for omitted stores in id list |
SendIapAnalyticsToAdjust | *Enabling/disabling sending IAP events to Adjust |
SendIapAnalyticsToAdmost | Enabling/disabling sending IAP events to Admost |
SendIapAnalyticsToFirebase | Enabling/disabling sending IAP events to Game Analytics |
SendDeferredEvents | Enabling/disabling sending deferred purchase events to Firebase, Admob, Unity, Game Analytics |
Products | IAP Product List |
Simulation Config | For simulating IAP in editor or debug mode |
* IAP events flow from Admost to Adjust through SDK-to-SDK interaction automatically. Enable this feature with caution, as it can potentially cause duplicate events.
API & Details
Dealer
Events
-
BusyStateChanged
: Notifies that Dealer service is busy.public delegate void BusyStateDelegate(bool isBusy);
- This event can be used to toggle in game indicators like a loading/processing view for the iap operation.
- If the provided parameter is
true
this means that module is busy processing either a purchase or a restore. - If the provided parameter is
false
this means that module is not busy.
-
Purchased
: Notifies that a purchase operation was successful.
public delegate void PurchaseSuccessDelegate(PurchaseInfo info, bool notifyUser);
-
Use this event to display a success feedback to the user.
-
Failed
: Notifies that a purchase operation has failed.
public delegate void PurchaseFailDelegate(IapProduct product, PurchaseFailReason failReason, bool notifyUser);
-
Use this event to display a failure feedback to the user.
-
RestoreSuccess
: Notifies that restore request was successful.- You can use this event to display a restore successful message.
-
RestoreFailed
: Notifies that restore request failed.- You can use this event to display a restore failure message.
-
Expired
: Notifies that a product has expired.public delegate void ProductExpireDelegate(IapProduct product);
- If you want to notify a user that their subscription has expired, you can use this event.
Methods
-
TryRestore() : bool
: Asks the store provider to restore user's previously purchased products. Returnstrue
if, method to the service invoked successfully,false
otherwise. -
TryPurchase(productId: string, tags: params string[]) : bool
: Asks the store to start purchasing flow for a certain in app product described by theproductId
. Returnstrue
if, method to the service invoked successfully,false
otherwise.- You can provide custom tags using the
tags
parameter to provide purchase metadata for analytics.- For example, purchases made from an in game shop interface can provide
in-game-shop
tag while an item purchased from an in game campaign banner can providesome-campaign-banner
tag. This allows in depth analysis of in app purchases.
- For example, purchases made from an in game shop interface can provide
- You can provide custom tags using the
-
GetProducts(filter: Func<IapProduct, bool> (null))
: Returns list of all products.- You can use the optional filter parameter to filter items returned.
-
GetProduct(productId: string)
: Try to get a specific product using its id. If no item exists with that id, returnsnull
. -
IsPurchased(IapProduct product)
: Checks whether the product with given id is purchased (currently in player's inventory).
Common
Methods
-
Initialize()
: Starts module initialization. You need to call this at the appropriate place. -
WhenInitialized(Action callback)
: Allows you to registercallback
that will be fired only after the module is successfully initialized. Use this to execute logic that requires this module to be initialized first. If the module has already initialized, immediately invokes the callback. -
WhenFailedToInitialize(Action callback)
: Allows you to registercallback
that will be fired only after the module fails to initialize for any reason. Use this to handle what should happen in case this module fails to initialize. If the module has already failed to initialize, immediately invokes the callback. -
WhenReady(Action callback)
: Combined version ofWhenInitialized
andWhenFailedToInitialize
. Delays execution ofcallback
till module is first initialized or failed to initialize, immediately invoke the callback if it is already initialized or failed to initialize.
Fields
-
State
: Initialization state of the module -
Instance
: Instance of the module -
LateInitialized
: When the module needs an internet connection but the player became online while playing the game, this becomestrue
-
Ready
: If the module is initialized successfully and ready to operate -
Config
: Configuration of the module. See configuration -
InitializationDuration
: Initialization duration in seconds