> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/bridge-sdk/api/payments.md).

# Payments

{% hint style="info" %}
You are reading the documentation for Bridge SDK **v2**. If you need the obsolete v1 documentation, see [Documentation (v1)](https://wiki.playgama.com/playgama/bridge-sdk-v1).
{% endhint %}

In-game purchases let players buy items, upgrades, or currency. **Often the highest-revenue feature** for games that fit the IAP model. Enable payments only after ads, storage, and the core game loop are stable.

## Two product types

| Type           | Example             | Lifecycle                                                                                                                                 |
| -------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Permanent**  | "Remove ads"        | Bought once. Use [`getPurchases()`](#list-of-purchased-items) to check ownership on every launch.                                         |
| **Consumable** | Coins, gems, energy | Bought, granted, then **must be consumed** with [`consumePurchase(id)`](#consume-purchase). Until consumed it sits in the purchases list. |

{% hint style="warning" %}
After granting in-game items for a consumable purchase, **always** call `consumePurchase(id)`. Otherwise the purchase remains "active" and `purchase(id)` calls for the same product will fail.
{% endhint %}

## Support

Check this before showing the store or purchase buttons. If payments are unsupported, hide the IAP UI or use a non-payment fallback.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.payments.isSupported
```

{% endtab %}

{% tab title="Unity" %}

```csharp
Bridge.payments.isSupported
```

{% endtab %}

{% tab title="Construct 3" %}
Use the PlaygamaBridge **Is Payments Supported** condition before showing the store or purchase buttons.
{% endtab %}

{% tab title="GDevelop" %}
Use the PlaygamaBridge **Is Payments Supported** condition before showing the store or purchase buttons.
{% endtab %}

{% tab title="Godot" %}

```gdscript
Bridge.payments.is_supported
```

{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_payments_is_supported()
```

{% endtab %}

{% tab title="Defold" %}

```lua
bridge.payments.is_supported()
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.payments.isSupported
```

{% endtab %}
{% endtabs %}

<details>

<summary>Platform support · 11 of 26 platforms</summary>

**Supports:** `crazy_games`, `discord`, `facebook`, `huawei`, `microsoft_store`, `msn`, `playdeck`, `playgama`, `portal`, `reddit`, `yandex`

**Does not support:** `dlightek`, `game_distribution`, `gamepush`, `gamesnacks`, `jio_games`, `lagged`, `ok`, `poki`, `samsung`, `telegram`, `tiktok`, `vk`, `xiaomi`, `y8`, `youtube`

</details>

## Setup

Configure products in the [config](/playgama/bridge-sdk/config.md) under the `payments` key. Add an `id` for each product (you reference it in code) and fill in platform-specific price data under each platform key. Example for one product:

```json
{
    ...    
    "payments": [
        {
            "id": "test_product",
            "playgama": {
                "amount": 1 // int price in Gam
            },
            "playdeck": {
                "amount": 1, // int price in Telegram Stars
                "description": "TEST PRODUCT"
            }
        }
    ]
}
```

## Purchase

Start a purchase flow for the product ID from your config. Call this only from a direct player action, such as pressing a buy button.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.payments.purchase("test_product") // id you specified in the config file
    .then((purchase) => {
        // success
        console.log('Purchase completed, id:', purchase.id)
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    var id = "test_product"; // id you specified in the config file
    var options = new Dictionary<string, object>();
    Bridge.payments.Purchase(id, options, OnPurchaseCompleted);
}

private void OnPurchaseCompleted(bool success, Dictionary<string, string> purchase)
{
    if (success)
    {
        Debug.Log($"OnPurchaseCompleted, success: {success}, id: {purchase["id"]}");
    }
    else
    {
        Debug.Log($"OnPurchaseCompleted, success: {success}");
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
In the event sheet:

1. On a trigger (e.g. **Button → On clicked**), optionally add extra options with **Add Action Parameter**, then add the **Payments Purchase** action (parameter: ID).
2. Add the **On Payments Purchase Completed** condition. Inside it, when **Is Last Action Completed Successfully**, read fields with the `PlaygamaBridge.PaymentsLastPurchasePropertyValue("id")` expression.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"compare-two-values","objectClass":"System","parameters":{"first-value":"PlaygamaBridge.PlatformId","comparison":0,"second-value":"\"playgama\""}}],"actions":[{"type":"comment","text":"optional"},{"id":"add-action-parameter","objectClass":"PlaygamaBridge","parameters":{"key":"\"externalId\"","value":"\"<YOUR_ID>\""}}]},{"eventType":"block","conditions":[],"actions":[{"id":"payments-purchase","objectClass":"PlaygamaBridge","parameters":{"id":"\"test_product\""}}]}]},{"eventType":"block","conditions":[{"id":"on-payments-purchase-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"is-last-action-completed-successfully","objectClass":"PlaygamaBridge"}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"Purchase completed, id: \" & PlaygamaBridge.PaymentsLastPurchasePropertyValue(\"id\")"}}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
In the events sheet:

1. On a trigger (e.g. **Button is clicked**), optionally add extra options with **Add Action Parameter**, then add the **Payments Purchase** action (parameter: Id).
2. Add the **On Payments Purchase Completed** condition. Inside it, when **Is Last Action Completed Successfully**, read fields with the `PlaygamaBridge::PaymentsLastPurchasePropertyValue("id")` expression.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::PaymentsPurchase"},"parameters":["","\"test_product\"",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnPaymentsPurchaseCompleted"},"parameters":["",""]}],"actions":[],"events":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::IsLastActionCompletedSuccessfully"},"parameters":["",""]}],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"Purchase completed, id: \" + PlaygamaBridge::PaymentsLastPurchasePropertyValue(\"id\")","\"info\"",""]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
func _ready():
    var id = "test_product" # id you specified in the config file
    var options = { } # optional
    Bridge.payments.purchase(id, options, funcref(self, "_on_purchase_completed"))

func _on_purchase_completed(success, purchase):
    print(success)
    print(purchase)
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
func _ready():
    var id = "test_product" # id you specified in the config file
    var options = { } # optional
    Bridge.payments.purchase(id, options, Callable(self, "_on_purchase_completed"))

func _on_purchase_completed(success, purchase):
    print(success)
    print(purchase)
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
var options = { }
playgama_bridge_payments_purchase("test_product", json_stringify(options)) // id you specified in the config file

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_payments_purchase_callback" {
    if async_load[? "success"] {
        var purchase = json_parse(async_load[? "data"])
        var productId = purchase.id
        // your logic here
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    local id = "test_product" -- id you specified in the config file
    bridge.payments.purchase(id, function (_, purchase)
        -- success
    end, function (_, error)
        -- error
    end)
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
var options = { } // optional

bridge.payments.purchase("test_product", options) // id you specified in the config file
    .then((purchase) => {
        // success
        console.log('Purchase completed, id:', purchase.id)
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}

Each platform returns its own purchase fields. Check the target platform documentation before depending on platform-specific properties.

Use the returned `purchase` data for backend verification before granting valuable items. Playgama API verification currently supports only `playgama`, `msn`, and `microsoft_store`.

```bash
curl -X POST "https://playgama.com/api/bridge/v1/verify" \
  -H "Content-Type: application/json" \
  -d '{"platform":"<PLATFORM_ID>","type":"purchase","data":{ <...purchase> }}'

#  Response:
#  {
#    success: boolean;
#    errorMessage?: string;

#    -- purchase --
#    orderId?: string;
#    productId?: string;
#    externalId?: string;
#  }
```

## Consume Purchase

Mark a consumable purchase as used after you grant the in-game item. Do not call this for permanent products.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.payments.consumePurchase("test_product") // id you specified in the config file
    .then((purchase) => {
        // success
        console.log('Consume completed, id:', purchase.id)
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    var id = "test_product"; // id you specified in the config file
    Bridge.payments.ConsumePurchase(id, OnConsumePurchaseCompleted);
}

private void OnConsumePurchaseCompleted(bool success, Dictionary<string, string> purchase)
{
    if (success)
    {
        Debug.Log($"OnConsumePurchaseCompleted, success: {success}, id: {purchase["id"]}");
    }
    else
    {
        Debug.Log($"OnConsumePurchaseCompleted, success: {success}");
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
In the event sheet:

1. On a trigger (e.g. **Button → On clicked**), add the **Payments Consume Purchase** action (parameter: ID).
2. Add the **On Payments Consume Purchase Completed** condition. Inside it, check **Is Last Action Completed Successfully**.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"payments-consume-purchase","objectClass":"PlaygamaBridge","parameters":{"id":"\"test_product\""}}]},{"eventType":"block","conditions":[{"id":"on-payments-consume-purchase-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"is-last-action-completed-successfully","objectClass":"PlaygamaBridge"}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"Consume completed, id: \" & PlaygamaBridge.PaymentsLastPurchasePropertyValue(\"id\")"}}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
In the events sheet:

1. On a trigger (e.g. **Button is clicked**), add the **Payments Consume Purchase** action (parameter: Id).
2. Add the **On Payments Consume Purchase Completed** condition. Inside it, check **Is Last Action Completed Successfully**.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::PaymentsConsumePurchase"},"parameters":["","\"test_product\"",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnPaymentsConsumePurchaseCompleted"},"parameters":["",""]}],"actions":[],"events":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::IsLastActionCompletedSuccessfully"},"parameters":["",""]}],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"Consume completed, id: \" + PlaygamaBridge::PaymentsLastPurchasePropertyValue(\"id\")","\"info\"",""]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
func _ready():
    var id = "test_product" # id you specified in the config file
    Bridge.payments.consume_purchase(id, funcref(self, "_on_consume_completed"))

func _on_consume_completed(success, purchase):
    print(success)
    print(purchase)
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
func _ready():
    var id = "test_product" # id you specified in the config file
    Bridge.payments.consume_purchase(id, Callable(self, "_on_consume_completed"))

func _on_consume_completed(success, purchase):
    print(success)
    print(purchase)
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_payments_consume_purchase("test_product") // id you specified in the config file

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_payments_consume_purchase_callback" {
    if async_load[? "success"] {
        var purchase = json_parse(async_load[? "data"])
        var productId = purchase.id
        // your logic here
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    local id = "test_product" -- id you specified in the config file
    bridge.payments.consume_purchase(id, function (_, purchase)
        -- success
    end, function ()
        -- error
    end)
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.payments.consumePurchase("test_product") // id you specified in the config file
    .then((purchase) => {
        // success
        console.log('Consume completed, id:', purchase.id)
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}

## Catalog of All Items

Load the product catalog before showing your store. Use it for localized prices, currency codes, and platform-specific product metadata.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.payments.getCatalog()
    .then(catalogItems => {
        // success
        catalogItems.forEach(catalogItem => {
            console.log('ID: ' + catalogItem.id)
            console.log('Price: ' + catalogItem.price)
            console.log('Price Currency Code: ' + catalogItem.priceCurrencyCode)
            console.log('Price Value: ' + catalogItem.priceValue)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    Bridge.payments.GetCatalog(OnGetCatalogCompleted);
}

private void OnGetCatalogCompleted(bool success, List<Dictionary<string, string>> catalog)
{
    Debug.Log($"OnGetCatalogCompleted, success: {success}, items:");
                
    if (success)
    {
        foreach (var item in catalog)
        {
            Debug.Log("ID: " + item["id"]);
            Debug.Log("Price: " + item["price"]);
            Debug.Log("Price Currency Code: " + item["priceCurrencyCode"]);
            Debug.Log("Price Value: " + item["priceValue"]);
        }
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
In the event sheet:

1. On a trigger (e.g. **Button → On clicked**), add the **Payments Get Catalog** action.
2. Add the **On Payments Get Catalog Completed** condition. Inside it, when `PlaygamaBridge.PaymentsCatalogItemsCount > 0`, loop with **System → For** from `0` to `PaymentsCatalogItemsCount - 1` and read each field with `PaymentsCatalogItemPropertyValue(index, "id" / "price" / "priceCurrencyCode" / "priceValue")`.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"payments-get-catalog","objectClass":"PlaygamaBridge"}]},{"eventType":"block","conditions":[{"id":"on-payments-get-catalog-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"compare-two-values","objectClass":"System","parameters":{"first-value":"PlaygamaBridge.PaymentsCatalogItemsCount","comparison":4,"second-value":"0"}}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"items\"","start-index":"0","end-index":"PlaygamaBridge.PaymentsCatalogItemsCount - 1"}}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"ID: \" & PlaygamaBridge.PaymentsCatalogItemPropertyValue(loopindex(\"items\"), \"id\")"}},{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"Price: \" & PlaygamaBridge.PaymentsCatalogItemPropertyValue(loopindex(\"items\"), \"price\")"}},{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"Price Currency Code: \" & PlaygamaBridge.PaymentsCatalogItemPropertyValue(loopindex(\"items\"), \"priceCurrencyCode\")"}},{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"Price Value: \" & PlaygamaBridge.PaymentsCatalogItemPropertyValue(loopindex(\"items\"), \"priceValue\")"}}]}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
In the events sheet:

1. On a trigger (e.g. **Button is clicked**), add the **Payments Get Catalog** action.
2. Add the **On Payments Get Catalog Completed** condition. Inside it, **Repeat** `PlaygamaBridge::PaymentsCatalogItemsCount()` times and read each field with `PaymentsCatalogItemPropertyValue(index, "id" / "price" / "priceCurrencyCode" / "priceValue")`.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::PaymentsGetCatalog"},"parameters":["",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnPaymentsGetCatalogCompleted"},"parameters":["",""]}],"actions":[{"type":{"value":"SetNumberVariable"},"parameters":["loopindex","=","0"]}],"events":[{"type":"BuiltinCommonInstructions::Repeat","repeatExpression":"PlaygamaBridge::PaymentsCatalogItemsCount()","conditions":[],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"ID:\" + PlaygamaBridge::PaymentsCatalogItemPropertyValue(loopindex, \"id\")","\"info\"",""]},{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"Price:\" + PlaygamaBridge::PaymentsCatalogItemPropertyValue(loopindex, \"price\")","\"info\"",""]},{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"Price Currency Code:\" + PlaygamaBridge::PaymentsCatalogItemPropertyValue(loopindex, \"priceCurrencyCode\")","\"info\"",""]},{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"Price Value:\" + PlaygamaBridge::PaymentsCatalogItemPropertyValue(loopindex, \"priceValue\")","\"info\"",""]},{"type":{"value":"SetNumberVariable"},"parameters":["loopindex","+","1"]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
func _ready():
    Bridge.payments.get_catalog(funcref(self, "_on_get_catalog_completed"))

func _on_get_catalog_completed(success, catalog):
    print(success)
    
    for item in catalog:
        print("ID: " + str(item.id))
        print("Price: " + str(item.price))
        print("Price Currency Code: " + str(item.priceCurrencyCode))
        print("Price Value: " + str(item.priceValue))
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
func _ready():
    Bridge.payments.get_catalog(Callable(self, "_on_get_catalog_completed"))

func _on_get_catalog_completed(success, catalog):
    print(success)
    
    for item in catalog:
        print("ID: " + str(item.id))
        print("Price: " + str(item.price))
        print("Price Currency Code: " + str(item.priceCurrencyCode))
        print("Price Value: " + str(item.priceValue))
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_payments_get_catalog()

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_payments_get_catalog_callback" {
    if async_load[? "success"] {
        var catalog = json_parse(async_load[? "data"])
        for (var i = 0; i < array_length(catalog); i += 1)
	{
	    var catalogItem = catalog[i]
            var productId = catalogItem.id
            var price = catalogItem.price
            var priceCurrencyCode = catalogItem.priceCurrencyCode
            var priceValue = catalogItem.priceValue
            // your logic here
	}
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    bridge.payments.get_catalog(function (_, catalog)
        -- success
        for key, value in pairs(catalog) do
            local id = value.id
            local price = value.price
            local priceCurrencyCode = value.priceCurrencyCode
            local priceValue = value.priceValue
        end
    end, function ()
        -- error
    end)
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.payments.getCatalog()
    .then(catalogItems => {
        // success
        catalogItems.forEach(catalogItem => {
            console.log('ID: ' + catalogItem.id)
            console.log('Price: ' + catalogItem.price)
            console.log('Price Currency Code: ' + catalogItem.priceCurrencyCode)
            console.log('Price Value: ' + catalogItem.priceValue)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}

## List of Purchased Items

Load the player's active purchases on startup and after reconnecting. Use this for permanent ownership checks and unprocessed consumables.

{% hint style="warning" %}
If the player loses connection during a purchase, it can remain unprocessed. Check purchases on every launch and grant or consume any pending items.
{% endhint %}

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.payments.getPurchases()
    .then(purchases => {
        // success
        purchases.forEach(purchase => {
            console.log('ID: ' + purchase.id)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    Bridge.payments.GetPurchases(OnGetPurchasesCompleted);
}

private void OnGetPurchasesCompleted(bool success, List<Dictionary<string, string>> purchases)
{
    Debug.Log($"OnGetPurchasesCompleted, success: {success}, items:");
    
    if (success)
    {
        foreach (var purchase in purchases)
        {
            Debug.Log("ID: " + purchase["id"]);
        }
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
In the event sheet:

1. On a trigger (e.g. **Button → On clicked**), add the **Payments Get Purchases** action.
2. Add the **On Payments Get Purchases Completed** condition. Inside it, when `PlaygamaBridge.PaymentsPurchasesCount > 0`, loop with **System → For** from `0` to `PaymentsPurchasesCount - 1` and read each purchase with `PaymentsPurchasePropertyValue(index, "id")`.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"payments-get-purchases","objectClass":"PlaygamaBridge"}]},{"eventType":"block","conditions":[{"id":"on-payments-get-purchases-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"compare-two-values","objectClass":"System","parameters":{"first-value":"PlaygamaBridge.PaymentsPurchasesCount","comparison":4,"second-value":"0"}}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"purchases\"","start-index":"0","end-index":"PlaygamaBridge.PaymentsPurchasesCount - 1"}}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"\"ID: \" & PlaygamaBridge.PaymentsPurchasePropertyValue(loopindex(\"purchases\"), \"id\")"}}]}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
In the events sheet:

1. On a trigger (e.g. **Button is clicked**), add the **Payments Get Purchases** action.
2. Add the **On Payments Get Purchases Completed** condition. Inside it, **Repeat** `PlaygamaBridge::PaymentsPurchasesCount()` times and read each purchase with `PaymentsPurchasePropertyValue(index, "id")`.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::PaymentsGetPurchases"},"parameters":["",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnPaymentsGetPurchasesCompleted"},"parameters":["",""]}],"actions":[{"type":{"value":"SetNumberVariable"},"parameters":["loopindex","=","0"]}],"events":[{"type":"BuiltinCommonInstructions::Repeat","repeatExpression":"PlaygamaBridge::PaymentsPurchasesCount()","conditions":[],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"ID:\" + PlaygamaBridge::PaymentsPurchasePropertyValue(loopindex, \"id\")","\"info\"",""]},{"type":{"value":"SetNumberVariable"},"parameters":["loopindex","+","1"]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
func _ready():
    Bridge.payments.get_purchases(funcref(self, "_on_get_purchases_completed"))

func _on_get_purchases_completed(success, purchases):
    print(success)
    
    for purchase in purchases:
        print("ID: " + str(purchase.id))
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
func _ready():
    Bridge.payments.get_purchases(Callable(self, "_on_get_purchases_completed"))

func _on_get_purchases_completed(success, purchases):
    print(success)
    
    for purchase in purchases:
        print("ID: " + str(purchase.id))
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_payments_get_purchases()

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_payments_get_purchases_callback" {
    if async_load[? "success"] {
        var purchases = json_parse(async_load[? "data"])
        for (var i = 0; i < array_length(purchases); i += 1)
	{
	    var purchase = purchases[i]
            var productId = purchase.id
            // your logic here
	}
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    bridge.payments.get_purchases(function (_, purchases)
        -- success
        for key, value in pairs(purchases) do
            local id = value.id
        end
    end, function ()
        -- error
    end)
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.payments.getPurchases()
    .then(purchases => {
        // success
        purchases.forEach(purchase => {
            console.log('ID: ' + purchase.id)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}
