• Content

Usage Based Billing

Overview

In this guide we’ll go over using add-ons with plans and subscriptions in combination with the various usage based billing models and how to log usage. 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 a Plan with Usage Plan Add-ons

For this guide we’re going to create a plan add-on we can use to subscribe to and log usage against. To do that, we’ll use the Create an add-on endpoint. When creating a usage plan add-on, you can charge by a percentage of usage logged, a unit amount per usage logged, or a quantity based pricing model for usage logged. In this guide, we will be creating two plans each with their own usage add-on; one using usage percentage and one with quantity based pricing.

There are three kinds of quantity based pricing models that can be used: tiered, volume, and stairstep. We will only be using the tiered model in this guide. Please see the documentation for more information about the quantity based pricing models.

To give ourselves a concrete example, let’s imagine a scenario for each of the usage add-ons we will be creating. In the quantity based pricing usage example, we will be creating a quantity based pricing usage add-on for a video streaming platform that gives 100 GBs of data for free and then charges for overage using a tiered quantity based pricing model.

The tiered pricing model charges for each unit based on the price of its corresponding tier; for the example above, there will be two tiers, one for quantities at or under 100, which is $0/GB and one for anything beyond that which is $10/GB. 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.

For the percentage usage example, we will be creating a percentage usage add-on for a payments company that takes 1% of each merchant’s monthly Total Payment Volume.

Each of these usage plan add-ons will be using a different measured unit which can be created through the admin console or using a client or the api with Create a measured unit. For the tiered pricing usage add-on, we will use a measured unit that represents GB and for the percentage usage add-on, it will be a measured unit that represents Total Payment Volume. We can create a plan with these add-ons as follows:

Python

Dotnet

Ruby

PHP

streaming_plan_create = {
  code: streaming_plan_code,
  name: "Tiered Streaming Data Plan",
  currencies: [
    {
      currency: "USD",
      unit_amount: 100
    }
  ],
  add_ons: [
    {
      name: "streaming data",
      code: "streaming_data",
      display_quantity: true,
      tier_type: "tiered",
      add_on_type: "usage",
      usage_type: "price",
      measured_unit_name: gigabytes_unit_name,
      tiers: [
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 0
            }
          ],
          ending_quantity: 100
        },
        {
          currencies: [
            {
              currency: "USD",
              unit_amount: 10
            }
          ],
          # This last tier"s ending_quantity can be set to the maximum
          # value of `999999999`.
          # If omitted, ending_quantity will default to `999999999`.
          ending_quantity: 999999999
        }
      ]
    }
  ]
}

payments_plan_create = {
  code: payments_plan_code,
  name: "Payments Plan",
  currencies: [
    {
      currency: "USD",
      unit_amount: 100
    }
  ],
  add_ons: [
    {
      name: "Payments",
      code: "payments",
      display_quantity: true,
      add_on_type: "usage",
      measured_unit_name: total_payment_volume_name,
      usage_type: "percentage",
      usage_percentage: 1
    }
  ]
}
streaming_plan = @client.create_plan(body: streaming_plan_create)
puts "Created Streaming Plan #{streaming_plan}"

payments_plan = @client.create_plan(body: payments_plan_create)
puts "Created Payments Plan #{payments_plan}"
streaming_plan_create = {
  "code": streaming_plan_code,
  "name": "Tiered Streaming Data Plan",
  "currencies": [ { "currency": "USD", "unit_amount": 100 } ],
  "add_ons": [
    {
      "name": "streaming data",
      "code": "streaming_data",
      "display_quantity": True,
      "tier_type": "tiered",
      "add_on_type": "usage",
      "usage_type": "price",
      "measured_unit_name": gigabytes_unit_name,
      "tiers": [
        {
          "currencies": [
            { "currency": "USD", "unit_amount": 0 } ,
          ],
          "ending_quantity" : 100
        },
        {
          "currencies": [
            { "currency": "USD", "unit_amount": 10 }
          ],
          # This last tier's ending_quantity can be set to the maximum
          # value of `999999999`. 
          # If omitted, ending_quantity will default to `999999999`.
          "ending_quantity": 999999999
        }
      ]
    }
  ]
}

payments_plan_create = {
  "code": payments_plan_code,
  "name": "Payments Plan",
  "currencies": [ { "currency": "USD", "unit_amount": 100 } ],
  "add_ons": [
    {
      "name": "Payments",
      "code": "payments",
      "display_quantity": True,
      "add_on_type": "usage",
      "measured_unit_name": total_payment_volume_name,
      "usage_type": "percentage",
      "usage_percentage": 1
    }
  ]
}

streaming_plan = client.create_plan(streaming_plan_create)
print("Created Streaming Plan %s" % streaming_plan)

payments_plan = client.create_plan(payments_plan_create)
print("Created Payments Plan %s" % payments_plan)
var streamingPlanCreate = new PlanCreate()
{
    Code = streamingPlanCode,
    Name = "Tiered Streaming Data Plan",
    Currencies = new List<PlanPricing>()
    {
        new PlanPricing() {
            Currency = "USD",
            UnitAmount = 100
        }
    },
    AddOns = new List<AddOnCreate>()
    {
        new AddOnCreate()
        {
            Name = "Streaming Data",
            Code = "streaming_data",
            DisplayQuantity = true,
            TierType = "tiered",
            AddOnType = "usage",
            UsageType = "price",
            MeasuredUnitName = gigabytesUnitName,
            Tiers = new List<Tier>()
            {
                new Tier()
                {
                    Currencies = new List<Pricing>()
                    {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 0
                        }
                    },
                    EndingQuantity = 100
                },
                new Tier()
                {
                    Currencies = new List<Pricing>()
                    {
                        new Pricing() {
                            Currency = "USD",
                            UnitAmount = 10
                        }
                    },
                    // This last tier's ending_quantity can be set to the maximum
                    // value of `999999999`.
                    // If omitted, ending_quantity will default to `999999999`.
                    EndingQuantity = 999999999
                }
            }
        }
    }
};
var streamingPlan = client.CreatePlan(streamingPlanCreate);
System.Console.WriteLine($"Created Streaming Plan {streamingPlan.Code}");

var paymentsPlanCreate = new PlanCreate()
{
    Code = paymentsPlanCode,
    Name = "Payments Plan",
    Currencies = new List<PlanPricing>()
    {
        new PlanPricing() {
            Currency = "USD",
            UnitAmount = 100
        }
    },
    AddOns = new List<AddOnCreate>()
    {
        new AddOnCreate()
        {
            Name = "Payments",
            Code = "payments",
            DisplayQuantity = true,
            AddOnType = "usage",
            MeasuredUnitName = totalPaymentVolumeUnitName,
            UsageType = "percentage",
            UsagePercentage = 1
        }
    }
};
var paymentsPlan = client.CreatePlan(paymentsPlanCreate);
System.Console.WriteLine($"Created Payments Plan {paymentsPlan.Code}");
$streaming_plan_create = [
  "code" => $streaming_plan_code,
  "name" => "Tiered Streaming Data Plan",
  "currencies" => [
    [
      "currency" => "USD",
      "unit_amount" => 100
    ]
  ],
  "add_ons" => [
    [
      "name" => "streaming data",
      "code" => "streaming_data",
      "display_quantity" => true,
      "tier_type" => "tiered",
      "add_on_type" => "usage",
      "usage_type" => "price",
      "measured_unit_name" => $gigabytes_unit_name,
      "tiers" => [
        [
          "currencies" => [
            [
              "currency" => "USD",
              "unit_amount" => 0
            ]
          ],
          "ending_quantity" => 100
        ],
        [
          "currencies" => [
            [
              "currency" => "USD",
              "unit_amount" => 10
            ]
          ],
          // This last tier"s ending_quantity can be set to the maximum
          // value of `999999999`.
          // If omitted, ending_quantity will default to `999999999`.
          "ending_quantity" => 999999999
        ]
      ]
    ]
  ]
];

$payments_plan_create = [
  "code" => $payments_plan_code,
  "name" => "Payments Plan",
  "currencies" => [
    [
      "currency" => "USD",
      "unit_amount" => 100
    ]
  ],
  "add_ons" => [
    [
      "name" => "Payments",
      "code" => "payments",
      "display_quantity" => true,
      "add_on_type" => "usage",
      "measured_unit_name" => $total_payment_volume_name,
      "usage_type" => "percentage",
      "usage_percentage" => 1
    ]
  ]
];
$streaming_plan = $client->createPlan($streaming_plan_create);
echo "Created Streaming Plan {$streaming_plan->getId()}" . PHP_EOL;

$payments_plan = $client->createPlan($payments_plan_create);
echo "Created Payments Plan {$payments_plan->getId()}" . PHP_EOL;

Step 2: Creating a Subscription with the Usage Plan Add-ons

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. We will be creating a subscription that has both of the usage add-ons we created earlier.

Python

Dotnet

Ruby

PHP

streaming_subscription_create = {
  plan_code: streaming_plan.code,
  currency: "USD",
  account: {
    code: account_code,
  },
  add_ons: [
    {
      code: "streaming_data",
    }
  ]
}

payments_subscription_create = {
  plan_code: payments_plan.code,
  currency: "USD",
  account: {
    code: account_code,
  },
  add_ons: [
    {
      code: "payments",
    }
  ]
}

streaming_subscription = @client.create_subscription(
  body: streaming_subscription_create
)
puts "Created Subscription #{streaming_subscription}"

payments_subscription = @client.create_subscription(
  body: payments_subscription_create
)
puts "Created Subscription #{payments_subscription}"
streaming_subscription_create = {
  "plan_code": streaming_plan.code,
  "currency": "USD",
  "account": { "code": account_code },
  "add_ons": [
    { "code": "streaming_data" }
  ]
}

payments_subscription_create = {
  "plan_code": payments_plan.code,
  "currency": "USD",
  "account": { "code": account_code },
  "add_ons": [
    { "code": "payments" }
  ]
}

streaming_subscription = client.create_subscription(streaming_subscription_create)
print("Created Subscription %s" % streaming_subscription)

payments_subscription = client.create_subscription(payments_subscription_create)
print("Created Subscription %s" % payments_subscription)
var streamingSubscriptionCreate = new SubscriptionCreate()
{
    PlanCode = streamingPlan.Code,
    Currency = "USD",
    Account = new AccountCreate()
    {
        Code = accountCode
    },
    AddOns = new List<SubscriptionAddOnCreate>()
    {
        new SubscriptionAddOnCreate()
        {
            Code = "streaming_data"
        }
    }
};

var streamingSubscription = client.CreateSubscription(streamingSubscriptionCreate);
System.Console.WriteLine($"Created Subscription {streamingSubscription.Id}");

var paymentsSubscriptionCreate = new SubscriptionCreate()
{
    PlanCode = paymentsPlan.Code,
    Currency = "USD",
    Account = new AccountCreate()
    {
        Code = accountCode
    },
    AddOns = new List<SubscriptionAddOnCreate>()
    {
        new SubscriptionAddOnCreate()
        {
            Code = "payments"
        }
    }
};

var paymentsSubscription = client.CreateSubscription(paymentsSubscriptionCreate);
System.Console.WriteLine($"Created Subscription {paymentsSubscription.Id}");
$streaming_subscription_create = [
  "plan_code" => $streaming_plan->getCode(),
  "currency" => "USD",
  "account" => [
    "code" => $account_code,
  ],
  "add_ons" => [
    [
      "code" => "streaming_data",
    ]
  ]
];

$payments_subscription_create = [
  "plan_code" => $payments_plan->getCode(),
  "currency" => "USD",
  "account" => [
    "code" => $account_code,
  ],
  "add_ons" => [
    [
      "code" => "payments",
    ]
  ]
];

$streaming_subscription = $client->createSubscription(
  $streaming_subscription_create
);
echo "Created Subscription {$streaming_subscription->getId()}" . PHP_EOL;

$payments_subscription = $client->createSubscription(
  $payments_subscription_create
);
echo "Created Subscription {$payments_subscription->getId()}" . PHP_EOL;

Step 3: Logging Usage for each of the Usage Subscription Add-ons

Once a subscription with a usage subscription add-on is created, you can log usage for it. Usage records can be logged in real-time or aggregated into hourly or daily records based on what works best with your systems. The closer to real-time you get with logging your usage, the cleaner your invoices will look. The usage_timestamp is when to apply the usage and the recording_timestamp is when the usage was recorded in your system. Please see the documentation for more information. For the purposes of this example, we will omit the usage_timestamp and recording_timestamp which will default them to the current time.

Remember, for the quantity based pricing usage subscription add-on, this usage will correllate with GBs and for the percentage usage subscription add-on, it will represent Total Payment Volume.

Python

Dotnet

Ruby

PHP

streaming_usage_create = {
  amount: 3,
  merchant_tag: "Order ID: 6350985309458302",
}

payments_usage_create = {
  amount: 54500,
  merchant_tag: "Order ID: 4939853977878713",
}

streaming_usage = @client.create_usage(subscription_id: streaming_subscription.id,
                                       add_on_id: "code-streaming_data",
                                       body: streaming_usage_create)
puts "Created Usage #{streaming_usage}"

payments_usage = @client.create_usage(subscription_id: payments_subscription.id,
                                      add_on_id: "code-payments",
                                      body: payments_usage_create)
puts "Created Usage #{payments_usage}"
streaming_usage_create = {
  "amount": 3,
  "merchant_tag": "Order ID: 6350985309458302"
}

payments_usage_create = {
  "amount": 54500,
  "merchant_tag": "Order ID: 4939853977878713"
}

streaming_usage = client.create_usage(
  streaming_subscription.id, 
  "code-streaming_data",
  streaming_usage_create
)
print("Created Usage %s" % streaming_usage)

payments_usage = client.create_usage(
  payments_subscription.id,
  "code-payments",
  payments_usage_create
)
print("Created Usage %s" % payments_usage)
var streamingUsageCreate = new UsageCreate()
{
    Amount = 3,
    MerchantTag = "Order ID: 6350985309458302"
};

var streamingUsage = client.CreateUsage(
    subscriptionId: streamingSubscription.Id,
    addOnId: "code-streaming_data",
    body: streamingUsageCreate
);
System.Console.WriteLine($"Created Usage {streamingUsage.Id}");

var paymentsUsageCreate = new UsageCreate()
{
    Amount = 54500,
    MerchantTag = "Order ID: 4939853977878713"
};

var paymentsUsage = client.CreateUsage(
    subscriptionId: paymentsSubscription.Id,
    addOnId: "code-payments",
    body: paymentsUsageCreate
);
System.Console.WriteLine($"Created Usage {paymentsUsage.Id}");
$streaming_usage_create = [
  "amount" => 3,
  "merchant_tag" => "Order ID: 6350985309458302",
];

$payments_usage_create = [
  "amount" => 54500,
  "merchant_tag" => "Order ID: 4939853977878713",
];

$streaming_usage = $client->createUsage(
  $streaming_subscription->getId(),
  "code-streaming_data",
  $streaming_usage_create
);
echo "Created Usage {$streaming_usage->getId()}" . PHP_EOL;

$payments_usage = $client->createUsage(
  $payments_subscription->getId(),
  "code-payments",
  $payments_usage_create
);
echo "Created Usage {$payments_usage->getId()}" . PHP_EOL;

Step 4: Updating a Usage record for each of the Usage Subscription Add-ons

Once you have logged a usage record, you can choose to update it later. If it has already been billed, you can only update the merchant_tag. Otherwise, you can update any of the fields. In this example, we will assume it has not yet been billed and will only update the amount.

Python

Dotnet

Ruby

PHP

streaming_usage_update = {
  amount: 2
}

payments_usage_update = {
  amount: 44500
}

updated_streaming_usage = @client.update_usage(usage_id: streaming_usage.id,
                                               body: streaming_usage_update)
puts "Updated streaming usage #{updated_streaming_usage}"

updated_payments_usage = @client.update_usage(usage_id: payments_usage.id,
                                              body: payments_usage_update)
puts "Updated streaming usage #{updated_payments_usage}"
streaming_usage_update =  { "amount": 2 }
payments_usage_update = { "amount": 44500 }

updated_streaming_usage = client.update_usage(
  streaming_usage.id,
  streaming_usage_update
)
print("Updated streaming usage %s" % updated_streaming_usage)

updated_payments_usage = client.update_usage(
  payments_usage.id,
  payments_usage_update
)
print("Updated streaming usage %s" % updated_payments_usage)
var streamingUsageUpdate = new UsageCreate()
{
    Amount = 2
};
var updatedStreamingUsage = client.UpdateUsage(
    usageId: streamingUsage.Id,
    body: streamingUsageUpdate
);
System.Console.WriteLine($"Update streaming usage {updatedStreamingUsage.Id}");

var paymentsUsageUpdate = new UsageCreate()
{
    Amount = 44500
};
var updatedPaymentsUsage = client.UpdateUsage(
    usageId: paymentsUsage.Id,
    body: paymentsUsageUpdate
);
System.Console.WriteLine($"Update payments usage {updatedPaymentsUsage.Id}");
$streaming_usage_update = [
  "amount" => 2
];

$payments_usage_update = [
  "amount" => 44500
];

$updated_streaming_usage = $client->updateUsage(
  $streaming_usage->getId(),
  $streaming_usage_update
);
echo "Updated streaming usage {$updated_streaming_usage->getId()}" . PHP_EOL;

$updated_payments_usage = $client->updateUsage(
  $payments_usage->getId(),
  $payments_usage_update
);
echo "Updated streaming usage {$updated_payments_usage->getId()}" . PHP_EOL;