In App Purchase Documentation.
For more information, visit our website @ www.sdkbox.com
Setting up your Unreal Engine 4 project for In App Purchase
This guide does not cover creating the project itself, or creating apps in the iOS or Google app stores. For instructions on how to do that, please visit the iOS and Android documentation.
The most important thing is setting the identifier used to identify the application in the Apple and Android store that you are going to buy from.
For Apple this is the bundle identifier, and for Android it is the android package name. This is configurable in the UE4 editor by visiting Project Settings and clicking on the iOS and Android sections and filling out those two fields with the appropriate values.
You can find more information for iOS here and for Android here
Installing the SDKBOX IAP Plugin for UE4
Download the SDKBOX IAP Plugin from the SDKBOX UE4 website here
In Your Engine
- Unpack the files into
Engine/Plugins/SDKBOXIAP
- Run the GenerateProjectFiles script in the Engine root.
- Open your engine project file and build the editor.
In Your Code Project
- Unpack the files in your
[Project Root]/Plugins
directory. - Relaunch the editor. This will prompt you to build the plugin for the editor, go ahead and accept to build the plugin and continue launching the editor.
Enable the Plugin
Goto Settings -> Plugins and scroll down to Project if you have added the plugin to your code project, otherwise it will be part of Built-In.
Make sure the the Enabled checkbox is checked. You may have to restart the editor after this step.
Initialize the Plugin
It is important to call the SDKBOX IAP initialization method early, or at least before you call any other methods. You can do this by calling it from your Game Instance Init event, or your first scene's Begin Play event.
The init method takes a JSON string as a parameter. You can pass a raw string if you would like, but you can also add the product descriptions in the Blueprint editor and build the string at runtime.
Important: on Android, you will need to supply the license key which you will find in the Services & APIs section for your app in the Google Play Console. This is very important, as IAP will not function correctly without it. This key should be part of the JSON string, or passed into AndroidKey on the Sdkbox IAP JSON String from Product Descriptions
function.
To add products in the Blueprint editor, first add a variable Products
of type SDKBox IAPProductDescription
and make it an Array.
Now you can add products in the editor by clicking on Products and adding items to the Default Value in the Details pane.
The Name is a string value that you will use to reference the product when purchasing.
The Id is the identifier used when creating the product in the store you are buying it from.
Consumable products can be purchased more than once, whereas Non-Consumable products can only be purchased once. This behavior is supported on all platforms.
You can have different Id's for each platform by specifying the Affinity for either iOS or Android. Specifying All will use the same details for all platforms.
You can now create a function to convert the Products variable into a JSON string that you can feed into the initialize function (pictured above).
Handling Events
You can handle events from the plugin by adding the Sdkbox IAP component to an actor in your scene.
There are 8 events that you can listen to.
You can click the +
to add an event handler that you can use to implement the In App Purchase flow for your application.
You will always receive the OnInitialized
event, and the Status
boolean will indicate whether or not it was successful.
Receiving Products from the Store
If the initialization was successful, you will receive the OnProductRequestSuccess
event and it will provide an array of products (not to be confused with product descriptions, which are similar but have limited information).
Making a Purchase
Handling Success or Failure
You can listen to the events for OnSuccess, OnFailure, and OnCanceled
. These events will pass you the product that is being processed.
Some events will also pass you a message that can be used for diagnostic purposes.
Restoring Products
To restore previously purchased products, simply call the restore function.
This will send you a OnRestored
event for each product that has been restored, and finally it will send a OnRestoreComplete
event to signal that all products have been restored. Note that it is possible to receive only the complete event in the case where you have no previously purchased products.
Verify In App Purchase Receipt
Receipt information is not sent by default, you should enable receipt verification using the following function.
And check product.receipt and product.receiptCipheredPayload for IAP receipt data in onSuccess event.
Note: only Google Play provides receipt data, iOS only provides a ciphered payload string for the user to perform IAP verification.
Code Reference
SDKBOX IAP Functions
UCLASS(NotBlueprintable)
class USdkboxIAPFunctions
: public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapInitialize(FString jsonstring);
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapShutdown();
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapPurchase(FString product);
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapRefresh();
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapRestore();
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static FString SdkboxIapJsonStringFromProductDescriptions(const TArray<FSdkboxIAPProductDescription>& Descriptions);
UFUNCTION(BlueprintCallable, meta = (Keywords = "SDKBOX iap"), Category = "SDKBOX")
static void SdkboxIapEnableUserSideVerification(bool enable);
};
SDKBOX IAP Product
UCLASS(ClassGroup=SDKBOX, HideCategories=(Activation, "Components|Activation", Collision), meta=(BlueprintSpawnableComponent))
class USdkboxIAPProduct
: public UObject
{
GENERATED_BODY()
public:
USdkboxIAPProduct(const FObjectInitializer& ObjectInitializer);
static USdkboxIAPProduct* ProductFromSdkboxProduct(const sdkbox::Product& product);
// The name of the product
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Name"))
FString Name;
// The product id of an In App Purchase
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Id"))
FString Id;
// Type of iap item true if consumable
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Consumable"))
bool Consumable;
// The title of the IAP item
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Title"))
FString Title;
// The description of the IAP item
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Description"))
FString Description;
// Price value in float
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="PriceValue"))
float PriceValue;
// Localized price
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Price"))
FString Price;
// price currency code
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="CurrencyCode"))
FString CurrencyCode;
// cyphered payload
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="ReceiptCipheredPayload"))
FString ReceiptCipheredPayload;
// receipt info. will be empty string for iOS
UPROPERTY(BlueprintReadOnly, Category=General, meta=(DisplayName="Receipt"))
FString Receipt;
};
SDKBOX IAP Product Description
UENUM(BlueprintType)
enum class EProductAffinityEnum : uint8
{
PAE_ALL UMETA(DisplayName="All"),
PAE_IOS UMETA(DisplayName="iOS"),
PAE_ANDROID UMETA(DisplayName="Android")
};
USTRUCT(BlueprintType)
struct FSdkboxIAPProductDescription
{
GENERATED_USTRUCT_BODY()
// The name of the product
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=General, meta=(DisplayName="Name"))
FString Name;
// The product id of an In App Purchase
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=General, meta=(DisplayName="Id"))
FString Id;
// Type of iap item true if consumable
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=General, meta=(DisplayName="Consumable"))
bool Consumable;
// Which platform this product description is for
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=General, meta=(DisplayName="Affinity"))
EProductAffinityEnum Affinity;
};
JSON Configuration
Here is an example of the JSON configuration. You will need to replace
"ios" :
{
"iap":{
"items":{
"remove_ads":{
"id":"<put the product id for ios here>"
}
}
}
},
"android":
{
"iap":{
"key":"<put your googleplay key here>",
"items":{
"remove_ads":{
"id":"<put the product id for android here>"
}
}
}
}
If you have products that are non-consumable, it is also necessary to supply this for each item. Only Android requires this step. Taking the same json above your config might now look like this example:
"android":
{
"iap":{
"key":"<put your googleplay key here>",
"items":{
"remove_ads":{
"id":"<put the product id for android here>",
"type":"non_consumable"
}
}
}
}