Agent Wranglers

PAY-66Recommended

Set a price in each currency instead of converting at checkout

Store a fixed price for each currency you sell in, in the price catalogue. Never compute a customer's price from a live exchange rate at checkout.

How to do it

A price converted at checkout changes every day, so the product page, the cart and the invoice can disagree. Round prices per currency, such as 129 SEK and 12 EUR, chosen on purpose. Pick the currency from the customer's billing country, not the browser language, and keep it for the life of a subscription. Review the prices when a rate moves more than a set share, such as 10%, and change them as a new price. Keep each price in the versioned price catalogue. A provider feature that converts for you is fine when it fixes the rate for the whole checkout and shows the rate to the customer.

Examples

SQL example

CREATE TABLE price_amounts (
  price_id     text NOT NULL REFERENCES prices (id),
  currency     char(3) NOT NULL,
  amount_minor bigint NOT NULL CHECK (amount_minor >= 0),
  PRIMARY KEY (price_id, currency)
);

Python example

def amount_for(db, price_id: str, currency: str) -> int:
    row = db.execute(
        "SELECT amount_minor FROM price_amounts WHERE price_id = %s AND currency = %s",
        (price_id, currency),
    ).fetchone()
    if row is None:
        raise ValueError(f"No {currency} amount for {price_id}")
    return row[0]

JavaScript example

export async function amountFor(db, priceId, currency) {
  const { rows } = await db.query('SELECT amount_minor FROM price_amounts WHERE price_id = $1 AND currency = $2', [priceId, currency])
  if (!rows.length) throw new Error(`No ${currency} amount for ${priceId}`)
  return Number(rows[0].amount_minor)
}

How to check

Search the checkout code for calls to an exchange rate service. None are found. A test loads the same product as a Swedish and a German customer and gets the stored SEK and EUR prices.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/payments/currencies-and-settlement/price-per-currency">Agent Wranglers payments and billing playbook</a>. In code you write, add a comment next to it with the same link.