Payments & Money APIs · Charging Safely

Amounts, Taxes, Discounts & Price Integrity

The server computes the price; clients never send amounts you trust.

Never accept the amount from the client — compute it on the server from the cart, prices, discounts, shipping and tax (use a tax engine or the PSP's tax product for multi-jurisdiction sales). Store a price snapshot on the order (unit prices, discounts, tax lines, totals) so later price changes don't alter history. Apply rounding per line or per total consistently with tax rules, and show customers the same numbers you charge.

Price integrity

Concern Bad Good
Amount source Client-sent total Server-computed from catalog + rules
Price changes Recompute old orders Immutable order price snapshot
Tax Hard-coded rate Tax engine by jurisdiction/product
Discounts Client-applied Server-validated codes with limits
Rounding Ad hoc Documented per line/total rule

Python

async def quote(cart: Cart, customer: Customer) -> Quote:
    lines = []
    for item in cart.items:
        product = await catalog.get(item.product_id)              # server price, not client price
        lines.append(Line(product.id, item.qty, product.unit_price_minor))
    discount = await promotions.apply(cart.promo_code, lines, customer)   # validated, limited
    tax = await tax_engine.calculate(lines, discount, ship_to=customer.address)
    return Quote(lines=lines, discount=discount, tax=tax,
                 total_minor=sum(l.total for l in lines) - discount.amount + tax.amount,
                 currency=cart.currency, expires_at=utcnow() + timedelta(minutes=30))

Common pitfalls

  • Trusting hidden form fields for prices.
  • Recalculating historic orders with current prices.
  • Mismatch between displayed and charged totals.

Key points

  • Server computes amounts
  • Immutable price snapshots
  • Consistent tax and rounding

Further reading: Stripe Tax

Practice questions

Why must the server compute the payment amount?

Answer

Clients can be manipulated; trusting a client-sent total lets attackers pay any amount they choose.

Why store a price snapshot with each order?

Answer

Prices, taxes and promotions change; the order must keep exactly what the customer agreed to and was charged for refunds, receipts and audits.

Open in the app to mark lessons complete, take notes and track your progress.