# Player balances

> Use the SDK to manage player currency balances.

The `PlayerBalances` namespace contains all the methods for fetching and updating a player's currency balances.

These methods will return the balances for the currently signed in player from the Authentication SDK.

> **Note:**
>
> All the methods in this namespace can throw an [EconomyException](./exceptions#economyexception).

## GetBalancesAsync##getbalances

Retrieve the currency balances for the current user. Takes an optional `GetBalancesOptions`.

When getting balances, you can use the `GetBalancesOptions` to set a limit on the number of balances to fetch (between 1 and 100 inclusive). This is to help with pagination. The default number is 20.

The following sample code retrieves the first five balances for the current user, and then retrieves the next five, including those for currencies that have since been deleted from the configuration.

```cs title="C#"
// Optional, defaults to 20
GetBalancesOptions options = new GetBalancesOptions
{
    ItemsPerFetch = 5
};

GetBalancesResult getBalancesResult = await EconomyService.Instance.PlayerBalances.GetBalancesAsync(options);
List<PlayerBalance> firstFiveBalances = getBalancesResult.Balances;
// do something with your balances

if (getBalancesResult.HasNext) {
    getBalancesResult = await getBalancesResult.GetNextAsync(options.ItemsPerFetch);
    List<PlayerBalance> nextFiveBalances = getBalancesResult.Balances;
    // do something with your balances
}
```

These methods return a `GetBalancesResult`. See [GetBalancesResult](#getbalancesresults).

### GetBalancesOptions

The options object for a `GetBalancesAsync` call. It has the following field:

* `ItemsPerFetch`: An int. Defaults to 20. Use this to set the maximum number of balances to fetch per call between 1 and 100 inclusive.

### GetBalancesResult##getbalancesresults

A `GetBalancesResult` provides paginated access to the list of balances retrieved. It has the following fields:

* `Balances`: A `List<PlayerBalance>` with the currently fetched balances.

It has the following methods:

* `GetNextAsync(int itemsToFetch = 20)`: This method asynchronously fetches more results. It has one optional parameter to limit the amount of results fetched (this can be between 1 and 100 inclusive, default is 20). It will return a new result, which contains both the original items and the newly fetched items in its `Balances` list.

## SetBalanceAsync##setbalance

Sets the balance of the specified currency to the specified value.

This method optionally takes a `SetBalancesOptions` object used to set the write lock. If provided, an exception is thrown unless the `writeLock` matches the `writeLock` received by a previous read, in order to provide optimistic concurrency. If not provided, the transaction proceeds regardless of any existing `writeLock` in the data.

This method returns the current balance after the update has been applied, if the operation is successful.

```cs title="C#"
string currencyID = "GOLD_BARS";
int newAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
SetBalanceOptions options = new SetBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.SetBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.SetBalanceAsync(currencyID, newAmount, options);
```

### SetBalanceOptions

The options object for a `SetBalanceAsync` call. It has the following field:

* `WriteLock`: A string. Defaults to `null`. Use this to set a write lock for optimistic concurrency. See [Write Lock](./common-objects#using-the-writelock).

## IncrementBalanceAsync##incrementbalance

Increments the balance of the specified currency by the specified value.

This method optionally takes a `IncrementBalancesOptions` object used to set the write lock. If provided, then an exception is thrown unless the `writeLock` matches the `writeLock` received by a previous read, in order to provide optimistic concurrency. If not provided, the transaction proceeds regardless of any existing `writeLock` in the data.

This method returns the current balance after the update is applied, if the operation is successful.

```cs title="C#"
string currencyID = "GOLD_BARS";
int incrementAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
IncrementBalanceOptions options = new IncrementBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.IncrementBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.IncrementBalanceAsync(currencyID, newAmount, options);
```

### IncrementBalanceOptions

The options object for a `IncrementBalanceAsync` call. It has the following field:

* `WriteLock`: A string. Defaults to `null`. Use this to set a write lock for optimistic concurrency. See [Write Lock](./common-objects#using-the-writelock).

## DecrementBalanceAsync##decrementbalance

Decrements the balance of the specified currency by the specified value.

This method optionally takes a `DecrementBalanceOptions` object used to set the write lock. If provided, then an exception is thrown unless the `writeLock` matches the `writeLock` received by a previous read, in order to provide optimistic concurrency. If not provided, the transaction proceeds regardless of any existing `writeLock` in the data.

This method returns the current balance after the update is applied, if the operation is successful.

```cs title="C#"
string currencyID = "GOLD_BARS";
int decrementAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
DecrementBalanceOptions options = new DecrementBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.DecrementBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.DecrementBalanceAsync(currencyID, newAmount, options);
```

### DecrementBalanceOptions

The options object for a `DecrementBalanceAsync` call. It has the following fields:

* `WriteLock`: A string. Defaults to `null`. Use this to set a write lock for optimistic concurrency. See [Write Lock](./common-objects#using-the-writelock).

## PlayerBalance

A player balance represents a single currency balance for a player. It has the following fields:

* `CurrencyId`: The ID of the currency this balance represents.
* `Balance`: The integer amount of this currency the player has.
* `WriteLock`: The current `writeLock` string.
* `Created`: The date this balance was created. It is an [EconomyDate](./common-objects#economydate) object.
* `Modified`: The date this balance was modified. It is an [EconomyDate](./common-objects#economydate) object.

It also has the following helper methods:

### GetCurrencyDefinitionAsync

This is a convenience method to get the currency definition for the currency associated with this balance. It returns a [CurrencyDefinition](./configuration#currencydefinition).

```cs title="C#"
PlayerBalance myPlayerBalance = ... // Get a player balance from one of the above methods
CurrencyDefinition currencyDefForMyPlayerBalance = myPlayerBalance.GetCurrencyDefinitionAsync();
```

## BalanceUpdated

This event can be subscribed to in order to be notified when the SDK updates the balance of a particular currency. The subscriber is passed the currency ID of the balance that was updated.

> **Note:**
>
> This event is be called for SDK initiated actions (for example, updating player's balances, making purchases). It is not called for any updates from other devices / service side changes.

```cs title="C#"
EconomyService.Instance.PlayerBalances.BalanceUpdated += currencyID => {
    Debug.Log($"The currency that was updated was {currencyID}");
};
```
