---
title: "Keep prices in a versioned catalogue · Agent Wranglers"
url: https://agentwranglers.se/playbook/pricing/plans-and-prices/price-catalogue
id: PRC-1
level: Recommended
applies: payments
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1194
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Keep prices in a versioned catalogue

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Plans and prices](https://agentwranglers.se/playbook/pricing/plans-and-prices.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: PRC-1
- Level: Recommended
- Chapter: [Plans and prices](https://agentwranglers.se/playbook/pricing/plans-and-prices.md)
- Rule: Keep every price in one server-side catalogue with a stable ID, and create a new price instead of changing the amount of one in use.
- Check: The app's database role cannot update the amount or currency of a price. Search the client code for amounts sent to the checkout endpoint. None are sent.
- Applies when: The project takes payments.
- How: The browser sends only product or price IDs, as [server-side business rules](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/server-side-business-rules.md) requires. Store each price with its amount in minor units, currency, interval and tax behaviour. To change an amount, create a new price and archive the old one. Orders and subscriptions keep pointing at the old price, so history and invoices stay true. Move subscribers to a new price on purpose, with notice.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### SQL example

```sql
CREATE TABLE prices (
  id               text PRIMARY KEY,
  product_id       text NOT NULL,
  amount_minor     bigint NOT NULL CHECK (amount_minor >= 0),
  currency         char(3) NOT NULL,
  billing_interval text CHECK (billing_interval IN ('month', 'year')),
  tax_behaviour    text NOT NULL CHECK (tax_behaviour IN ('inclusive', 'exclusive')),
  archived_at      timestamptz
);
GRANT SELECT, INSERT ON prices TO app_role;
GRANT UPDATE (archived_at) ON prices TO app_role;
```

## Sources

- [Stripe, manage products and prices](https://docs.stripe.com/products-prices/manage-prices)

## Related rules

- PAY-74 [Offer pay later through a licensed lender](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law/pay-later-credit.md) in Payments and billing
- PAY-51 [Show prices the way each market expects](https://agentwranglers.se/playbook/payments/tax/tax-inclusive-prices.md) in Payments and billing
- PAY-66 [Set a price in each currency instead of converting at checkout](https://agentwranglers.se/playbook/payments/currencies-and-settlement/price-per-currency.md) in Payments and billing
- USG-12 [Keep every metered price above its cost](https://agentwranglers.se/playbook/usage-billing/margins-and-model-cost/margin-guard.md) in Usage-based billing
- USG-30 [Name the tier model of every metered price](https://agentwranglers.se/playbook/usage-billing/usage-on-invoices/tiered-or-volume.md) in Usage-based billing
- ECM-46 [Tell customers when a price is personalised for them](https://agentwranglers.se/playbook/ecommerce/catalog-and-prices/personalised-price-notice.md) in E-commerce and fulfilment
- APS-52 [Work out every amount on the server](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/server-side-business-rules.md) in Application security
- PRC-2 [Tell subscribers before a price rise](https://agentwranglers.se/playbook/pricing/plans-and-prices/price-increase-notice.md) in Pricing, plans and entitlements
- PRC-12 [Compute tiered and volume prices in one tested function](https://agentwranglers.se/playbook/pricing/plans-and-prices/tiered-and-volume-pricing.md) in Pricing, plans and entitlements
- PRC-13 [Bill committed-use contracts against the commitment and true up at term end](https://agentwranglers.se/playbook/pricing/plans-and-prices/committed-use-true-up.md) in Pricing, plans and entitlements
- PRC-16 [Keep old prices as archived catalogue prices with an end date](https://agentwranglers.se/playbook/pricing/plan-changes-trials-and-free-tiers/grandfathered-prices.md) in Pricing, plans and entitlements

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/pricing/plans-and-prices/price-catalogue">Agent Wranglers pricing, plans and entitlements playbook</a>`. In code you write, add a comment next to it with the same link.

- Next: [Tell subscribers before a price rise](https://agentwranglers.se/playbook/pricing/plans-and-prices/price-increase-notice.md)
- [Plans and prices](https://agentwranglers.se/playbook/pricing/plans-and-prices.md)
