Home : Developer Center : SDK Guides

Overview

Through this set of guides, we demonstrate how the Zuora SDK can be used to perform common use cases.

This set of guides assumes that:

  • You have a self-service portal that is used by end subscribers for purchasing and managing products and services. This is not a hard requirement; if you do not have a self-service portal, most of the use cases will still be relevant.
  • The Orders feature is enabled in your Zuora tenant. If this feature is enabled in your tenant, you can see Orders under Customers in the left navigation panel in Zuora Central. To obtain access to this feature, submit a request at Zuora Global Support.
  • The Invoice Settlement feature is enabled in your Zuora tenant. If this feature is enabled in your tenant, you can see Credit and Debit Memos under Billing in the left navigation panel in Zuora Central. To obtain access to this feature, submit a request at Zuora Global Support.
  • You have set up a payment gateway instance in your Zuora tenant.
  • The Zuora Finance feature is enabled in your Zuora tenant.
  • The Zuora Tax feature is enabled in your Zuora tenant.

You may find it helpful to review the SDK Technical Reference included in the Zuora Samples project when following this guide.

Note: Zuora Samples Project, built by Zuora, provides all the server code you need for common integration use cases, such as creating a subscription with Zuora Billing.

Visit Zuora Developers Community to report issues or discuss the SDK.

Installation

Add the following dependency to the dependencies in the pom.xml file of your project:

<dependency>
    <groupId>com.zuora.sdk</groupId>
    <artifactId>zuora-sdk-java</artifactId>
    <version>${version}</version>
</dependency>

Note: Replace ${version} with the latest Zuora SDK version. Check Maven Central for the latest version.

Base URL

The base URLs for different Zuora environments are different. You can use environment-based variables to manage base URLs and the different credentials you have for different Zuora environments.

When using the SDK you should select the endpoint base URL you wish to use.

Tenant Base URL for REST endpoint
US Production https://rest.zuora.com
US API Sandbox https://rest.apisandbox.zuora.com
US Central Sandbox https://rest.test.zuora.com
US Performance Test https://rest.pt1.zuora.com
US Cloud Production https://rest.na.zuora.com
US Cloud API Sandbox https://rest.sandbox.na.zuora.com
EU Production https://rest.eu.zuora.com
EU Sandbox https://rest.sandbox.eu.zuora.com
EU Central Sandbox https://rest.test.eu.zuora.com

Authentication

  1. Create a dedicated user for making API calls. See Create an API User for details. This step must be performed by a Zuora administrator from your organization who has a company email address.
  2. Create an OAuth client for the user. This step must be performed by an administrator.
    1. In Zuora, navigate to Settings > Administration > Manage Users, and click the user name (in hypertext) that is created in step 1.
    2. In the New OAuth Client section on the user profile page, enter a client name, and click create. A new window will open showing the client ID and client secret.

      Create a new OAuth client

      Client ID and secret are generated

      Client ID and secret are generated

    3. Note down the client ID and client secret. You’ll need them in step 3. This is a one-time process. See Create an OAuth Client for a User for details.
  3. Add the following snippet to your code to authenticate:
    String CLIENT_ID = "{CLIENT_ID}";
    String CLIENT_SECRET = "{CLIENT_SECRET}";
    String ENDPOINT = "{ENDPOINT_BASE}";
    ZuoraClient zuoraClient = new ZuoraClient(CLIENT_ID, CLIENT_SECRET, ENDPOINT);

Products and Plans

Introduces the following key concepts:

  • Products
  • Plans, including Prices

An example is also provided to show how to create a product and a plan that contains a price in a single call.

Overview

Products

Products describe the specific goods or services you offer to your customers. For example, if you offer both a Standard and a Premium version of your service, each version would be a separate product. They can be used in conjunction with plans and prices to configure pricing.

Plans

Plans are collections of prices that define the unit cost, currency, and (optional) billing cycle for recurring, one-time, and usage-based purchases of products. While products help you track inventory or provisioning, plans and prices help you track payment terms. Different physical goods or levels of service should be represented by products, and pricing and billing cycle options should be represented by prices grouped together into a plan. This approach lets you change prices without having to change your provisioning scheme.

For example, you have a single “Gold” product that has prices of $100/month, $1000/year, and a $50 one-time charge. In this example, the alternative billing cycles and pricing options are each represented by a different plan and the recurring and one-time prices are represented by different prices.

Create a product and a plan that contains a price

Create a “Gold” product and a “Monthly Plan” plan with a single price called “Monthly Membership” that charges the end subscriber a flat fee of $5 a month starting on the day of the month that the subscription item for this price becomes effective.

ProductCreateRequest productCreateRequest = ProductCreateRequest.builder()
.name("Gold")
.build()

String DEFAULT_ACCOUNTING_CODE = zuoraClient.priceHelper().getDefaultAccountingCodeName();

PlanCreateRequest planCreateRequest = PlanCreateRequest.builder()
.name("Monthly Plan")
.prices(Arrays.asList(PriceCreateRequest.builder()
.name("Monthly Membership")
.amount(Currency.getInstance("USD"), 5.0)
.build())
.accountingCode(DEFAULT_ACCOUNTING_CODE)
.startEvent(Event.CONTRACT_EFFECTIVE)
.build()

productCreateRequest.addPlan(planCreateRequest);

Product product = zuoraClient.products().create(productCreateRequest);

Accounts and Subscriptions

Overview

In this use case, we’ll show you how to handle the acquisition of new customers and how to create a subscription for an existing customer.

Accounts
An account represents your customer. An account is also the owner of a subscription.

Subscriptions
A subscription contains all of the subscription items to which the customer is subscribed.

Contacts
Accounts have both a bill-to contact and a sold-to contact. By default, if you specify only one of these contacts, both contacts are populated with the contact details you provided. The bill-to contact is used to determine the invoice address, whereas the sold-to contact is used to calculate tax. If the invoice delivery preference is email, the bill-to contact must contain an email address.

Create a subscription for an existing customer

The following example creates a subscription for an existing customer.

An existing customer called Jenny Smith signs up for a subscription to a “Gold” product and a “Monthly Plan” plan with a single price named “Monthly Membership”.

After a one-month free trial, the product is activated for billing. The “Monthly Membership” price specifies that it is the service activation date that should trigger billing for the product to start so the serviceActivation parameter in the SubscriptionCreateRequest is set to one month after the start of the free trial.

Terms: 12-month initial term with a 12-month renewal term.

The invoice is generated immediately. An existing payment method is used and the payment is collected.

ProductCreateRequest productCreateRequest = ProductCreateRequest.builder()
.name("Gold")
.build();
​
PlanCreateRequest planCreateRequest = PlanCreateRequest.builder()
.name("Gold Monthly Plan")
.build();
​
String DEFAULT_ACCOUNTING_CODE = zuoraClient.priceHelper().getDefaultAccountingCodeName();
​
// Create a monthly charge
PriceCreateRequest priceCreateRequest = PriceCreateRequest.builder()
.amount(Currency.getInstance("USD"), 30.0)
.name("Monthly Membership - Starts on Service Activation")
.accountingCode(DEFAULT_ACCOUNTING_CODE)
.description("Gold Monthly Membership")
.timing(BillingTiming.IN_ADVANCE)
.interval(Interval.MONTH)
.startEvent(Event.SERVICE_ACTIVATION)
.alignment(Alignment.SUBSCRIPTION_ITEM)
.on(RecurringOn.ACCOUNT_CYCLE_DATE)
.build();
​
planCreateRequest.addPrice(priceCreateRequest);
​
Product product = zuoraClient.products().create(productCreateRequest);
​
//Get the Payment method
PaymentMethod paymentMethod = zuoraClient.paymentMethods().get("2c92c0f971c65dfe0171dfdb6df80ad9");
​
//Create an account
ContactCreateRequest contactCreateRequest = ContactCreateRequest.builder()
.firstName("Jenny")
.lastName("Smith")
.address(Address.builder().country("USA").state("CA").build())
.build();
​
AccountCreateRequest accountCreateRequest = AccountCreateRequest.builder()
.name("Jenny Smith")
.billTo(contactCreateRequest)
.paymentMethod(paymentMethod.getId())
.build();
​
Account account = zuoraClient.accounts().create(accountCreateRequest);
​
//Create a subscription
​LocalDate todaysDate = LocalDate.now();
String todaysDateStr = todaysDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
​
SubscriptionCreateRequest subscriptionCreateRequest = SubscriptionCreateRequest.builder()
.account(account)
.termStartDate(todaysDate)
.initialTerm(Term.builder()
.type(TermType.TERMED)
.interval(Interval.MONTH.getValue())
.intervalCount(12)
.build())
.renewalTerm(Term.builder()
.type(TermType.TERMED)
.interval(Interval.MONTH.getValue())
.intervalCount(12)
.build())
.plans(product.getPlans())
.serviceActivation(todayDates.plusMonths(1))
.customerAcceptance(todayDates.plusMonths(1))
.processingOption(ProcessingOption.builder()
.collectionMethod(CollectionMethod.COLLECT_PAYMENT)
.paymentMethod("2c92c0f872c68b450172dad9c61e436b")
.documentDate(todaysDateStr)
.build()
);

​Subscription subscription = zuoraClient.subscriptions().create(subscriptionCreateRequest);

//Retrieve invoices
​
List<BillingDocument> billingDocuments = zuoraClient.billingDocuments()
.findByAccount(account, BillingDocumentType.INVOICE);

Edit the contact information for a customer account

A subscriber wants to change their contact information. Specifically, a subscriber with an account with the same bill-to and sold-to contacts wants to change their bill-to contact.

Account account = zuoraClient.accounts().get(“A-000001”);
Contact contact = account.getBillTo();

Contact updatedContact = contact.toBuilder()
.firstName(“Jenny”)
.lastName(“Smith”)
.build();
zuoraClient.contacts().update(updatedContact);

Retrieve a customer’s subscriptions

A subscriber wants to view their subscriptions.

Use the zuoraClient.accounts().getSubscriptions() method to retrieve all subscriptions associated with a customer’s account. For example, the following SDK example retrieves all subscriptions for an account.

Account account = zuoraClient.accounts().get(“A-000001”);
List<Subscription> subscriptions = account.getSubscriptions();

Payment Methods

Payment Pages 2.0 overview

Zuora’s Payment Pages allow end subscribers to send payment method details to your company in a secure and PCI-compliant manner. The payment page is hosted in Zuora and iframed directly onto your company’s website.

Payment Pages are usually embedded into the customer acquisition flow and shown to the end subscribers prior to order submission. When the payment method details have been captured in Zuora, subsequent payments can be processed through that payment method.

The following diagram shows the default workflow of Zuora Payment Pages:

Create payment pages

To learn how to do this implement your own Payment Pages, see Payment Pages 2.0 Implementation Overview.

Note: As an alternative to using Zuora’s native iFrame, you can use Direct POST to implement Payment Pages 2.0 if you want full control over the look and feel of your payment form. See Implement Payment Pages 2.0 via Direct POST to learn more. However, using Direct POST to collect payment methods is not covered in this guide.

Zuora also implements 3D Secure 2.0 (3DS2) for Payment Pages 2.0 to help you comply with PSD2 and Strong Customer Authentication. For more detailed information, see Zuora’s implementation of 3D Secure 2.0.

After your Payment Page is set up, you can use it to collect payment method information of end subscribers. The Zuora JavaScript library handles the submission of Payment Page data. See Payment Pages 2.0 sample code suite on the Zuora GitHub site for sample code of Payment Pages 2.0 and the corresponding libraries.

Add a payment method to an existing account

Payment methods created from Payment Pages must be associated with a Zuora account.

Zuora Payment Pages 2.0 allows your subscribers to enter their payment method information without creating or logging into their account. Such standalone payment methods will be deleted if they are not associated with a Zuora account within 240 hours. To avoid standalone payment methods from being deleted you must either:

  • Associate this payment method with an existing customer account

or

  • Create a new customer account and associate the payment method with the new account.

To create or add a payment method to an existing account, use the field_accountId client parameter of Payment Pages 2.0. See Link Payment Methods from Payment Pages to Accounts for details.

Retrieve the payment methods for an account

Use the zuoraClient.accounts().getPaymentMethods() method to retrieve all payment methods associated with a customer’s account. For example, the following SDK example retrieves all payment methods for an account.

Account account = zuoraClient.accounts().get(“A-000001”);
List<PaymentMethod> paymentMethods = account.getPaymentMethods();

Invoices

View invoices

Subscribers want to view the invoices associated with their accounts.

Retrieve the invoices for an account

Use the zuoraClient.accounts().getInvoices() method to retrieve all invoices associated with a customer’s account. For example, the following SDK example retrieves all invoices for an account.

Account account = zuoraClient.accounts().get(“A-000001”);
List<BillingDocument> invoices = account.getInvoices();

Retrieve credit memos

Overview

The end subscriber wants to view the credits in their account. You can retrieve the credit memos and view the details on the customer portal.

Retrieve credit memos for a customer account

Use the zuoraClient.billingDocuments().findByAccount() method to retrieve all credit memos associated with a customer’s account. For example, the following example retrieves all credit memos for an account.

Account account = zuoraClient.accounts().get(“A-000001”);

List<BillingDocument> creditMemos = zuoraClient.billingDocuments()
.findByAccount(account,BillingDocumentType.CREDIT_MEMO);

Retrieve a credit memo

Use the zuoraClient.BillingDocuments.get() method to retrieve a credit memo.

BillingDocument creditMemo = zuoraClient.billingDocuments().get(“CM00000012”);

Retrieve the payments for an account

The following example shows how to retrieve all payments for an account (accountNumber = “A-000001”).

Account account = zuoraClient.accounts().get(“A-000001”);

List<Payment> payments = account.getPayments();

Add a product to a subscription

Overview

When a subscriber decides to add a product to their subscription, he or she needs to pick a plan for the product. When you add the plan to their subscription you can at the same override the pricing that is how the subscriber will be charged for this product.

In this scenario, the subscriptions().addPlan() method is used. You will need to provide the following information in the request:

  • The key of the subscription to be updated.
  • The identifier of the plan to be added.

If you want to change the default pricing for the end subscriber you will also need:

  • The identifier of the price to be changed.
  • The new pricing details.

Depending on your company’s subscription settings, at least one of the following start dates is also required. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the Zuora UI. For more information about start dates, see Billing Trigger Dates.

  • contractEffective: The contract effective date of the product addition.
  • serviceActivation: The service activation date of the product addition.
  • customerAcceptance: The end subscriber acceptance date of the product addition.

Add a product to a subscription

The following code example adds a plan to an existing subscription with a recurring flat fee charge. It overrides the price by changing the per-unit price to 200.

ProductCreateRequest productCreateRequest = ProductCreateRequest.builder().name("Gold").build();
Product product = zuoraClient.products().create(productCreateRequest);

Plan plan = zuoraClient.products().getPlan(“Gold Membership Plan”);

plan.getItems().stream().filter(item -> item.getName() == "Gold Monthly Price"). item.setUnitAmounts(Collections.singletonMap(Currency.getInstance("USD"), 200.0));

Subscription subscription = zuoraClient.subscriptions().get(“S00007412”);

Subscription subscription = zuoraClient.subscriptions().addPlan(subscription, plan, LocalDate.now());

Remove a product from a subscription

Overview

When an end subscriber wants to remove a product from a subscription they are actually removing a subscription plan from a subscription.

Important: The subscription plan ID is unique to the subscription and is not the same as the catalog plan ID. To retrieve the subscription plan ID for a subscription, retrieve the subscription and use the getSubscriptionPlans() method to retrieve a list of subscription plans and their IDs.

Remove a product from a subscription

The following SDK example shows how to remove a specific product from a subscription (subscriptionNumber = “S00007412”).

Subscription subscription = zuoraClient.subscriptions().get(“S00007412”);

List<SubscriptionPlan> subscriptionPlans = zuoraClient.subscriptions()
.get(“S00007412”)
.getSubscriptionPlans();

Subscription subscription = zuoraClient.subscriptions()
.removeSubscriptionPlan(subscription, subscriptionPlans.get(0));

Renew a subscription

Overview

When a subscription is due to expire, you can request for it to be renewed at the end of its current term.

Renew a subscription

The following SDK example shows how to renew a subscription (subscriptionNumber = “S00007412”). First, retrieve the subscription instance first, then use the subscriptions().renew() method to renew the subscription.

Subscription subscription = zuoraClient.subscriptions()
.get(“S00007412”);

subscription = zuoraClient.subscriptions().renew(subscription.getId());

Cancel a subscription

Overview

In this use case, the subscriber wants to cancel their subscription.

Cancel a subscription

The following SDK example shows how to cancel a subscription (subscriptionNumber=”S00007412″). First, retrieve the subscription instance, then use the subscriptions().cancel() method to cancel the subscription.

Subscription subscription = zuoraClient.subscriptions()
.get(“S00007412”);

Subscription subscription = zuoraClient.subscriptions().cancel(subscription);

Update the product quantity on a subscription

Overview

You can update the product quantity on a subscription only if the product’s price is not a flat fee, a discount, or an overage price.

Depending on your company’s subscription settings, at least one of the following start dates is required. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the Zuora UI. For more information about the start dates, see Billing Trigger Dates.

  • contractEffective: the contract effective date of the product update
  • serviceActivation: the service activation date of the product update
  • customerAcceptance: the end subscriber acceptance date of the product update

Update the product quantity on a subscription

The following SDK example shows how to change the quantity to 60 for a product on a subscription (subscriptionNumber=”S00007412″).

Subscription subscription = zuoraClient.subscriptions().get(“S00007412”);

SubscriptionItem subscriptionItem = subscriptions.getSubscriptionPlans().get(0).getItems().get(0);

SubscriptionItemRequest subscriptionItemRequest = subscriptionItem.toBuilder().setQuantity(60.0).build();

Subscription subscription = zuoraClient.subscriptions().updateSubscriptionItem(subscription, subscriptionItemRequest, LocalDate.now());