JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 7
  • Score
    100M100P100Q41474F
  • License MIT

PricingCore - A high-precision, currency-agnostic pricing engine with BigInt precision, multiple markup strategies, multiple rounding strategies, and ISO 4217 currency support via currency-codes package

Package Exports

  • pricing-core
  • pricing-core/currency
  • pricing-core/math
  • pricing-core/rounding

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (pricing-core) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

PricingCore

License: MIT Node.js ES Modules

A high-precision, currency-agnostic pricing engine built in Node.js using BigInt for financial calculations. Perfect for e-commerce, retail, and financial applications that need accurate pricing across multiple currencies.

๐Ÿš€ Quick Start for Developers

# Install
npm install pricing-core

# Import and use
import { calculatePrice, pctToBps, toSmallestUnit, formatPrice } from 'pricing-core';

# Calculate price with 30% margin
const cost = toSmallestUnit(2.50, 'USD');  // $2.50 โ†’ 250 cents
const margin = pctToBps(30);                // 30% โ†’ 3000 bps
const price = calculatePrice(cost, margin, 'ceilStepUSD'); // Round to nickels

console.log(formatPrice(price, 'USD', true)); // "$3.60"

๐ŸŽฏ Why PricingCore?

  • ๐Ÿ”ข BigInt Precision - No floating-point errors in financial calculations
  • ๐ŸŒ 180+ Currencies - Full ISO 4217 support via currency-codes package
  • โšก High Performance - Integer-only arithmetic for maximum speed
  • ๐Ÿ”ง Developer Friendly - Clean API, comprehensive examples, ES modules
  • ๐Ÿ“ฑ CLI Testing - Interactive testing environment included

โœจ Key Features

  • ๐Ÿ”ข BigInt Precision: All calculations use BigInt to avoid floating-point errors
  • ๐ŸŒ Currency Agnostic: Support for any currency with configurable decimal places
  • ๐Ÿ“Š Margin-Based Pricing: Calculate prices using gross margin on selling price
  • ๐ŸŽฏ Multiple Rounding Strategies: Built-in and custom rounding options
  • โšก High Performance: Integer-only arithmetic for maximum speed
  • ๐Ÿ”ง Extensible: Easy to add new rounding strategies and currencies
  • ๐Ÿ“ฑ CLI Testing: Interactive command-line interface for testing

๐Ÿš€ Quick Start

Installation

npm install pricing-core
# Install specific version
npm install pricing-core@v1.0.12

Basic Usage

import { calculatePrice, pctToBps, toSmallestUnit, formatPrice } from 'pricing-core';

// Calculate price for a $2.50 item with 30% margin
const cost = toSmallestUnit(2.50, 'USD');  // Convert to cents
const margin = pctToBps(30);                // 30% โ†’ 3000 bps
const price = calculatePrice(cost, margin, 'margin', 'ceilStepUSD'); // Round to nickels

console.log(formatPrice(price, 'USD', true)); // "$3.60"

๐Ÿ“š Core API

Main Functions

calculatePrice(costUnits, markupValue, strategy, rounding)

Calculate the selling price based on cost and markup strategy.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units (e.g., cents)
  • markupValue (BigInt | number): Markup amount based on strategy
  • strategy (string): Markup strategy to use (default: 'margin')
  • rounding (string | function): Rounding strategy or custom function

Returns: BigInt - Price in smallest currency units

Supported Strategies:

  • margin: Margin on selling price (price = cost / (1 - margin))
  • costPlus: Fixed percentage added to cost (price = cost * (1 + markup))
  • keystone: Double the cost (price = cost * 2)
  • keystonePlus: Keystone plus additional percentage (price = cost * 2 * (1 + markup))
  • fixedAmount: Fixed amount added to cost (price = cost + markup)
  • targetMargin: Target margin on cost (price = cost / (1 - margin))
  • markupOnCost: Percentage markup on cost (price = cost * (1 + markup))

Examples:

// Margin strategy (original behavior)
const cost = toSmallestUnit(10.99, 'USD');  // 1099 cents
const margin = pctToBps(35);                // 35% margin
const price = calculatePrice(cost, margin, 'margin', 'charm99');

// Cost-plus strategy
const markup = pctToBps(25);                // 25% markup
const costPlusPrice = calculatePrice(cost, markup, 'costPlus', 'ceilStepUSD');

// Keystone strategy
const keystonePrice = calculatePrice(cost, 0, 'keystone', 'identity');

pctToBps(percentage)

Convert percentage to basis points.

Parameters:

  • percentage (number): Percentage value (e.g., 30 for 30%)

Returns: number - Basis points (e.g., 3000 for 30%)

Convenience Functions

calculatePriceWithMargin(costUnits, marginBps, rounding)

Legacy function for backward compatibility - uses margin strategy.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • marginBps (BigInt | number): Margin in basis points
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

calculateCostPlusPrice(costUnits, markupBps, rounding)

Calculate price using cost-plus markup strategy.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • markupBps (BigInt | number): Markup in basis points (e.g., 2500 for 25%)
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

calculateKeystonePrice(costUnits, rounding)

Calculate price using keystone markup (double the cost).

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

calculateKeystonePlusPrice(costUnits, additionalMarkupBps, rounding)

Calculate price using keystone plus additional markup.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • additionalMarkupBps (BigInt | number): Additional markup in basis points
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

calculateFixedAmountPrice(costUnits, fixedAmount, rounding)

Calculate price by adding a fixed amount to cost.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • fixedAmount (BigInt | number): Fixed amount to add in smallest currency units
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

calculateMarkupOnCostPrice(costUnits, markupBps, rounding)

Calculate price using markup on cost percentage.

Parameters:

  • costUnits (BigInt | number): Cost in smallest currency units
  • markupBps (BigInt | number): Markup percentage in basis points
  • rounding (string | function): Rounding strategy

Returns: BigInt - Price in smallest currency units

Currency Utilities

toSmallestUnit(amount, currency)

Convert decimal amount to smallest currency unit.

Parameters:

  • amount (number): Amount in base currency (e.g., 2.50 for $2.50)
  • currency (string | CurrencyConfig): Currency code or config

Returns: BigInt - Amount in smallest units

Example:

const cents = toSmallestUnit(2.50, 'USD');     // 250n
const yen = toSmallestUnit(1000, 'JPY');       // 1000n
const euros = toSmallestUnit(5.75, 'EUR');     // 575n

fromSmallestUnit(units, currency)

Convert from smallest currency unit back to decimal.

Parameters:

  • units (BigInt): Amount in smallest units
  • currency (string | CurrencyConfig): Currency code or config

Returns: number - Amount in base currency

formatPrice(amount, currency, inSmallestUnits)

Format price with proper currency formatting.

Parameters:

  • amount (BigInt | number): Amount to format
  • currency (string | CurrencyConfig): Currency code or config
  • inSmallestUnits (boolean): Whether amount is in smallest units

Returns: string - Formatted price string

Example:

formatPrice(250, 'USD', true);    // "$2.50"
formatPrice(1000, 'JPY', true);   // "ยฅ1,000"
formatPrice(575, 'EUR', true);    // "โ‚ฌ5.75"

createCurrency(code, symbol, decimalPlaces)

Create a custom currency configuration.

Parameters:

  • code (string): ISO currency code
  • symbol (string): Currency symbol
  • decimalPlaces (number): Number of decimal places

Returns: CurrencyConfig - Custom currency configuration

Example:

const btc = createCurrency('BTC', 'โ‚ฟ', 8);  // Bitcoin with 8 decimals
const satoshis = toSmallestUnit(0.001, btc); // 100000n

Currency Information Functions

getSupportedCurrencies()

Get all supported currency codes.

Returns: string[] - Array of supported currency codes

getCurrenciesByDecimalPlaces(decimalPlaces)

Get currencies filtered by number of decimal places.

Parameters:

  • decimalPlaces (number): Number of decimal places to filter by

Returns: string[] - Array of currency codes with the specified decimal places

Example:

const zeroDecimalCurrencies = getCurrenciesByDecimalPlaces(0); // ['JPY', 'KRW', 'XOF', ...]
const twoDecimalCurrencies = getCurrenciesByDecimalPlaces(2); // ['USD', 'EUR', 'GBP', ...]

getCurrenciesByRegion()

Get currencies grouped by geographical region.

Returns: Object - Currencies grouped by region

Example:

const regions = getCurrenciesByRegion();
console.log(regions['Asia Pacific']); // ['JPY', 'CNY', 'KRW', 'INR', ...]

getCurrencyByNumber(number)

Get currency information by ISO 4217 number.

Parameters:

  • number (number): ISO 4217 currency number (e.g., 840 for USD)

Returns: CurrencyConfig | null - Currency configuration or null if not found

Example:

const usd = getCurrencyByNumber(840); // Returns USD configuration

getCurrenciesByCountry(country)

Get currencies used by a specific country.

Parameters:

  • country (string): Country name (case-insensitive)

Returns: CurrencyConfig[] - Array of currency configurations for the country

Example:

const colombiaCurrencies = getCurrenciesByCountry('colombia'); // Returns COP and COU

getISOPublishDate()

Get the publish date of the ISO 4217 data.

Returns: string - Publish date in YYYY-MM-DD format

Example:

const publishDate = getISOPublishDate(); // "2024-06-25"

getCurrencyDetails(code)

Get detailed currency information including countries and ISO number.

Parameters:

  • code (string): ISO currency code

Returns: Object | null - Detailed currency information or null if not found

Example:

const eurDetails = getCurrencyDetails('EUR');
console.log(eurDetails.countries); // ['andorra', 'austria', 'belgium', ...]

๐ŸŒ Supported Currencies

The package includes complete ISO 4217 currency support via the currency-codes package, providing 180+ currencies from around the world with automatic updates:

Major Currencies

Currency Code Symbol Decimal Places Smallest Unit
US Dollar USD $ 2 $0.01
Euro EUR โ‚ฌ 2 โ‚ฌ0.01
British Pound GBP ยฃ 2 ยฃ0.01
Japanese Yen JPY ยฅ 0 ยฅ1
Chinese Yuan CNY ยฅ 2 ยฅ0.01
Indian Rupee INR โ‚น 2 โ‚น0.01
Canadian Dollar CAD C$ 2 C$0.01
Australian Dollar AUD A$ 2 A$0.01
Swiss Franc CHF CHF 2 CHF0.01
South Korean Won KRW โ‚ฉ 0 โ‚ฉ1

Currency Categories by Decimal Places

  • 0 decimal places: JPY, KRW, XOF, XAF, KMF, CLP, DJF, GNF, ISK, PYG, VUV, XPF, XDR, XAU, XAG, XPT, XPD, XTS, XXX
  • 2 decimal places: Most currencies (USD, EUR, GBP, etc.)
  • 3 decimal places: BHD, IQD, JOD, KWD, LYD, OMR, TND
  • 4 decimal places: CLF, UYW

Regional Coverage

  • North America: USD, CAD, MXN
  • Europe: EUR, GBP, CHF, SEK, NOK, DKK, PLN, CZK, HUF
  • Asia Pacific: JPY, CNY, KRW, INR, SGD, HKD, TWD, THB, MYR
  • Latin America: BRL, ARS, CLP, COP, PEN, UYU, PYG
  • Africa: ZAR, EGP, NGN, KES, GHS, MAD, TND, DZD
  • Middle East: SAR, AED, QAR, KWD, BHD, OMR, JOD, LBP, ILS
  • Oceania: AUD, NZD, FJD, PGK, WST, TOP, VUV

Special Currencies

  • Precious Metals: XAU (Gold), XAG (Silver), XPT (Platinum), XPD (Palladium)
  • Special Drawing Rights: XDR (IMF SDR)
  • Testing: XTS (Testing purposes)
  • No Currency: XXX (Transactions without currency)

Currency-Codes Integration

This package leverages the currency-codes package for:

  • Automatic Updates: Currency data is automatically updated when the underlying package updates
  • Official Data: Uses official ISO 4217 data from the maintainer
  • Rich Metadata: Includes country information, ISO numbers, and currency names
  • Maintenance: No need to manually maintain currency data

๐ŸŽฏ Markup Strategies

The pricing engine supports multiple markup strategies to fit different business models and pricing philosophies:

Available Strategies

  • margin: Margin on selling price (price = cost / (1 - margin))

    • Best for: Maintaining consistent profit margins
    • Example: 30% margin means 30% of the selling price is profit
  • costPlus: Fixed percentage added to cost (price = cost * (1 + markup))

    • Best for: Simple, predictable markup
    • Example: 25% markup means add 25% to the cost
  • keystone: Double the cost (price = cost * 2)

    • Best for: Traditional retail markup
    • Example: $10 cost โ†’ $20 price
  • keystonePlus: Keystone plus additional percentage (price = cost * 2 * (1 + markup))

    • Best for: Premium retail with additional markup
    • Example: $10 cost โ†’ $20 keystone โ†’ $25 with 25% additional markup
  • fixedAmount: Fixed amount added to cost (price = cost + markup)

    • Best for: Low-cost items or minimum pricing
    • Example: $5 cost + $2 markup = $7 price
  • targetMargin: Target margin on cost (price = cost / (1 - margin))

    • Best for: Cost-based margin calculations
    • Example: 40% margin on cost means 40% of cost is profit
  • markupOnCost: Percentage markup on cost (price = cost * (1 + markup))

    • Best for: Cost-based percentage markup
    • Example: 50% markup on cost means add 50% to cost

Strategy Selection Guide

Business Type Recommended Strategy Reasoning
E-commerce margin Consistent profit margins across products
Retail keystone or keystonePlus Traditional retail markup
Restaurants costPlus Simple food cost markup
Services fixedAmount Predictable service fees
Luxury Goods keystonePlus Premium positioning with additional markup
Wholesale markupOnCost Cost-based pricing for B2B

๐ŸŽฏ Rounding Strategies

Built-in Strategies

  • identity: No rounding (keep computed price as-is)
  • ceilStep5: Round up to next 5ยข increment
  • ceilStep10: Round up to next 10ยข increment
  • ceilStepUSD: Round up to next nickel (USD-specific)
  • ceilStepEUR: Round up to next 5 centimes (EUR-specific)
  • ceilStepJPY: Round up to next yen (JPY-specific)
  • ceilStepINR: Round up to next 5 paise (INR-specific)
  • charm99: Force .99 ending for psychological pricing

Custom Rounding

Create your own rounding functions:

// Round to nearest quarter (25ยข)
const roundToQuarter = (units) => {
  const quarter = 25n;
  const remainder = units % quarter;
  if (remainder === 0n) return units;
  
  const halfQuarter = quarter / 2n;
  if (remainder >= halfQuarter) {
    return units + (quarter - remainder);
  } else {
    return units - remainder;
  }
};

const price = calculatePrice(cost, margin, roundToQuarter);

๐Ÿ“– Examples

Example 1: Basic USD Pricing

import { calculatePrice, pctToBps, toSmallestUnit, formatPrice } from 'pricing-core';

const cost = toSmallestUnit(2.50, 'USD');  // $2.50 โ†’ 250 cents
const margin = pctToBps(30);                // 30% โ†’ 3000 bps
const price = calculatePrice(cost, margin, 'margin', 'ceilStepUSD');

console.log(formatPrice(price, 'USD', true)); // "$3.60"

Example 2: Multi-Currency Batch Pricing

const products = [
  { name: 'Widget A', cost: 10.99, currency: 'USD', margin: 35 },
  { name: 'Widget B', cost: 15.50, currency: 'EUR', margin: 30 },
  { name: 'Widget C', cost: 2000, currency: 'JPY', margin: 25 }
];

products.forEach(product => {
  const costUnits = toSmallestUnit(product.cost, product.currency);
  const marginBps = pctToBps(product.margin);
  const price = calculatePrice(costUnits, marginBps, 'margin', 'identity');
  
  console.log(`${product.name}: ${formatPrice(price, product.currency, true)}`);
});

Example 3: Different Markup Strategies

const cost = toSmallestUnit(20.00, 'USD');  // $20.00 cost

// 1. Margin strategy (30% margin on selling price)
const marginPrice = calculatePrice(cost, pctToBps(30), 'margin', 'ceilStepUSD');
console.log(`Margin pricing: ${formatPrice(marginPrice, 'USD', true)}`);

// 2. Cost-plus strategy (25% markup on cost)
const costPlusPrice = calculatePrice(cost, pctToBps(25), 'costPlus', 'ceilStepUSD');
console.log(`Cost-plus pricing: ${formatPrice(costPlusPrice, 'USD', true)}`);

// 3. Keystone strategy (double the cost)
const keystonePrice = calculatePrice(cost, 0, 'keystone', 'ceilStepUSD');
console.log(`Keystone pricing: ${formatPrice(keystonePrice, 'USD', true)}`);

// 4. Fixed amount markup ($5.00)
const fixedPrice = calculatePrice(cost, toSmallestUnit(5.00, 'USD'), 'fixedAmount', 'ceilStepUSD');
console.log(`Fixed amount pricing: ${formatPrice(fixedPrice, 'USD', true)}`);

Example 3: Custom Currency (Crypto)

const btc = createCurrency('BTC', 'โ‚ฟ', 8);  // Bitcoin with 8 decimal places
const btcCost = toSmallestUnit(0.001, btc);  // 0.001 BTC โ†’ 100000 satoshis
const btcMargin = pctToBps(15);               // 15% margin

const btcPrice = calculatePrice(btcCost, btcMargin, 'margin', 'identity');
console.log(formatPrice(btcPrice, btc, true)); // "โ‚ฟ0.00115000"

๐Ÿงช Developer Experience

Quick Commands

npm run dev          # Run tests + examples
npm start            # Launch interactive CLI
npm run demo         # Run comprehensive examples
npm test             # Run test suite
npm run examples     # Run pricing examples
npm run cli          # Interactive testing environment

ES Modules Support

This package is built with ES modules and is fully compatible with modern Node.js. All functions include JSDoc comments for excellent IDE support.

Installing from npm

# Install the package directly from npm
npm install pricing-core

๐Ÿ”ง Advanced Usage

Custom Currency Configuration

import { createCurrency } from 'pricing-core';

// Create a custom currency for a local market
const localCurrency = createCurrency('LOCAL', 'L', 3);  // 3 decimal places
const amount = toSmallestUnit(12.345, localCurrency);

Batch Processing

// Process multiple items efficiently
const items = [
  { cost: 5.99, margin: 25, currency: 'USD' },
  { cost: 12.50, margin: 30, currency: 'EUR' },
  { cost: 1500, margin: 20, currency: 'JPY' }
];

const results = items.map(item => {
  const costUnits = toSmallestUnit(item.cost, item.currency);
  const marginBps = pctToBps(item.margin);
  const price = calculatePrice(costUnits, marginBps, 'margin', 'identity');
  
  return {
    ...item,
    price: formatPrice(price, item.currency, true)
  };
});

Error Handling

try {
  const price = calculatePrice(cost, margin, 'unknownRounding');
} catch (error) {
  if (error.message.includes('Unknown rounding style')) {
    console.log('Invalid rounding strategy');
  } else if (error.message.includes('marginBps must be between')) {
    console.log('Invalid margin percentage');
  }
}

๐Ÿ“ฆ Package Structure

pricing-core/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ index.js          # Main exports
โ”‚   โ”œโ”€โ”€ core/
โ”‚   โ”‚   โ”œโ”€โ”€ calculator.js # BigInt pricing calculator
โ”‚   โ”‚   โ””โ”€โ”€ math.js       # Integer-safe helpers
โ”‚   โ”œโ”€โ”€ rounding/
โ”‚   โ”‚   โ”œโ”€โ”€ index.js      # Rounding registry
โ”‚   โ”‚   โ”œโ”€โ”€ identity.js   # No rounding
โ”‚   โ”‚   โ”œโ”€โ”€ ceilStep.js   # Step-based rounding
โ”‚   โ”‚   โ””โ”€โ”€ charm99.js    # .99 ending
โ”‚   โ””โ”€โ”€ currency.js       # Currency utilities
โ”œโ”€โ”€ test/                 # Test suite
โ”œโ”€โ”€ cli.js                # CLI testing environment
โ””โ”€โ”€ examples.js           # Comprehensive examples

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

๐Ÿ“„ License

MIT License - see LICENSE file for details.

๐Ÿ”’ Security

Please do NOT report security vulnerabilities through public GitHub issues.

If you discover a security vulnerability, please email security@fivespiceindiangrocery.com.

See SECURITY.md for more details.

๐Ÿ†˜ Support

  • Issues: GitHub Issues
  • Examples: Run npm run examples for comprehensive examples
  • CLI: Run npm start for interactive testing
  • currency-codes - ISO 4217 currency data and utilities

Made with โค๏ธ for accurate financial calculations