# Core concepts

> The vocabulary of GameCoin on one page, from currencies and buckets to orders, keys and environments.

## How the pieces fit

GameCoin stores your game's economy in two layers. You describe it once in the catalog; your players then fill it with balances, items and orders.

```text
Studio                                    your account
└─ Game                                   one per game
   ├─ Catalog   (shared by both environments)
   │  ├─ Currencies   gems (paid) · gold (free)
   │  ├─ Items        potion (consumable) · fire-sword (durable)
   │  └─ Packs        gems-500 = 500 gems + 50 free, for 4.99 €
   └─ Environments    test · live      (players, balances and orders are separate in each)
      └─ Players
         ├─ Wallet       one balance per currency, split in paid and bonus
         ├─ Inventory    the items the player owns
         └─ Orders       the packs the player bought with euros
```

The catalog is created in the dashboard, which is in French for now. Everything a player does with it goes through the API or an SDK.

## Currencies

A currency is a name for your game's money: `gems`, `gold`, `credits`. Its **code** has 2 to 24 characters: a lowercase letter, then lowercase letters, digits or `_`. A code never changes.

| Kind | What it means | Example |
|---|---|---|
| **Paid** | Packs can sell it for euros. The catalog flag is `purchasable: true`. | `gems` |
| **Free** | Only your game hands it out: rewards, quests, daily bonuses. | `gold` |

A paid currency can also be given for free. The two kinds differ only in what packs can sell.

## Balances and buckets

A player has one **balance** per currency. Every balance is split in two **buckets**:

| Bucket | Filled by | Why it is kept apart |
|---|---|---|
| `paid` | A pack bought with euros | Real money paid for these coins: a refund takes them back |
| `bonus` | A grant from your server, a reward, the free part of a pack | Free coins: no refund applies to them |

`total` is `paid + bonus`. All amounts are positive whole numbers; there are no decimals. By default a spend takes the free coins first. The rules are on [Wallets and ledger](/docs/concepts/wallets-and-ledger).

## Items

An item is something a player owns: a potion, a skin, a sword. You sell it for a currency, never for euros.

| Field | Meaning |
|---|---|
| `sku` | Its code, for example `potion`. 1 to 48 characters from `a-z 0-9 _ . -`. |
| `type` | `consumable` can be used up with `consume`. `durable` stays: a player keeps a skin or a sword. |
| `price` | An amount in a currency, or `null` when the item cannot be bought with a currency. |
| `maxOwned` | The most a player can own. A durable item defaults to 1; a consumable has no limit. |
| `clientPurchasable` | Whether the browser may buy it. If `false`, only your server can. |

## Packs

A pack is what a player buys with euros. It gives currency, items, or both. A pack has a price in euros, **VAT included**, from 0.50 € to 500.00 €, and an optional `maxPerPlayer`.

Each line of `grants` has an `amount` that goes to the `paid` bucket and a `bonus` that goes to the `bonus` bucket. The pack `gems-500` has `amount: 500` and `bonus: 50`: the player pays for 500 gems and receives 50 more.

## Orders

An order is one purchase of a pack. It freezes a copy of the pack and the VAT at the moment of purchase, so changing the catalog later never changes an order.

| Status | Meaning |
|---|---|
| `pending` | Created; the player has not paid yet. It expires after one hour. |
| `fulfilled` | Paid and delivered: the currency and items are in the player's account. |
| `refunded` | Refunded: the currency and items were taken back. |
| `failed` | The payment was declined. |
| `expired` | Nobody paid within the hour. |
| `canceled`, `chargeback` | Reserved for later. You will not see them yet. |
| `paid` | A passing state: payment and delivery happen together, so you read `fulfilled`. |

The full life of an order is on [Selling packs](/docs/guides/selling-packs).

## Players

| Kind | How it is named | Created by |
|---|---|---|
| **Your player** (`external`) | `ext:<your id>`, with the id your game already uses | Your server, the first time it writes to that id |
| **Anonymous player** (`hosted`) | The id GameCoin gave it | The browser SDK, for a game without a backend |

A player id is a GameCoin id or `ext:` plus your own id, and it is URL-encoded exactly once. The details are on [Players and tokens](/docs/concepts/players-and-tokens).

## Keys, tokens and environments

| Name | Looks like | Lives in | Can |
|---|---|---|---|
| **Secret key** | `gc_sk_test_…` | Your server only | Everything the server API offers |
| **Publishable key** | `gc_pk_test_…` | The game, in the browser | Read the catalog, create an anonymous player |
| **Player token** | `gc_pt_…` | The browser, for one hour | Act as one player: read, spend, buy, consume, pay |

The key also picks the **environment**: `test` (simulated payments, disposable data) or `live` (reserved for verified studios). The catalog is shared; players, balances, ledger and orders are separate in each. See [Keys and environments](/docs/concepts/keys-and-environments).

> [!WARNING]
> A browser can never add to a balance by itself. Only your server (with the secret key) or a paid order can, with one exception: a gift code that you issued adds free coins, once per player. This is the rule that keeps a game without a backend safe. Read [Security model](/docs/concepts/security-model).

## Ledger

The **ledger** is the list of every change to every balance. Each entry is final: it is never edited or deleted. It says what changed in each bucket, the balance after, why, and which order or item it came from. The balance of a player always equals the sum of their entries.

## Where next

- Go through [the quickstart](/docs/quickstart) to see these pieces work.
- Read one page per subject, starting with [Wallets and ledger](/docs/concepts/wallets-and-ledger).
- Pick a [guide](/docs/guides/no-backend-game) that matches your game.
