> For the complete documentation index, see [llms.txt](https://guides.paynow.gg/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guides.paynow.gg/integrations-and-commands/custom-variables.md).

# Custom Variables

Custom variables ask the customer a question at checkout and feed the answer into your commands. One product can then cover what would otherwise be a dozen near-identical ones.

*Dashboard → Store → Custom Variables. Needs `custom_variable_read`.*

## Creating one

1. Go to **Store → Custom Variables**.
2. Click **Create**.

| Field           | What it does                                                                                                                                           |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Name**        | Shown to the customer.                                                                                                                                 |
| **Identifier**  | How you reference it in commands, as `{identifier}`.                                                                                                   |
| **Description** | Optional. Appears under the input on the product page.                                                                                                 |
| **Type**        | Dropdown (a fixed set of options, such as server region or item colour), Text (freeform, such as a username or name tag), or Number (levels, amounts). |

**Text** and **Number** support **regex validation**.

{% hint style="warning" %}
**Validate every text input that reaches a command.** A freeform field is customer-supplied text going straight into your server console. Without a regex, someone can enter spaces, quotes or command syntax and change what actually executes.

For a name tag, `^[A-Za-z0-9_]{1,16}$` is a reasonable start: letters, digits and underscores only, capped at 16 characters.
{% endhint %}

## Using them in commands

Given a `{kit}` dropdown of bronze, silver and gold, a `{name}` text field and a `{slots}` number field:

```bash
oxide.usergroup add {customer.steam.id} {kit}
say "{customer.name} just purchased the {kit} package!"
o.grant user {customer.steam.id} backpacks.size.{slots}
```

If the customer picks **gold**, **Lord** and **6**, the executed commands are:

```bash
oxide.usergroup add 7656119XXXXXXXXXXX gold
say "Lord just purchased the gold package!"
o.grant user 7656119XXXXXXXXXXX backpacks.size.6
```

Attach variables to a product from its [edit page](/products/creating-a-product.md). They mix freely with the built-in placeholders; see [Commands & Placeholders](/integrations-and-commands/commands.md).

## Dropdown pricing

Dropdown options can carry an extra charge.

| Field               | What it does                                |
| ------------------- | ------------------------------------------- |
| **Name / Value**    | Shown to the customer and used in commands. |
| **Pricing Type**    | Fixed or Percentage.                        |
| **Additional Cost** | Extra charged for that option.              |

This replaces whole tiers of products. Instead of Bronze, Silver and Gold Kit as three products with three sets of commands, sell one Kit product with a `{kit}` dropdown priced at +$0 / +$5 / +$12. One product to maintain, and the customer sees the upgrade options while they're already buying. See also [Upselling](/marketing/upselling.md).

## Blank variables

Variables are optional. If a customer leaves one blank, the placeholder resolves to nothing, so `o.grant user {id} backpacks.size.{slots}` with `{slots}` empty produces a malformed command. Set a sensible default, or validate that it can't be empty.
