Skip to content

Launch Billing Flow

This asynchronous function starts the purchase flow for a selected product.
It connects directly to the Google Play Billing system and displays the native purchase UI to the user.

Depending on the product type, this function can launch either a one-time purchase or a subscription flow.
For subscriptions, an Offer Token must be provided to specify a particular base plan or promotional offer.

Once the purchase process finishes, one of the delegates will trigger — indicating whether the purchase succeeded, is pending, or failed.


Parameters

1. Product Id

The unique product ID to purchase, as defined in your Google Play Console.
Must exactly match the ID used when configuring your product.


2. Product Type

Specifies whether the purchase is a In-App product or a Subscription.
See EProductType for available values.


3. Offer Token

A required token for subscription purchases, representing the selected base plan or offer.
Can be obtained from the queried FProductDetails data by using Query Product Details node.
For in-app products, this parameter can be left empty.


4. On Success

Triggered when the purchase completes successfully.
Returns a FPurchase object containing all purchase data.
Use this delegate to unlock content or grant in-game items.


5. On Pending

Triggered when a purchase is pending (e.g., cash-based payments or delayed transactions).
You can notify the player that the transaction is awaiting confirmation.


6. On Failure

Triggered if the billing flow fails, is cancelled, or encounters a network issue.
Returns:
- Response CodeEBillingResponseCode
- Error MessageFString with debug information.

Use this delegate to log errors and handle cancellations.


Examples

In-App Purchase

In the below example, we are launching a purchase flow for an In-App Product using its product ID from the Google Play Console.
You can create your own functions to handle successful purchases, pending transactions, or failures, depending on your project’s logic.

For In-App Product purchases, the Offer Token field can be left empty.
For Subscription purchases, you must provide a valid token corresponding to the selected base plan or offer.


Subscription

In this example, we’re starting a subscription purchase using a product ID from the Google Play Console.
Depending on your project’s setup, you can implement your own logic to handle successful purchases, pending states, and failures.

The key difference when working with subscriptions is the use of an Offer Token, which identifies the selected base plan and offer.
You can obtain this token using the Get Subscription Offer Token node from the previously retrieved FProductDetails data by using Query Product Details node.

If a subscription has multiple base plans or offers, make sure to store the relevant product details and select the desired one when launching the billing flow.
If there’s only one plan available, the Offer Token can be left blank — the first available plan will be used automatically.


C++ Usage

You can also launch the billing flow directly from C++ using the static LaunchBillingFlow function.
Provide a valid Product ID, Product Type, and (optionally) an Offer Token for subscriptions.

In-App Purchase

#include "BillingCPPLibrary.h"

void UMyGameInstance::StartPurchase()
{
    FString ProductId = TEXT("gems_pack_1");

    FOnPurchaseSuccessfulNative OnSuccess;
    OnSuccess.BindLambda([](const FPurchase& Purchase)
    {
        UE_LOG(LogTemp, Log, TEXT("Purchase successful"));
    });

    FOnPurchasePendingNative OnPending;
    OnPending.BindLambda([](const FPurchase& Purchase)
    {
        UE_LOG(LogTemp, Warning, TEXT("Purchase pending"));
    });

    FOnPurchaseFailedNative OnFailure;
    OnFailure.BindLambda([](EBillingResponseCode Code, const FString& Message)
    {
        UE_LOG(LogTemp, Error, TEXT("Purchase failed: %s (Code: %d)"), *Message, static_cast<int32>(Code));
    });

    UBillingCPPLibrary::LaunchBillingFlow(ProductId, EProductType::INAPP, OnSuccess, OnPending, OnFailure);
}

Subscription

#include "BillingCPPLibrary.h"

void UMyGameInstance::StartPurchase()
{
    FString ProductId = TEXT("premium_subscription");

    // For subscriptions, retrieve the offer token from your stored ProductDetails
    FString OfferToken = TEXT("baseplan_offer_token");

    FOnPurchaseSuccessfulNative OnSuccess;
    OnSuccess.BindLambda([](const FPurchase& Purchase)
    {
        UE_LOG(LogTemp, Log, TEXT("Purchase successful"));
    });

    FOnPurchasePendingNative OnPending;
    OnPending.BindLambda([](const FPurchase& Purchase)
    {
        UE_LOG(LogTemp, Warning, TEXT("Purchase pending"));
    });

    FOnPurchaseFailedNative OnFailure;
    OnFailure.BindLambda([](EBillingResponseCode Code, const FString& Message)
    {
        UE_LOG(LogTemp, Error, TEXT("Purchase failed: %s (Code: %d)"), *Message, static_cast<int32>(Code));
    });

    UBillingCPPLibrary::LaunchBillingFlow(ProductId, EProductType::INAPP, OfferToken, OnSuccess, OnPending, OnFailure);
}