cancel
Showing results for 
Search instead for 
Did you mean: 

How to make the IAP (In-App Purchase) to work with Unreal Engine?

davidchen127
Explorer
Dear all, 
I'm trying to implement the IAP for Oculus Go/Quest with Unreal Engine (4.23.1). I've followed the documentation and set up the environment (the plugin is added in Build.cs and the "OnlineSubsystemOculus" plugin is enable in Unreal) and include the "OVR_Platform.h" in my code. The IAP items were also given on the developer dashboard. But still I can't get any of those APIs to work, such as ovr_IAP_GetProductsBySKU. Can someone share experience about the right procedure or steps for implementing IAP with UE4?
p.s. I also checked the unreal sample project provided by Oculus in that Platform SDK v17. But in that project, it doesn't use the OSSOculus APIs but just the Unreal built-in Online APIs.
Thank you in advance for any help.
2 ACCEPTED SOLUTIONS

Accepted Solutions

en-austin
Protege
Hi,

Though we're not specifically using ovr_IAP_GetProductsBySKU, we are using IAPs with Quest for the past few UE4 versions (I believe starting with 4.22). Below is a snippet of code that executes when the player makes a choice for an IAP on our UI:

const IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld(), OCULUS_SUBSYSTEM);
    check(OnlineSub);

    const FOnlineSubsystemOculus* OculusSubsystem = static_cast<const FOnlineSubsystemOculus*>(OnlineSub);
    check(OculusSubsystem);

    UE_LOG_VR(Verbose, TEXT("Attempting to buy %d coins with SKU '%s'"), Amount, *SKU);
    const char* c_sku = TCHAR_TO_ANSI(*SKU);
   
    OculusSubsystem->AddRequestDelegate(
        ovr_IAP_LaunchCheckoutFlow(c_sku),
        FOculusMessageOnCompleteDelegate::CreateLambda([this, c_sku, Amount](ovrMessageHandle Message, bool bIsError)
        {
            if (bIsError)
            {
                UE_LOG_VR(Error, TEXT("Purchase Error of %s"), c_sku);
            }
            else
            {
                ovrPurchaseHandle Handle = ovr_Message_GetPurchase(Message);
                ovrID ID = ovr_Purchase_GetPurchaseID(Handle);
                UE_LOG_VR(Verbose, TEXT("Purchase Success (%llu)"), ID);

                ovr_IAP_ConsumePurchase(c_sku);
            }




View solution in original post

en-austin
Protege
Good luck @davidchen127 - sounds like it's close if you got the Oculus purchase UI to pop up once. If you get a good log file and you like another pair of eyes on it, feel free to post it and I'll take a peek.

View solution in original post

18 REPLIES 18

en-austin
Protege
Hi,

Though we're not specifically using ovr_IAP_GetProductsBySKU, we are using IAPs with Quest for the past few UE4 versions (I believe starting with 4.22). Below is a snippet of code that executes when the player makes a choice for an IAP on our UI:

const IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld(), OCULUS_SUBSYSTEM);
    check(OnlineSub);

    const FOnlineSubsystemOculus* OculusSubsystem = static_cast<const FOnlineSubsystemOculus*>(OnlineSub);
    check(OculusSubsystem);

    UE_LOG_VR(Verbose, TEXT("Attempting to buy %d coins with SKU '%s'"), Amount, *SKU);
    const char* c_sku = TCHAR_TO_ANSI(*SKU);
   
    OculusSubsystem->AddRequestDelegate(
        ovr_IAP_LaunchCheckoutFlow(c_sku),
        FOculusMessageOnCompleteDelegate::CreateLambda([this, c_sku, Amount](ovrMessageHandle Message, bool bIsError)
        {
            if (bIsError)
            {
                UE_LOG_VR(Error, TEXT("Purchase Error of %s"), c_sku);
            }
            else
            {
                ovrPurchaseHandle Handle = ovr_Message_GetPurchase(Message);
                ovrID ID = ovr_Purchase_GetPurchaseID(Handle);
                UE_LOG_VR(Verbose, TEXT("Purchase Success (%llu)"), ID);

                ovr_IAP_ConsumePurchase(c_sku);
            }




davidchen127
Explorer

en-austin said:

Hi,

Though we're not specifically using ovr_IAP_GetProductsBySKU, we are using IAPs with Quest for the past few UE4 versions (I believe starting with 4.22). Below is a snippet of code that executes when the player makes a choice for an IAP on our UI:

const IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld(), OCULUS_SUBSYSTEM);
    check(OnlineSub);

    const FOnlineSubsystemOculus* OculusSubsystem = static_cast<const FOnlineSubsystemOculus*>(OnlineSub);
    check(OculusSubsystem);

    UE_LOG_VR(Verbose, TEXT("Attempting to buy %d coins with SKU '%s'"), Amount, *SKU);
    const char* c_sku = TCHAR_TO_ANSI(*SKU);
   
    OculusSubsystem->AddRequestDelegate(
        ovr_IAP_LaunchCheckoutFlow(c_sku),
        FOculusMessageOnCompleteDelegate::CreateLambda([this, c_sku, Amount](ovrMessageHandle Message, bool bIsError)
        {
            if (bIsError)
            {
                UE_LOG_VR(Error, TEXT("Purchase Error of %s"), c_sku);
            }
            else
            {
                ovrPurchaseHandle Handle = ovr_Message_GetPurchase(Message);
                ovrID ID = ovr_Purchase_GetPurchaseID(Handle);
                UE_LOG_VR(Verbose, TEXT("Purchase Success (%llu)"), ID);

                ovr_IAP_ConsumePurchase(c_sku);
            }






Thank you for the answer. This helps a lot. I'll give a try and hopefully solve the problem.
An extension question, do we need to initialize the subsystem like Oculus instruct on their website of the OVR_Platform SDK?

en-austin
Protege
The Oculus Online Subsystem gets initialized upon application boot, provided you have valid AppId keys configured in your DefaultEngine.ini under the heading [OnlineSubsystemOculus] and the Online Subsystem plugin enabled in your project.

You can trace the code and output logs through OnlineSubsytemOculus.cpp - follow the InitWithWindowsPlatform function for Rift/S and InitWithAndroidPlatform function for Qo/Quest.

This is the document I referenced when setting our app up initially:
https://developer.oculus.com/documentation/unreal/ps-setup/


davidchen127
Explorer
ok, that totally resolves my doubt. Thank you very much! I'll try it out and see if I can get a nice result.  🙂

davidchen127
Explorer

en-austin said:

The Oculus Online Subsystem gets initialized upon application boot, provided you have valid AppId keys configured in your DefaultEngine.ini under the heading [OnlineSubsystemOculus] and the Online Subsystem plugin enabled in your project.

You can trace the code and output logs through OnlineSubsytemOculus.cpp - follow the InitWithWindowsPlatform function for Rift/S and InitWithAndroidPlatform function for Qo/Quest.

This is the document I referenced when setting our app up initially:



I've followed the instruction on the website and everything seems fine, at least no complaint from VS.
Now I'm trying to purchase a item (the SKU is "TestItem") combining your code and the Oculus example.
However, when I ran this code, it crashed the app and jump back to home screen. But there was one time, it did pop out the Checkout page and asked if I want to purchase this item. 
I have another button to make sure that the OSS is initiated before I can ran the following purchase code. The initialization status was shown on the screen so I knew it's done.
Would you please check if there is something incorrect in the code?
p.s. The item was also created on the Oculus Dashboard already.

FOnlineSubsystemOculus* OSS = static_cast<FOnlineSubsystemOculus*>(IOnlineSubsystem::Get());
check(OSS);
if (OSS->IsInitialized())
{
ovrRequest RequestId = ovr_IAP_LaunchCheckoutFlow("TestItem");
OSS->AddRequestDelegate(
RequestId, FOculusMessageOnCompleteDelegate::CreateLambda([this](ovrMessageHandle Message, bool bIsError) {
if (bIsError)
{
//UE_LOG(LogTemp, Log, TEXT("Error"));
}
else
{
ovrPurchaseHandle Handle = ovr_Message_GetPurchase(Message);
ovrID ID = ovr_Purchase_GetPurchaseID(Handle);
//UE_LOG(LogTemp, Log, TEXT("Done, %llu"), ID);
}
}));
}
else
{
OSS->Init();
}

motorsep
Rising Star
@en-austin

What are the chances for you guys to expose all IAP functionality to Blueprints, in the nearest future (like, for UE 4.26 release) ?

en-austin
Protege
Hi @motorsep ,

Not likely for our project - I'm comfortable with C++ and our Blueprint developers are happy making gameplay rather than getting too bogged down with platform details. I'm guessing your project is more Blueprint driven?
We do use Blueprint to create the initial Oculus Session ("room" in Oculus terms), and also catch and handle any errors network disconnection errors - but this is mostly for the ease of driving our UI through UMG.

en-austin
Protege
Hi @davidchen127 ,

Your code looks pretty good to me, are you trying this on Android (Go or Quest)? If on Quest you need to have platform approval through Oculus' Quest approval process.
I frequently resort to logging on Android as my first step in debugging - basically placing log messages all over the area of code that I suspect is problematic. If that fails I end up using Android Studio to properly set breakpoints and such when attached to a debug build on the Quest.

motorsep
Rising Star

en-austin said:

Hi @motorsep ,

Not likely for our project - I'm comfortable with C++ and our Blueprint developers are happy making gameplay rather than getting too bogged down with platform details. I'm guessing your project is more Blueprint driven?
We do use Blueprint to create the initial Oculus Session ("room" in Oculus terms), and also catch and handle any errors network disconnection errors - but this is mostly for the ease of driving our UI through UMG.



Somehow I read your title as "Staff Member" and that's why I asked 😛 

Yeah, I am a solo dev and my project is all BP. It's critical for me to be able to do everything in BP and Platform SDK, sadly, is all C++ as far as I can tell. I can never get straight answer from Oculus about them exposing Platform SDK stuff to BP 😞 I wish someone from Oculus dev community already made a Marketplace plugin for UE4 to let BP devs use Platform SDK without touching C++.