> For the complete documentation index, see [llms.txt](https://axiomemu.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://axiomemu.gitbook.io/docs/data/cashshop.md).

# CashShop.xml

Defines every item, package, and banner shown in the in-game cash shop. Covers three currencies (WCoin C, WCoin P, Goblin Points), category hierarchy, per-product options, and time-boxed banners.

## File Location

```
Data/CashShop/CashShop.xml
```

Loaded once at GameServer startup. Changes require a restart.

## Structure

```xml
<CashShop>
    <Categories>
        <Category .../>
    </Categories>
    <Packages>
        <Package ...>
            <Products>
                <Ref Base="..." Main="..."/>
            </Products>
        </Package>
    </Packages>
    <Products>
        <Product .../>
    </Products>
    <Banners>
        <Banner .../>
    </Banners>
</CashShop>
```

Four top-level blocks. Each `<Category>` is a tab or sub-tab. Each `<Package>` is a grouped purchase that contains references to individual `<Product>` entries. Standalone `<Product>` entries are single-item purchases. `<Banner>` entries are promotional tiles.

## Currencies and Flag Enums

### Coin indices (`CoinIndex` on packages)

| Value | Currency      |
| ----- | ------------- |
| `508` | WCoin (C)     |
| `509` | WCoin (P)     |
| `0`   | Goblin Points |

`CoinIndex` lives on `<Package>` only. Standalone `<Product>` entries do not carry a `CoinIndex` attribute - the package that references them dictates the currency.

### Common flag values

| Flag          | Values                                                  |
| ------------- | ------------------------------------------------------- |
| `SalesFlag`   | `182` = Purchasable, `183` = Not Purchasable            |
| `GiftFlag`    | `184` = Giftable, `185` = Not Giftable                  |
| `EventFlag`   | `199` = Event, `200` = Normal                           |
| `OpenFlag`    | `201` = Open (default), other values close the category |
| `CapsuleFlag` | `176` = Capsule, `177` = Normal                         |
| `DeleteFlag`  | `180` = Deleted, `181` = Active                         |

### Product types

`ProductType` is stored and relayed to the client; it classifies how the client renders and categorises the entry. Default is `170` for `<Package>`, `140` for `<Product>`.

| Value | Meaning                                                          |
| ----- | ---------------------------------------------------------------- |
| `135` | Fixed amount. TODO: verify                                       |
| `136` | Fixed quantity. TODO: verify                                     |
| `137` | Premium. TODO: verify                                            |
| `138` | Consumption. TODO: verify                                        |
| `139` | Eternity (permanent)                                             |
| `140` | Period (time-limited, pairs with `Duration`)                     |
| `170` | Package container (used on `<Package>`, not standalone products) |
| `406` | Premium item. TODO: verify                                       |
| `515` | Goblin point pack. TODO: verify                                  |

## Category Attributes

| Attribute   | Type   | Default      | Effect                                                   |
| ----------- | ------ | ------------ | -------------------------------------------------------- |
| `Seq`       | int    | *(required)* | Unique category ID. Packages and products reference this |
| `Name`      | string | *(required)* | Display name on the tab                                  |
| `Parent`    | int    | `0`          | Parent category's `Seq`. `0` = root tab                  |
| `Order`     | int    | `0`          | Sort order within its parent. Lower shows first          |
| `Root`      | 0 or 1 | `1`          | `1` = top-level tab, `0` = sub-category                  |
| `EventFlag` | enum   | `200`        | `199` marks category as event-only                       |
| `OpenFlag`  | enum   | `201`        | `201` = open, any other value hides the category         |

## Package Attributes

Packages group multiple products behind one purchase. Each `<Package>` holds a `<Products>` block with `<Ref>` entries pointing at the actual items.

| Attribute      | Type            | Default      | Effect                                                                                               |
| -------------- | --------------- | ------------ | ---------------------------------------------------------------------------------------------------- |
| `Category`     | int             | *(required)* | `Seq` of the owning category                                                                         |
| `BaseIndex`    | int             | *(required)* | Package identifier, part 1. Unique per shop                                                          |
| `MainIndex`    | int             | *(required)* | Package identifier, part 2                                                                           |
| `Name`         | string          | *(required)* | Display name                                                                                         |
| `Description`  | string          | *(empty)*    | Tooltip text                                                                                         |
| `ItemIndex`    | int             | *(required)* | Primary item index shown as the package icon                                                         |
| `CoinIndex`    | `508`/`509`/`0` | `0`          | Currency used. Must match the client's coin-type field in the purchase packet or the buy is rejected |
| `CoinValue`    | int             | `0`          | Price in that currency                                                                               |
| `BonusGP`      | int             | `0`          | Extra Goblin Points credited on purchase                                                             |
| `ProductType`  | enum            | `170`        | Usually `170` for packages                                                                           |
| `SalesFlag`    | enum            | `182`        | `182` = purchasable                                                                                  |
| `GiftFlag`     | enum            | `184`        | `184` = giftable                                                                                     |
| `CapsuleFlag`  | enum            | `177`        | `176` marks as a random-contents capsule                                                             |
| `EventFlag`    | enum            | `200`        | `199` = event-only                                                                                   |
| `DeleteFlag`   | enum            | `181`        | `181` = active, `180` = soft-deleted                                                                 |
| `CashType`     | int             | `0`          | Internal cash type classification                                                                    |
| `CashTypeFlag` | int             | `668`        | Internal cash type flag                                                                              |

### `<Ref>` children

Inside `<Products>`, each `<Ref Base="..." Main="..."/>` points at a `<Product>` entry by its `BaseIndex` + `MainIndex`. The loader caps the number of refs per package; extras beyond the cap are silently dropped.

| Attribute | Type | Effect                       |
| --------- | ---- | ---------------------------- |
| `Base`    | int  | Target product's `BaseIndex` |
| `Main`    | int  | Target product's `MainIndex` |

## Product Attributes

Individual items. Either standalone purchases (appear in the shop directly) or referenced by packages via `<Ref>`.

| Attribute                | Type   | Default      | Effect                                                                                                                                                                                                        |
| ------------------------ | ------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BaseIndex`              | int    | *(required)* | Product identifier part 1                                                                                                                                                                                     |
| `MainIndex`              | int    | *(required)* | Product identifier part 2                                                                                                                                                                                     |
| `Name`                   | string | *(required)* | Display name                                                                                                                                                                                                  |
| `ItemIndex`              | int    | *(required)* | Item index from `Item.xml`                                                                                                                                                                                    |
| `ItemLevel`              | int    | `0`          | Item +level at grant                                                                                                                                                                                          |
| `CoinValue`              | int    | `0`          | Price. Only charged when the product is purchased standalone; package-referenced products apply this as the per-product cost inside the package flow and must be balanced against the `<Package>` `CoinValue` |
| `ProductType`            | enum   | `140`        | See [Product types](#product-types)                                                                                                                                                                           |
| `PropertyType`           | int    | `142`        | Internal property flag                                                                                                                                                                                        |
| `StorageGroup`           | int    | `0`          | Inventory storage bucket                                                                                                                                                                                      |
| `Opt1` / `Opt2` / `Opt3` | int    | `0`          | Item options 1-3                                                                                                                                                                                              |
| `NewOpt`                 | int    | `0`          | Modern item option                                                                                                                                                                                            |
| `SetOpt`                 | int    | `0`          | Set option                                                                                                                                                                                                    |
| `HarmonyOpt`             | int    | `0`          | Jewel of Harmony option                                                                                                                                                                                       |
| `OptEx`                  | int    | `0`          | Excellent option bitmask                                                                                                                                                                                      |
| `Sock1` ... `Sock5`      | int    | `255`        | Socket options (255 = empty socket slot)                                                                                                                                                                      |
| `Quantity`               | int    | `0`          | Quantity granted per purchase                                                                                                                                                                                 |
| `Duration`               | int    | `0`          | Duration in seconds for time-limited items (pairs with `ProductType="140"`). `0` = permanent                                                                                                                  |

## Banner Attributes

Promotional tiles shown at the top of the shop.

| Attribute   | Type   | Effect                                             |
| ----------- | ------ | -------------------------------------------------- |
| `Seq`       | int    | Unique banner ID                                   |
| `Name`      | string | Internal name                                      |
| `ImageFile` | string | Client-side image filename                         |
| `LinkURL`   | string | Click destination URL                              |
| `Order`     | int    | Sort order                                         |
| `Direction` | int    | Rotation direction for animated banners            |
| `StartDate` | string | `YYYY-MM-DD` start date. Banner hidden before this |
| `EndDate`   | string | `YYYY-MM-DD` end date. Banner hidden after this    |

## Examples

{% tabs %}
{% tab title="Simple standalone product" %}
{% code title="CashShop.xml fragment" %}

```xml
<Products>
    <Product BaseIndex="281" MainIndex="349"
             Name="Magic Backpack (Permanent)"
             ItemIndex="7330" ItemLevel="0"
             CoinValue="690" ProductType="139"
             PropertyType="142" Quantity="1" Duration="0"/>
</Products>
```

{% endcode %}

Standalone +0 Magic Backpack for 690 WCoin(C). ProductType `139` = Eternity (permanent).
{% endtab %}

{% tab title="Package referencing products" %}
{% code title="CashShop.xml fragment" %}

```xml
<Packages>
    <Package Category="13" BaseIndex="3" MainIndex="260"
             Name="Magic Backpack" Description="Permanent"
             ItemIndex="7330" CoinIndex="508" CoinValue="690" BonusGP="0"
             ProductType="170" SalesFlag="182" GiftFlag="184"
             CapsuleFlag="177" EventFlag="200" DeleteFlag="181"
             CashType="0" CashTypeFlag="668">
        <Products>
            <Ref Base="281" Main="349"/>
        </Products>
    </Package>
</Packages>
```

{% endcode %}

Package in category 13 (Special Packages) bundles one product (Base=281, Main=349).
{% endtab %}

{% tab title="Category tree" %}
{% code title="CashShop.xml fragment" %}

```xml
<Categories>
    <Category Seq="1" Name="WCoin (C)" EventFlag="200" OpenFlag="201"
              Parent="0" Order="1" Root="1"/>
    <Category Seq="13" Name="Special Packages" EventFlag="200" OpenFlag="201"
              Parent="1" Order="1" Root="0"/>
    <Category Seq="14" Name="Consumables" EventFlag="200" OpenFlag="201"
              Parent="1" Order="2" Root="0"/>
</Categories>
```

{% endcode %}

Root tab "WCoin (C)" with two sub-categories shown in order 1 and 2.
{% endtab %}

{% tab title="Time-boxed banner" %}
{% code title="CashShop.xml fragment" %}

```xml
<Banners>
    <Banner Seq="1" Name="Summer Sale"
            ImageFile="summer_sale.jpg"
            LinkURL="https://example.com/sale"
            Order="1" Direction="0"
            StartDate="2026-06-01" EndDate="2026-08-31"/>
</Banners>
```

{% endcode %}

Banner shows only between 2026-06-01 and 2026-08-31.
{% endtab %}
{% endtabs %}

## Cross-File Dependencies

| Attribute                                   | Related in                                                                                                                                                                                                               |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ItemIndex`                                 | Must exist in [Item.xml](/docs/data/item/item.md)                                                                                                                                                                        |
| `Opt*` / `NewOpt` / `SetOpt` / `HarmonyOpt` | Effects defined in [ItemOption.xml](/docs/data/item/itemoption.md), [SetItemOption.xml](/docs/data/item/setitemoption.md), [JewelOfHarmonyOption.xml](/docs/data/item/jewelofharmonyoption.md)                           |
| `Sock1-5`                                   | Socket option indices from [SocketItemOption.xml](/docs/data/item/socketitemoption.md)                                                                                                                                   |
| `CoinIndex` / `CoinValue`                   | WCoin (C), WCoin (P), Goblin Point balances maintained by DataServer. Master toggle: [Common.dat](/docs/gameserver/common-dat.md#cash-shop-settings) `CashShopSwitch`                                                    |
| `BonusGP`                                   | Related to [Common.dat](/docs/gameserver/common-dat.md#cash-shop-settings) `CashShopGoblinPointValue_AL0-3` (per-tier GP tick reward). TODO: verify whether `BonusGP` is capped by those values or applied independently |
| Gift flag                                   | Gift purchases are audit-logged; controlled by [Common.dat](/docs/gameserver/common-dat.md#log-settings) `WriteCashShopLog`                                                                                              |
| Wallet top-up by GMs                        | [Command.xml](/docs/data/command-xml.md) `/setcoin` (dispatched to the `CommandSetCoin` handler). GM authority comes from [GameMaster.xml](/docs/data/experiencetable/gamemaster.md)                                     |

## Common Issues

* **Product shows in shop but cannot be purchased** - `SalesFlag="183"` (not purchasable) on the package, or `DeleteFlag="180"` (soft-deleted)
* **Package contains broken items** - one of the `<Ref Base Main>` pairs does not match any `<Product>` entry. Extras beyond the per-package ref cap are dropped silently at load
* **Gift button greyed out** - `GiftFlag="185"` (not giftable) on the package
* **Category empty in-game** - no packages or products reference that `Seq`, or `OpenFlag` is not `201`
* **Event category always visible** - `EventFlag` on category should be `199` for event-only visibility; setting `199` alone does not schedule show/hide
* **Banner never appears** - current date is outside `StartDate`..`EndDate` range, or the `ImageFile` is missing from the client
* **"Loaded 0 categories"** - XML syntax error, or root node is not `<CashShop>`. The loader logs category / package / product / banner counts at startup
* **Wrong currency charged** - the client sends a `CoinIndex` with the purchase; the server rejects the buy if it does not match the package's `CoinIndex`
