money-safe
v0.1.0TYPE-SAFE MONEY
DOCS INTERFACE · GUIDE / RECIPES / REFERENCE · MINOR UNITS STAY EXPLICIT
Checkout

Checkout

ts
import { amount } from '@crapthings/money-safe';

type CheckoutLine = {
  sku: string;
  unitPrice: string;
  quantity: number;
};

export function calculateCheckout(lines: CheckoutLine[]) {
  const subtotal = lines.reduce(
    (sum, line) => sum.plus(amount(line.unitPrice, 'CNY').times(line.quantity)),
    amount('0.00', 'CNY')
  );

  const discount = subtotal.times('0.10', { rounding: 'half-up' });
  const shipping = subtotal.toMinor() >= 9900 ? amount('0.00', 'CNY') : amount('12.00', 'CNY');
  const total = subtotal.minus(discount).plus(shipping);

  return {
    subtotal: subtotal.toDecimal(),
    discount: discount.toDecimal(),
    shipping: shipping.toDecimal(),
    total: total.toDecimal(),
    displayTotal: total.format('zh-CN'),
    paymentPayload: total.toJSON()
  };
}

Use decimal strings for public input, then use paymentPayload for service, database, or payment-provider boundaries.

This matches the checked example file.