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. |
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.
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
{ 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
{
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:
{
"event": "store_purchase",
"userId": "123456789012345678",
"guildId": "123456789012345678",
"productId": "vip",
"customerEmail": "[email protected]",
"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. |