Skip to content

billingclient

YYBartT edited this page Aug 29, 2024 · 3 revisions

BillingClient

Google Play Billing package: com.android.billingclient.api

Functions

These are the functions available in the Google Play Billing extension:

Structs

These are the structs returned by the Google Play Billing extension:

Constants

These are the constants used by the Google Play Billing extension:



Back To Top

GPBilling_Init

This function initialises the Google Play Billing API.

Note

By default this is set as the extension's Init function and called automatically. You can also call the function yourself manually. Subsequent calls to the function won't do anything.


Syntax:

GPBilling_Init()



Returns:

N/A


Example:

GPBilling_Init();



Back To Top

GPBilling_ConnectToStore

This function will attempt to connect the Google Play Billing API with the Play Store.

The function will return one the gpb_error_type constants to inform you of the status of the connection attempt.

This function must be called before calling any other IAP functions and the return status should be gpb_no_error. This does not, however, mean that the Store is available, only that the connection attempt has been successful. Before you can successfully define, query or purchase any products, you must ensure that the connection is valid.

To check the availability of the Play Store, the function will also trigger one of two callbacks in the In-App Purchase Async Event.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_ConnectToStore()



Returns:

gpb_error_type


Triggers:

In-App Purchase Async Event

If the initial returned status is gpb_no_error.

Key Type Description
id gpb_event_type gpb_store_connect or gpb_store_connect_failed, depending on whether a connection could be made to the Play Store.

Example:

In this extended example, we first send an API request to connect to the store in some event. This would normally be done in the Create Event of a dedicated controller object that is one of the first things created in your game:

/// Create Event
var _init = GPBilling_ConnectToStore();
if (_init == gpb_error_unknown)
{
    show_debug_message("ERROR - Billing API Has Not Connected!");
    alarm[0] = game_get_speed(gamespeed_fps) * 10;
}

Note

If the connection request has failed, then we can – for example - call an alarm, where we can call this same code again to test for store connection periodically.

Assuming the API has correctly requested a store connection, it will trigger an In-App Purchase Async Event where you can check to see if the API has successfully connected to the Google Play Store or not:

if(os_type != os_android) exit;

var _event_id = async_load[? "id"];
switch (_event_id)
{
    // ...

    case gpb_store_connect:
        // At this point we have just finished connecting to the store so we need to:

        // 1) Add the products to the local IAP
        GPBilling_AddProduct(IAP_100gems);
        GPBilling_AddProduct(IAP_noads);
        GPBilling_AddSubscription(IAP_premium);

        // 2) Query purchase data (async)
        GPBilling_QueryPurchasesAsync(gpb_purchase_skutype_inapp);

        // 3) Query products and subscriptions
        // (required to use 'GPBilling_Sku_GetOriginalJson')
        GPBilling_QueryProducts();
        GPBilling_QuerySubscriptions();
        break;

    case gpb_store_connect_failed:
        // Store has failed to connect, so try again periodically
        alarm[0] = game_get_speed(gamespeed_fps) * 10;
        break;

    // ...
}

In the above example, if the store connection fails, you'll see we set an alarm, setting it to count down 10 seconds. In this event we can then try to initialise the store once more using the same code that we have in the Create Event, shown above.




Back To Top

GPBilling_IsStoreConnected

This function checks if the Google Play Billing API currently has a connection to the Google Play Store. The function will return true if it has and false if it hasn't.

Note

If there is no connection, you should not permit any further Google Play Billing API function calls and you could also disable or hide any purchase options for the user in your game UI until the connection has been re-established. In general, you should always call this function and check connectivity before doing any interactions with the Billing API.


Syntax:

GPBilling_IsStoreConnected()



Returns:

Boolean


Example:

/// Left Mouse Released event
if (!GPBilling_IsStoreConnected()) exit;

GPBilling_PurchaseSubscription(product_id);



Back To Top

GPBilling_GetStatus

This function returns the status of the Google Play Billing extension.

The status can be one of gpb_no_error, gpb_error_not_initialised or gpb_error_no_skus.


Syntax:

GPBilling_GetStatus()



Returns:

gpb_error_type


Example:

GPBilling_GetStatus();



Back To Top

GPBilling_AddProduct

This function can be used to add a consumable product to the internal product list for purchase. You supply the Product ID (as a string, the same as the product ID on the Google Play Console for the game), and the function will return either gpb_error_unknown or gpb_no_error. For subscription products, you should be using the function GPBilling_AddSubscription.

Note

There is no difference between a consumable and a non-consumable product as far as the API is concerned. So, for non-consumable IAPs – like a "no ads" IAP, for example – you simply don't call the GPBilling_ConsumeProduct function on it. However, non-consumables should still be acknowledged using the GPBilling_AcknowledgePurchase function when purchased.


Syntax:

GPBilling_AddProduct(product_id)
Argument Type Description
product_id String The product ID (SKU) of the IAP product to add.



Returns:

gpb_error_type


Example:

The following code is being called from the In-App Purchase Async Event when it has been triggered by the function GPBilling_ConnectToStore:

var _eventId = async_load[? "id"];
switch (_eventId)
{
    // ...

    case gpb_store_connect:
        GPBilling_AddProduct(IAP_100gems);
        GPBilling_AddProduct(IAP_noads);
        GPBilling_AddSubscription(IAP_premium);

        GPBilling_QueryProducts();
        GPBilling_QuerySubscriptions();
        break;

    // ...
}



Back To Top

GPBilling_AddSubscription

This function can be used to add a subscription product to the internal product list for purchase. You supply the Product ID (as a string, the same as the product ID on the Google Play Console for the game), and the function will return one of the constants listed below.

The function returns either gpb_error_unknown or gpb_no_error.

For consumable products, you should be using the function GPBilling_AddProduct.


Syntax:

GPBilling_AddSubscription(product_id)
Argument Type Description
product_id String The product ID (SKU) to add.



Returns:

N/A


Example:

The following code is being called from the In-App Purchase Async Event when it has been triggered by the function GPBilling_ConnectToStore.

var _eventId = async_load[? "id"];
switch (_eventId)
{
    // ...

    case gpb_store_connect:
        GPBilling_AddProduct(IAP_100gems);
        GPBilling_AddProduct(IAP_noads);
        GPBilling_AddSubscription(IAP_premium);

        GPBilling_QueryProducts();
        GPBilling_QuerySubscriptions();
        break;

    // ...
}



Back To Top

GPBilling_QueryProducts

This function can be used to query the state of any consumable products (for subscriptions, please use the function GPBilling_QuerySubscriptions).

This function will generate an In-App Purchase Async Event where the async_load DS map "id" key holds the constant gpb_product_data_response, as well as the key "json_response".

Note

You should NOT call this function at the same time as the equivalent subscription query, as this may cause the Google API to error. Instead, call one function, and then in the In-App Purchase Async Event callback, call the other function if you need to.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_QueryProducts()



Returns:

N/A


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The value gpb_product_data_response
json_response String A JSON encoded string containing the response data:

* "success" (Boolean) - Whether the query was successfully processed
* "skuDetails"(Array of sku_details) - An array containing the details of every activated IAP product

Example:

The following code is being called from the In-App Purchase Async Event when it has been triggered by the function GPBilling_ConnectToStore.

var _event_id = async_load[? "id"];
switch (_event_id)
{
    // ...

    case gpb_store_connect:
        GPBilling_AddProduct(IAP_100gems);
        GPBilling_AddProduct(IAP_noads);
        GPBilling_AddSubscription(IAP_premium);

        GPBilling_QueryProducts();
        GPBilling_QuerySubscriptions();
        break;

    // ...
}

The query products function will then trigger another call to the In-App Purchase Async Event, which can be parsed by adding another case to the switch statement, this time checking the async_load key "id" for the constant gpb_product_data_response. Something like this:

case gpb_product_data_response:
    var _json = async_load[? "response_json"];
    var _response_data = json_parse(_json);
    if (_response_data.success)
    {
        var _sku_detail, _arr_sku_details = _response.skuDetails;
        for (var i = 0; i < array_length(_arr_sku_details); ++i)
        {
            _sku_detail = _arr_sku_details[i];
            show_debug_message($"{_sku_detail.title} ({_sku_detail.productId})\n-----\n");
            show_debug_message($"{_sku_detail.description}");
            show_debug_message($"{_sku_detail.price}");
        }
        GPBilling_QuerySubscriptions();
    }
    break;

Note

After parsing the returned product data, we then call the equivalent query function for subscriptions, and then when that triggers another asynchronous callback we'd call the function GPBilling_QueryPurchasesAsync to check for any purchases that haven't been consumed.




Back To Top

GPBilling_QuerySubscriptions

This function can be used to query the state of any subscription products (for consumables, please use the function GPBilling_QueryProducts).

This function will generate an In-App Purchase Async Event where the async_load DS map "id" key holds the constant gpb_subscription_data_response, as well as the key "json_response". This key contains a JSON object string that holds an Array of sku_details structs.

The DS map for each individual product will contain the following keys:

Note

You should NOT call this function at the same time as the equivalent products query, as this may cause the Google API to error. Instead, call one function, and then in the In-App Purchase Async Event callback, call the other function if you need to.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_QuerySubscriptions()



Returns:

N/A


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The value gpb_product_data_response
json_response String A JSON encoded string containing the response data:

* "success" (Boolean) - Whether the query was successfully processed
* "skuDetails"(Array of sku_details) - An array containing the details of every activated IAP product

Example:

The following code is being called from the In-App Purchase Async Event when it has been triggered by the function GPBilling_ConnectToStore.

var _event_id = async_load[? "id"];
switch (_event_id)
    {
    case gpb_store_connect:
        GPBilling_AddSubscription(global.IAP_PurchaseID[0]);
        GPBilling_AddSubscription(global.IAP_PurchaseID[1]);
        GPBilling_QuerySubscriptions();
        break;
    }

The query subscriptions function will then trigger another call to the In-App Purchase Async Event, which can be parsed by adding another case to the switch statement, this time checking the async_load key "id" for the constant gpb_subscription_data_response, something like this:

case gpb_subscription_data_response:
    var _json = async_load[? "response_json"];
    var _response_data = json_parse(_json);
    if (_response_data.success)
    {
        var _arr_sku_details = _response.skuDetails;
        for (var i = 0; i < array_length(_arr_sku_details); ++i)
        {
            var _sku_detail = _arr_sku_details[i];
            show_debug_message($"{_sku_detail.title} ({_sku_detail.productId})\n-----\n");
            show_debug_message($"{_sku_detail.description}");
            show_debug_message($"{_sku_detail.price}");
        }
        GPBilling_QueryPurchasesAsync(gpb_purchase_skutype_inapp);
    }
    break;

Note

After parsing the returned subscription data, we then call the function GPBilling_QueryPurchasesAsync to check for any purchases that haven't been consumed. If you haven't already queried consumable products, then you should probably do that first, then in the corresponding In-App Purchase Async Event callback, you'd check the purchase status.




Back To Top

GPBilling_PurchaseProduct

This function sends a purchase request to the Billing API and attempts to purchase the product with the given ID. The ID value should be a string and is the product identifier name on the Google Play Console, for example "buy_100_gold". The function will return one of the constants listed below to indicate the initial status of the purchase request, and then an In-App Purchase Async Event will be triggered with the callback.

The function returns one of gpb_error_not_initialised, gpb_error_no_skus, gpb_error_selected_sku_list_empty or gpb_no_error.

The In-App Purchase Async Event callback will return the async_load DS map, which will contain an "id" key with the constant gpb_iap_receipt for a purchase request, as well as the key "response_json", which will contain a JSON formatted string with the purchase data.

Keep in mind that any NON-consumable purchases will also have the purchased state (1), as the Google Billing API makes no distinction between consumable and non-consumable and it's up to you to decide when and if a purchase is consumed. However, all purchases must be acknowledged within 2 days of purchase, even if they are not being consumed. This is done automatically when a consumable is used, however for non-consumables this must be done using the function GPBilling_AcknowledgePurchase. If you do not acknowledge a purchase within 2 days, it will be refunded.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_PurchaseProduct(product_id)
Argument Type Description
product_id String The ID of the product as shown on the Google Play Console.



Returns:

gpb_error_type


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The constant gpb_iap_receipt
response_json String A JSON encoded string containing the response data:

* "success" (Boolean) - Whether the query was successfully processed
* "purchases"(Array of purchase) - An array containing the details of every purchase. Only present if "success" is true.

Example:

The following code would be used in (for example, but not limited to) a mouse pressed event to purchase a product:

/// Mouse Left Pressed Event
if (!GPBilling_IsStoreConnected()) exit;

GPBilling_PurchaseProduct(product_id);

You would then have something like the following code in the In-App Purchase Async Event to deal with the purchase callback.

Note

The following code shows a simple purchase verification scheme, however you should ideally verify the purchase with an HTTP call to your server, supplying the returned token string, and then consume the purchase when you receive verification in the Http Async Event.

var _event_id = async_load[? "id"];
switch (_event_id)
{
    case gpb_iap_receipt:
        var _json = async_load[? "response_json"];
        var _response_data = json_parse(_json);
        if (_response_data.success)
        {
            var _purchases = _response_data.purchases;
            for (var i = 0; i < array_length(_purchases); ++i)
            {
                var _purchase = _purchases[i];
                var _ptoken = _purchase.purchaseToken;
                var _sig = GPBilling_Purchase_GetSignature(_ptoken);
                var _pjson = GPBilling_Purchase_GetOriginalJson(_ptoken);
                if (GPBilling_Purchase_VerifySignature(_pjson, _sig))
                {
                    GPBilling_ConsumeProduct(_ptoken);
                    array_push(global.CurrentTokens, _ptoken);
                    array_push(global.CurrentProducts, _purchase.productId);
                }
            }
        }
        break;

    // ...
}

Note

We store the purchase tokens and product IDs of those products we consume or acknowledge in global arrays. This is done so that we can track the purchases correctly when the consumed or acknowledged response comes back (see the functions GPBilling_AcknowledgePurchase and GPBilling_ConsumeProduct for more details).




Back To Top

GPBilling_PurchaseSubscription

This function will send a subscription purchase request to the Billing API and attempt to subscribe to the product with the given ID. The ID value should be a string and is the subscription identifier name on the Google Play Console, for example "improved_version". The function will return one of the constants listed below to indicate the initial status of the subscription request, and then an In-App Purchase Async Event will be triggered with the callback.

The function returns one of gpb_error_not_initialised, gpb_error_no_skus, gpb_error_selected_sku_list_empty or gpb_no_error.

The In-App Purchase Async Event callback will return the async_load DS map, which will contain an "id" key with the constant gpb_iap_receipt for a purchase request, as well as the key "response_json", which will contain a JSON formatted string with the purchase data.

Note

Keep in mind that all subscription purchases must be acknowledged within 2 days of purchase, using the function GPBilling_AcknowledgePurchase. If you do not acknowledge a purchase within 2 days, it will be refunded.

Note

After the initial purchase, the subscription will be renewed automatically by Google, and all you have to do is query the subscription state each time the game starts to unlock or block any additional content as required.

⚠️ IMPORTANT Setting up and using subscriptions requires an external server to be able to communicate with your app and with the Google Play servers for verification and other purposes. This is outside of the scope of this documentation and instead we refer you to the following documents:

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_PurchaseSubscription(product_id)
Argument Type Description
product_id String The ID of the product as shown on the Google Play Console.



Returns:

gpb_error_type


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The constant gpb_iap_receipt
response_json String A JSON encoded string containing the response data:

* "success" (Boolean) - Whether the query was successfully processed
* "purchases" (Array of purchase) - An array containing the details of every purchase. Only present if "success" is true.

Example:

The following code would be used in (for example, but not limited to) a mouse pressed event to purchase a product:

/// Mouse Left Pressed Event
if (!GPBilling_IsStoreConnected()) exit;

GPBilling_PurchaseSubscription(product_id);

You would then have something like the following code in the In-App Purchase Async Event to deal with the purchase callback.

Note

The following code shows a simple purchase verification scheme, however you should ideally verify the purchase with an HTTP call to your server, supplying the returned token string, and then consume the purchase only when you receive verification in the Http Async Event.

var _event_id = async_load[? "id"];
switch (_event_id)
{
    case gpb_iap_receipt:
        var _json = async_load[? "response_json"];
        var _response_data = json_parse(_json);
        if (_response_data.success)
        {
            var _purchases = _response_data.purchases;
            for (var i = 0; i < array_length(_purchases);  ++i)
            {
                var _purchase = _purchases[i];
                var _ptoken = _purchase.purchaseToken;
                var _sig = GPBilling_Purchase_GetSignature(_ptoken);
                array_push(global.CurrentTokens, _ptoken);
                array_push(global.CurrentProduct, _purchase.productId);

                // SERVER VERIFICATION CODE HERE
                // Here you would send the token and signature to
                // your servers for verification with the Google
                // Play API and then return the result, which would
                // then be received in an Asynchronous HTTP event.
                // Once received, the subscription can then
                // be acknowledged, and content, bonuses, etc.
                // can be unlocked in your game.
            }
        }
        break;
}

Note

We store the purchase tokens and product IDs of those products we consume or acknowledge in global arrays. This is done so that we can track the purchases correctly when the consumed or acknowledged response comes back (see the functions GPBilling_AcknowledgePurchase and GPBilling_ConsumeProduct for more details).




Back To Top

GPBilling_AcknowledgePurchase

This function acknowledges a purchase or subscription.

The function returns either gpb_no_error or gpb_error_unknown.

When you receive a notification that a purchase has been made, it needs to be acknowledged with the Google servers within 2 days, otherwise it is refunded. This is done automatically for consumable purchases when you call the function GPBilling_ConsumeProduct, but for non-consumable and subscriptions, you must call this function to let Google know the purchase has been received correctly.

On calling the function initially, it will return one of the constants listed below to inform you of the request status, and if this is gpb_no_error then an In-App Purchase Async Event will be triggered where the async_load DS map will have the key "id" which will correspond to the extension constant gpb_acknowledge_purchase_response. Additionally, the map will have the key "response_json" which will be a JSON string that can be converted into a Struct using the json_parse function.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_AcknowledgePurchase(purchase_token)
Argument Type Description
purchase_token String The unique string token for the purchase being acknowledged.



Returns:

gpb_error_type


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The constant gpb_acknowledge_purchase_response.
response_json String A JSON encoded string containing the details of the acknowledgement.

* "responseCode" (Real) - This can be checked before proceeding to deal with the acknowledgement response. It can have one of the following integer values:
* -3 - The request has reached the maximum timeout before Google Play responds.
* -2 – Requested feature is not supported by Play Store on the current device.
* -1 – The Play Store service is not connected currently.
* 0 – Success
* 1 – User has cancelled the action
* 2 – Network connection is down
* 4 – Requested product is not available for purchase
* 6 – Fatal error during the API action
* 7 – Failure to purchase since item is already owned
* 8 – Failure to consume since item is not owned

* "purchaseToken" (String) - A reference to the purchase token.

Example:

This example shows how you'd deal with the callback in the In-App Purchase Async Event for an acknowledged product (for an example of when the GPBilling_AcknowledgePurchase function should be called, see the Example for the function GPBilling_PurchaseSubscription):

var _event_id = async_load[? "id"];
switch (_event_id)
{
    case gpb_acknowledge_purchase_response:
        var _response_data = json_parse(async_load[? "response_json"]);
        var _num = -1;
        if (_response_data.responseCode == 0)
        {
            var _sz = array_length(global.CurrentProducts);
            for (var i = 0; i < _sz; ++i)
            {
                if (global.CurrentProducts[i] == "yoyo_noads")
                {
                    global.NoAds = true;
                    _num = i;
                    break;
                }
                // Add further checks for other products here...
            }
            if (_num > -1)
            {
                array_delete(global.CurrentProducts, _num, 1);
                array_delete(global.CurrentTokens, _num, 1);
            }
        }
        else
        {
            // Parse the other response codes here
            // and react appropriately
        }
        break;
}



Back To Top

GPBilling_ConsumeProduct

This function will consume a purchase. When you receive a notification that a purchase has been made, it needs to be consumed or acknowledged with the Google servers within 2 days, otherwise it is refunded. Consumable purchases are acknowledged automatically when you call this function, but for non-consumable and subscription purchases, see the function GPBilling_AcknowledgePurchase.

The function either returns gpb_no_error or gpb_error_unknown.

On calling the function initially, it will return one of the constants listed below to inform you of the request status, and if this is gpb_no_error then an In-App Purchase Async Event will be triggered where the async_load DS map will have the key "id" which will correspond to the extension constant gpb_product_consume_response. Additionally, the map will have the key "response_json" which will be a JSON string that can be converted into a Struct using the json_parse function.

If you have the "responseCode" key, then it can be checked for one of the following integer values:

  • -3 – The request has reached the maximum timeout before Google Play responds.
  • -2 – Requested feature is not supported by Play Store on the current device.
  • -1 – The Play Store service is not connected currently.
  • 0 – Success
  • 1 – User has cancelled the action
  • 2 – Network connection is down
  • 4 – Requested product is not available for purchase
  • 6 – Fatal error during the API action
  • 7 – Failure to purchase since item is already owned
  • 8 – Failure to consume since item is not owned

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_ConsumeProduct(purchase_token)
Argument Type Description
purchase_token String The unique string token for the purchase being acknowledged.



Returns:

gpb_error_type


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The constant gpb_product_consume_response.
response_json String A JSON encoded string containing the following:

* responseCode - One of the following values:

* -3 – The request has reached the maximum timeout before Google Play responds.
* -2 – Requested feature is not supported by Play Store on the current device.
* -1 – The Play Store service is not connected currently.
* 0 – Success
* 1 – User has cancelled the action
* 2 – Network connection is down
* 4 – Requested product is not available for purchase
* 6 – Fatal error during the API action
* 7 – Failure to purchase since item is already owned
* 8 – Failure to consume since item is not owned

* purchaseToken (String) - The purchase token string of the consumed product.

Example:

This example shows how you'd deal with the callback in the In-App Purchase Async Event for a consumed product (for an example of when the GPBilling_ConsumeProduct function should be called, see the Example for the function GPBilling_PurchaseProduct):

var _eventId = async_load[? "id"];
switch (_eventId)
{
    // ...

    case gpb_product_consume_response:
        var _response_data = json_parse(async_load[? "response_json"]);
        var _num = -1;
        if (struct_exists(_response_data, "purchaseToken"))
        {
            for (var i = 0; i < array_length(global.CurrentTokens); ++i)
            {
                if (_response_data.purchaseToken == global.CurrentTokens[i])
                {
                    if (global.CurrentProducts[i] == "yoyo_500gold")
                    {
                        global.Gold += 500;
                        _num = i;
                        break;
                    }
                    // Check any other products here...
                }
            }
            if (_num > -1)
            {
                array_delete(global.CurrentProducts, _num, 1);
                array_delete(global.CurrentTokens, _num, 1);
            }
        }
        else
        {
            // Parse the error response codes here
            // and react appropriately
        }
        break;

    // ...
}



Back To Top

GPBilling_Sku_GetDescription

This function will return the descriptive text as defined on the Google Play Developer Console for the given SKU (product ID) You supply the product ID as a string, and the function will return a string with the description.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetDescription(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);



Back To Top

GPBilling_Sku_GetFreeTrialPeriod

This function will return the Trial Period as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a string in ISO 8601 format, for example "P7D" which would equate to seven days.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Note

This function is only valid for subscriptions which have a trial period configured.


Syntax:

GPBilling_Sku_GetFreeTrialPeriod(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

N/A


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _period = GPBilling_Sku_GetFreeTrialPeriod(global.IAP_PurchaseID[0]);
var _days = string_digits(_period);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, "Trial Period: " + _days + " days");



Back To Top

GPBilling_Sku_GetIconUrl

This function returns the URL for the icon of the given SKU (product ID) as created on the Google Play Developer Console. You supply the product ID as a string, and the function will return a string with the URL. You can then use the sprite_add function to retrieve this image (which will trigger an Image Loaded Event and then display it in your game).

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetIconUrl(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

In this example, we first call the function to get the URL of the icon for a product (probably in an In-App Purchase Async Event, after querying the product details):

var _url = GPBilling_Sku_GetIconUrl(global.IAP_PurchaseID[0]);
iap_sprite = sprite_add(_url, 0, false, false, 0, 0);

This will trigger an Image Loaded Event where you can then store the returned image for drawing:

if (ds_map_find_value(async_load, "id") == iap_sprite)
{
    if (ds_map_find_value(async_load, "status") >= 0)
    {
        sprite_index = iap_sprite;
    }
}



Back To Top

GPBilling_Sku_GetIntroductoryPrice

This function will return the introductory price as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a formatted string with the price that includes the currency sign, for example "€3.99".

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Warning

This function is only valid for subscriptions which have an introductory period configured.


Syntax:

GPBilling_Sku_GetIntroductoryPrice(sku)
Argument Type Description
sku String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetIntroductoryPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);



Back To Top

GPBilling_Sku_GetIntroductoryPriceAmountMicros

This function will return the introductory price as defined on the Google Play Developer Console for the given SKU (product ID) in micros, where 1,000,000 micros equals one unit of the currency. You supply the product ID as a string, and the function will return an integer value for the price in micros, for example 7990000 (which would be 7.99 in currency).

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Warning

This function is only valid for subscriptions which have an introductory period configured.


Syntax:

GPBilling_Sku_GetIntroductoryPriceAmountMicros(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

Real


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _m = GPBilling_Sku_GetIntroductoryPriceAmountMicros(global.IAP_PurchaseID[0]);
var _c = GPBilling_Sku_GetPriceCurrencyCode(global.IAP_PurchaseID[0]);
var _val = string(_m / 1000000);
var _symbol = "";
switch (_c)
{
    case "GBP": _symbol = "£"; break;
    case "JPY": _symbol = "¥"; break;
    case "EUR": _symbol = ""; break;
}
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _symbol + _val);



Back To Top

GPBilling_Sku_GetIntroductoryPriceCycles

This function will return the introductory price cycles as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a string of the value for the number of billing cycles that the user will pay the introductory price for, for example "3".

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Warning

This function is only valid for subscriptions which have an introductory period configured.


Syntax:

GPBilling_Sku_GetIntroductoryPriceCycles(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetIntroductoryPrice(global.IAP_PurchaseID[0]);
var _cycles = GPBilling_Sku_GetIntroductoryPriceCycles(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);
draw_text(x, y + 80, "for " + _cycles + " months");



Back To Top

GPBilling_Sku_GetIntroductoryPricePeriod

This function will return the introductory price period as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a string in ISO 8601 format, for example "P7D" would equate to seven days.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Warning

This function is only valid for subscriptions which have an introductory period configured.


Syntax:

GPBilling_Sku_GetIntroductoryPricePeriod(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _period = GPBilling_Sku_GetIntroductoryPricePeriod(global.IAP_PurchaseID[0]);
var _days = string_digits(_period);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, "Offer Lasts For " + _days + " days!");



Back To Top

GPBilling_Sku_GetOriginalJson

This function will return the original JSON corresponding to the given SKU (product ID), containing all the details about the product. You supply the product ID as a string, and the function will return a JSON string that can be decoded into a Struct using the json_parse function. The struct's contents will correspond to the details listed in the Google Billing documentation (see the Android developer documentation on SkuDetails for more information).

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetOriginalJson(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code can be called after querying a product to retrieve all the information about it without calling the individual SKU functions:

var _json = GPBilling_Sku_GetOriginalJson(global.IAP_PurchaseID[0]);
var _data = json_parse(_json);
global.IAP_PurchaseData[0, 0] = _data.price;
global.IAP_PurchaseData[0, 1] = _data.title;
global.IAP_PurchaseData[0, 2] = _data.description;



Back To Top

GPBilling_Sku_GetOriginalPrice

This function will return the original price as defined on the Google Play Developer Console for the given SKU (product ID), where the original price is the price of the item before any applicable sales have been applied. You supply the product ID as a string, and the function will return a formatted string with the price that includes the currency sign, for example "€3.99".

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetOriginalPrice(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetOriginalPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);



Back To Top

GPBilling_Sku_GetOriginalPriceAmountMicros

This function will return the original price as defined on the Google Play Developer Console for the given SKU (product ID) in micros, where 1,000,000 micros equals one unit of the currency. The original price is defined as the price of the item before any applicable sales have been applied, and the value represents the localised, rounded price for a particular currency. You supply the product ID as a string, and the function will return an integer value for the price in micros, for example 7990000 (which would be 7.99 in currency).

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetOriginalPriceAmountMicros(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

Real


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _m = GPBilling_Sku_GetOriginalPriceAmountMicros(global.IAP_PurchaseID[0]);
var _c = GPBilling_Sku_GetPriceCurrencyCode(global.IAP_PurchaseID[0]);
var _val = string(_m / 1000000);
var _symbol = "";
switch (_c)
{
    case "GBP": _symbol = "£"; break;
    case "JPY": _symbol = "¥"; break;
    case "EUR": _symbol = ""; break;
}
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _symbol + _val);



Back To Top

GPBilling_Sku_GetPrice

This function will return the current price as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a formatted string with the price that includes the currency sign, for example "€3.99".

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetPrice(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);



Back To Top

GPBilling_Sku_GetPriceAmountMicros

This function will return the current price as defined on the Google Play Developer Console for the given SKU (product ID) in micros, where 1,000,000 micros equals one unit of the currency, and the value represents the localized, rounded price for a particular currency. You supply the product ID as a string, and the function will return an integer value for the price in micros, for example 7990000 (which would be 7.99 in currency).

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetPriceAmountMicros(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

Real


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _m = GPBilling_Sku_GetPriceAmountMicros(global.IAP_PurchaseID[0]);
var _c = GPBilling_Sku_GetPriceCurrencyCode(global.IAP_PurchaseID[0]);
var _val = string(_m / 1000000);
var _symbol = "";
switch (_c)
{
    case "GBP": _symbol = "£"; break;
    case "JPY": _symbol = "¥"; break;
    case "EUR": _symbol = ""; break;
}
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _symbol + _val);



Back To Top

GPBilling_Sku_GetPriceCurrencyCode

This function will return the currency code for the given SKU (product ID). You supply the product ID as a string, and the function will return a string in ISO 4217 format, for example "EUR" would equate to the Euro currency.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetPriceCurrencyCode(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _m = GPBilling_Sku_GetPriceAmountMicros(global.IAP_PurchaseID[0]);
var _c = GPBilling_Sku_GetPriceCurrencyCode(global.IAP_PurchaseID[0]);
var _val = string(_m / 1000000);
var _symbol = "";
switch (_c)
{
    case "GBP": _symbol = "£"; break;
    case "JPY": _symbol = "¥"; break;
    case "EUR": _symbol = ""; break;
}
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _symbol + _val);



Back To Top

GPBilling_Sku_GetSubscriptionPeriod

This function will return the subscription renewal period as defined on the Google Play Developer Console for the given SKU (product ID). You supply the product ID as a string, and the function will return a string in ISO 8601 format, for example "P7D" would equate to seven days.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.

Warning

This function is only valid for subscription IAPs.


Syntax:

GPBilling_Sku_GetSubscriptionPeriod(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _period = GPBilling_Sku_GetSubscriptionPeriod(global.IAP_PurchaseID[0]);
var _days = string_digits(_period);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, "Renewal Period: " + _days + " days");



Back To Top

GPBilling_Sku_GetTitle

This function will return the title of a given SKU (product ID) as defined on the Google Play Developer Console. You supply the product ID as a string, and the function will return a string with the product title.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetTitle(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

String


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);



Back To Top

GPBilling_Sku_GetType

This function will return the in-app purchase type of a given SKU (product ID) as defined on the Google Play Developer Console. You supply the product ID as a string, and the function will return a constant with the IAP product type.

Note

This function requires you to have called GPBilling_QueryProducts or GPBilling_QuerySubscriptions first, but once those have returned their respective Async callbacks, this function can be used anywhere in your game code to retrieve the required information.


Syntax:

GPBilling_Sku_GetType(product_id)
Argument Type Description
product_id String The unique SKU (product ID) of the product.



Returns:

gpb_purchase_skutype


Example:

The following code would be called in the Draw Event of an object used to display the information for a given IAP product:

var _name = GPBilling_Sku_GetTitle(global.IAP_PurchaseID[0]);
var _desc = GPBilling_Sku_GetDescription(global.IAP_PurchaseID[0]);
var _price = GPBilling_Sku_GetPrice(global.IAP_PurchaseID[0]);
draw_set_halign(fa_center);
draw_text(x, y + 32, _name);
draw_text(x, y + 48, _desc);
draw_text(x, y + 64, _price);
if (GPBilling_Sku_GetType(global.IAP_PurchaseID[0]) == gpb_purchase_skutype_subs)
{
    draw_text(x, y + 80, "Subscription!");
}



Back To Top

GPBilling_Purchase_GetState

Google Play Billing Function: Purchase.getPurchaseState

This function can be used to check the current state of a product purchase. You supply the unique purchase token (as a string), and the function will return one of the gpb_purchase_state constants to indicate the current state of the purchase.


Syntax:

GPBilling_Purchase_GetState(purchase_token)
Argument Type Description
purchase_token String The purchase token for the purchase to check.



Returns:

gpb_purchase_state


Example:

if (GPBilling_Purchase_GetState(global.CurrentToken) == gpb_purchase_state_purchased)
{
    sprite_index = spr_IconConsume;
}



Back To Top

GPBilling_Purchase_GetSignature

Google Play Billing Function: Purchase.getSignature

This function will return a string containing the signature of the purchase data that was signed with the private key of the developer. If the function fails, then an empty string "" will be returned.


Syntax:

GPBilling_Purchase_GetSignature(purchase_token)
Argument Type Description
purchase_token String The purchase token for the purchase to check.



Returns:

String


Example:

for (var i = 0; i < array_length(global.CurrentTokens); ++i)
{
    var _sig = GPBilling_Purchase_GetSignature(global.CurrentTokens[i]);
    var _json = GPBilling_Purchase_GetOriginalJson(global.CurrentTokens[i]);
    if (GPBilling_Purchase_VerifySignature(_json, _sig))
    {
        GPBilling_ConsumeProduct(global.CurrentTokens[i]);
    }
}



Back To Top

GPBilling_Purchase_VerifySignature

This function can be used to verify a purchase before consuming or acknowledging it. You supply a JSON string plus the unique signature for a purchase. You can retrieve these details using the GPBilling_Purchase_GetSignature and GPBilling_Purchase_GetOriginalJson functions, and the function will return true if the purchase can be verified, or false otherwise.

Warning

This form of verification isn't truly secure because it requires you to bundle purchase verification logic within your app. This logic becomes compromised if your app is reverse engineered. Instead we recommend that you create your own server to verify any product purchases.


Syntax:

GPBilling_Purchase_VerifySignature(original_json, signature)
Argument Type Description
original_json String The original JSON related to the purchase being verified
signature String The unique signature used to verify the purchase



Returns:

Boolean


Example:

for (var i = 0; i < array_length(global.CurrentTokens); ++i)
{
    var _sig = GPBilling_Purchase_GetSignature(global.CurrentTokens[i]);
    var _json = GPBilling_Purchase_GetOriginalJson(global.CurrentTokens[i]);
    if (GPBilling_Purchase_VerifySignature(_json, _sig))
    {
        GPBilling_ConsumeProduct(global.CurrentTokens[i]);
    }
}



Back To Top

GPBilling_Purchase_GetOriginalJson

Google Play Billing Function: Purchase.getOriginalJson(

This function will return the original JSON string related to a purchase. You supply the unique purchase token (a string) and the function will return a JSON object string that can be decoded into a Struct using the json_parse function. This struct will contain all the details about the given purchase. If the function fails, then an empty string "" will be returned.


Syntax:

GPBilling_Purchase_GetOriginalJson(purchaseToken)
Argument Type Description
purchaseToken String The purchase token for the purchase to check.



Returns:

String


Example:

for (var i = 0; i < array_length(global.CurrentTokens); ++i)
{
    var _sig = GPBilling_Purchase_GetSignature(global.CurrentTokens[i]);
    var _json = GPBilling_Purchase_GetOriginalJson(global.CurrentTokens[i]);
    if (GPBilling_Purchase_VerifySignature(_json, _sig))
    {
        GPBilling_ConsumeProduct(global.CurrentTokens[i]);
    }
}



Back To Top

GPBilling_QueryPurchasesAsync

Google Play Billing Function: queryPurchasesAsync

This function replaces GPBilling_QueryPurchases and works in an asynchronous manner. It is used for querying the purchase state of the different products available for your game. This function should always be called before permitting any in-app purchases, preferably near the startup of the game itself. The function takes a gpb_purchase_skutype as the "type" argument.

This function will generate an In-App Purchase Async Event where the async_load DS map "id" key holds the constant gpb_query_purchase_async, a "sku_type" key that contains the argument provided during the function call, as well as the key "response_json". This key contains a JSON object string, which – when decoded using json_parse – will be a Struct. This struct will have the key "success" - which will be true if the query has been successfully processed, and false otherwise – as well as the key "purchases" (only if "success" is true).

  • "success" – This will be either true or false depending on whether the purchase query succeeded or not.

  • "purchases" – This is a JSON array, where each entry corresponds to an object for an individual purchase. This will be an additional key if "success" is true.

When the "purchases" key exists, this can then be looped through (as shown in the extended example below) to get the individual structs with the product and purchase information.

Purchases that have been made but not consumed will have a "purchaseState" of 1 for purchased, while purchases that are in progress but not yet resolved will have a state of 2 for pending.

Keep in mind that any NON-consumable purchases will also have the purchased state (1), as the Google Billing API makes no distinction between consumable and non-consumable and it's up to you to decide when and if a purchase is consumed. However, all purchases must be acknowledged within 2 days of purchase, even if they are not being consumed. This is done automatically when a consumable is used, however for non-consumables this must be done using the function GPBilling_AcknowledgePurchase. If you do not acknowledge a purchase within 2 days, it will be refunded.

This function operates asynchronously, which means that it does not immediately return the requested result. Instead, upon completion of the task, it will trigger the In-App Purchase Async Event.


Syntax:

GPBilling_QueryPurchasesAsync(skuType)
Argument Type Description
skuType String The type of product to be queried.



Returns:

N/A


Triggers:

In-App Purchase Async Event

Key Type Description
id gpb_event_type The constant gpb_query_purchase_async
sku_type String The constant gpb_query_purchase_async
response_json String A JSON encoded string containing the response data. The response contains the following:

* "success" (Boolean) - Whether the query has been successfully processed.
* "purchases" - An Array of purchase structs.

Example:

For this example, we would first want to connect to the store, then add products and then query the product status, before checking the purchase state of each product. So, for example, we'd have a Create Event like this:

var _init = GPBilling_ConnectToStore();
if (_init == gpb_error_unknown)
{
    show_debug_message("ERROR - Billing API Has Not Connected!");
    alarm[0] = game_get_speed(gamespeed_fps) * 10;
}

Assuming the API has correctly requested a store connection, it will trigger an In-App Purchase Async Event where you can check to see if the API has successfully connected to the Google Play Store or not, and then add each of the products that you want to be available to the user, and then query the product details:

var _event_id = async_load[? "id"];
switch (_event_id)
{
    case gpb_store_connect:
        GooglePlayBilling_AddProduct(global.IAP_PurchaseID[0]);
        GooglePlayBilling_AddProduct(global.IAP_PurchaseID[1]);
        GPBilling_QueryProducts();
        break;
}

The query products function will then trigger another In-App Purchase Async Event, and we can add another case to our switch statement where we can check the state of any purchases from those that we've added, and consume or acknowledge any purchased product as required:

case gpb_product_data_response:
    var _response_data = json_parse(async_load[? "response_json"]);
    if (_response_data.success)
    {
        GPBilling_QueryPurchasesAsync();
    }
    break;
case gpb_query_purchase_async:
    var _response_data = json_parse(async_load[? "response_json"]);
    if (_response_data.success)
    {
        var _purchases = _response_data.purchases;
        for (var i = 0; i < array_length(_purchases); ++i)
        {
            var _purchase = _purchases[i];
            if (_purchase.purchaseState == 1)
            {
                var _pid = _purchase.productId;
                var _token = _purchase.purchaseToken;
                var _add = false;
                if (_pid == global.IAP_PurchaseID[0])
                {
                    GPBilling_ConsumeProduct(_token);
                    _add = true;
                }
                else if (_pid == global.IAP_PurchaseID[1])
                {
                    if (_purchase.acknowledged == 0)
                    {
                        GPBilling_AcknowledgePurchase(_token);
                        _add = true;
                    }
                }
                if (_add)
                {
                    array_push(global.CurrentTokens, _token);
                    array_push(global.CurrentProduct, _pid);
                }
            }
        }
    }
    break;

We store the purchase tokens and product IDs of those products we consume or acknowledge in global arrays. This is done so that we can track the purchases correctly when the consumed or acknowledged response comes back (see the functions GPBilling_AcknowledgePurchase and GPBilling_ConsumeProduct for more details).




Back To Top

gpb_event_type

This group of constants represents the possible event types.

These constants are referenced by the following functions:


Member Description
gpb_iap_receipt The async_load DS map contains data on a purchase request
gpb_purchase_status The async_load DS map contains data on a purchase status
gpb_product_data_response The async_load DS map contains a product data response
gpb_store_connect The API has connected to the Google Play Store.
gpb_store_connect_failed The API has failed to connect to the Google Play Store.
gpb_product_consume_response The async_load DS map contains a consume response
gpb_acknowledge_purchase_response The async_load DS map contains a purchase response
gpb_subscription_data_response The async_load DS map contains a subscriptions query response
gpb_query_purchase_async The async_load DS map contains an async purchase query response


Back To Top

gpb_error_type

This set of constants represents the possible error types.

These constants are referenced by the following functions:


Member Description
gpb_error_unknown An unknown error occurred
gpb_no_error The Billing API has been initialised correctly.
gpb_error_not_initialised The Billing API has not been initialised before calling this function.
gpb_error_no_skus There are no SKUs in the product list or subscription list.
gpb_error_selected_sku_list_empty You have tried to purchase a subscription when there is no subscription in the list (although there may be products in the list)


Back To Top

gpb_purchase_state

Google Play Billing Constant: Purchase.PurchaseState

This set of constants represents the possible states of a purchase.

These constants are referenced by the following functions:


Member Description
gpb_purchase_state_pending The purchase is pending
gpb_purchase_state_purchased The purchase is purchased
gpb_purchase_state_unspecified The purchase state is unspecified


Back To Top

gpb_purchase_skutype

Google Play Billing Constant: BillingClient.ProductType

This set of constants represents the possible SKU Types.

These constants are referenced by the following functions:

These constants are referenced by the following structs:


Member Description
gpb_purchase_skutype_inapp This constant indicates that the product is a consumable purchase.
gpb_purchase_skutype_subs This constant indicates that the product is a subscription purchase.


Back To Top

sku_details

This struct contains details on a single SKU item.


Member Type Description
skuDetailsToken String This is a unique token created by Google for the details request.
productId String The product ID (SKU, a string) as listed on the Google Play Console for the game.
type gpb_purchase_skutype The SKU type of the product, either gpb_purchase_skutype_inapp or gpb_purchase_skutype_subs.
price String The formatted price of the item, including its currency sign. The price does not include tax.
price_amount_micros Real The price in micro-units (an integer), where 1,000,000 micro-units equals one unit of the currency. For example, if the price is "€7.99", then the price in micros is 7990000. This value represents the localised and rounded price for a particular currency.
price_currency_code Real The ISO 4217 currency code for the price and original price, as an integer. For example, if the price is specified in British pounds sterling, then the code returned would be "GBP".
title String The title of the product as defined in the Google Play Console.
description String The product description as defined in the Google Play Console.


Back To Top

purchase

Google Play Billing Class: Purchase

This struct contains details on a single purchase.


Member Type Description
orderId String A unique order identifier for the transaction. This identifier corresponds to the Google Payments order ID.
packageName String The application package from which the purchase originated.
productId String The product ID (SKU).
purchaseTime Real The time the product was purchased (as an integer). This is in milliseconds since the epoch (Jan 1, 1970).
purchaseState Real The state of purchase (an integer). Possible values are: 0. Unspecified State, 1. Purchased, 2. Pending.
purchaseToken String A token that uniquely identifies a purchase for a given item and user pair. This should be used for any server verification.
autoRenewing Boolean Indicates whether the subscription renews automatically (will always be false for non-subscription purchases).
acknowledged Real The acknowledgement state of the in-app product. Possible values are: 0. Yet to be acknowledged, 1. Acknowledged.
quantity Real The quantity of the purchase.