Please Select Your Location

Thailand
Australia
Österreich
België
Canada
Canada - Français
中国
Česká republika
Denmark
Deutschland
France
HongKong
Iceland
India
Ireland
Italia
日本
Korea
Latvija
Lietuva
Lëtzebuerg
Malaysia
Malta
Mexico
Nederland
New Zealand
Norge
Polska
Portugal
Russia
Saudi Arabia
Singapore
Southeast Asia
España
Suisse
Suomi
Sverige
台灣
Ukraine
United Kingdom
United States
Việt Nam
المملكة العربية السعودية (Arabic)

Unreal

ViveportIAPurchaseDemo.h

#include "Components/ActorComponent.h"
#include "ViveportType.h"
#include "ViveportIAPurchaseType.h"

#include "ViveportIAPurchaseDemo.generated.h"

UCLASS(ClassGroup = (Viveport), meta = (BlueprintSpawnableComponent))
class VIVEPORTSDK_API UViveportIAPurchaseDemo : public UActorComponent
{
    GENERATED_BODY()

public:
    // Called when the game starts
    void BeginPlay() override;

    void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

    /** The APP ID and Key for IAP testing*/
    FString VIVEPORT_ID = "app_test_id";
    FString API_KEY = "app_test_key";

private:
    /** Callback objects */
    class MyViveportApiStatus : public ViveportApiStatus
    {
    protected:
        UViveportIAPurchaseDemo* mDemo;
    public:
        void SetDemoPtr(UViveportIAPurchaseDemo* p) { mDemo = p; }
    };

    class MyViveportIAPurchaseListener : public IAPurchaseListener
    {
    protected:
        UViveportIAPurchaseDemo* mDemo;
    public:
        void SetDemoPtr(UViveportIAPurchaseDemo* p) { mDemo = p; }
    };

    class MyInitCallback : public MyViveportApiStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(
            int nErrorCode
        ) override;
    };

    MyInitCallback myInitCallback;

    class MyShutdownCallback : public MyViveportApiStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(
            int nErrorCode
        ) override;
    };

    MyShutdownCallback myShutdownCallback;

    class MyIsReadyCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnSuccess(
            const FString& pchCurrencyName
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyIsReadyCallback myIsReadyCallback;

    class MyGetBalanceCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnBalanceSuccess(
            const FString& pchBalance
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyGetBalanceCallback myGetBalanceCallback;

    class MyRequestCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnRequestSuccess(
            const FString& pchPurchaseId
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyRequestCallback myRequestCallback;

    class MyPurchaseCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnPurchaseSuccess(
            const FString& pchPurchaseId
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyPurchaseCallback myPurchaseCallback;

    class MyQueryCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnQuerySuccess(
            const FQueryResponse& response
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyQueryCallback myQueryCallback;

public:
    ViveportApiStatus* GetInitCallback() { return &myInitCallback; }
    ViveportApiStatus* GetShutdownCallback() { return &myShutdownCallback; }
    IAPurchaseListener* GetIsReadyCallback() { return &myIsReadyCallback; }
    IAPurchaseListener* GetBalanceCallback() { return &myGetBalanceCallback; }
    IAPurchaseListener* GetRequestCallback() { return &myRequestCallback; }
    IAPurchaseListener* GetPurchaseCallback() { return &myPurchaseCallback; }
    IAPurchaseListener* GetQueryCallback() { return &myQueryCallback; }
};

ViveportIAPurchaseDemo.cpp

#include "ViveportSDKPrivatePCH.h"
#include "ViveportIAPurchaseDemo.h"
#include "ViveportApi.h"
#include "ViveportIAPurchase.h"

void UViveportIAPurchaseDemo::BeginPlay()
{
    Super::BeginPlay();

    myInitCallback.SetDemoPtr(this);
    myShutdownCallback.SetDemoPtr(this);
    myIsReadyCallback.SetDemoPtr(this);
    myGetBalanceCallback.SetDemoPtr(this);
    myRequestCallback.SetDemoPtr(this);
    myPurchaseCallback.SetDemoPtr(this);
    myQueryCallback.SetDemoPtr(this);

    // Call ViveportApi::Init()
    UViveportApi::Init(&myInitCallback, VIVEPORT_ID);
}

void UViveportIAPurchaseDemo::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    Super::EndPlay(EndPlayReason);

    // Call ViveportApi::Shutdown()
    UViveportApi::Shutdown(&myShutdownCallback);
}

/***************************************************************
*                    MyInitCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyInitCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyInitCallback] Init success."));
    FString fstring("Init success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    UViveportIAPurchase::IsReady(mDemo->GetIsReadyCallback(), mDemo->API_KEY);
}

void UViveportIAPurchaseDemo::MyInitCallback::OnFailure(int nErrorCode)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyInitCallback] Init failure.
           Error = %d"), nErrorCode);
    FString fstring = FString::Printf(TEXT("Init failure. Error = %d"), nErrorCode);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyShutdownCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyShutdownCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyShutdownCallback] Shutdown success."));
    FString fstring("Shutdown success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportIAPurchaseDemo::MyShutdownCallback::OnFailure(int nErrorCode)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyShutdownCallback] Shutdown
           failure. Error = %d"), nErrorCode);
    FString fstring = FString::Printf(TEXT("Shutdown failure. error=%d"), nErrorCode);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyIsReadyCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyIsReadyCallback::OnSuccess(const FString& pchCurrencyName)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyIsReadyCallback] IsReady success.
           Currency name = %s"), *pchCurrencyName);
    FString fstring = FString::Printf(TEXT("Is ready success, currency name = %s"), *pchCurrencyName);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Get balance
    UViveportIAPurchase::GetBalance(mDemo->GetBalanceCallback());
}

void UViveportIAPurchaseDemo::MyIsReadyCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyIsReadyCallback] IsReady failure.
           Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("IsReady failure. Code = %d, message = %s"), nCode,
                                      *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyGetBalanceCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyGetBalanceCallback::OnBalanceSuccess(const FString& pchBalance)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyGetBalanceCallback] GetBalance
           success. Balance = %s"), *pchBalance);
    FString fstring = FString::Printf(TEXT("GetBalance success. Balance = %s"), *pchBalance);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    int32 balance = FCString::Atoi(*pchBalance);
    if (balance > 0)
    {
        // You can choose one of the below Request APIs you need.
        // 1. Request purchase (if you don't need to keep the item name by Query API)
        UViveportIAPurchase::Request(mDemo->GetRequestCallback(), "1");

        // 2. Request purchase (if you need to keep the item name by Query API)
        // UViveportIAPurchase::Request(mDemo->GetRequestCallback(), "1", "Knife");
    }
}

void UViveportIAPurchaseDemo::MyGetBalanceCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyGetBalanceCallback] GetBalance
           failure. Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("GetBalance failure. code = %d, message = %s"), nCode,
                                           *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyRequestCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyRequestCallback::OnRequestSuccess(const FString& pchPurchaseId)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyRequestCallback] Request success.
           Purchase id = %s"), *pchPurchaseId);
    FString fstring = FString::Printf(TEXT("Request success. Purchase id = %s"), *pchPurchaseId);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Query purchase
    UViveportIAPurchase::Purchase(mDemo->GetPurchaseCallback(), pchPurchaseId);
    //UViveportIAPurchase::Query(mDemo->GetQueryCallback(), pchPurchaseId);
}

void UViveportIAPurchaseDemo::MyRequestCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyRequestCallback] Request failure.
           Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Request failure. code = %d, message = %s"), nCode,
                                           *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyPurchaseCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyPurchaseCallback::OnPurchaseSuccess(const FString& pchPurchaseId)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyPurchaseCallback] Purchase success.
           Purchase id = %s"), *pchPurchaseId);
    FString fstring = FString::Printf(TEXT("Purchase success. Purchase id = %s"), *pchPurchaseId);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Query purchase
    // You can choose one of the below Query APIs you need.
    // 1. Query (if you only need to query specific purchase id and know the purchase status)
    UViveportIAPurchase::Query(mDemo->GetQueryCallback(), pchPurchaseId);

    // 2. Query (if you only need to query specific purchase id and know the purchase status)
    //    And you can refer the detailed sample in ViveportIAPQueryPurchaseListDemo.h and
    //    ViveportIAPQueryPurchaseListDemo.cpp.
    // UViveportIAPurchase::Query(mDemo->GetQueryCallback());
}

void UViveportIAPurchaseDemo::MyPurchaseCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyPurchaseCallback] Purchase failure.
           Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Purchase failure. Code = %d, message = %s"), nCode,
                                      *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyQueryCallback
***************************************************************/

void UViveportIAPurchaseDemo::MyQueryCallback::OnQuerySuccess(const FQueryResponse& response)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPurchaseDemo][MyQueryCallback] Query success.
           Purchase id = %s"), *(response.purchase_id));
    FString fstring = FString::Printf(TEXT("Query success. Purchase id = %s"),
                                      *(response.purchase_id));
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportIAPurchaseDemo::MyQueryCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPurchaseDemo][MyQueryCallback] Query failure.
                                     Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Query failure. Code = %d, message = %s"), nCode,
                                           *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

ViveportIAPSubscriptionDemo.h

#include "Components/ActorComponent.h"
#include "ViveportType.h"
#include "ViveportIAPurchaseType.h"

#include "ViveportIAPSubscriptionDemo.generated.h"

UCLASS(ClassGroup = (Viveport), meta = (BlueprintSpawnableComponent))
class VIVEPORTSDK_API UViveportIAPSubscriptionDemo : public UActorComponent
{
    GENERATED_BODY()

public:
    // Called when the game starts
    void BeginPlay() override;

    void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

    /** The VIVEPORT_ID and API_KEY for IAP testing*/
    FString VIVEPORT_ID = "app_test_id";
    FString API_KEY = "app_test_key";

    /** The Plan ID of Subscription*/
    FString PLAN_ID = "PlanID";

private:
    /** Callback objects */
    class MyViveportApiStatus : public ViveportApiStatus
    {
    protected:
        UViveportIAPSubscriptionDemo* mDemo;
    public:
        void SetDemoPtr(UViveportIAPSubscriptionDemo* p) { mDemo = p; }
    };

    class MyViveportIAPurchaseListener : public IAPurchaseListener
    {
    protected:
        UViveportIAPSubscriptionDemo* mDemo;
    public:
        void SetDemoPtr(UViveportIAPSubscriptionDemo* p) { mDemo = p; }
    };

    class MyInitCallback : public MyViveportApiStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(
            int nErrorCode
        ) override;
    };

    MyInitCallback myInitCallback;

    class MyShutdownCallback : public MyViveportApiStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(
            int nErrorCode
        ) override;
    };

    MyShutdownCallback myShutdownCallback;

    class MyIsReadyCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnSuccess(
            const FString& pchCurrencyName
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyIsReadyCallback myIsReadyCallback;

    class MyGetBalanceCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnBalanceSuccess(
            const FString& pchBalance
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyGetBalanceCallback myGetBalanceCallback;

    class MyRequestSubscriptionPlanIDCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnRequestSubscriptionWithPlanIDSuccess(
            const FString& pchSubscriptionId
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyRequestSubscriptionPlanIDCallback myRequestSubscriptionPlanIDCallback;

    class MySubscribeCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnSubscribeSuccess(
            const FString& pchSubscriptionId
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MySubscribeCallback mySubscribeCallback;

    class MyQuerySubscriptionCallback : public MyViveportIAPurchaseListener
    {
    public:
        void OnQuerySubscriptionSuccess(
            const TArray& subscriptionlist
        ) override;
        void OnFailure(
            int nCode,
            const FString& pchMessage
        ) override;
    };

    MyQuerySubscriptionCallback myQuerySubscriptionCallback;

public:
    ViveportApiStatus* GetInitCallback() { return &myInitCallback; }
    ViveportApiStatus* GetShutdownCallback() { return &myShutdownCallback; }
    IAPurchaseListener* GetIsReadyCallback() { return &myIsReadyCallback; }
    IAPurchaseListener* GetBalanceCallback() { return &myGetBalanceCallback; }
    IAPurchaseListener* GetRequestSubscriptionPlanIDCallback()
    { return &myRequestSubscriptionPlanIDCallback; }
    IAPurchaseListener* GetSubscribeCallback() { return &mySubscribeCallback; }
    IAPurchaseListener* GetQuerySubscriptionCallback() { return &myQuerySubscriptionCallback; }
};

ViveportIAPSubscriptionDemo.cpp

#include "ViveportSDKPrivatePCH.h"
#include "ViveportIAPSubscriptionDemo.h"
#include "ViveportApi.h"
#include "ViveportIAPurchase.h"

void UViveportIAPSubscriptionDemo::BeginPlay()
{
    Super::BeginPlay();

    myInitCallback.SetDemoPtr(this);
    myShutdownCallback.SetDemoPtr(this);
    myIsReadyCallback.SetDemoPtr(this);
    myGetBalanceCallback.SetDemoPtr(this);
    myRequestSubscriptionPlanIDCallback.SetDemoPtr(this);
    mySubscribeCallback.SetDemoPtr(this);
    myQuerySubscriptionCallback.SetDemoPtr(this);

    // Call ViveportApi::Init()
    UViveportApi::Init(&myInitCallback, VIVEPORT_ID);
}

void UViveportIAPSubscriptionDemo::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    Super::EndPlay(EndPlayReason);

    // Call ViveportApi::Shutdown()
    UViveportApi::Shutdown(&myShutdownCallback);
}

/***************************************************************
*                    MyInitCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyInitCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyInitCallback] Init success."));
    FString fstring("Init success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    UViveportIAPurchase::IsReady(mDemo->GetIsReadyCallback(), mDemo->API_KEY);
}

void UViveportIAPSubscriptionDemo::MyInitCallback::OnFailure(int nErrorCode)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyInitCallback] Init failure.
                                   Error = %d"), nErrorCode);
    FString fstring = FString::Printf(TEXT("Init failure. Error = %d"), nErrorCode);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyShutdownCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyShutdownCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyShutdownCallback]
                                   Shutdown success."));
    FString fstring("Shutdown success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportIAPSubscriptionDemo::MyShutdownCallback::OnFailure(int nErrorCode)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo][MyShutdownCallback]
                                     Shutdown failure. Error = %d"), nErrorCode);
    FString fstring = FString::Printf(TEXT("Shutdown failure. error=%d"), nErrorCode);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyIsReadyCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyIsReadyCallback::OnSuccess(const FString& pchCurrencyName)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyIsReadyCallback] IsReady
                                    success. Currency name = %s"), *pchCurrencyName);
    FString fstring = FString::Printf(TEXT("Is ready success, currency name = %s"), *pchCurrencyName);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Get balance
    UViveportIAPurchase::GetBalance(mDemo->GetBalanceCallback());
}

void UViveportIAPSubscriptionDemo::MyIsReadyCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo][MyIsReadyCallback]
                                     IsReady failure. Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("IsReady failure. Code = %d, message = %s"),
                                            nCode, *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyGetBalanceCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyGetBalanceCallback::OnBalanceSuccess(const FString& pchBalance)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyGetBalanceCallback] GetBalance
                                   success. Balance = %s"), *pchBalance);
    FString fstring = FString::Printf(TEXT("GetBalance success. Balance = %s"), *pchBalance);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    int32 balance = FCString::Atoi(*pchBalance);
    if (balance > 0)
    {
        // Request subscription
        UViveportIAPurchase::RequestSubscriptionWithPlanID(
        mDemo->GetRequestSubscriptionPlanIDCallback(), mDemo->PLAN_ID);
    }
}

void UViveportIAPSubscriptionDemo::MyGetBalanceCallback::OnFailure(int nCode, const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo][MyGetBalanceCallback] GetBalance
                                     failure. Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("GetBalance failure. code = %d, message = %s"), nCode,
                                      *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyRequestSubscriptionPlanIDCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyRequestSubscriptionPlanIDCallback::
     OnRequestSubscriptionWithPlanIDSuccess(const FString& pchSubscriptionId)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyRequestSubscriptionPlanIDCallback]
                                   Request subscription success. Subscription id = %s"),
                                   *pchSubscriptionId);
    FString fstring = FString::Printf(TEXT("Request subscription success. Subscription id = %s"),
                                            *pchSubscriptionId);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Subscribe the item
    UViveportIAPurchase::Subscribe(mDemo->GetSubscribeCallback(), pchSubscriptionId);
    //UViveportIAPurchase::QuerySubscription(mDemo->GetQuerySubscriptionCallback(),
                                             pchSubscriptionId);
}

void UViveportIAPSubscriptionDemo::MyRequestSubscriptionPlanIDCallback::OnFailure(int nCode,
                                   const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo]
    [MyRequestSubscriptionPlanIDCallback] Request subscription failure. Code = %d, message = %s")
    , nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Request subscription failure. Code = %d, message = %s"),
                                            nCode, *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MySubscribeCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MySubscribeCallback::OnSubscribeSuccess(
                                   const FString& pchSubscriptionId)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MySubscribeCallback] Subscribe
                                   success. Subscription id = %s"), *pchSubscriptionId);
    FString fstring = FString::Printf(TEXT("Subscribe success. Subscription id = %s"),
                                           *pchSubscriptionId);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Query subscription
    UViveportIAPurchase::QuerySubscription(mDemo->GetQuerySubscriptionCallback(), pchSubscriptionId);
}

void UViveportIAPSubscriptionDemo::MySubscribeCallback::OnFailure(int nCode,
                                                                  const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo][MySubscribeCallback] Subscribe
                                     failure. Code = %d, message = %s"), nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Subscribe failure. Code = %d, message = %s"),
                                            nCode, *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*                    MyQuerySubscriptionCallback
***************************************************************/

void UViveportIAPSubscriptionDemo::MyQuerySubscriptionCallback::OnQuerySubscriptionSuccess
                                  (const TArray& subscriptionlist)
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportIAPSubscriptionDemo][MyQuerySubscriptionCallback]
                                   Query subscription success."));
    FString fstring = FString::Printf(TEXT("Query subscription success."));
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportIAPSubscriptionDemo::MyQuerySubscriptionCallback::OnFailure(int nCode,
                                   const FString& pchMessage)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportIAPSubscriptionDemo][MyQuerySubscriptionCallback]
                                     Query subscription failure. Code = %d, message = %s"),
                                     nCode, *pchMessage);
    FString fstring = FString::Printf(TEXT("Query subscription failure. Code = %d, message = %s"),
                                            nCode, *pchMessage);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}