npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@moirei/complex-pricing

v1.0.1

Published

Ecommerce complex pricing package for the frontend and node.js.

Downloads

7

Readme

@moirei/complex-pricing

This package is a port of the laravel-pricing package with typescript support for the frontend and node.js.

Installation

$ npm i @moirei/complex-pricing
# or
$ yarn add @moirei/complex-pricing

Usage

import Pricing from '@moirei/complex-pricing'

const pricing = new Pricing({
    model: "package",
    unit_amount: 25,
    units: 5,
});
// or
const pricing = Pricing.make(...)

const price = pricing.price(4); // returns 25.0

Get export content

To export/save and re-instantiate the underlying data, use the get method.

const content = pricing.get();

pricing = pricing.make(content);

Pricing Models

In large applications, pricing for provided goods or service are often not straight forward. For instance, you might want to charge $10 on an item for every 5 units purchased in AU, while at the same time, for your customers in US, regressively charge $50, $40, $30 for every quantity ranged between 0-30, 31-40, 50-infinity respectively.

This package has the concept of standard, package, volume, and graduated pricing intended to cover most (if not all) complex pricing scenarios. It also allows naming for multi-currency and multi-region use cases.

Standard

This is the classic pricing model where your price result is a linear multiple of the unit price.

const pricing = Pricing.make({
    model: "standard",
    unit_amount: 25,
});
// or
const pricing = Pricing.make().standard(25)

const price = pricing.price(4); // returns 100.0

Package

Package pricing computes the total result in package groups. For example, an amount of $25.0 for every 5 units. Results are rounded up such that 8 units returns $50.0.

const pricing = Pricing.make({
    model: "package",
    unit_amount: 25,
    units: 5,
});
// or
const pricing = Pricing.make().package(25, 5)

const price = pricing.price(4); // returns 25.0
const price = pricing.price(8); // returns 100.0

Volume

Use volume pricing to apply charges based on tier of the quantity. For example, with the tiers below; charges on 1-5 units fall in the first tier, 6-10 within the second tier, and within the third for 11 units and above.

const tiers = [
    {
        max: 5,
        unit_amount: 3,
    },
    {
        max: 10,
        unit_amount: 2,
    },
    {
        max: 'infinity',
        unit_amount: 1,
        flat_amount: 0.3,
    }
];
const pricing = Pricing.make({
    model: "volume",
    tiers: tiers,
});
// or
const pricing = Pricing.make().volume(tiers)

const price = pricing.price(4); // returns 4 x 3 = 12.0
const price = pricing.price(8); // returns 8 x 2 = 16.0
const price = pricing.price(12); // returns (12 x 1) + 0.3 = 12.3

Graduated

Use graduated pricing to progressively calculate a charge based on all applicable tiers. For example, with the tiers below, a unit of 6 falls between tiers 0-1, 12 falls between 0-2, and so on.

const tiers = [
    {
        max: 5,
        unit_amount: 4,
    },
    {
        max: 10,
        unit_amount: 3,
        flat_amount: 0.1,
    },
    {
        max: 15,
        unit_amount: 2,
        flat_amount: 0.2,
    },
    {
        max: 'infinity',
        unit_amount: 1,
        flat_amount: 0.3,
    }
];
const pricing = Pricing.make({
    model: "graduated",
    tiers: tiers,
});
// or
const pricing = Pricing.make().graduated(tiers)

const price = pricing.price(4);  // returns 4 x 4 = 16.0
const price = pricing.price(8);  // returns (5 x 4) + (3 x 3 + 0.1) = 29.1
const price = pricing.price(12); // returns (5 x 4) + (5 x 3 + 0.1) + (2 x 2 + 0.2) = 39.3

Flat Fees

For volume and graduated pricing, use flat_amount for the provided tiers to include a flat fee for every charge.

Miscellaneous Data

Use the data method to update or get the content miscellaneous data.

// set data
pricing.data({
    currency: 'AUD'
}) // returns the instance so it may be chainable
pricing.data('meta.tiers_count', 4); // returns 4

const currency = pricing.data('currency') // returns 'AUD'
const tiers_count = pricing.data('meta.tiers_count') // returns 4

const data = pricing.data(); // dump all

Contribution Guidelines

Any pull requests or discussions are welcome. Note that every pull request providing new feature or correcting a bug should be created with appropriate unit tests.

Changelog

Please see CHANGELOG.