Set up your product catalog

Quickstart API
v1 API

Products describe the goods or services you offer to your customers. Each product has a unique ID and SKU.

Plans are collections of prices. While products help you track inventory or provisioning, plans and prices help you track payment terms.

Prices determine how you charge your customers for the product they subscribe to. Since products allow you to track inventory and provisioning you can change prices without having to change your provisioning scheme.

Create products, plans, and prices

Different physical goods or levels of service are represented by products, and pricing and billing cycle options are represented by prices grouped together in a plan. For example, you offer a single "Gold" product, and it has two plans - monthly plan and yearly plan. Each plan has a price for $100 for the monthly plan, and $1000 year for the yearly plan.

You can easily create prices without explicitly specifying the type of the price. Based on the fields you specified, the type of the price is automatically identified and determined. For example, if you want to create per-unit prices, you only need to specify the following required fields, then Zuora will automatically create a per-unit price for you:

  • unit_of_measure
  • unit_amounts
If you want to create flat-fee prices, you simply need to specify the amounts field.

To create a usage-based price that charges your customers based on their usage of your products or service, the required fields you should specify only include:

  • unit_of_measure
  • unit_amounts
  • recurring> usage

Create flat fee prices

Many businesses offer their customers a choice of service options, a model called good-better-best. If you want to offer three different service levels: Basic, Growth, and Enterprise, and offer a monthly or a yearly price for each service level. The following table is what that would look like on Zuora:

BasicGrowthEnterprise
$10/mo. or $100/yr.$20/mo. or $200/yr.$75/mo. or $850/yr.

For these products, we can break down them as follows:

ProductProductProduct
BasicGrowthEnterprise
Plan 1Plan 1Plan 1
Basic MonthlyGrowth MonthlyEnterprise Monthly
Price 1Price 1Price 1
$10 monthly$20 monthly$75 monthly
Plan 2Plan 2Plan 2
Basic YearlyGrowth YearlyEnterprise Yearly
Price 2Price 2Price 2
$100 yearly$220 yearly$850 yearly

The following code examples show how to create a good-better-best model on Zuora for the Basic product and its plans and prices. You can reference the following code samples and create products, plans, and prices for Growth and Enterprise products.

  1. Create a Basic product for the Basic service level.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/products"
    -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
    -H "Content-Type: application/json" 
    -d '{ 
        "name": "Basic",
        "description": "Basic Product", 
        "start_date": "2022-04-01", 
        "end_date": "2032-04-01"
    }'
    Copy
    Copied
    ProductCreateRequest productRequest = new ProductCreateRequest()
        .name('Basic')
        .startDate('2022-04-01')
        .endDate('2032-04-01')
        .description('Basic Product');
    
    Product basicProduct = zuoraClient.products().createProduct(productRequest);
    Copy
    Copied
    const productRequest = {
        name: 'Basic',
        description: 'Basic Product', 
        start_date: '2022-04-01', 
        end_date: '2032-04-01',
    };
    
    const basicProduct = await zuoraClient.products.createProduct(productRequest);
  1. Create a Basic Monthly plan for the Basic product.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/plans"
         -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
         -H "Content-Type: application/json" 
         -d '{
              "name": "Basic Monthly",
              "product_id": "2c94a116ef504f65b5ef1e9e9e8377e1",
              "description": "Monthly plan of the Basic product", 
              "start_date": "2022-04-01", 
              "end_date": "2032-04-01"
            }'
    Copy
    Copied
    PlanCreateRequest monthlyPlanRequest = new PlanCreateRequest()
        .name('Basic Monthly')
        .productId(basicProduct.getId())
        .startDate('2022-04-01')
        .endDate('2032-04-01')
        .description('Monthly plan of the Basic product')
          
    Plan basicMonthlyPlan = zuoraClient.plans().createPlan(monthlyPlanRequest);
    Copy
    Copied
    const monthlyPlanRequest = {
        name: 'Basic Monthly',
        product_id: basicProduct.id,
        description: 'Monthly plan of the Basic product', 
        start_date: '2022-04-01', 
        end_date: '2032-04-01',
    };
    
    const basicMonthlyPlan = await zuoraClient.plans.createPlan(monthlyPlanRequest);
  2. Create a Basic Monthly Fee price for the Basic Monthly plan.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/prices"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
            "name": "Basic Monthly Fee",
            "plan_id": "2c921528ef504f65b5ef1e9e9e8362f2",
            "description": "Monthly fee of the Basic Monthly plan", 
            "amounts": {
                "USD": 10
            },
            "recurring": {
                "on": "account_cycle_date",
                "interval": "month",
                "timing": "in_advance"
            },
            "start_event": "contract_effective", 
            "price_base_interval": "billing_period",
            "deferred_revenue_accounting_code": "Credit Card",
            "recognized_revenue_accounting_code": "Credit Card"
        }' 
    Copy
    Copied
    Map<String, BigDecimal> monthlyAmounts = new HashMap<String, BigDecimal>(){{
        put("USD", new BigDecimal("10.0"));
    }};
    
    PriceCreateRequest monthlyPriceRequest = new PriceCreateRequest()
        .amounts(monthlyAmounts)
        .name("Basic Monthly Fee")
        .priceBaseInterval(PriceBaseIntervalEnum.BILLING_PERIOD)
        .planId(basicMonthlyPlan.getId())
        .description("Monthly fee of the Basic Monthly plan")
        .recurring(new Recurring()
            .on(OnEnum.ACCOUNT_CYCLE_DATE)
            .interval(IntervalEnum.MONTH)
            .timing(TimingEnum.ADVANCE)
        )
        .startEvent(StartEventEnum.CONTRACT_EFFECTIVE)
        .deferredRevenueAccountingCode("Credit Card")
        .recognizedRevenueAccountingCode("Credit Card");
    
    Price baseMonthlyPrice = zuoraClient.prices().postPrice(monthlyPriceRequest);
    Copy
    Copied
    const monthlyPriceRequest = {
        name: 'Basic Monthly Fee',
        amounts: {
            USD: 10
        },
        recurring: {
            on: 'account_cycle_date',
            interval: 'month',
            timing: 'in_advance',
        },
        plan_id: basicMonthlyPlan.id,
        description: 'Monthly fee of the Basic Monthly plan',
        start_event: 'contract_effective',
        price_base_interval: 'billing_period',
    };
    
    const baseMonthlyPrice = await zuoraClient.prices.createPrice(monthlyPriceRequest);
  3. Create a Basic Yearly plan for the Basic product.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/plans"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
            "name": "Basic Yearly",
            "product_id": "2c94a116ef504f65b5ef1e9e9e8377e1",
            "description": "Yearly plan of the Basic product", 
            "start_date": "2022-04-01", 
            "end_date": "2032-04-01"
        }'
    Copy
    Copied
    PlanCreateRequest yearlyPlanRequest = new PlanCreateRequest()
        .name('Basic Yearly')
        .productId(basicProduct.getId())
        .startDate('2022-04-01')
        .endDate('2032-04-01')
        .description('Yearly plan of the Basic product');
            
    Plan basicYearlyPlan = zuoraClient.plans().createPlan(yearlyPlanRequest);
    Copy
    Copied
    const yearlyPlanRequest = {
        name: 'Basic Yearly',
        product_id: basicProduct.id,
        description: 'Yearly plan of the Basic product', 
        start_date: '2022-04-01', 
        end_date: '2032-04-01',
    };
    
    const basicYearlyPlan = await zuoraClient.plans.createPlan(yearlyPlanRequest);
  4. Create a Basic Yearly Fee price for the Basic Yearly plan.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/prices"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
            "name": "Basic Yearly Fee",
            "plan_id": "8ad08aef81375b10018137f8659d4e1e",
            "description": "Yearly fee of the Basic Yearly plan", 
            "amounts": {
                "USD": 100
            },
            "recurring": {
                "on": "account_cycle_date",
                "interval": "year",
                "timing": "in_advance"
            },
            "start_event": "contract_effective", 
            "price_base_interval": "billing_period",
            "deferred_revenue_accounting_code": "Credit Card",
            "recognized_revenue_accounting_code": "Credit Card"
        }' 
    Copy
    Copied
    Map<String, BigDecimal> yearlyAmounts = new HashMap<String, BigDecimal>() {{
        put("USD", new BigDecimal(100.0));
    }};
    
    PriceCreateRequest yearlyPriceRequest = new PriceCreateRequest()
        .amounts(yearlyAmounts)
        .name("Basic Yearly Fee")
        .priceBaseInterval(PriceBaseIntervalEnum.BILLING_PERIOD)
        .planId(basicYearlyPlan.getId())
        .description("Yearly fee of the Basic Yearly plan")
        .recurring(new Recurring()
            .on(OnEnum.ACCOUNT_CYCLE_DATE)
            .interval(IntervalEnum.YEAR)
            .timing(TimingEnum.ADVANCE)
        )
        .startEvent(StartEventEnum.CONTRACT_EFFECTIVE)
        .deferredRevenueAccountingCode("Credit Card")
        .recognizedRevenueAccountingCode("Credit Card");
    
    Price baseYearlyPrice = zuoraClient.prices().postPrice(yearlyPriceRequest);
    Copy
    Copied
    const yearlyPriceRequest = {
        name: 'Basic Yearly Fee',
        amounts: {
            USD: 100
        },
        recurring: {
            on: 'account_cycle_date',
            interval: 'year',
            timing: 'in_advance',
        },
        plan_id: '8ad09fc284eac7840184f0bb12733cea',
        description: "Yearly fee of the Basic Yearly plan",
        start_event: "contract_effective",
        price_base_interval: "billing_period",
    };
    
    const baseYearlyPrice = await zuoraClient.prices.createPrice(yearlyPriceRequest);

Create per-unit prices

For per-unit prices, the amount to charge is expressed as a price per unit. The price is calculated based on the quantity of a service or product purchased by the customer, where the total price charged per period would be the quantity multiplied by the per-unit price. An example of a per unit charge would be a software-as-a-service vendor that charges $50 per user per month for their service.

Suppose that you are offering the following product and price:

  • Product: SaaS Service
  • Plan: SaaS Service Monthly plan
  • Price: $20 per unit per month
Before creating the corresponding price, ensure that you have configured the unit of measure in your Zuora tenant. In this scenario, you can set up user or license as the unit of measure. See Customize Units of Measure for more information.

To create a per unit pricing model lie this on Zuora using the Products, Plans and Prices APIs:

  1. Create the per-unit product
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/products"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{ 
                "name": "SaaS service",
                "description": "SaaS service charged on active users", 
                "start_date": "2022-06-01", 
                "end_date": "2032-06-01",
        }' 
    Copy
    Copied
    ProductCreateRequest productRequest = new ProductCreateRequest()
        .name('SaaS service')
        .startDate('2022-06-01')
        .endDate('2032-06-01')
        .description('SaaS service charged on active users');
            
    Product newProduct = zuoraClient.products().createProduct(productRequest); 
    Copy
    Copied
    const productRequest = {
        name: 'SaaS service',
        description: 'SaaS service charged on active users',
        start_date: '2022-06-01',
        end_date: '2032-06-01',
    };
    
    const newProduct = await zuoraClient.products.createProduct(productRequest);
    console.log(newProduct);
  2. Create the per-unit monthly plan
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/plans"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
                "name": "SaaS Service Monthly Plan",
                "product_id": "2c94a116ef504f65b5ef1e9e9e8377e1",  
                "description": "Monthly plan of the SaaS service", 
                "start_date": "2022-06-01", 
                "end_date": "2032-06-01"
            }' 
    Copy
    Copied
    PlanCreateRequest planRequest = new PlanCreateRequest()
        .name('SaaS Service Monthly Plan')
        .productId(newProduct.getId())
        .startDate('2022-06-01')
        .endDate('2032-06-01')
        .description('Monthly plan of the SaaS Service')
            
    Plan newPlan = zuoraClient.plans().createPlan(planRequest);
    Copy
    Copied
    const planRequest = {
        name: 'SaaS Service Monthly Plan',
        product_id: newProduct.id,
        description: 'Monthly plan of the SaaS Service',
        start_date: '2022-06-01',
        end_date: '2032-06-01',
    };
    
    const newPlan = await zuoraClient.plans.createPlan(planRequest);
  3. Create a price for the monthly plan
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/prices"
     -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
     -H "Content-Type: application/json" 
     -d '{
          "name": "Monthly Per Unit Price",
          "unit_of_measure": "License",
          "unit_amounts": {
            "USD": 20
          },
          "recurring": {
            "interval": "month",
            "on": "account_cycle_date",
            "interval_count": "1",
            "timing": "in_advance"
          },
          "plan_id": "2c921528ef504f65b5ef1e9e9e8362f2",
          "description": "Monthly per unit price", 
          "start_event": "contract_effective", 
          "price_base_interval": "month",
          "quantity": 10,
          "recognized_revenue_accounting_code": "Service Revenue",
          "deferred_revenue_accounting_code": "Service Revenue" 
        }'
    Copy
    Copied
    Map<String, BigDecimal> unitAmount = new HashMap<String, BigDecimal>().put("USD", new BigDecimal("20.00"));
            
    PriceCreateRequest priceRequest = new PriceCreateRequest()
        .unitAmounts(unitAmount)
        .unitOfMeasure("License")
        .name("Monthly Per Unit Price")
        .priceBaseInterval(PriceBaseIntervalEnum.MONTH)
        .planId(newPlan.getId())
        .description("Monthly per unit price")
        .recurring(new Recurring()
            .interval(IntervalEnum.MONTH)
            .intervalCount(1)
            .timing(TimingEnum.ADVANCE)
            .on(OnEnum.ACCOUNT_CYCLE_DATE)
        )
        .quantity(new BigDecimal("10"))
        .startEvent(StartEventEnum.CONTRACT_EFFECTIVE)
        .recognizedRevenueAccountingCode("Service Revenue")
        .deferredRevenueAccountingCode("Service Revenue");
    
    Price newPrice = zuoraClient.prices().postPrice(priceRequest);
    Copy
    Copied
    const priceRequest = {
        name: 'Monthly Per Unit Price',
        unit_of_measure: 'License',
        unit_amounts: {
            USD: 20
        },
        recurring: {
            interval: 'month',
            interval_count: 1,
            timing: 'in_advance',
            on: 'account_cycle_date',
        },
        quantity: 10,
        plan_id: newPlan.id,
        description: 'Monthly per unit price', 
        start_event: 'contract_effective', 
        price_base_interval: 'month',
    };
    
    const newPrice = await zuoraClient.prices.postPrice(priceRequest);
  4. When you create subscriptions, specify a quantity to charge for each unit.
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/subscriptions"
     -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
     -H "Content-Type: application/json" 
     -d '{ 
        "account_data":{
            "bill_to": {
                "first_name": "Amy",
                "last_name": "Lawrence",
                "email": "amy.lawrence@zuora.com",
                "address":{
                    "line1": "123 ABC Street",
                    "city": "San Francisco",
                    "state": "California",
                    "country": "US"
                }
            },
            "name": "Amy Lawrence account",
            "currency": "USD"
        },
        "subscription_plans": [{
            "plan_id": "8ad095b8813772670181383d05136860",
            "prices": [{
                "price_id": "8ad0877b81375b220181388c877428f9",
                "quantity": 20        
            }]
        }]
    }' 
    Copy
    Copied
    AccountContactCreateRequest contactCreateRequest = new AccountContactCreateRequest()
        .firstName("Amy")
        .lastName("Lawrence")
        .address(new Address()
    .line1("123 ABC Street")
    .city("San Francisco")
    .state("CA")
    .country("US"));
                
    AccountCreateRequest accountCreateRequest = new AccountCreateRequest()
            .name("Amy Lawrence account")
            .billTo(contactCreateRequest)
            .currency("USD");
                
    Account newAccount = zuoraClient.accounts().createAccount(accountCreateRequest);
    
    SubscriptionItemCreateRequest newItem = new SubscriptionItemCreateRequest()
        .priceId(newPrice.getId())
        .quantity(new BigDecimal("20"));
    
    List itemList = new ArrayList().add(newItem);
    
    SubscriptionChildPlanCreateRequest subPlan = new SubscriptionChildPlanCreateRequest()
    .planId(newPlan.getId())
    .prices(itemList);
    
    SubscriptionCreateRequest subRequest = new SubscriptionCreateRequest().accountData(newAccount).subscriptionPlans(Collections.singletonList(subPlan));
        
    Subscription createdSubscription = zuoraClient.subscriptions().createSubscription(subRequest);
    Copy
    Copied
    const planId = newPlan.id;
    const priceId= newPrice.id;
    
    const account = {
        bill_to: {
            first_name: 'Amy',
            last_name: 'Lawrence',
            email: 'amy.lawrence@zuora.com',
            address:{
                line1: '123 ABC Street',
                city: 'San Francisco',
                state: 'California',
                country: 'United States',
            }
        },
        name: 'Amy Lawrence account',
        currency: 'USD',
    };
    
    const subscription_plans = [{
        plan_id: newPlan.Id,
        prices: [{
            price_id: newPrice.id,
            quantity: 20        
        }]
    }];
    
    const subscriptionRequest = {
        account_data: account,
        subscription_plans: subscription_plans,
    };
    
    const createdSubscription = await zuoraClient.subscriptions.createSubscription(subscriptionRequest);

Create usage-based prices

With usage-based pricing, you charge your customers based on how much of your service they use during the billing cycle, instead of explicitly setting quantities, as in the per unit and flat rate pricing. Another difference is that with per-unit and and flat rate pricing you can collect payment for the billing cycle in advance or in arrears. With metered billing you have to collect payment in arrears. You must also record and report usage.

To charge on a per-minute basis for usage with more usage driving the per-minute price lower for the customer. Here is what pricing looks like in Zuora:

  • Product: VoIP service
  • Plan: Per-minute pricing plan
  • Price: 0.15 USD per minute
With metered usage recurring[usage]=true, you bill your customer in arrears. Based on how much of your service they consume and track their usage with the Usage API. At the end of the billing period, the total usage is multiplied by the unit_amount to calculate how much the customer owes.

See the following steps and code examples:

  1. Create a product for the VoIP service
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/products"
    -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
    -H "Content-Type: application/json" 
    -d '{ 
        "name": "VoIP service",
        "description": "Product with a usage price", 
        "start_date": "2022-04-01", 
        "end_date": "2032-04-01"
    }'
    Copy
    Copied
    ProductCreateRequest productRequest = new ProductCreateRequest()
        .name('VoIP Service')
        .startDate('2022-04-01')
        .endDate('2032-04-01')
        .description('Product with a usage price');
    
    Product productWithUsagePrice = zuoraClient.products().createProduct(productRequest);
    Copy
    Copied
    const productRequest = {
        name: 'VoIP Service',
        description: 'Product with a usage price', 
        start_date: '2022-04-01', 
        end_date: '2032-04-01',
    };
    
    const productWithUsagePrice = await zuoraClient.products.createProduct(productRequest);
  2. Create the per-minute pricing plan
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/plans"
    -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
    -H "Content-Type: application/json" 
    -d '{
        "name": "Plan with usage price",
        "product_id": "2c94a116ef504f65b5ef1e9e9e8377e1",
        "description": "Plan with a per-minute usage price", 
        "start_date": "2022-04-01", 
        "end_date": "2032-04-01",
        "active_currencies": ["USD"]
    }'
    Copy
    Copied
    PlanCreateRequest planRequest = new PlanCreateRequest()
        .name('Plan with usage price')
        .productId(productWithUsagePrice.getId())
        .startDate('2022-04-01')
        .endDate('2032-04-01')
        .description('Plan with a per-minute usage price')
        .activeCurrencies(['USD']);
            
    Plan planWithUsagePrice = zuoraClient.plans().createPlan(planRequest);
    Copy
    Copied
    const planRequest = {
        name: 'Plan with usage price',
        product_id: productWithUsagePrice.id,
        description: 'Plan with a per-minute usage price', 
        start_date: '2022-04-01', 
        end_date: '2032-04-01',
    };
    
    const planWithUsagePrice = await zuoraClient.plans.createPlan(planRequest);
  3. Create the usage-based price
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/prices"
    -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
    -H "Content-Type: application/json" 
    -d '{
        "name": "Per-minute Usage Price",
        "plan_id": "2c921528ef504f65b5ef1e9e9e8362f2",
        "description": "Per minute usage price", 
        "unit_of_measure": "Minutes",
        "recurring": {
            "on": "account_cycle_date",
            "usage": true,
            "interval": "month"
        },
        "unit_amounts":{
            "USD":0.15
        },
        "start_event": "contract_effective", 
        "price_base_interval": "billing_period"
    }'
    Copy
    Copied
    Map<String, BigDecimal> unitAmounts = new HashMap<String, BigDecimal>() {{
        put("USD", new BigDecimal("0.15"));
    }};
    
    PriceCreateRequest priceRequest = new PriceCreateRequest()
        .name("Per-minute Usage Price")
        .planId(planWithUsagePrice.getId())
        .description("Per minute usage price")
        .unitOfMeasure("Minutes")
        .recurring(new Recurring()
            .on(OnEnum.ACCOUNT_CYCLE_DATE)
            .usage(true)
            .interval(IntervalEnum.MONTH)
        )
        .unitAmounts(unitAmounts)
        .startEvent(StartEventEnum.CONTRACT_EFFECTIVE)
        .priceBaseInterval(PriceBaseIntervalEnum.BILLING_PERIOD);
    
    Price usagePrice = zuoraClient.prices().createPrice(priceRequest);
    Copy
    Copied
    const priceRequest = {
        name: 'Per-minute usage-based price',
        unit_of_measure: 'Minutes',
        unit_amounts: {
            USD: 0.15
        },
        recurring: {
            usage: true,
            on: 'account_cycle_date',
            interval:'month'
        },
        plan_id: planWithUsagePrice.id,
        description: 'Per minute usage price',
        start_event: 'contract_effective',
        price_base_interval: 'billing_period',
    };
    
    const usagePrice = await zuoraClient.prices.createPrice(priceRequest);

Create plans that contain multiple prices

Plans can use multiple prices to define different pricing options. The plan description is shared between prices and appears the same on the customer’s receipts and invoices - only the pricing differs.

For example, you offer the software service to your customers. For the basic plan, the subscription fee is charged at a rate of $100 per month, which includes 20 licenses. If your customer needs to purchase more than 20 licenses, extra licenses are charged at $5 per license per month.

  • Product: Software service - Basic
  • Plan: Software Service - Basic Monthly Plan
  • Prices:
    • Flat fee: $100 per month
    • Per-unit price: $5 per unit per month
In this case, you should add the two prices to the same plan by specifying the same plan_id when creating them.

The steps and the corresponding code samples are as follows:

  1. Create the "Software service - Basic" product
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/products"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{ 
            "name": "Software service - Basic",
            "description": "Software service - basic edition", 
            "start_date": "2022-06-01", 
            "end_date": "2032-06-01"
            }' 
    Copy
    Copied
    ProductCreateRequest productRequest = new ProductCreateRequest()
        .name('Software service - Basic')
        .startDate('2022-06-01')
        .endDate('2032-06-01')
        .description('Software service - basic edition');
            
    Product newProduct = zuoraClient.products().createProduct(productRequest);
    Copy
    Copied
    const productRequest = {
        name: 'Software service - Basic',
        description: 'Software service - basic edition',
        start_date: '2022-01-01',
        end_date: '2032-12-31',
    };
    
    const newProduct = await zuoraClient.products.createProduct(productRequest);
  2. Create the monthly plan for the "Software service - Basic" product
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/plans"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
                "name": "Software Service - Basic Monthly Plan",
                "product_id": "2c94a116ef504f65b5ef1e9e9e8377e1",  
                "description": "Monthly plan of the SaaS service", 
                "start_date": "2022-06-01", 
                "end_date": "2032-06-01"
            }' 
    Copy
    Copied
    PlanCreateRequest planRequest = new PlanCreateRequest()
        .name('Software Service - Basic Monthly Plan')
        .productId(newProduct.getId())
        .startDate('2022-06-01')
        .endDate('2032-06-01')
        .description('Monthly plan of the SaaS Service');
            
    Plan newPlan = zuoraClient.plans().createPlan(planRequest);
    Copy
    Copied
    const planRequest = {
        name: 'Software Service - Basic Monthly Plan',
        product_id: newProduct.id,
        description: 'Monthly plan of the SaaS Service', 
        start_date: '2022-06-01', 
        end_date: '2032-06-01',
    };
    
    const newPlan = await zuoraClient.plans.createPlan(planRequest);
  3. Create the monthly flat-fee price
    cURLJavaNode
    Copy
    Copied
     curl -X POST "https://rest.test.zuora.com/v2/prices"
         -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
         -H "Content-Type: application/json" 
         -d '{
             "name": "Basic Monthly Flat Fee",
             "plan_id": "2c921528ef504f65b5ef1e9e9e8362f2",
             "description": "Monthly flat fee of the Basic Monthly plan", 
             "amounts": {
                 "USD": 100
             },
             "recurring": {
                 "on": "account_cycle_date",
                 "interval": "month",
                 "timing": "in_advance"
             },
             "start_event": "contract_effective", 
             "price_base_interval": "billing_period"
             }' 
    Copy
    Copied
     Map<String, BigDecimal> monthlyAmounts = new HashMap<String, BigDecimal>() {{
         put("USD", new BigDecimal("100.00"));
     }};
    
     PriceCreateRequest monthlyPriceRequest = new PriceCreateRequest()
         .amounts(monthlyAmounts)
         .name("Basic Monthly Flat Fee")
         .priceBaseInterval(PriceBaseIntervalEnum.BILLING_PERIOD)
         .planId(basicMonthlyPlan.getId())
         .description("Monthly flat fee of the Basic Monthly plan")
         .recurring(new Recurring()
             .on(OnEnum.ACCOUNT_CYCLE_DATE)
             .interval(IntervalEnum.MONTH)
             .timing(TimingEnum.ADVANCE)
         )
         .startEvent(StartEventEnum.CONTRACT_EFFECTIVE);
    
     Price flatFeePrice = zuoraClient.prices().postPrice(monthlyPriceRequest);
    Copy
    Copied
     const priceRequest = {
         name: 'Basic Monthly Flat Fee',
         amounts: {
             USD: 100
         },
         recurring: {
             timing: 'in_advance',
             on: 'account_cycle_date',
             interval:'month',
             interval_count: 1,
         },
         plan_id: newPlan.id,
         description: 'Monthly flat fee of the Basic Monthly plan',
         start_event: 'contract_effective',
         price_base_interval: 'month',
     };
     
     const flatFeePrice = await zuoraClient.prices.createPrice(priceRequest);
  4. Create the monthly per-unit price
    cURLJavaNode
    Copy
    Copied
    curl -X POST "https://rest.test.zuora.com/v2/prices"
        -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
        -H "Content-Type: application/json" 
        -d '{
            "name": "Monthly Per Unit Price",
            "unit_of_measure": "License",
            "unit_amounts": {
                "USD": 5
            },
            "recurring": {
                "interval": "month",
                "on": "account_cycle_date",
                "interval_count": "1",
                "timing": "in_advance"
            },
            "plan_id": "2c921528ef504f65b5ef1e9e9e8362f2",
            "description": "Monthly per unit price", 
            "start_event": "contract_effective", 
            "price_base_interval": "month",
            "quantity": 0 
            }' 
    Copy
    Copied
    Map<String, BigDecimal> unitAmount = new HashMap<String, BigDecimal>().put("USD", new BigDecimal("5.00"));
            
    PriceCreateRequest priceRequest = new PriceCreateRequest()
        .unitAmounts(unitAmount)
        .unitOfMeasure("License")
        .name("Monthly Per Unit Price")
        .priceBaseInterval(PriceBaseIntervalEnum.MONTH)
        .planId(newPlan.getId())
        .description("Monthly per unit price")
        .recurring(new Recurring()
            .interval(IntervalEnum.MONTH)
            .intervalCount(1)
            .timing(TimingEnum.ADVANCE)
            .on(OnEnum.ACCOUNT_CYCLE_DATE)
        )
        .quantity(new BigDecimal("0"))
        .startEvent(StartEventEnum.CONTRACT_EFFECTIVE);
    
    Price perUnitPrice = zuoraClient.prices().postPrice(priceRequest);
    Copy
    Copied
    const priceRequest = {
        name: 'Monthly Per Unit Price',
        unit_of_measure: 'License',
        unit_amounts: {
            USD: 5
        },
        recurring: {
            timing: 'in_advance',
            on: 'account_cycle_date',
            interval:'month',
            interval_count: 1,
        },
        plan_id: newPlan.id,
        description: 'Monthly per unit price',
        start_event: 'contract_effective',
        price_base_interval: 'month',
        quantity: 0,
    };
    
    const perUnitPrice = await zuoraClient.prices.createPrice(priceRequest);

List all products

You can use the "List all products" operation to retrieve all products in your tenant. The List all products operation returns an array of products (paginated, 10 per call), without plans and prices information by default. The response may contain a next_page field, which is the index to the next product that cannot be displayed on the current page. To fetch the next page of the list, set this index as the value of the cursor query parameter in the subsequent request.To retrieve all plans and prices related to each product, set the value of the expand[] query parameter to plans.prices.

The following example retrieves all products with plans and prices:

cURLJavaNode
Copy
Copied
curl -X GET "https://rest.test.zuora.com/v2/products?expand[]=plans.prices"
     -H "Authorization: Bearer 72db3da461ba40c69fb1c2dc440ad204"
     -H "Content-Type: application/json"
Copy
Copied
List expandParameters = new ArrayList();
expandParameters.add("plans.prices");

ProductListResponse productsWithPlansAndPrices = zuoraClient.products().getProducts(null, expandParameters, null);
System.out.println(expandParameters);
Copy
Copied
const products = await zuoraClient.products.getProducts(({
    expand: ['plans.prices']
}));
console.log(products);