• Content

Quantity-Based Pricing

Overview

In this guide we’ll go over using add-ons with plans and subscriptions in combination with the various quantity-based pricing models. Before continuing with this guide, it’s recommended that you’ve taken a look at the Quickstart Guide and the Subscription Management Guide.

Estimated Completion time

30 minutes

Step 1: Creating an Item

For this guide we’re going to create an item we can use to add to plans and subscriptions. To do that, we’ll use the Create Item endpoint. When creating items, we can specify various item attributes such as name, accounting codes, external SKU, default pricing, etc. For the purposes of this guide, we’ll just keep things as simple as possible (there’s no need to define a default price, for instance, that will be overwritten by the various pricing models we’ll use below); for more options, see the endpoint documentation above.

To give ourselves a concrete example, let’s imagine our product is T-shirts and we’ll be creating plans to schedule regular deliveries of T-shirts that our customers can give out at vendor booths or other events. We can create a t-shirt item as so:

Ruby

Node.js

Python

Java

Dotnet

PHP

item_create = {
  code: "promo-shirt",
  name: "Custom Promotional T-shirt"
}
item = @client.create_item(body: item_create)
puts "Created Item #{item}"
const itemCreate = {
  code: 'promo-shirt',
  name: 'Custom Promotional T-shirt'
}
const item = await client.createItem(itemCreate)
console.log('Created Item: ', item.code)
ItemCreate itemReq = new ItemCreate();

itemReq.setCode("promo-shirt");
itemReq.setName("Custom Promotional T-shirt");

Item item = client.createItem(itemReq);
System.out.println("Created item " + item.getCode());
item_create = {
    "code": "promo-shirt",
    "name": "Custom Promotional T-shirt"
}
item = client.create_item(item_create)
print("Created Item %s" % item)
var itemReq = new ItemCreate()
{
    Code = "promo-shirt",
    Name = "Custom Promotional T-shirt"
};
Item item = client.CreateItem(itemReq);
Console.WriteLine($"Created item {item.Code}");
$item_create = array(
    "code" => "promo-shirt",
    "name" => "Custom Promotional T-shirt"
);
$item = $client->createItem($item_create);

echo 'Created Item:' . PHP_EOL;
var_dump($item);

Note that you have the option to use an item or an add-on to setup quantity-based pricing models. Items are best when you are selling the same product across multiple plans, while add-ons are best when the offering is specific to each plan.

Step 2: Creating a Plan with the Item Add-on

There are three kinds of pricing models we want to cover in this guide: tiered, volume, and stairstep. We include examples of all three here. See the documentation for the Plan Creation endpoint for more options. All of the quantity-based pricing models are used to set different prices depending on quantities purchased; exactly how they do that differs from model to model.

Using the Tiered Pricing Model

The tiered pricing model charges for each unit based on the price of its corresponding tier; for example, there might be two tiers, one for quantities at or under 100 and another tier for quantities over that. Amounts in the first tier (100 in our example) will charge for each item at the rate in the first tier; any amounts in excess of our first tier (e.g., if the amount is 105, the excess 5) will charge for each item at the rate in the second tier. Here is an example of how to set it up:

Ruby

Node.js

Python

Java

Dotnet

PHP

plan_create = {
  code: "tiered-tshirt-plan",
  name: "Tiered T-shirt Plan",
  currencies: [
    {
      currency: "USD",
      unit_amount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: "tiered",
      tiers: [
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 20
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 15
            }
          ],
          ending_quantity: 999999999 # maximum value
        }
      ]
    }
  ]
}
plan = @client.create_plan(body: plan_create)
puts "Created Plan #{plan}"
const planCreate = {
  code: 'tiered-tshirt-plan',
  name: 'Tiered T-shirt Plan',
  currencies: [
    {
      currency: 'USD',
      unitAmount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: 'tiered',
      tiers: [
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 20
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 15
            }
          ],
          ending_quantity: 999999999 // maximum value
        }
      ]
    }
  ]
}
const plan = await client.createPlan(planCreate)
console.log('Created Plan: ', plan.code)
PlanCreate planCreate = new PlanCreate();

planCreate.setName("Tiered T-shirt Plan");
planCreate.setCode("tiered-tshirt-plan");

List<PlanPricing> currencies = new ArrayList<PlanPricing>();
PlanPricing planPrice = new PlanPricing();
planPrice.setCurrency("USD");
planPrice.setUnitAmount(100.0f);
currencies.add(planPrice);

planCreate.setCurrencies(currencies);

List<AddOnCreate> addOns = new ArrayList<AddOnCreate>();
AddOnCreate addOn = new AddOnCreate();
addOn.setItemCode(item.getCode());
addOn.setDisplayQuantity(true);
addOn.setTierType("tiered");

List<Tier> tiers = new ArrayList<Tier>();
Tier tier = new Tier();
tier.setEndingQuantity(100);
List<Pricing> tierCurrencies = new ArrayList<Pricing>();
Pricing price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(20.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

tier = new Tier();
tier.setEndingQuantity(999999999); // maximum value
tierCurrencies = new ArrayList<Pricing>();
price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(15.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

addOn.setTiers(tiers);
addOns.add(addOn);

planCreate.setAddOns(addOns);

Plan plan = client.createPlan(planCreate);
System.out.println("Created Plan " + plan.getCode());
plan_create = {
    "name": "Tiered T-shirt Plan",
    "code": "tiered-tshirt-plan",
    "currencies": [{"currency": "USD", "unit_amount": 100}],
    "add_ons": [
        {
            "item_code": item.code,
            "display_quantity": True,
            "tier_type": "tiered",
            "tiers": [
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 20
                        }
                    ],
                    "ending_quantity": 100
                },
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 15
                        }
                    ],
                    "ending_quantity": 999999999 # maximum value
                }
            ],
        }
    ]
}
plan = client.create_plan(plan_create)
print("Created Plan %s" % plan)
var planReq = new PlanCreate()
{
    Name = "Tiered T-shirt Plan",
    Code = "tiered-tshirt-plan",
    Currencies = new List<PlanPricing>() {
        new PlanPricing() {
            Currency = "USD",
            UnitAmount = 100
        }
    },
    AddOns = new List<AddOnCreate>() {
        new AddOnCreate() {
            ItemCode = item.Code,
            DisplayQuantity = true,
            TierType = "tiered",
            Tiers = new List<Tier>() {
                new Tier() {
                    EndingQuantity = 100,
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 20
                        }
                    }
                },
                new Tier() {
                    EndingQuantity = 999999999, // maximum value
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 15
                        }
                    }
                }
            }
        }
    }
};
Plan plan = client.CreatePlan(planReq);
Console.WriteLine($"Created plan {plan.Code}");
$plan_create = array(
    "name" => "Tiered T-shirt Plan",
    "code" => "tiered-tshirt-plan",
    "currencies" => [
        array(
            "currency" => "USD",
            "unit_amount" => 100
        )
    ],
    "add_ons" =>[
        array(
            "item_code" => $item->getCode(),
            "display_quantity" => true,
            "tier_type" => "tiered",
            "tiers" => [
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 20
                        ),
                    ],
                    "ending_quantity" => 100
                ),
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 15
                        ),
                    ],
                    "ending_quantity" => 999999999 // maximum value
                )
            ]
        )
    ]
);

$plan = $client->createPlan($plan_create);

echo 'Created Plan:' . PHP_EOL;
var_dump($plan);

Using the Volume Pricing Model

The volume pricing model charges for each unit based on the price of the highest tier reached; for example, again there might be two tiers, one for quantities at or under 100 and another tier for quantities over that. If the total quantity is under 100, each item will be charged at the first tier price, otherwise each item (including the first 100) will be charged at the second tier price. Here is an example of how to set it up:

Ruby

Node.js

Python

Java

Dotnet

PHP

plan_create = {
  code: "volume-tshirt-plan",
  name: "Volume T-shirt Plan",
  currencies: [
    {
      currency: "USD",
      unit_amount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: "volume",
      tiers: [
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 20
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 15
            }
          ],
          ending_quantity: 999999999 # maximum value
        }
      ]
    }
  ]
}
plan = @client.create_plan(body: plan_create)
puts "Created Plan #{plan}"
const planCreate = {
  code: 'volume-tshirt-plan',
  name: 'Volume T-shirt Plan',
  currencies: [
    {
      currency: 'USD',
      unitAmount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: 'volume',
      tiers: [
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 20
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 15
            }
          ],
          ending_quantity: 999999999 // maximum value
        }
      ]
    }
  ]
}
const plan = await client.createPlan(planCreate)
console.log('Created Plan: ', plan.code)
PlanCreate planCreate = new PlanCreate();

planCreate.setName("Volume T-shirt Plan");
planCreate.setCode("volume-tshirt-plan");

List<PlanPricing> currencies = new ArrayList<PlanPricing>();
PlanPricing planPrice = new PlanPricing();
planPrice.setCurrency("USD");
planPrice.setUnitAmount(100.0f);
currencies.add(planPrice);

planCreate.setCurrencies(currencies);

List<AddOnCreate> addOns = new ArrayList<AddOnCreate>();
AddOnCreate addOn = new AddOnCreate();
addOn.setItemCode(item.getCode());
addOn.setDisplayQuantity(true);
addOn.setTierType("volume");

List<Tier> tiers = new ArrayList<Tier>();
Tier tier = new Tier();
tier.setEndingQuantity(100);
List<Pricing> tierCurrencies = new ArrayList<Pricing>();
Pricing price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(20.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

tier = new Tier();
tier.setEndingQuantity(999999999); // maximum value
tierCurrencies = new ArrayList<Pricing>();
price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(15.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

addOn.setTiers(tiers);
addOns.add(addOn);

planCreate.setAddOns(addOns);

Plan plan = client.createPlan(planCreate);
System.out.println("Created Plan " + plan.getCode());
plan_create = {
    "name": "Volume T-shirt Plan",
    "code": "volume-tshirt-plan",
    "currencies": [{"currency": "USD", "unit_amount": 100}],
    "add_ons": [
        {
            "item_code": item.code,
            "display_quantity": True,
            "tier_type": "volume",
            "tiers": [
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 20
                        }
                    ],
                    "ending_quantity": 100
                },
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 15
                        }
                    ],
                    "ending_quantity": 999999999 # maximum value
                }
            ],
        }
    ]
}
plan = client.create_plan(plan_create)
print("Created Plan %s" % plan)
var planReq = new PlanCreate()
{
    Name = "Volume T-shirt Plan",
    Code = "volume-tshirt-plan",
    Currencies = new List<PlanPricing>() {
        new PlanPricing() {
            Currency = "USD",
            UnitAmount = 100
        }
    },
    AddOns = new List<AddOnCreate>() {
        new AddOnCreate() {
            ItemCode = item.Code,
            DisplayQuantity = true,
            TierType = "volume",
            Tiers = new List<Tier>() {
                new Tier() {
                    EndingQuantity = 100,
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 20
                        }
                    }
                },
                new Tier() {
                    EndingQuantity = 999999999, // maximum value
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 15
                        }
                    }
                }
            }
        }
    }
};
Plan plan = client.CreatePlan(planReq);
Console.WriteLine($"Created plan {plan.Code}");
$plan_create = array(
    "name" => "Volume T-shirt Plan",
    "code" => "volume-tshirt-plan",
    "currencies" => [
        array(
            "currency" => "USD",
            "unit_amount" => 100
        )
    ],
    "add_ons" =>[
        array(
            "item_code" => $item->getCode(),
            "display_quantity" => true,
            "tier_type" => "volume",
            "tiers" => [
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 20
                        ),
                    ],
                    "ending_quantity" => 100
                ),
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 15
                        ),
                    ],
                    "ending_quantity" => 999999999 // maximum value
                )
            ]
        )
    ]
);

$plan = $client->createPlan($plan_create);

echo 'Created Plan:' . PHP_EOL;
var_dump($plan);

Using the Stairstep Model

The stairstep model charges a fixed price based on the highest tier reached; for example, there might be two tiers, one for quantities at or under 100 and another tier for quantities over that. If the total quantity is under 100 all items will be covered by a single charge at the total tier price (no matter what the quantity actually is within that range), otherwise all items will be covered by a single charged at the second tier price. Here is an example of how to set it up:

Ruby

Node.js

Python

Java

Dotnet

PHP

plan_create = {
  code: "stairstep-tshirt-plan",
  name: "Stairstep T-shirt Plan",
  currencies: [
    {
      currency: "USD",
      unit_amount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: "stairstep",
      tiers: [
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 2_000
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 4_000
            }
          ],
          ending_quantity: 999999999 # maximum value
        }
      ]
    }
  ]
}
plan = @client.create_plan(body: plan_create)
puts "Created Plan #{plan}"
const planCreate = {
  code: 'stairstep-tshirt-plan',
  name: 'Stairstep T-shirt Plan',
  currencies: [
    {
      currency: 'USD',
      unitAmount: 100
    }
  ],
  add_ons: [
    {
      item_code: item.code,
      display_quantity: true,
      tier_type: 'stairstep',
      tiers: [
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 2000
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: 'USD',
              unit_amount: 4000
            }
          ],
          ending_quantity: 999999999 // maximum value
        }
      ]
    }
  ]
}
const plan = await client.createPlan(planCreate)
console.log('Created Plan: ', plan.code)
PlanCreate planCreate = new PlanCreate();

planCreate.setName("Stairstep T-shirt Plan");
planCreate.setCode("stairstep-tshirt-plan");

List<PlanPricing> currencies = new ArrayList<PlanPricing>();
PlanPricing planPrice = new PlanPricing();
planPrice.setCurrency("USD");
planPrice.setUnitAmount(100.0f);
currencies.add(planPrice);

planCreate.setCurrencies(currencies);

List<AddOnCreate> addOns = new ArrayList<AddOnCreate>();
AddOnCreate addOn = new AddOnCreate();
addOn.setItemCode(item.getCode());
addOn.setDisplayQuantity(true);
addOn.setTierType("stairstep");

List<Tier> tiers = new ArrayList<Tier>();
Tier tier = new Tier();
tier.setEndingQuantity(100);
List<Pricing> tierCurrencies = new ArrayList<Pricing>();
Pricing price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(2000.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

tier = new Tier();
tier.setEndingQuantity(999999999); // maximum value
tierCurrencies = new ArrayList<Pricing>();
price = new Pricing();
price.setCurrency("USD");
price.setUnitAmount(4000.0f);
tierCurrencies.add(price);
tier.setCurrencies(tierCurrencies);
tiers.add(tier);

addOn.setTiers(tiers);
addOns.add(addOn);

planCreate.setAddOns(addOns);

Plan plan = client.createPlan(planCreate);
System.out.println("Created Plan " + plan.getCode());
plan_create = {
    "name": "Stairstep T-shirt Plan",
    "code": "stairstep-tshirt-plan",
    "currencies": [{"currency": "USD", "unit_amount": 100}],
    "add_ons": [
        {
            "item_code": item.code,
            "display_quantity": True,
            "tier_type": "stairstep",
            "tiers": [
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 2000
                        }
                    ],
                    "ending_quantity": 100
                },
                {
                    "currencies": [
                        {
                            "currency": "USD",
                            "unit_amount": 4000
                        }
                    ],
                    "ending_quantity": 999999999 # maximum value
                }
            ],
        }
    ]
}
plan = client.create_plan(plan_create)
print("Created Plan %s" % plan)
var planReq = new PlanCreate()
{
    Name = "Stairstep T-shirt Plan",
    Code = "stairstep-tshirt-plan",
    Currencies = new List<PlanPricing>() {
        new PlanPricing() {
            Currency = "USD",
            UnitAmount = 100
        }
    },
    AddOns = new List<AddOnCreate>() {
        new AddOnCreate() {
            ItemCode = item.Code,
            DisplayQuantity = true,
            TierType = "stairstep",
            Tiers = new List<Tier>() {
                new Tier() {
                    EndingQuantity = 100,
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 2000
                        }
                    }
                },
                new Tier() {
                    EndingQuantity = 999999999, // maximum value
                    Currencies = new List<Pricing>() {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 4000
                        }
                    }
                }
            }
        }
    }
};
Plan plan = client.CreatePlan(planReq);
Console.WriteLine($"Created plan {plan.Code}");
$plan_create = array(
    "name" => "Stairstep T-shirt Plan",
    "code" => "stairstep-tshirt-plan",
    "currencies" => [
        array(
            "currency" => "USD",
            "unit_amount" => 100
        )
    ],
    "add_ons" =>[
        array(
            "item_code" => $item->getCode(),
            "display_quantity" => true,
            "tier_type" => "stairstep",
            "tiers" => [
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 2000
                        ),
                    ],
                    "ending_quantity" => 100
                ),
                array(
                    "currencies" => [
                        array(
                            "currency" => "USD",
                            "unit_amount" => 4000
                        ),
                    ],
                    "ending_quantity" => 999999999 // maximum value
                )
            ]
        )
    ]
);

$plan = $client->createPlan($plan_create);

echo 'Created Plan:' . PHP_EOL;
var_dump($plan);

As you can see, the format for all three pricing models is the same, the amounts just have different meanings.

Step 4: Creating a Subscription

Creating a Subscription with the Item Add-on

Once a plan is created, you can then add it to an account as a subscription. Note that for the purposes of this cookbook, it assumes an account has already been created, but an account can also be created at this time; see the Subscription Create endpoint for more information. Any of the above plans can be used for this.

Ruby

Node.js

Python

Java

Dotnet

PHP

subscription_create = {
  plan_code: plan.code,
  currency: "USD",
  account: {
    code: account_code,
  },
  add_ons: [
    {
      code: item.code,
      quantity: 101
    }
  ]
}
subscription = @client.create_subscription(
  body: subscription_create
)
puts "Created Subscription #{subscription}"
const subscriptionReq = {
  planCode: plan.code,
  currency: `USD`,
  account: {
    code: accountCode
  },
  add_ons: [
    {
      code: item.code,
      quantity: 101
    }
  ]
}
const sub = await client.createSubscription(subscriptionReq)
console.log('Created subscription: ', sub.uuid)
SubscriptionCreate subscriptionCreate = new SubscriptionCreate();
AccountCreate accountCreate = new AccountCreate();
List<SubscriptionAddOn> subscriptionAddOns = new List<SubscriptionAddOn>();

accountCreate.setCode(accountCode);
subscriptionCreate.setCurrency("USD");
subscriptionCreate.setAccount(accountCreate);
subscriptionCreate.setPlanCode(plan.getCode());

SubscriptionAddOn subscriptionAddOn = new SubscriptionAddOn();
subscriptionAddOn.setCode(item.getCode());
subscriptionAddOn.setQuantity(101);
subscriptionAddOns.add(subscriptionAddOns);
subscriptionCreate.setSubscriptionAddOns(subscriptionAddOns);

Subscription subscription = client.createSubscription(subscriptionCreate);
System.out.println("Created Subscription with Id: " + subscription.getUuid());
sub_create = {
    "plan_code": plan.code,
    "currency": "USD",
    "account": {"code": account_code},
    "add_ons": [{"code": item.code, "quantity": 101}],
}
sub = client.create_subscription(sub_create)
print("Created Subscription %s" % sub)
var subReq = new SubscriptionCreate()
{
    Currency = "USD",
    Account = new AccountCreate()
    {
        Code = accountCode
    },
    PlanCode = plan.Code,
    AddOns = new List<SubscriptionAddOnCreate>() {
        new SubscriptionAddOnCreate() {
            Code = item.Code,
            Quantity = 101
        }
    }
};
Subscription subscription = client.CreateSubscription(subReq);
Console.WriteLine($"Created Subscription with Id: {subscription.Uuid}");
$sub_create = array(
    "plan_code" => $plan->getCode(),
    "currency" => "USD",
    "account" => array(
        "code" => $account_code
    ),
    "add_ons" => [
        array(
            "code" => $item->getCode(),
            "quantity" => 101
        )
    ]
);

$subscription = $client->createSubscription($sub_create);

echo 'Created Subscription:' . PHP_EOL;
var_dump($subscription);