Welcome to the Oculus Developer Forums!

Your participation on the forum is subject to the Oculus Code of Conduct.

In general, please be respectful and kind. If you violate the Oculus Code of Conduct, your access to the developer forums may be revoked at the discretion of Oculus staff.

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

davidchen127davidchen127 Posts: 7
NerveGear
edited June 2020 in Platform SDK Development
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.

Best Answers

Answers

  • davidchen127davidchen127 Posts: 7
    NerveGear
    edited June 2020
    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);<br>&nbsp;&nbsp;&nbsp; check(OnlineSub);<br><br>&nbsp;&nbsp;&nbsp; const FOnlineSubsystemOculus* OculusSubsystem = static_cast&lt;const FOnlineSubsystemOculus*&gt;(OnlineSub);<br>&nbsp;&nbsp;&nbsp; check(OculusSubsystem);<br><br>&nbsp;&nbsp;&nbsp; UE_LOG_VR(Verbose, TEXT("Attempting to buy %d coins with SKU '%s'"), Amount, *SKU);<br>&nbsp;&nbsp;&nbsp; const char* c_sku = TCHAR_TO_ANSI(*SKU);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; OculusSubsystem-&gt;AddRequestDelegate(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ovr_IAP_LaunchCheckoutFlow(c_sku), <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FOculusMessageOnCompleteDelegate::CreateLambda([this, c_sku, Amount](ovrMessageHandle Message, bool bIsError)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (bIsError)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UE_LOG_VR(Error, TEXT("Purchase Error of %s"), c_sku);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ovrPurchaseHandle Handle = ovr_Message_GetPurchase(Message);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ovrID ID = ovr_Purchase_GetPurchaseID(Handle);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UE_LOG_VR(Verbose, TEXT("Purchase Success (%llu)"), ID);<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ovr_IAP_ConsumePurchase(c_sku);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }



    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-austinen-austin Posts: 27 Oculus Start Member
    edited June 2020
    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/


  • davidchen127davidchen127 Posts: 7
    NerveGear
    ok, that totally resolves my doubt. Thank you very much! I'll try it out and see if I can get a nice result.  :)
  • davidchen127davidchen127 Posts: 7
    NerveGear
    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();
    }

  • motorsepmotorsep Posts: 1,504 Oculus Start Member
    @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-austinen-austin Posts: 27 Oculus Start Member

    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-austinen-austin Posts: 27 Oculus Start Member

    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.
  • motorsepmotorsep Posts: 1,504 Oculus Start Member
    en-austin said:

    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 :P 

    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++.
  • davidchen127davidchen127 Posts: 7
    NerveGear
    Hi @en-austin,
    My target platform is Oculus Go, and I can only test it by uploading to the store and then download it from my Go. Otherwise the entitlement check will fail. I've also checked many times of the code logic and couldn't think of anything. Maybe I should try the Android Studio for debugging.
    Thanks a lot for your advice.
  • davidchen127davidchen127 Posts: 7
    NerveGear
    Hi @en-austin,
    I used the Android device monitor to log when I triggered the crash. Here is the Assert level of log and I don't know maybe you can help me find some clues what exactly led to the crash. I've attached it as text file in the attachment.
    Thank you in advance.
  • davidchen127davidchen127 Posts: 7
    NerveGear
    edited June 2020
    Hi @en-austin,
    I think I successfully did the checkout of IAP. It was the part I used a string instead of a const char* as the argument for the checkout function. But it works now. 
    However, I can't consume this purchased consumable item because after I jumped to that Oculus purchase screen, my app already stopped. So I suppose the function to consume the item can't be reached.
    Have you encountered similar problem before?
  • en-austinen-austin Posts: 27 Oculus Start Member

    Great to hear about the progress! Even though the Quest suspends your app to display the Oculus purchase UI, it should resume right where it left off once your app comes back into the foreground.

    You can see from my purchase success path that I call ovr_IAP_ConsumePurchase within the lambda that resumes once the Oculus purchase UI returns control to my app. I haven't encountered the problem you describe, perhaps add some logging before and after the points were the Purchase UI is invoked and see if it resumes properly? 
  • en-austinen-austin Posts: 27 Oculus Start Member

    Yeah, I hear you regarding the lack of Blueprint access to the Oculus platform. In C++ world, I'm also finding a lot of Oculus platform stuff that doesn't exist in Epic's cross-platform frameworks for exposing stuff like IAPs, networking, etc. Luckily in these cases I still have the option to tap into the Oculus native SDKs - but yeah, it's still some digging and such that would be nice not to have to do :-)

  • OoKushoOOoKushoO Posts: 5
    NerveGear
    Hey Austin, I would love to know how do you use Android studio to debug, the oculus quest.
    dont have much experience debugging for android devices
  • en-austinen-austin Posts: 27 Oculus Start Member
    Hi, this video is a bit older but it got me started debugging with Android Studio:
    The entire video is a good watch but the Android Studio specific part starts around 13:50

  • twistedpixel_bobtwistedpixel_bob Posts: 38
    Brain Burst
    I am trying to use a different function from the ovr_platform API and it keeps giving me this error about the library not being linked. error LNK2019: unresolved external symbol ovr_Platform_InitializeStandaloneOculusEx
    I included the file in the build.cs file and enabled the plugin as described in the docs.  Was there anything else you needed to do? It seems like it is not linking the library...

Sign In or Register to comment.