Skip to main content

Billing Usage

Zuora

Billing Usage

In this walkthrough, we're going to follow two Zuora API users, Boris and Natasha, as they upload usage records in preparation for a bill run. Someone else created the rate plans with usage charges and customers subscribed to these rate plans some time ago. You can use Boris and Natasha's code samples to customize their actions to fit your own needs.

Learning Path for Advanced API Users

If you are an advanced API user, then you might want to review only Implementation sections of this walkthrough to get a quick list of the steps for uploading usage data without the additional details:

Usage and Tracking Metered Resources

Usage is the amount of resources a customer uses. You track the usage of metered resources, then charge based on the amount that your customers consume.

You can charge for usage by adding usage-based fees to product rate plans, tracking usage, then uploading usage records to Zuora. 

You can set up rate plans to include all types of charges: one-time fees, recurring fees, and usage fees. Of these charges, usage-based fees require you to meter your customers' usage and upload that data to Zuora so that Zuora can calculate the charges.

Billing usage allows you to bill users according to their actual use of your resources; when their usage levels vary, so do their bills. As such, usage is always billed in arrears. For example, you bill in November for usage consumed in October, or you bill in the fourth quarter for usage consumed in the third quarter. You can bill usage on a recurring, monthly, quarterly, semi-annual, and annual basis.

If the number of usage records that you need to upload is 50 or fewer, then you can use the create() call with a Usage object to do the upload. If you need to upload a larger number of usage records, then you need to create a CSV file of 4MB or smaller, and upload that file with the create() call and an Import object.

Upload Best Practices

Consider the size of your upload, and consider your company's best practices for usage data association before you start an upload.

Upload size

There are two ways to upload usage data, both using the create() call. You can use the Usage object to send up to 50 records in a single call. That method works well when you don't have a lot of data to upload. However, the method is cumbersome with more than 50 records because you need to do the upload through a series of bath calls. When you have a large set of data, especially more than 50 records, use the Import object instead of the Usage object.

This walkthrough follows both methods of uploading usage. To use the Usage object, follow Boris. To use the Import object, follow Natasha.

Associate Usage Records with Accounts, Charges, or Subscriptions

Widget Mail has a best practice require to connect usage data with a specific subscription. To meet this requirement, Boris and Natasha need to use either the SubscriptionId or the SubscriptionNumber field for each Usage object.

You might also have requirements to specific subscriptions or charges. 

Use the ChargeId or ChargeNumber field to connect usage to its charge. Use SubscriptionId or SubscriptionNumber to apply usage data to all charges with the same unit of measure in the subscription.

If you omit all of the fields ChargeIdChargeNumberSubscriptionId, and SubscriptionName, then usage is billed against all charges associated with the account that have the same UOM values. The two charge-related fields, ChargeId and ChargeNumber, connect usage with a specific charge. The two subscription-related fields, SubscriptionId and SubscriptionName, connect usage with a specific subscription.

You only need one charge-related field or one subscription-related field to connect the usage data to a specific charge or subscription; you don't need both the ID and the number fields.

Upload a Small Number of Usage Records

Boris is a Zuora API user who works for Widget Mail, which provides an email infrastructure in the cloud.  His company offers plans that include both recurring fees and usage-based fees. Monthly recurring fees include a base number of emails with a per-email tiered set of charges over this default amount.

Boris needs to import a set of usage records so that the data is ready for a scheduled bill run.

Solution

Boris has three usage records to upload. He decides to use a create() call with the Usage object, which can send up to 50 records in a single call. 

Preparation

Boris gathers the following information about each record:

  • Account ID (AccountId): required by Zuora
  • Quantity of units used (Quantity): required by Zuora
  • Units of measure (UOM): required by Zuora
  • Start date and time of usage (StartDateTime): required by Zuora
  • End date and time of usage (EndDateTime)
  • Subscription ID (SubscriptionId)

Each of these items corresponds to a field in the Usage object that he needs to pass in the create() call. Not all of these bits of information are required by Zuora, but he needs to provide optional fields to meet the requirements of Widget Mail's own processes. Your company might have its own best practices that require you to use fields that are not otherwise required by the API.

Field Descriptions

The example values are the values that Boris uses in his code sample. If you use his code samples, then substitute your own values. Because Boris is uploading three sets of usage data, he is creating three Usage objects. Each object has its own set of values.

Name Required? Description
AccountId required

The ID of the account associated with the usage data. Boris must provide a value for either the AccountId field or the AccountNumber field so that the Zuora API knows which account the usage record applies to.

Type: zns:ID
Character limit: 32
Values: a valid account ID

Example values:

  • 4028z596336e2e6g1233773ge7c5011c8
  • 4028g485225d1d5f01247692fd6b249j9
  • 4028e718548p7h9b73401849fd6b249c3
EndDateTime optional The end date of a range of time during which usage is tracked. The Zuora API doesn't require this field because it doesn't need this field to calculate usage. However, Widget Mail uses this field for its reports so Widget Mail's best practices require Boris to include this value.

Type

  • date supported as of WSDL version 69+
  • dateTime supported through WSDL version 68

Character limit: 29
Valuesa valid date and time value

Example values

  • 2012-11-30T15:00:00
  • 2012-11-30T15:00:00
  • 2012-11-30T15:00:00
Quantity required Indicates the number of units used. This number is the point of uploading usage data because it tells Zuora how much of a metered rescource was used.

Type: decimal
Character limit:16
Values: a valid decimal amount equal to or greater than 0

Example values

  • 2548533
  • 8944
  • 26541
StartDateTime required The start date of a range of time during which usage is tracked.

Type: dateTime
Character limit: 29
Valuesa valid date and time value

Example values

  • 2012-10-01T15:00:00
  • 2012-10-01T15:00:00
  • 2012-10-01T15:00:00
SubscriptionId optional The ID of the subscription that contains the fees related to the usage data. This field connects usage with a specific subscription. Widget Mail's best practices require Boris to connect usage to specific subscriptions. 

Type: zns:ID
Character limit: 32
Values: a valid subscription ID

Example values

  • 4028e6962eb8004a012ebd076551723a
  • 402892ca29f3191a0129f31a86ad00ac
  • 4028e6992276b15101228441bf7531ce
UOM required Specifies the units to measure usage. Units of measure are configured in the web-based UI. Your values depend on your configuration in Z-Billing > Settings.

Type: string
Character limit
Valuesa valid unit of measure

Example values

  • Each
  • Each
  • Each

Implementation with the Usage object

Boris sends his create() call with three Usage objects.

Code sample: create three Usage objects

<ns1:create>
<ns1:zObjects xsi:type="ns2:Usage">
   <ns2:AccountId>4028z596336e2e6g1233773ge7c5011c8</ns2:AccountId>
   <ns2:EndDateTime>2012-11-30T15:00:00</ns2:EndDateTime>
   <ns2:Quantity>2548533</ns2:Quantity>
   <ns2:StartDateTime>2012-10-01T15:00:00</ns2:StartDateTime>
   <ns2:SubscriptionId>4028e6962eb8004a012ebd076551723a</ns2:SubscriptionId>
   <ns2:UOM>Each</ns2:UOM>
</ns1:zObjects>
<ns1:zObjects xsi:type="ns2:Usage">
   <ns2:AccountId>4028g485225d1d5f01247692fd6b249j9</ns2:AccountId>
   <ns2:EndDateTime>2012-11-30T15:00:00</ns2:EndDateTime>
   <ns2:Quantity>8944</ns2:Quantity>
   <ns2:StartDateTime>2012-10-01T15:00:00</ns2:StartDateTime>
   <ns2:SubscriptionId>402892ca29f3191a0129f31a86ad00ac</ns2:SubscriptionId>
   <ns2:UOM>Each</ns2:UOM>
</ns1:zObjects>
<ns1:zObjects xsi:type="ns2:Usage">
   <ns2:AccountId>4028e718548p7h9b73401849fd6b249c3</ns2:AccountId>
   <ns2:EndDateTime>2012-11-30T15:00:00</ns2:EndDateTime>
   <ns2:Quantity>26541</ns2:Quantity>
   <ns2:StartDateTime>2012-10-01T15:00:00</ns2:StartDateTime>
   <ns2:SubscriptionId>4028e6992276b15101228441bf7531ce</ns2:SubscriptionId>
   <ns2:UOM>Each</ns2:UOM>
</ns1:zObjects>
</ns1:create>

After successful completion of the call, Boris receives a response that includes the IDs of the new Usage objects. Your values differ from his because IDs are unique.

Upload a Large Number of Usage Records

Natasha is a Zuora API user who works for Widget Mail, which provides an email infrastructure in the cloud.  Her company offers plans that include both recurring fees and usage-based fees. Monthly recurring fees include a base number of emails with a per-email tiered set of charges over this default amount.

Natasha needs to import a large set of usage records so that the data is ready for a scheduled bill run. 

Solution

Natasha has a large set of usage data, so she decides to use a create() call with the Import object, which can load a CSV file up to 4MB in a single call.

The number of records that can fit in a 4MB CSV file depends on the size of your dataset. If you are using all of the fields at maximum character size, then your number of records is smaller than someone else's number who is using just the Zuora-required fields.

Preparation

Natasha receives a CSV file that contains all the information she needs about each record. Each field in the file corresponds to a field that Zuora needs to record usage. These fields have similar names as the fields that Boris used when he uploaded a small number of records with the Usage object, but they aren't identical. Check the field names in your CSV file to make sure they're correct.

  • Account ID (ACCOUNT_ID): required by Zuora
  • Units of measure (UOM): required by Zuora
  • Quantity of units used (QTY): required by Zuora
  • Start date of usage (StartDate): required by Zuora
  • End date of usage (EndDate)
  • Subscription ID (SUBSCRIPTION_ID)
  • Charge ID (CHARGE_ID)
  • Description (DESCRIPTION)

Not all of these bits of information are required by Zuora. Natasha omits data for the charge ID and description fields because they are optional in Zuora and Widget Mail's best practices don't use them. However, Natasha does use the fields for the subscription ID and end date because these fields, while optional in Zuora, are requirements of Widget Mail's own processes. Your company might have its own best practices that require you to use fields that are not otherwise required by the API.

Field descriptions

The example values are the values that Natasha uses in her code sample. If you use her code samples, then substitute your own values.

These field descriptions are specifically for the Import object, not the fields in Natasha's CSV file.

Name Required? Description
FileContent required

A Base64-encoded file that contains the contents of the import.

Type: DataHandler
Character limit
Values: Base64-encoded file

Example value: zuora-usage.csv

ImportType required

The type of item that you want to import. Natasha is importing usage records.

Type: string (enum)
Character limit: 7
ValuesUsage

Example value: Usage

Name required A descriptive name for the import operation. Natasha calls her import Nov2012 because it's Widget Mail's best practice to name usage imports by the name of the month of the usage data's date range. Your value depends on your own policies. You can leave the field value empty to use the default, import <ImportType_value>.

Type: string
Character limit: 100
Values: null or a string of 100 characters or fewer

Example value: Nov2012

Implementation with the Import object

Natasha sends her create() call for one Import object to import a single CSV file that contains many usage records.

Code sample: create one Import object

<ns1:create>
 <ns1:zObjects xsi:type="ns2:Import">
   <ns2:FileContent>zuora-usage.csv</ns2:FileContent>
   <ns2:ImportType>Usage</ns2:ImportType>
   <ns2:Name></ns2:Name>
 </ns1:zObjects>
</ns1:create>

After successful completion of the call, Natasha receives a response that includes the ID of the new Import object. Your value differs from hers because IDs are unique.

What next?

Boris and Natasha have uploaded all of the usage records needed for the next bill run. They can update the individual usage records if changes are needed. Otherwise, the usage records are ready to be billed during the next bill run or individual invoice generation.