A Store item which synchronizes the user's data via SyncedStore. More...
Import Statement: | import Felgo 3.0 |
Inherits: |
This item acts exactly like Store and additionally syncs the balance of the user's Currency and their SingleUseGood purchases using FelgoGameNetwork's WebStorage.
For information how to use the item, see the Soomla Store Plugin documentation. For information about the game network components, see the FelgoGameNetwork item documentation.
The androidPublicKey
property is mandatory if you want to use in-app purchases on Google Play Store.
Every app on Google Play Store has a unique public key for communication between the app and Play Store. To find the public key, open your application's details in your Developer Console after uploading a draft apk, then click on Monetization Setup, and look at the field titled Your License Key for This Application. For more information have a look at Getting an app's license key.
This property holds all currencies you want to provide within your game's assets. You need at least one currency defined to be able to offer virtual purchases.
You define your virtual currencies like the following example. For more information have a look at Currency item.
Store { currencies: [ Currency { id: creditsCurrency; itemId: "currency_credits_id"; name: "Credits"; } ] }
See also Currency.
Currency packs are collections you can offer your users to buy a certain amount of your in-game currencies. You need at least one currency and one currency pack defined to be able to offer virtual purchases.
You define your virtual currencies packs like the following example. For more information have a look at CurrencyPack item.
Store { currencies: [ Currency { id: creditsCurrency; itemId: "currency_credits_id"; name: "Credits"; } ] currencyPacks: [ CurrencyPack { id: credits10Pack itemId: "credits_pack_10_id" name: "10 Credits" currencyId: creditsCurrency.itemId // The currency you want to offer with this pack currencyAmount: 10 purchaseType: StorePurchase { id: credits10Purchase; productId: credits10Pack.itemId; } } ] }
See also CurrencyPack and Currency.
Set this property to the id of Felgo Game Network.
By default, it will be set to the id gameNetwork
if one is found in the project, or it is undefined if no such id is found.
Note: It is required that a Felgo Game Network component exists for this component to synchronize the data with the web server.
This is an example how to use it:
// ... FelgoGameNetwork { id: myGameNetwork // other gameNetwork code here } SyncedStore { id: myGameNetworkView gameNetworkItem: myGameNetwork } // ...
The goods
property holds all virtual goods you want to offer within your game. Depending on your store design goods can either be purchased with virtual currency (VirtualPurchase) or from the platform's stores directly (StorePurchase).
The Store plugin offers different types of goods to simplify the handling of virtual items, including LifetimeGood, SingleUseGood and SingleUsePackGood.
You define virtual goods like the following example:
Store { goods: [ SingleUseGood { id: vacGood itemId: "vac_item_id" name: "Vacuum Cleaner" description: "All Squabies are sucked in by your mom's vacuum cleaner" purchaseType: VirtualPurchase { itemId: goldCurrency.itemId; amount: 50; } } ] }
See also LifetimeGood, SingleUseGood, and SingleUsePackGood.
[read-only] inServerSync : bool |
This read-only property gets true
when all read or write requests are handled and all data is in sync. It stays at the initial value false
when a connection error occurs and the write requests are
stored for later sending. It also changes to false
when data is written with setValue() or when a server value is synced initially at app startup, and also after initiallyInServerSync is true
.
This read-only property gets true
the first time all the keys are synced with the server or there is no Internet connection.
See also inServerSync.
The secret
property is used to encrypt the purchase and inventory data stored locally on the device. Be sure to set the secret only once per app and don't change it while running your game and after publishing
your app (and updates), otherwise all purchased items from your user get lost.
Be sure to keep your game's secret in private. The property is mandatory.
A boolean read-only flag holding the state if billing (in-app purchases in general) is supported on the currently used device.
Possible reasons for unsupported devices are for example an unsupported platform (e.g. the current device is MeeGo powered), activated parental control (iOS) or an outdated Google Play app on Android. If supported is
false
calls involving StorePurchase items won't succeed, you then could inform the user that his device is currently not able to perform in-app purchases.
testMode : bool |
Set this to true to enable testing mode, which lets you simulate store interactions without actually using the Store item. By default, testMode is true on desktop and false on mobile platforms.
Note: On desktop, only testMode is supported.
An integer holding the current version of your game's store assets described by currencies, currencyPacks and goods.
Bump the version every time you make changes to your game's assets to overwrite the old settings. Like changes to secret, version
changes will delete all user
items stored locally, so don't change it while running your game and after publishing your app unless you have to do so.
If you omit this property a default value of 1
is used.
This handler is called when the balance of a currency given with the itemId parameter changes. The amountAdded parameter describes the positive (when added) or negative (when subtracted) change of the balance.
Note: In most cases the usage of the Currency::balance property is preferable over the usage of this signal in order to retrieve the current balance of a given Currency, as you can then benefit from the advantages of QML property bindings.
Note: The corresponding handler is onCurrencyBalanceChanged
.
This handler is called if a connection error occurred and thus the key-value pairs are not in sync with the server. You can for example show a dialog to the user if that happens.
Note: The corresponding handler is onErrorAndNotInitiallySynced
.
This handler is called when the balance of a good item given with the itemId parameter changes. The amountAdded parameter describes the positive (when added) or negative (when subtracted) change of the balance.
Note: In most cases the usage of the good's balance property is preferable over the usage of this signal in order to retrieve the current balance of a given Currency, as you can then benefit from the advantages of QML property bindings.
Note: The corresponding handler is onGoodBalanceChanged
.
This handler is called whenever a purchase of an item with VirtualPurchase type failed because the user's payment item balance is not sufficient. For example, you can then give the hint that new credits can be purchased:
Store { onInsufficientFundsError: { nativeUtils.displayMessageBox("Out of Gold", "You can purchase new gold in Squaby's in-game store.") } }
This handler is also called if you try to decrease a Currency's balance with takeItem where the amount taken off is higher than the remaining balance.
Note: The corresponding handler is onInsufficientFundsError
.
This handler is called whenever an item with the given itemId can't be found in the last store request.
Note: The corresponding handler is onItemNotFoundError
.
This handler is called whenever an item with StorePurchase or VirtualPurchase type was purchased successfully. If the purchase is of type StorePurchase the signal storePurchased also gets emitted, so make sure to prevent certain actions from performing twice after a purchase.
Note: The corresponding handler is onItemPurchased
.
See also storePurchased.
This handler is called right after restoreAllTransactions finished. You can use it to hide a status indicator as long as the user's transactions are loaded.
The success parameter indicates if the restoreAllTransactions was successful or not. If the restore operation was successful this would be the right place to re-download content of a LifetimeGood or update the game's UI.
Note: The corresponding handler is onRestoreAllTransactionsFinished
.
See also restoreAllTransactions and restoreAllTransactionsStarted.
This handler is called right after restoreAllTransactions gets called. As the method works asynchronous your game should display a status indicator as long until restoreAllTransactionsFinished gets emitted.
Note: The corresponding handler is onRestoreAllTransactionsStarted
.
See also restoreAllTransactions and restoreAllTransactionsFinished.
This handler is called whenever a user cancels the purchase of an item with type StorePurchase. This may happen if the user selects the cancel button of the platform's store overlay or no valid payment options are given.
Note: The corresponding handler is onStorePurchaseCanceled
.
See also storePurchased and storePurchaseStarted.
This handler is called whenever a user starts a purchase of an item with type StorePurchase. This implies usually that the platform's store overlay is shown and asks the user for a valid store account.
Note: The corresponding handler is onStorePurchaseStarted
.
See also storePurchased and storePurchaseCanceled.
This handler is called whenever an item with StorePurchase type was purchased successfully. Whenever this signal is emitted the signal itemPurchased also gets emitted, so make sure to prevent certain actions from performing twice after a purchase.
Note: The corresponding handler is onStorePurchased
.
See also itemPurchased.
This handler is called whenever an unexpected error occurred during the last store request. You can use this handler to ask the player for sending a support request so you can resolve this issue.
Note: The corresponding handler is onUnexpectedError
.
This handler is called when a call of setValue() was not successful, because the server data got modified from another device compared to the (old) local data. If dataConflictStrategy is set to "userResolve"
,
the mergedData
is undefined but conflict
is true
.
Example value for data property:
{ "key": "testKey", "value": "serverValue", "updated_at": "2013-06-12T14:26:10Z", "client_value": "clientValue", "client_updated_at": "2013-06-11T14:26:10Z", "conflict": true, "mergedData": "serverValue" }
In this handler, you can call setValue() with your custom merged value if dataConflictStrategy is set to "userResolve"
.
Note: The corresponding handler is onWriteConflict
.
void buyItem(string itemId) |
Call this method to purchase the given item from a platform store or with virtual currency, depending on the purchase type. Purchasable items are CurrencyPack, LifetimeGood, SingleUseGood, and SingleUsePackGood.
If testMode is true and the good item has a purchase type of VirtualPurchase, the purchase is simulated.
See also getItemBalance.
Returns the balance of the an item with the given itemId
. Keep in mind that only items of type Currency, LifetimeGood and SingleUseGood have a meaningful balance. You can also use the item's balance property to retrieve the balance of the specific item.
If testMode is true, the simulated balance is returned.
Call this method to give a user a specific amount of the item with the given itemId
, without charging for it.
Keep in mind that only items of type Currency, LifetimeGood and SingleUseGood can be given. The
amount
is optional, if amount
is omitted a value of 1
is used as default value.
If testMode is true, the call is simulated (and the balance changes immediately).
See also getItemBalance and takeItem.
Use this method to export CSV data sets for importing to the specific platform stores.
In order to be able to use in-app purchases on Google Play and iOS App Store you have to define the in-app products beforehand in the platform developer consoles. This is a tedious process as you generally have to define at least a name, description and item id for each platform separately.
To improve this step you can use printStoreProductLists() to print a corresponding CSV list which you then can save into a text file and import to the specific platform stores.
Note: You are not required to use the output of this function, it's only meant to make publishing your game a lot easier.
Calling this method makes only sense if you've defined the itemId, name, description and price properties in your virtual items which are encapsulated by a StorePurchase item. Here is an example:
CurrencyPack { id: gold10Pack itemId: "gold_pack_10_id" name: "10 Pieces of Gold" description: "Buy this item to get additional 10 pieces of Gold" currencyId: goldCurrency.itemId currencyAmount: 10 purchaseType: StorePurchase { id: gold10Purchase; productId: gold10Pack.itemId; price: 0.89; } }
Here is how to use the method:
Component.onCompleted: store.printStoreProductLists()
Note: Be sure to remove the code snippet again before shipping your game!
================================================================================ Google Play CSV file: net.vplay.plugins.SoomlaSample.noads,published,managed_by_android,false,en_US;No Ads;Buy this item to remove the app banner,true,2990000 net.vplay.plugins.SoomlaSample.gold_pack_10,published,managed_by_publisher,false,en_US;10 Gold Nuggets;Buy 10 Gold Nuggets,true,890000 net.vplay.plugins.SoomlaSample.gold_pack_50,published,managed_by_publisher,false,en_US;50 Gold Nuggets;Buy 50 Gold Nuggets,true,3990000 iTunes Connect CSV file: SKU Product ID Reference Name Type Cleared For Sale Wholesale Price Tier Displayed Name Description Effective Date [SKU] net.vplay.plugins.SoomlaSample.noads net.vplay.plugins.SoomlaSample.noads Non-Consumable yes [PRICE TIER] No Ads Buy this item to remove the app banner now [SKU] net.vplay.plugins.SoomlaSample.gold_pack_10 net.vplay.plugins.SoomlaSample.gold_pack_10 Consumable yes [PRICE TIER] 10 Gold Nuggets Buy 10 Gold Nuggets now [SKU] net.vplay.plugins.SoomlaSample.gold_pack_50 net.vplay.plugins.SoomlaSample.gold_pack_50 Consumable yes [PRICE TIER] 50 Gold Nuggets Buy 50 Gold Nuggets now ================================================================================
On iOS the productId must be unique across all in-app purchases and uploaded apps. It's therefore best practice to prepend the productId with your game's package identifier (like
net.vplay.plugins.SoomlaSample
). Please also keep in mind that the productId may only contain alphanumeric characters, underscores, and periods.
Note: Make sure that your text editor does not transform the tab delimiters to whitespaces, otherwise Application Loader won't accept your file.
Note: You need to upload a draft apk with "BILLING" permissions set before being able to define in-app products first.
Call this method to reload your good's purchase details from the app store backends. This updates the properties of StorePurchase, like marketPriceAndCurrency.
Usually this call happens automatically at the app start. In some cases this automatic call can fail, for example if there is no internet connection. You can then use this method to retry loading the details.
See also StorePurchase.
Call this function to set the simualted balances of all goods and currencies to 0.
Only works if testMode is true.
Call this method to restore all items of type LifetimeGood associated with a user's platform app store account after re-installing your game on a specific device.
Please keep in mind that only items associated with a specific account can be restored and therefore cross-platform restores between Android and iOS are not possible.
This method should be triggered by the user and not called automatically on every app start. The signal restoreAllTransactionsFinished will get emitted as soon as all in-app purchases are restored.
See also restoreAllTransactionsStarted and restoreAllTransactionsFinished.
Update local values with stored values on server. Useful if the player is online on multiple devices at the same time.
Call this method to take away a specific amount of the item with the given itemId
from a user, without refunding for it.
Keep in mind that only items of type Currency, LifetimeGood and SingleUseGood can be given. The
amount
is optional, if amount
is omitted a value of 1
is used as default value.
The method returns true if the operation was successful or false if the amount to be taken is higher than the remaining balance of the item or the amount
is 0
.
If testMode is true, the call is simulated (and the balance changes immediately).
See also getItemBalance and giveItem.