# Configuration

URL: https://zerodev.ca/docs/store/configuration

> Panels, products, prices, rewards and messages in store.json5 and store-lang.json5.



Store has two files in AthenaBot's `configuration/` folder:

| File               | What it holds                                                   |
| ------------------ | --------------------------------------------------------------- |
| `store.json5`      | License, currency, providers, panels, products and permissions. |
| `store-lang.json5` | Every message the plugin sends.                                 |

Restart AthenaBot after editing either file.

## store.json5

| Option                      | What it does                                                                        |
| --------------------------- | ----------------------------------------------------------------------------------- |
| `LICENSE_KEY`               | Your Store license key.                                                             |
| `currency`                  | The default currency for every product, such as `usd`, `eur` or `inr`.              |
| `providers`                 | API keys for each payment provider. See [Payment Providers](/docs/store/providers). |
| `panel_linking`             | Your panels and their products.                                                     |
| `permissions.store_command` | Permission level that can run `/store`. Keep this at `admin` or similar.            |

Anyone who can see a panel can buy from it.

## Panels

Each key under `panel_linking`, such as `panel1`, is a panel ID. It has a `type` and one entry per product.

```json5 title="configuration/store.json5"
panel_linking: {
  ranks: {
    type: "BUTTON",
    vip: {
      name: "VIP",
      description: "The VIP role and its perks.",
      emoji: "%custom_emoji_27%",
      color: "green",
      price: 5.00,
      providers: ["stripe", "paypal"],
      max_purchases: 1,
      rewards: [{ type: "role", role_id: "000000000000000000" }],
    },
  },
},
```

| Option | What it does                                                                                                         |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
| `type` | `SELECT_MENU` for a dropdown, or `BUTTON` for one button per product. Buttons show the price, such as `VIP ($5.00)`. |

A panel shows up to 25 products.

## Products

Each key under a panel, such as `vip`, is a product ID. It is saved with every purchase and shown in `/store lookup`.

| Option           | Required   | What it does                                                                                                          |
| ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------- |
| `name`           | Yes        | Shown in Discord, on the checkout page and on the receipt.                                                            |
| `price`          | Yes        | The price, such as `5.00`.                                                                                            |
| `providers`      |            | The providers a buyer can pick from, such as `["stripe", "paypal", "crypto"]`. With more than one, the buyer chooses. |
| `provider`       |            | A single provider. Used when `providers` is not set.                                                                  |
| `currency`       |            | Overrides the default `currency`.                                                                                     |
| `description`    |            | Shown on the Stripe checkout page.                                                                                    |
| `emoji`          |            | A custom emoji, as `%custom_emoji_<id>%`.                                                                             |
| `color`          |            | Button panels only. `gray`, `blue`, `green` or `red`.                                                                 |
| `max_purchases`  |            | How many times one member can buy it. `0` is unlimited.                                                               |
| `polar_price_id` | Polar only | The product's Price ID in Polar.                                                                                      |
| `rewards`        |            | What the buyer gets. See below.                                                                                       |

If a product sets neither `providers` nor `provider`, the first provider in `providers` at the top of the file is used.

Provider names are `stripe`, `paypal`, `razorpay`, `polar` and `crypto`.

## Rewards

Rewards run in order once the payment is confirmed.

### Role

```json5
{ type: "role", role_id: "000000000000000000" }
```

Gives the buyer a role. Members who already have the role cannot buy the product again, whatever `max_purchases` says. AthenaBot's role must be above the role it gives.

### Webhook

```json5
{
  type: "webhook",
  url: "https://example.com/hooks/purchase",
  method: "POST",
  headers: { "Content-Type": "application/json", "Authorization": "Bearer your-secret" },
}
```

Sends a request to your own server, so you can deliver anything: a license key, game items or an account upgrade. `method` defaults to `POST`. The body is:

```json
{
  "event": "store_purchase",
  "userId": "123456789012345678",
  "guildId": "123456789012345678",
  "productId": "vip",
  "customerEmail": "customer1@example.com",
  "amountTotal": 500,
  "currency": "usd",
  "transactionId": "cs_live_...",
  "timestamp": "2026-10-10T12:00:00.000Z"
}
```

`amountTotal` is in cents. Add a secret header and check it on your server, since anyone could call that URL.

## store-lang.json5

Messages use AthenaBot's components format. `%primary_color%` is your accent colour and `%custom_emoji_<id>%` any AthenaBot emoji.

### Panels

Add a message under `panels` for every panel ID. It is shown above the buttons or menu.

### Replies

| Key                                   | Shown when                                           | Placeholders                                                                                                           |
| ------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `panel_sent`                          | A panel is posted.                                   | `%panel%`, `%channel%`                                                                                                 |
| `select_provider`                     | The buyer picks how to pay.                          | `%product%`, `%price%`, `%currency%`                                                                                   |
| `checkout_ready`                      | The checkout link is ready.                          | `%product%`, `%price%`, `%currency%`, `%checkout_url%`                                                                 |
| `checkout_paid`                       | The payment goes through. Replaces `checkout_ready`. | `%product%`, `%price%`, `%currency%`                                                                                   |
| `purchase_receipt_dm`                 | DM'd to the buyer.                                   | `%product%`, `%transaction_id%`, `%amount%`, `%currency%`                                                              |
| `already_owned`                       | The buyer has the role or hit `max_purchases`.       | `%product%`                                                                                                            |
| `product_not_found`                   | The product is missing from the config.              | `%product%`                                                                                                            |
| `error_message`                       | Checkout fails.                                      | `%message%`                                                                                                            |
| `purchase_log`                        | Posted in `store-logs`.                              | `%product%`, `%panel%`, `%transaction_id%`, `%user_mention%`, `%user_id%`, `%amount%`, `%currency%`, `%error_details%` |
| `transaction_lookup_results`          | `/store lookup` finds purchases.                     | `%count%`, `%results%`                                                                                                 |
| `no_transactions_found`               | `/store lookup` finds nothing.                       |                                                                                                                        |
| `messages.select_product_placeholder` | The empty select menu text.                          |                                                                                                                        |
