# Prices (/en/features/products/prices)

How XPay models prices: one-time, recurring, customer-set amounts, stock, scheduling, and the seven price status states.

A <ApiLink href="/api-reference/objects/price">Price</ApiLink> is the configuration that determines what a customer pays for a product: the amount, the currency, whether it's charged once or repeatedly, how much stock is available, and when the price is valid. Every <ApiLink href="/api-reference/objects/product">Product</ApiLink> carries one or more prices, and each price is independent. You can run an old price and a new one side by side, archive an outdated one, or hold one in **Scheduled** state until a launch date.

This page covers the three price types, how currency and stock work, scheduling with start and end dates, and the seven price status states the dashboard can show.

## Price types [#price-types]

A price has one of three types. The type is set when the price is created and **cannot be changed afterward**. To switch a product from one type to another, add a new price.

### One Time [#one-time]

The customer pays the **amount** once. This is the default type and the most common choice for catalog products.

A One Time price needs an amount and a currency. Stock and start or expiration dates are optional.

### Recurring [#recurring]

A subscription-style price billed at a chosen interval (daily, weekly, monthly, yearly, or every N of those).

Recurring prices are **not yet active for checkout**. They show up in the dashboard with an **Unsupported** status until subscriptions ship for your account. Until then, create One Time or Custom prices instead.

When subscriptions become available, recurring prices will let you bill the same customer on a schedule you set: every month, every three months, once a year. The interval and interval count are set on the price itself.

### Custom (customers choose what to pay) [#custom-customers-choose-what-to-pay]

The customer enters the amount themselves at checkout. Use this for donations, "pay what you want", tipping, or any flow where the merchant doesn't set a fixed amount.

A Custom price has these configuration fields:

| Field        | What it does                                                                            |
| ------------ | --------------------------------------------------------------------------------------- |
| **Currency** | The currency the customer pays in.                                                      |
| **Minimum**  | The smallest amount the customer can enter. Optional. Defaults to no floor.             |
| **Maximum**  | The largest amount the customer can enter. Optional. Defaults to no ceiling.            |
| **Preset**   | The amount the form pre-fills with. Optional. The customer can change it before paying. |

Custom prices don't carry stock. Inventory tracking applies to fixed-amount sales.

## Currency [#currency]

Each price carries one currency. A product can have several prices in different currencies, and each is independent (a 100 EGP price and a 5 USD price on the same product are two separate prices, with their own statuses, stock, and schedules).

Currency is set when the price is created and isn't editable later. The default currency for new prices is your account's settlement currency.

## Stock [#stock]

The **Stock** field tracks how many units are available at this price.

| Stock value | What it means                                                                             |
| ----------- | ----------------------------------------------------------------------------------------- |
| Empty       | Unlimited. The dashboard shows "Not limited" on the price detail.                         |
| A number    | A finite quantity. Each successful payment that includes this price decrements the count. |

When stock reaches zero, the price's status flips to **Sold out** and new checkouts against it are blocked.

Stock is allowed to go negative briefly under heavy concurrent traffic. When that happens, the status flips to **Oversold**. New checkouts are still blocked, and you can resolve manually by editing the price (raise stock, archive the price, or reach out to affected customers).

Only items the customer actually buys count against stock. An optional add-on the customer never adds (quantity 0) doesn't decrement it. If the add-on is out of stock, the checkout shows it as sold out and the customer can't add it, without blocking the rest of the order.

Stock is not available on Custom prices.

## Scheduling [#scheduling]

Two optional fields control when a price is usable.

| Field               | What it does                                                                                                                    |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Start Date**      | Before this date, the price's status is **Scheduled** and checkout against it is blocked. Use it to queue a price for a launch. |
| **Expiration Date** | After this date, the price's status is **Expired** and checkout against it is blocked. Use it to retire a price automatically.  |

Either field can be set on its own; both are optional. A price with neither is valid from creation until you archive it.

## Status states [#status-states]

The dashboard shows one badge per price. The status is computed from the price's `active` flag, type, stock, and schedule, in the precedence below (first match wins).

| Status          | Color   | When it shows                                                        | Checkout                                    |
| --------------- | ------- | -------------------------------------------------------------------- | ------------------------------------------- |
| **Archived**    | Warning | The price was deactivated by you or by archiving the parent product. | Blocked. The price isn't selectable.        |
| **Unsupported** | Error   | A Recurring price, until subscriptions ship for your account.        | Blocked.                                    |
| **Expired**     | Warning | Today is on or after the price's **Expiration Date**.                | Blocked.                                    |
| **Scheduled**   | Neutral | Today is before the price's **Start Date**.                          | Blocked. Will activate automatically.       |
| **Oversold**    | Error   | Stock went negative under concurrent traffic. Resolve manually.      | Blocked.                                    |
| **Sold out**    | Warning | Stock reached zero.                                                  | Blocked. Edit stock or archive to clean up. |
| **Active**      | Success | None of the above. The price is fully usable.                        | Allowed.                                    |

Only **Active** prices can be checked out against. Any other status returns a price-specific error to the customer's payment attempt and asks them to pick another option.

## Adding and editing prices [#adding-and-editing-prices]

Prices live on the product detail page (**Product catalog → click any product*&#x2A;). The first price is created when you create the product. To add another price to an existing product, click the &#x2A;*+** button next to the **Pricing** heading. To edit, archive, or delete a single price, use the action menu on the price's row.

A few constraints to keep in mind:

* **Type can't change.** To switch from One Time to Custom (or any other change), add a new price and archive the old one.
* **Currency can't change.** Same approach: add a new price in the new currency.
* **Delete is reserved for never-used prices.** A price with any successful transaction can't be deleted, only archived. Archive keeps the historical record.
* **The action menu is disabled** when you don't have catalog write permission. Ask an account admin to grant it.

## Where to next [#where-to-next]

<Cards>
  <Card icon="<PackageOpen />" title="Product catalog" href="/features/products/product-catalog">
    The full product flow: create, read, archive, delete.
  </Card>

  <Card icon="<BadgePercent />" title="Coupons" href="/features/products/coupons">
    Apply percentage or fixed-amount discounts on top of any price.
  </Card>

  <Card icon="<ShoppingBag />" title="Line items and pricing (developer)" href="/integrate/checkout-session/line-items-and-pricing">
    The code-side companion: how to attach prices to a Checkout Session and the rules for
    `priceData` overrides.
  </Card>
</Cards>