Note: This set of guides is based on the REST APIs of Zuora Billing. We also offer a Zuora SDK for Java that allows you to perform common use cases in a programmable way. See SDK Guides to learn more.
Through this set of guides, we attempt to demonstrate common use cases of Zuora Billing REST APIs. The sequence of the guides indicates a typical but loose order that these use cases would occur.
Tell us how we can improve the API guides by completing this anonymous two-question feedback form.
This set of guides assume that you have the following systems and configurations.
To learn about product catalogs in Zuora and how to define your catalog, refer to these two Knowledge Center articles:
The base URLs for different Zuora environments are different. You can use environment-based variables to manage base URLs and credentials for different Zuora environments.
In code examples, we use the base URL of the US API Sandbox environment. When running your API operations, you need to replace this base URL (https://rest.apisandbox.zuora.com) with the actual base URL.
Tenant | Base URL for REST endpoint |
---|---|
US Cloud 1 Production | https://rest.na.zuora.com |
US Cloud 1 API Sandbox | https://rest.sandbox.na.zuora.com |
US Cloud 2 Production | https://rest.zuora.com |
US Cloud 2 API Sandbox | https://rest.apisandbox.zuora.com |
US Central Sandbox | https://rest.test.zuora.com |
US Performance Test | https://rest.pt1.zuora.com |
US Production Copy | Submit a request at Zuora Global Support to enable the Zuora REST API in your tenant and obtain the base URL for REST endpoints. See REST endpoint base URL of Production Copy (Service) Environment for existing and new customers for more information. |
EU Production | https://rest.eu.zuora.com |
EU Sandbox | https://rest.sandbox.eu.zuora.com |
EU Central Sandbox | https://rest.test.eu.zuora.com |
Zuora recommends that you use OAuth to authenticate to the Zuora REST API.
Create a new OAuth client
Client ID and secret are generated
After you obtain the bearer token, you can start making API calls with it.
The following code example generates an OAuth token.
API operation
Request
GET https://rest.apisandbox.zuora.com/oauth/token
Request body (form-encoded)
client_id: 6909f6c1-3eeb-4cd2-9778-a3656f077842 client_secret: 196s6a2V8mNHCFZUFhp9mxw=1Nu8laAQuS4/BOa grant_type: client_credentials
Response
{ "access_token": "6447d349d8854f0d8d5535484b0b862b", "token_type": "bearer", "expires_in": 3598, "scope": "entity.11e643f4-a3ee-8bad-b061-0025904c57d6 platform.write service.genesis.read service.genesis.write service.usage.delete service.usage.update service.usage.write tenant.12270 user.2c92c0f86680fd7777777ad86e455692", "jti": "6447d34955555f0d8d5535484b0b862b" }
For a video demo of the process, see Making Zuora API calls using Postman. The video uses Postman, but the steps apply to other API tools.
When retrieving information using GET methods, the optional pageSize
query parameter sets the maximum number of rows to return in a response. The default and maximum values for different objects are different. If this value is empty or invalid, pageSize
typically defaults to 10.
The default value for the maximum number of rows retrieved can be overridden at the method level.
If more rows are available, the response will include a nextPage
element, which contains a URL for requesting the next page.
Below is an example of the nextPage
element in the response for the Get product catalog operation.
{ "products": [ ... ], "nextPage": "/v1/catalog/products?page=2&pageSize=10", "success": true }
To get the second page of results, you need to make another call using the base URL and the nextPage
value.
For example:
GET https://rest.apisandbox.zuora.com/v1/catalog/products?page=2&pageSize=10
In this use case, we’ll show you how to retrieve the product catalog and rate plans from Zuora and use the data in your portal.
A product catalog is where you define the products and pricing. A product represents a product or service that your company sells. The pricing is described as product rate plans. A rate plan represents a collection of charges that your customers may incur when buying your product. When a customer purchases a product, they can pick from one of the available rate plans.
Retrieving the product catalog involves the following two steps.
zuora-version
parameter set to 257.0 to get the products first. Rate plan links are included in the data of products.The Get product catalog operation returns an array of products (paginated, up to 40 per call), including all rate plans and rate plan charges of each product. The response may contain the URL for the next page (nextPage
), if any.
If your portal needs to access products and rate plan charges quickly and frequently, Zuora recommends caching the bolded fields in the response samples below, which includes:
The following example retrieves the product catalog on your tenant. Remember to specify the value (257.0) for the zuora-version
header parameter. If the zuora-version
header is not specified, the complete set of product rate plan data will be returned. In this case, if you have a large number of product rate plans or charges, the operation may time out.
API operation
Request
GET https://rest.apisandbox.zuora.com/v1/catalog/products
Response
{ "products": [ { "id": "b0906259301453e36227ab65e4d95ecc", "sku": "SKU-00000001", "name": "CloudStream Gamer", "description": "", "category": "Base Products", "effectiveStartDate": "2017-05-01", "effectiveEndDate": "2025-05-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b0906259301453e36227ab65e4d95ecc/productRatePlan", "productFeatures": [] }, { "id": "b0906259255eefc93b8e0fca57bc95bf", "sku": "SKU-00000002", "name": "CloudStream Vehicle Fleet Management", "description": "", "category": "Base Products", "effectiveStartDate": "2000-01-01", "effectiveEndDate": "2100-12-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b0906259255eefc93b8e0fca57bc95bf/productRatePlan", "productFeatures": [] }, { "id": "b0906259f03ec45b9bd6abae126ccd33", "sku": "SKU-00000003", "name": "CloudStream Home Automation", "description": "", "category": "Base Products", "effectiveStartDate": "2000-01-01", "effectiveEndDate": "2100-12-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b0906259f03ec45b9bd6abae126ccd33/productRatePlan", "productFeatures": [] }, { "id": "b09062595a330a664dbd8589e950da9c", "sku": "SKU-00000004", "name": "AllBrighter Bundle", "description": "", "category": "Base Products", "effectiveStartDate": "2000-01-01", "effectiveEndDate": "2100-12-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b09062595a330a664dbd8589e950da9c/productRatePlan", "productFeatures": [] }, { "id": "b09062592aa3420fd0c6dad01d519461", "sku": "SKU-00000005", "name": "AllBrighter Interdental Electric Flosser", "description": "", "category": "Base Products", "effectiveStartDate": "2000-01-01", "effectiveEndDate": "2100-12-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b09062592aa3420fd0c6dad01d519461/productRatePlan", "productFeatures": [] }, { "id": "b09062590ae15c846093cdf738ea56c2", "sku": "SKU-00000006", "name": "AllBrighter Shipping Charge", "description": "", "category": "Base Products", "effectiveStartDate": "2000-01-01", "effectiveEndDate": "2100-12-31", "allowFeatureChanges": false, "productRatePlans": "/v1/rateplan/b09062590ae15c846093cdf738ea56c2/productRatePlan", "productFeatures": [] } ], "success": true }
This code example retrieves the product rate plan data for a product ( id
= b0906259301453e36227ab65e4d95ecc
). You can use either the product ID returned in the response of the Get product catalog
operation to form the endpoint, or parse the link associated with the productRatePlans
value in the response.
API operation
Request
GET https://rest.apisandbox.zuora.com/v1/rateplan/b0906259301453e36227ab65e4d95ecc/productRatePlan
Response
{ "productRatePlans": [ { "id": "40289f466464127601646473d6f7000f", "status": "Active", "name": "New Rate Plan", "description": "", "effectiveStartDate": "2016-07-01", "effectiveEndDate": "2020-07-31", "productRatePlanCharges": [ { "id": "40289f4664641276016464740dd0001c", "name": "New Component", "type": "Recurring", "model": "FlatFee", "uom": null, "pricingSummary": [ "USD100" ], "pricing": [ { "currency": "USD", "price": 100, "tiers": null, "includedUnits": null, "overagePrice": null, "discountPercentage": null, "discountAmount": null } ], "defaultQuantity": null, "applyDiscountTo": null, "discountLevel": null, "discountClass": null, "productDiscountApplyDetails": [], "endDateCondition": "Subscription_End", "upToPeriods": null, "upToPeriodsType": null, "billingDay": "DefaultFromCustomer", "listPriceBase": "Per_Billing_Period", "billingTiming": "IN_ADVANCE", "billingPeriod": "Month", "billingPeriodAlignment": "AlignToCharge", "specificBillingPeriod": null, "smoothingModel": null, "numberOfPeriods": null, "overageCalculationOption": null, "overageUnusedUnitsCreditOption": null, "unusedIncludedUnitPrice": null, "usageRecordRatingOption": null, "priceChangeOption": null, "priceIncreasePercentage": null, "useTenantDefaultForPriceChange": null, "taxable": false, "taxCode": "", "taxMode": null, "DeliveryFrequencyUnit__c": "Months", "FinanceAmount__c": null, "ResidualValue__c": null, "Rate__c": null, "ProjectedMonthlyCost__c": null, "Leaseterm__c": "12", "DeliveryFrequency__c": "0", "triggerEvent": "ContractEffective", "description": "", "revenueRecognitionRuleName": "Recognize upon invoicing", "revRecTriggerCondition": "ContractEffectiveDate", "revRecCode": "", "useDiscountSpecificAccountingCode": null, "financeInformation": { "recognizedRevenueAccountingCode": "", "recognizedRevenueAccountingCodeType": null, "deferredRevenueAccountingCode": "", "deferredRevenueAccountingCodeType": null } } ] } ], "success": true }
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. New customer acquisition refers to the scenario that a new end subscriber registers a new account, signs up for a subscription, and pays for the subscription from the self-service portal.
For the new customer acquisition scenario, on the back end, we’ll use the Create order operation to create a new account, create a new subscription, generate the invoice, and collect the payment immediately in Zuora.
Zuora accounts
An account is a customer account that collects all of the critical information about the customer, such as contact information, payment terms, and payment methods. An account is also the owner of a subscription. A subscription contains all of the charges that the customer is subscribed to, and all the billing documents (invoices / credit memos / debit memos). For details about the Account object, see Account in the API Reference.
Zuora contacts
Zuora requires two types of contacts to be associated with an account: bill-to contact and sold-to contact. Bill-to contact determines the invoice deliverability, whereas sold-to contact determines the taxation. If the invoice delivery preference is email, the bill-to contact must contain an email address. For details, see Get contact in the API Reference.
Zuora orders and order actions
An order is an envelope that contains many different actions that can apply to a subscription. For example, creating subscriptions, or adding / removing products. The object model between Accounts, Subscriptions, Orders and Order Action are discussed in Orders Object Model.
Before using the Create order action to submit an order, you can use the Preview order operation to preview the invoices that will be generated for the customer as a result of the order. This can be helpful during a checkout flow to show the cart subtotal and taxes to the customer.
Notes on Tax
A tax preview call is made during the order preview, but no tax is committed to the tax engine during preview. Tax is committed when an invoice is generated and posted, either as part of the initial order capture or future bill runs.
Use case
API operation
Create order (new subscription)
Request
POST https://rest.apisandbox.zuora.com/v1/order
Request body
{ "orderDate": "2019-01-01", "newAccount": { "billCycleDay": 0, "billToContact":{ "address1": "123 Beacon Street", "city":"Copenhagen", "country": "DNK", "postalCode": "1068", "firstName": "Gem", "lastName": "Green" }, "soldToContact":{ "address1": "123 Main St", "city":"Chamblee", "state": "Georgia", "country": "USA", "postalCode": "30341", "firstName": "Shaf", "lastName": "Ahnaf" }, "currency":"EUR", "autoPay":true, "name":"Demo Account USS - 03", "paymentMethod": { "type": "Betalingsservice", "accountHolderInfo": { "accountHolderName": "Gem Green", "addressLine1": "123 Beacon Street", "city": "Copenhagen", "zipCode": "1068", "email": "gem.green@example.com" }, "accountNumber": "980001701791619", "identityNumber": "132426", "bankCode": "985" } }, "subscriptions": [ { "orderActions": [ { "type": "CreateSubscription", "triggerDates": [ { "name": "ContractEffective", "triggerDate": "2019-01-01" }, { "name": "ServiceActivation", "triggerDate": "2019-02-01" }, { "name": "CustomerAcceptance", "triggerDate": "2019-02-01" } ], "createSubscription": { "terms": { "initialTerm": { "startDate": "2019-01-01", "period": 12, "periodType": "Month", "termType": "TERMED" }, "renewalSetting": "RENEW_WITH_SPECIFIC_TERM", "renewalTerms": [ { "period": 12, "periodType": "Month" } ] }, "subscribeToRatePlans": [ { "productRatePlanId": "b090625904924ec6c7d8f7db06f3d252" } ] } } ] } ], "processingOptions": { "runBilling": true, "collectPayment": true } }
Response
{ "success": true, "orderNumber": "OM-00002", "accountNumber": "A00000001", "status": "Completed", "subscriptions": [ { "subscriptionNumber": "SM-00001", "status": "Active" } ], "invoiceNumbers": [ "INV00000001" ], "paymentNumber": "P-00000002", "paidAmount": 300 }
Creating a subscription for an existing customer is slightly different. You need to replace the newAccount
field with the existingAccountNumber
field.
The following example creates the same subscription as in the example above for an existing customer (accountNumber
= A00000002
).
API operation
Create order (new subscription)
Request
POST https://rest.apisandbox.zuora.com/v1/order
Request body
{ "orderDate": "2019-01-01", "existingAccountNumber": "A00000002", "subscriptions": [ { "orderActions": [ { "type": "CreateSubscription", "triggerDates": [ { "name": "ContractEffective", "triggerDate": "2019-01-01" }, { "name": "ServiceActivation", "triggerDate": "2019-02-01" }, { "name": "CustomerAcceptance", "triggerDate": "2019-02-01" } ], "createSubscription": { "terms": { "initialTerm": { "startDate": "2019-01-01", "period": 12, "periodType": "Month", "termType": "TERMED" }, "renewalSetting": "RENEW_WITH_SPECIFIC_TERM", "renewalTerms": [ { "period": 12, "periodType": "Month" } ] }, "subscribeToRatePlans": [ { "productRatePlanId": "b090625904924ec6c7d8f7db06f3d262" } ] } } ] } ], "processingOptions": { "runBilling": true, "collectPayment": true } }
Response
{ "success": true, "orderNumber": "OM-00003", "accountNumber": "A00000002", "status": "Completed", "subscriptions": [ { "subscriptionNumber": "SM-00002", "status": "Active" } ], "invoiceNumbers": [ "INV00000002" ], "paymentNumber": "P-00000003", "paidAmount": 300 }
Use case
API operation
Preview order (new subscription)
Request
POST https://rest.apisandbox.zuora.com/v1/orders/preview
Request body
{ "orderDate": "2019-01-01", "previewOptions": { "previewThruType": "SpecificDate", "specificPreviewThruDate" : "2019-01-01", "previewTypes": [ "OrderMetrics", "BillingDocs”, "ChargeMetrics" ] }, "previewAccountInfo": { "billCycleDay": 28, "soldToContact":{ "city":"Chamblee", "state": "Georgia", "country": "USA", "postalCode": "30341" }, "currency":"USD" }, "subscriptions": [ { "orderActions": [ { "type": "CreateSubscription", "triggerDates": [ { "name": "ContractEffective", "triggerDate": "2018-12-01" }, { "name": "ServiceActivation", "triggerDate": "2018-12-01" }, { "name": "CustomerAcceptance", "triggerDate": "2019-01-01" } ], "createSubscription": { "terms": { "initialTerm": { "startDate": "2018-12-01", "period": 12, "periodType": "Month", "termType": "TERMED" }, "renewalSetting": "RENEW_WITH_SPECIFIC_TERM", "renewalTerms": [ { "period": 12, "periodType": "Month" } ] }, "subscribeToRatePlans": [ { "productRatePlanId": "b090625904924ec6c7d8f7db06f3d252" } ] } } ] } ] }
Response
{ "success": true, "previewResult": { "chargeMetrics": [ { "subscriptionNumber": null, "charges": [ { "productRatePlanId": "b090625904924ec6c7d8f7db06f3d252", "productRatePlanChargeId": "b09062591cf82bc670222fbc55401a8d", "originRatePlanId": null, "chargeNumber": null, "cmrr": { "regular": 15.99, "discount": null, "regularDelta": 15.99, "discountDelta": null }, "tcv": { "regular": 191.88, "discount": null, "regularDelta": 191.88, "discountDelta": null }, "tcb": { "regular": 191.88, "discount": null, "regularDelta": 191.88, "discountDelta": null } } ] } ], "invoices": [ { "amount": 30.38, "amountWithoutTax": 30.38, "taxAmount": 0.00, "targetDate": "2019-01-01", "invoiceItems": [ { "serviceStartDate": "2018-12-01", "serviceEndDate": "2018-12-27", "amountWithoutTax": 14.39, "taxAmount": 0.000000000, "chargeDescription": null, "chargeName": "Gamer Elite", "chargeNumber": null, "processingType": "Charge", "productName": "CloudStream Gamer", "productRatePlanChargeId": "b09062591cf82bc670222fbc55401a8d", "subscriptionNumber": null, "additionalInfo": { "quantity": 1, "unitOfMeasure": "" } }, { "serviceStartDate": "2018-12-28", "serviceEndDate": "2019-01-27", "amountWithoutTax": 15.99, "taxAmount": 0.000000000, "chargeDescription": null, "chargeName": "Gamer Elite", "chargeNumber": null, "processingType": "Charge", "productName": "CloudStream Gamer", "productRatePlanChargeId": "b09062591cf82bc670222fbc55401a8d", "subscriptionNumber": null, "additionalInfo": { "quantity": 1, "unitOfMeasure": "" } } ] } ], "orderMetrics": [ { "orderActions": [ { "sequence": 0, "type": "CreateSubscription", "orderMetrics": [ { "productRatePlanChargeId": "b09062591cf82bc670222fbc55401a8d", "originRatePlanId": null, "tcb": [ { "subscriptionOwner": "A00000015", "invoiceOwner": "A00000015", "amount": 191.88, "endDate": "2019-11-30", "termNumber": 1, "tax": null, "type": "Regular", "startDate": "2018-12-01" } ], "quantity": [ { "subscriptionOwner": "A00000015", "invoiceOwner": "A00000015", "amount": 1.000000000, "endDate": "2019-11-30", "termNumber": 1, "startDate": "2018-12-01" } ], "productRatePlanId": "b090625904924ec6c7d8f7db06f3d252", "tcv": [ { "subscriptionOwner": "A00000015", "invoiceOwner": "A00000015", "amount": 191.88, "endDate": "2019-11-30", "termNumber": 1, "type": "Regular", "startDate": "2018-12-01" } ], "chargeNumber": null, "mrr": [ { "subscriptionOwner": "A00000015", "invoiceOwner": "A00000015", "amount": 15.99, "endDate": "2019-11-30", "termNumber": 1, "type": "Regular", "startDate": "2018-12-01" } ] } ] } ], "subscriptionNumber": null } ] } }
In this use case, we’ll update the bill-to contact information of an account using the Update account operation.
Zuora requires two types of contacts to be associated with an account: bill-to contact and sold-to contact. Bill-to contact determines where the invoice should be delivered, whereas sold-to contact determines how taxes are calculated. If the invoice delivery preference is email, the bill-to contact must contain an email address.
The following example updates the bill-to contact information for an account (id
= 2c92c0f968e566ad0168ef36f27d057c
).
API operation
Update contact
Request
PUT https://rest.apisandbox.zuora.com/v1/accounts/2c92c0f968e566ad0168ef36f27d057c
Request body
{ "billToContact":{ "FirstName": "FN_new", "LastName": "LN_new", "Address1": "123 Main St", "City": "Atlanta", "State": "GA", "Country": "USA" } }
Response
{ "Success": true, }
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 an 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:
To learn how to do this implement your own Payment Pages, see Payment Pages 2.0 Implementation Overview.
Note: 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 out of the scope of 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 codes of Payment Pages 2.0 and the corresponding libraries.
Payment methods created from Payment Pages must be associated with a Zuora account. If end subscribers create a payment method while creating an account, thee created payment method is automatically associated with the created account.
Zuora Payment Pages 2.0 provides the flexibility to allow end subscribers to enter their payment method information without creating or logging into their accounts. Such standalone payment methods will be deleted if they are not associated with any Zuora account within 240 hours. To avoid standalone payment methods from being deleted, end customers have to either:
or
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.
Alternatively, you can use the CRUD: Update payment method operation to associate a standalone payment method to an account. It gives you more flexibility to associate payment methods with customer accounts. An API example is provided below.
For example, a standalone PayPal Express Checkout payment method (PaymentMethodId
= 2c92c0fb732e0ff601734c51b6bd086a) was already created. Later, you can use the following API example to associate it with the customer account (AccountId
= 2c92c0f968e566ad0168ef1fd8645d6f).
API operation
Request
PUT https://rest.zuora.com/v1/object/payment-method/2c92c0fb732e0ff601734c51b6bd086a
Request body
{ "AccountId": "2c92c0f968e566ad0168ef1fd8645d6f", "Email": "jo.zo@zuora.com", "UseDefaultRetryRule": true }
Response
{ "Success": true, "Id": "2c92c0fb732e0ff601734c51b6bd086a" }
A check box might be introduced outside of the iFrame to allow end subscribers to identify the card as the default payment method. Once a payment method is created via Payment Page, a refID
will be returned, which is the ID of the payment method. At that point, the Update account operation can be used (if the checkbox is selected) to update the default payment method of the account.
Note: You can update the default payment method of an account only after this payment method has been associated with the account.
After you have a default payment method, payments can be automatically collected and processed. You can use either Payment Runs in Zuora or the Advanced Payment Manager app of Zuora Collect to collect payments.
If you want to use Payment Runs to collect payments, enable AutoPay for all accounts. If you want to use the Advanced Payment Manager to collect payments, set APM
to True
for all accounts.
The following example updates the account (accountId
= 2c92c0f968e566ad0168ef36f27d057c) to set the default payment method (paymentMethodId
= 2c92c0f872c68b450172dad9c61e436b).
API operation
Request
PUT https://rest.zuora.com/v1/accounts/2c92c0f968e566ad0168ef36f27d057c
Request body
{ "defaultPaymentMethodId": "2c92c0f872c68b450172dad9c61e436b" }
Response
{ "success": true }
You can delete a payment method if it is not the default payment method for a customer account. Use the Delete payment method operation to delete a non-default payment method.
The following API example deletes the non-default payment method (paymentMethodId
= 2c92c0f8707b70a401707f96b27a279b).
API operation
Request
DELETE https://rest.zuora.com/v1/payment-methods/2c92c0f8707b70a401707f96b27a279b
Response
{ "success": true }
End subscribers might want to view their invoices associated with their accounts. To retrieve invoices, the following steps are required:
Use the Get invoices operation to retrieve all invoices associated with customers’ accounts. The returned response contains the link to different versions of invoices.
For example, the following API example retrieves all invoices on the account (accountId
= 2c92c0f968e566ad0168ef36f27d057c).
Note that zuora-version:228.0
is used in the header of the request for better performance.
API operation
Request
GET https://rest.apisandbox.zuora.com/v1/transactions/invoices/accounts/2c92c0f968e566ad0168ef36f27d057c
Response
{ "invoices": [ { "id": "2c92c0946a547ed7016a575efdca44a8", "accountId": "2c92c0f968e566ad0168ef36f27d057c", "accountNumber": "A00010085", "accountName": "West Corp", "invoiceDate": "2020-06-19", "invoiceNumber": "INV00001932", "dueDate": "2020-06-19", "invoiceTargetDate": "2020-06-19", "amount": 6745.850000000, "balance": 6745.850000000, "creditBalanceAdjustmentAmount": 0.000000000, "createdBy": "2c92c0f956bc8fcb0156f8eee04b4d54", "status": "Draft", "body": "/v1/files/2c92c08b72c69a5e0172c9a9476c70c0", "invoiceItems": "/v1/invoices/2c92c08572c68b110172c9a91c557f89/items", "invoiceFiles": "/v1/invoices/2c92c08b6b695b93016b6d7692236079/files" } ], "success": true }
To download the latest invoice PDF file, you can use the path returned in the body
field and make another call. To download all historical versions of invoice PDF files, use the path returned in the pdfFileUrl
field instead.
For example, the following API example allows you to retrieve the latest version of the invoice PDF file:
API operation
Request
GET https://rest.apisandbox.zuora.com/v1/files/2c92c08b72c69a5e0172c9a9476c70c0
Response
The Content-Type
header in the response is application/pdf
, so you can download the response as the invoice PDF file.
Zuora notifications and callouts
Zuora has predefined triggers on which callouts and emails can be sent. A standard callout performs a POST operation to a specified external URL. It supports the basic authentication scheme, as well as the simple (non-nested) JSON structure in the request.
Refer to Standard events to view all standard events for notifications and callouts. To get more details on Zuora’s callout configuration, see Configure Callout Notifications.
Custom event triggers and notification
To define a custom event, you must specify the base object and the trigger condition. When a Zuora object changes, the trigger condition defined on the object is evaluated. If the condition is satisfied, a business event will be triggered.
Custom event triggers allow the creation of custom trigger conditions that can result in a callout or email. Custom event triggers can be created only through API and require an OAuth authentication. The trigger is supported only for specified objects listed in the Create an event trigger operation. Additionally, the condition must rely on the fields of the base objects.
See Custom events for more information.
Take the following steps to create a custom callout or email:
1. Create a custom event trigger. For example, you want to create an event trigger named “RPC changed” on the RatePlanCharge object. Changing a rate plan charge record on the RatePlanCharge object can trigger this event.
API operation
Request
POST https://rest.apisandbox.zuora.com/events/event-triggers
Request body
{ "active": true, "baseObject": "RatePlanCharge", "condition": "changeType == 'UPDATE' && RatePlanCharge.CustomField__c != RatePlanCharge.CustomField__c_old", "description": "RPC changed", "eventType": { "description": "RPCCustomFieldChanged", "displayName": "RPCCustomFieldChanged", "name": "RPCCustomFieldChanged" } }
Response
{ "id": "629fc708b8ba4746a22a420ba3e005e2", "baseObject": "RatePlanCharge", "condition": "changeType == 'UPDATE'", "description": "RPC changed", "eventType": { "name": "RPCChanged", "displayName": "RPCChanged", "description": "RPCChanged", "namespace": "user.notification" }, "active": true }
2. Create a notification definition using one of the following approaches:
https://www.example.com/callout/AccountEdit
when the AccountEdit event type is triggered. Later, if changes are made to a qualified account, a callout will be made.API operation
Create a notification definition
Request
POST https://rest.apisandbox.zuora.com/notifications/notification-definitions
Request body
{ "active": true, "callout": { "active": true, "calloutAuth": { "domain": "example_domain", "password": "example_password", "preemptive": true, "username": "example_user" }, "calloutBaseurl": "https://www.example.com/callout/AccountEdit", "calloutParams": { "AccountName": "", "AccountNumber": "" }, "calloutRetry": true, "description": "Callout when an account is edited", "eventTypeName": "AccountEdit", "httpMethod": "POST", "name": "Callout for Account Edited", "requiredAuth": true }, "calloutActive": true, "communicationProfileId": "6e569e1e05f040eda51a927b140c0ac5", "description": "Notification sent out when an account is edited", "emailActive": true, "emailTemplateId": "6e569e1e05f040eda51a927b140c0ac6", "eventTypeName": "AccountEdit", "filterRule": { "condition": "Account.Balance >= _VIP_BALANCE_AMOUNT && Account.Status == _ACCOUNT_STATUS", "description": "Filter rule to test if an account is a VIP account", "parameters": { "_ACCOUNT_STATUS": { "description": "The status of the VIP Account", "displayName": "VIP Account Status", "options": [ "Draft", "Active", "Canceled" ], "valueType": "STRING" }, "_VIP_BALANCE_AMOUNT": { "description": "The minimum account balance", "displayName": "VIP Account Balance", "options": null, "valueType": "BIG_DECIMAL" } } }, "filterRuleParams": { "_EDITED_FROM": "UI", "_VIP_ACCOUNT_BALANCE": "100000" }, "name": "Account Edit Notification" }
Response
{ "active": true, "callout": { "active": true, "calloutAuth": { "domain": "example_domain", "password": "example_password", "preemptive": true, "username": "example_user" }, "calloutBaseurl": "https://www.example.com/callout/AccountEdit", "calloutParams": { "AccountName": "", "AccountNumber": "" }, "calloutRetry": true, "description": "Callout when an account is edited", "eventTypeName": "AccountEdit", "httpMethod": "POST", "id": "6e569e1e05f040eda51a927b140c0ac7", "name": "Callout for Account Edited", "requiredAuth": true }, "calloutActive": true, "communicationProfileId": "6e569e1e05f040eda51a927b140c0ac5", "createdBy": "6e569e1e05f040eda51a927b140c0ac3", "createdOn": "2017-04-18T07:36:19.798Z", "description": "Notification sent out when an account is edited", "emailActive": true, "emailTemplateId": "6e569e1e05f040eda51a927b140c0ac6", "eventTypeName": "AccountEdit", "filterRule": { "condition": "Account.Balance >= _VIP_BALANCE_AMOUNT && Account.Status == _ACCOUNT_STATUS", "description": "Filter rule to test if an account is a VIP account", "eventTypeName": null, "id": "6e569e1e05f040eda51a927b140c0ac8", "parameters": { "_ACCOUNT_STATUS": { "description": "The status of the VIP Account", "displayName": "VIP Account Status", "options": [ "Draft", "Active", "Canceled" ], "valueType": "STRING" }, "_VIP_BALANCE_AMOUNT": { "description": "The minimum account balance", "displayName": "VIP Account Balance", "options": null, "valueType": "BIG_DECIMAL" } } }, "filterRuleParams": { "_EDITED_FROM": "UI", "_VIP_ACCOUNT_BALANCE": "100000" }, "id": "6e569e1e05f040eda51a927b140c0ac2", "name": "Account Edit Notification", "updatedBy": "6e569e1e05f040eda51a927b140c0ac4", "updatedOn": "2017-04-18T07:36:19.798Z" }
The following eight use cases all use the Create order operation to manage the subscriptions.
To use this operation, the Orders feature must be enabled for your tenant in the first place. Otherwise, you have to use Amendments or Subscriptions operations to manage the subscriptions.
Orders are contractual agreements between merchants and customers. All the operations on subscriptions in orders are done by order actions in the Create order operation. Zuora calculates order metrics when orders take place. The benefit of using the Create order operation is that it allows up to 50 order actions to be submitted in a single Create order operation.
In this use case, the end subscriber wants to cancel a subscription. When an end subscriber decides to terminate their subscription, there are three ways for the merchant to manage billing:
cancellationPolicy
field to EndOfLastInvoicePeriod
.cancellationPolicy
field to EndOfCurrentTerm
.To use this option for subscription cancellation, set the cancellationPolicy
field to SpecificDate
and specify the date for the cancellationEffectiveDate
field.
Note: Zuora also recommends you run billing and payment on subscription cancellation.
For this use case, only the CancelSubscription order action within the Create order operation is required. The cancellation is made effective on a specific day. The account that owns the order already exists. In the Create order operation, you will need to specify the following details for the subscription cancellation:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns the order.subscriptionNumber
: The number of the subscription to be canceled.cancellationPolicy
: The policy of the cancellation.cancellationEffectiveDate
: The effective date of the cancellation policy.At least one of the following billing trigger dates is also required in the Create order operations. The required billing trigger dates are determined by your company’s default subscription settings and it can vary by product. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the Zuora UI. For more information about the billing trigger dates, see Billing Trigger Dates.
ContractEffective
: The contract effective date of the cancellation.ServiceActivation
: The service activation date of the cancellation.CustomerAcceptance
: The end subscriber acceptance date of the cancellation.In the following eight use cases, you also need to specify the billing trigger date appropriately.
The following API request cancels the subscription S-0000123 and the cancellation is effective on a specific day, July 1, 2020. The account that owns this order is A-0000123.
As recommended, this Create order operation will also run billing and payment when canceling the subscription. Therefore you will get the invoice and payment information in the response if any.
API operation
Create order (Cancel a subscription)
Request
POST https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate": "2020-07-01", "existingAccountNumber": "A-0000123", "subscriptions": [ { "subscriptionNumber": "A-S0000123", "orderActions": [ { "type": "CancelSubscription", "triggerDates": [ { "name": "ContractEffective", "triggerDate": "2020-07-01" } ], "cancelSubscription": { "cancellationPolicy": "SpecificDate", "cancellationEffectiveDate": "2020-07-01" } } ] } ], "processingOptions": { "runBilling": true, "collectPayment": true } }
To make the subscription cancellation effective at the end of the last invoiced period, replace the highlighted bold lines in the above API request with the following:
{ "cancellationPolicy": "EndOfLastInvoicePeriod" }
To make the subscription cancellation effective at the end of the current term for a termed subscription, replace the highlighted lines in the API request above with the following:
{ "cancellationPolicy": "EndOfCurrentTerm" }
When the request is successful, the following response is returned.
Response
{ "success": true, "orderNumber": "O-00000832", "accountNumber": "A-0000123", "status": "Completed", "subscriptionNumbers": [ "A-S0000123" ], "invoiceNumbers": [ "INV00000093" ], "paymentNumber": "P-00000003", "paidAmount": 10.000000000 }
When a subscription expires or before it expires, you can renew the subscription. In this scenario, the RenewSubscription order action is used in the Create order operation. You will need to specify the following details:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns the order.subscriptionNumber
: The number of the subscription to be renewed.Tip: To create the order under a new account instead of an existing account, specify the newAccount
field instead of the existingAccountNumber
field.
At least one of the following billing trigger dates is also required in the Create order operations. The required billing trigger dates are determined by your company’s default subscription settings and it can vary by product. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the Zuora UI. For more information about the billing trigger dates, see Billing Trigger Dates.
ContractEffective
: The contract effective date of the renewal.ServiceActivation
: The service activation date of the renewal.CustomerAcceptance
: The end subscriber acceptance date of the renewal.Note: The renewal is effective as soon as you create and save the renewal. If you specify a future date for the ContractEffective
or ServiceActivation
field, this future date will be ignored.
The following API request renews the subscription A-S00000003 for an existing account A00000001 without running billing or payment, and the renewal is effective immediately on June 16, 2020.
API operation
Create order (Renew a subscription)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-06-16", "existingAccountNumber": "A00000001", "subscriptions":[ { "subscriptionNumber":"A-S00000003", "orderActions":[ { "type": "RenewSubscription", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-06-16" }, { "name":"ServiceActivation", "triggerDate":"2020-06-16" }, { "name":"CustomerAcceptance", "triggerDate":"2020-06-16" } ] } ] } ], "processingOptions":{ "runBilling":false, "collectPayment":false } }
Response
{ "success": true, "orderNumber": "O-00000009", "accountNumber": "A00000001", "status": "Completed", "subscriptionNumbers": [ "A-S00000003" ] }
When an end subscriber decides to add a product to their subscription, he or she needs to pick one product rate plan from the product. When you add the product rate plan to their subscription, you can also change the default pricing of the product rate plan charge, which determines how the current end subscriber will be charged for this product.
Note: The product rate plan ID comes from the product catalog.
In this scenario, the AddProduct order action is used in the Create Order operation. You will need to provide the following information in the API request:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns the order.subscriptionNumber
: The number of the subscription to be updated.productRatePlanId
: The ID of the product rate plan to be added for the product.If you want to change the default pricing for the end subscriber, use the chargeOverrides
field and its nested fields to specify the following details, which are optional:
productRatePlanChargeId
: The ID of the product rate plan charge to be used for the product rate plan.pricing
: The pricing information on the product rate plan charge.Depending on your company’s subscription settings, at least one of the following billing trigger 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 the billing trigger 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.The following API request adds the following product rate plan to an existing account A00000144. It uses the recurring charge with the flat fee charge model.
productRatePlanId
= 2c92c0f96a34607f016a4bc964950ad9productRatePlanChargeId
= 2c92c0f86a34593d016a4bc9cd027ee9Moreover, the API request also overrides the default price of the rate plan charge and changes the per-unit price to 10 by using the chargeOverrides
field and its nested fields. If you don’t need to change the default pricing of the charge, you can skip the chargeOverrides
field and its nested fields in your API request.
This API request also runs billing and payment at the same time. You will get the invoice and payment information in the response if there is any.
API operation
Create order (Add a product)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-04-14", "existingAccountNumber":"A00000144", "subscriptions":[ { "subscriptionNumber":"A-S00019660", "orderActions":[ { "type":"AddProduct", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-04-14" }, { "name":"ServiceActivation", "triggerDate":"2020-04-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-04-14" } ], "addProduct":{ "productRatePlanId":"2c92c0f96a34607f016a4bc964950ad9", "chargeOverrides":[ { "productRatePlanChargeId":"2c92c0f86a34593d016a4bc9cd027ee9", "pricing":{ "recurringFlatFee":{ "listPrice":10 } } } ] } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success":true, "orderNumber":"O-00013282", "accountNumber":"A00000144", "status":"Completed", "subscriptionNumbers":[ "A-S00019660" ], "invoiceNumbers":[ "INV00000187" ], "paymentNumber":"P-00000085", "paidAmount":328.940000000 }
When an end subscriber wants to remove a product from their subscription, the end subscriber is actually removing a rate plan from the existing subscription.
Important: The rate plan ID is unique to the particular subscription and does not come from the product catalog. To get the rate plan ID for a particular subscription, you can use the Get subscription operation. The ID of the rate plan in this subscription is indicated by the returned id
field nested in the rataPlans
field.
In this scenario, the RemoveProduct order action is used in the Create order operation. You will need to provide the following information in the API request:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns this order.subscriptionNumber
: The number of existing subscription to be updated.ratePlanId
: The ID of the rate plan to remove from the subscription.Depending on your company’s subscription settings, at least one of the following billing trigger dates is also required. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the Zuora UI.
ContractEffective
: The contract effective date of product removal.ServiceActivation
: The service activation date of product removal.CustomerAcceptance
: The end subscriber acceptance date of the product removal.The following API request removes a rate plan (ratePlanId = 2c92c0fa7177a59b01717e9e580b15e7) from an active subscription A-S00019660 for an existing account A00000144.
This API request also runs billing and payment at the same time. Therefore you will get the invoice and payment information in the response if any. With the Invoice Settlement feature enabled, the credit memo number can also be returned in the response.
API operation
Create order (Remove a product)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-04-14", "existingAccountNumber":"A00000144", "subscriptions":[ { "subscriptionNumber":"A-S00019660", "orderActions":[ { "type":"RemoveProduct", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-04-14" }, { "name":"ServiceActivation", "triggerDate":"2020-04-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-04-14" } ], "removeProduct":{ "ratePlanId":"2c92c0fa7177a59b01717e9e580b15e7" } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success":true, "orderNumber":"O-00013284", "accountNumber":"A00000144", "status":"Completed", "subscriptionNumbers":[ "A-S00019660" ], "creditMemoNumbers":[ "CM00000004" ] }
When an end subscriber wants to upgrade or downgrade a product for a subscription, two order actions are required in the single Create order operation. One action is to remove the previous rate plan from the subscription, and the other is to add the new rate plan.
id
field nested in the rataPlans
field.In this scenario, both RemoveProduct and AddProduct actions are used in the Create order operation. You will need to provide the following information in the API request:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns this order.subscriptionNumber
: The number of existing subscription to be updated.The following fields are required for the RemoveProduct action:
ContractEffective
: The contract effective date of product removal.ServiceActivation
: The service activation date of product removal.CustomerAcceptance
: The end subscriber acceptance date of product removal.ratePlanId
: The ID of the rate plan to be removed from the subscription.The following fields are required for the AddProduct action:
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.productRatePlanId
: The ID of the product rate plan to add to the subscription.The following details are optional. Use the chargeOverrides
field and its nested fields to specify them only if you want to change the default pricing for the end subscriber.
productRatePlanChargeId
: The ID of the product rate plan charge to use when adding the product rate plan.pricing
: The pricing information on the product rate plan charge.The following API request removes the rate plan (ratePlanId
= 2c92c0fa7177a59d017179784d957ae6) from the subscription A-S00019660 for the existing account A00000144. It also adds another product rate plan (productRatePlanId
= 2c92c0f96a34607f016a4bc964950ad9).
The chargeOverrides
field is optional, which is used in this API request to change the default pricing of the rate plan charge (productRatePlanChargeId
= 2c92c0f86a34593d016a4bc9cd027ee9).
This API request also runs billing and payment at the same time. Therefore you will get the invoice and payment information in the response if any.
API operation
Create order (Upgrade/Downgrade a product)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-04-14", "existingAccountNumber":"A00000144", "subscriptions":[ { "subscriptionNumber":"A-S00019660", "orderActions":[ { "type":"RemoveProduct", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-04-14" }, { "name":"ServiceActivation", "triggerDate":"2020-04-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-04-14" } ], "removeProduct":{ "ratePlanId":"2c92c0fa7177a59d017179784d957ae6" } }, { "type":"AddProduct", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-04-14" }, { "name":"ServiceActivation", "triggerDate":"2020-04-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-04-14" } ], "addProduct":{ "productRatePlanId":"2c92c0f96a34607f016a4bc964950ad9", "chargeOverrides":[ { "productRatePlanChargeId":"2c92c0f86a34593d016a4bc9cd027ee9", "pricing":{ "recurringFlatFee":{ "listPrice":12.99 } } } ] } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success":true, "orderNumber":"O-00013285", "accountNumber":"A00000144", "status":"Completed", "subscriptionNumbers":[ "A-S00019660" ], "invoiceNumbers":[ "INV00000188" ], "paymentNumber":"P-00000086", "paidAmount":7.360000000 }
You can update the product quantity on a subscription only if the product uses the following pricing charge models:
If you request to update the product quantity for other pricing charge models, the request will result in an error.
In this scenario, the UpdateProduct order action is used in the Create order operation. You will need to provide the following information in the API request:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns this ordersubscriptionNumber
: The number of existing subscription to be updated.ratePlanId
: The ID of the subscription rate plan to be updated.chargeUpdates
: The details of the update including the charge number (chargeNumber
) and pricing information (pricing
).Depending on your company’s subscription settings, at least one of the following billing trigger 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 the billing trigger 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.The following API request updates the subscription A-S00019745 for the existing account A00000144. The subscription rate plan ID to be updated is 2c92c0f9715ce77b01717f5c34ef5ba5 and the recurring charge (C-00030203) that uses the Volume pricing charge model (recuringVolume
) is involved. The quantity is changed to 50 for this rate plan charge.
This API request also runs billing and payment at the same time. Therefore you will get the invoice and payment information in the response if any.
API operation
Create order (Update product quantity)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-04-15", "existingAccountNumber":"A00000144", "subscriptions":[ { "subscriptionNumber":"A-S00019745", "orderActions":[ { "type":"UpdateProduct", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-04-15" }, { "name":"ServiceActivation", "triggerDate":"2020-04-15" }, { "name":"CustomerAcceptance", "triggerDate":"2020-04-15" } ], "updateProduct":{ "ratePlanId":"2c92c0f9715ce77b01717f5c34ef5ba5", "chargeUpdates":[ { "chargeNumber":"C-00030203", "pricing":{ "recurringVolume":{ "quantity":50 } } } ] } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success":true, "orderNumber":"O-00013281", "accountNumber":"A00000144", "status":"Completed", "subscriptionNumbers":[ "A-S00019745" ], "invoiceNumbers":[ "INV00000186" ], "paymentNumber":"P-00000084", "paidAmount":268.67 }
If the end subscriber requests to suspend a subscription, use the Suspend order action in the Create order operation to do it. You will need to specify the following details in the Create order operation as usual:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns the order.subscriptionNumber
: The number of the subscription to be suspended.It is also required to specify the suspend policy in the API request. For example, the subscription can be suspended on a specific date or after a certain number of periods from today. Use the suspendPolicy
field in the API request for this purpose, which supports the following values:
Today
EndOfLastInvoicePeriod
FixedPeriodsFromToday
SpecificDate
Depending on the suspend policy that you choose, some other fields might also be required. For example, if you set suspendPolicy
field to FixedPeriodsFromToday
, you also need to specify the suspendPeriods
and suspendPeriodsType
fields. There are several restrictions on the suspend date to ensure that the suspend date is valid. For more information, see Suspend Date.
According to your company’s subscription settings, at least one of the following billing trigger dates is also required. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the UI. For more information about the billing trigger dates, see Billing Trigger Dates.
ContractEffective
: The contract effective date of the suspension.ServiceActivation
: The service activation date of the suspension.CustomerAcceptance
: The end subscriber acceptance date of the suspension.After a subscription is suspended, no other order action is allowed except for the Resume action.
The following API request suspends the subscription A-S00000006 for an existing account A00000001. Based on the suspend policy in this API request, the subscription will be suspended after 2 months from today, which is September 14, 2020.
The API request also runs billing and payment. So you will get the invoice and payment information in the response if there is any.
API operation
Create order (Suspend a subscription)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-07-14", "existingAccountNumber": "A00000001", "subscriptions":[ { "subscriptionNumber":"A-S00000006", "orderActions":[ { "type": "Suspend", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-07-14" }, { "name":"ServiceActivation", "triggerDate":"2020-07-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-07-14" } ], "suspend": { "suspendPolicy": "FixedPeriodsFromToday", "suspendPeriods": 2, "suspendPeriodsType": "Month" } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success": true, "orderNumber": "O-00000047", "accountNumber": "A00000001", "status": "Completed", "subscriptionNumbers": [ "A-S00000006" ], "invoiceNumbers": [ "INV00000098" ], "paymentNumber": "P-00000007", "paidAmount": 1496.400000000 }
When a subscription is in the Suspended status, the only action you can take is to resume a suspended subscription with the Resume order action. You will need to specify the following details in the Create order operation as usual:
orderDate
: The date when the order is signed.existingAccountNumber
: The number of the account that owns the order.subscriptionNumber
: The number of the subscription to be resumed.Similar to what you did to suspend a subscription, it is required to specify the resume policy in the API request to indicate when the suspended subscription is resumed. Use the resumePolicy field in the API request for this purpose, which supports the following values:
Today
FixedPeriodsFromSuspendDate
FixedPeriodsFromToday
SpecificDate
SuspendDate
No matter what resume policy you choose, the resume date cannot be earlier than the suspend date and cannot be later than the subscription term end date. For more information, see Resume Date.
According to your company’s subscription settings, at least one of the following billing trigger dates is also required. To check the subscription settings, navigate to Billing Settings > Default Subscription and Order Settings in the UI. For more information about the billing trigger dates, see Billing Trigger Dates.
ContractEffective
: The contract effective date of the resume.ServiceActivation
: The service activation date of the resume.CustomerAcceptance
: The end subscriber acceptance date of the resume.The following API request resumes the subscription A-S00000006 for an existing account A00000001. This subscription is suspended from September 14, 2020 in the Suspend a subscription case. This API request resumes the subscription one month after the suspend date. So the subscription A-S00000006 will be resumed on October 14, 2020.
In addition, this API request extends the subscription term by the length of the suspension (which is 2 months in the Suspend a subscription example) by using the extendsTerm
field, which is an optional field. It also runs billing and payment. So you will get the invoice and payment information in the response if there is any.
API operation
Create order (Resume a subscription)
Request
POST: https://rest.apisandbox.zuora.com/v1/orders
Request body
{ "orderDate":"2020-07-14", "existingAccountNumber": "A00000001", "subscriptions":[ { "subscriptionNumber":"A-S00000006", "orderActions":[ { "type": "Resume", "triggerDates":[ { "name":"ContractEffective", "triggerDate":"2020-07-14" }, { "name":"ServiceActivation", "triggerDate":"2020-07-14" }, { "name":"CustomerAcceptance", "triggerDate":"2020-07-14" } ], "resume": { "resumePolicy": "FixedPeriodsFromSuspendDate", "resumePeriods": 1, "resumePeriodsType": "Month", "extendsTerm": true } } ] } ], "processingOptions":{ "runBilling":true, "collectPayment":true } }
Response
{ "success": true, "orderNumber": "O-00000053", "accountNumber": "A00000001", "status": "Completed", "subscriptionNumbers": [ "A-S00000006" ] }
If you use usage-based charge models (such as per-unit or tiered-pricing), you have to aggregate usage data and upload to Zuora. The configured charge model will be applied to convert usage into charges.
In Zuora, usage is measured by units and no restrictions exist for what is measured by your units. For example, a unit can represent a seat, a license, or even a gigabyte of storage. You can also create new units of measure at any time by navigating to Billing > Customize Units of Measure in the Zuora UI.
You have several options to upload usage records to Zuora, and you can choose the option that best fits your needs.
Regardless of the upload option you choose, usage uploads are automatically set to the Pending status. This status indicates that the usage is waiting to be billed. After the usage is billed (when you post an invoice that contains these usage charges), the status will be updated to Processed.
Option 1: Use the create action operation
You can use the Create action to create up to 50 usage records in a single call by passing the values of each required field in the JSON payload. This operation does not require the template file that is required in option 2.
Option 2: Using the mass upload usage operation
To upload usage charges using the mass upload usage operation, you must first download and populate the Export Usage File template from the Zuora UI. Note the usage file will not import successfully if any of the column field names in the downloaded usage template do not exist in the uploaded usage file.
To download the template, do the following:
To receive notifications, enable the Import notifications for completion and failure by navigating to Billings > Setup Profiles, Notifications and Email Templates through the Zuora UI.
API operation
Create action (Create usage object)
Request
POST: https://rest.apisandbox.zuora.com/v1/action/create
Request body
{ "objects":[ { "AccountNumber":"A00000035", "UOM":"GB", "Quantity":"50", "StartDateTime":"2020-03-01T02:00:00", "EndDateTime":"2020-03-30T02:00:00", "SubscriptionNumber":"A-S00019746", "ChargeNumber":"C-00030206", "Description":"This is a usage charge for Sub A-S00019746" }, { "AccountNumber":"A00000034", "UOM":"Each", "Quantity":"20", "StartDateTime":"2020-03-01T02:00:00", "EndDateTime":"2020-03-30T02:00:00", "SubscriptionNumber":"A-S00019747", "ChargeNumber":"C-00030207", "Description":"This is a usage charge for Sub A-S00019747" } ], "type":"Usage" }
Response
[ { "Success":true, "Id":"2c92c0f87186ea0d01718898c35a0bd2" }, { "Success":true, "Id":"2c92c0f87186ea0d01718898c3710bd3" } ]
The sample usage CSV file is as follows:
ACCOUNT_ID,UOM,QTY,STARTDATE,ENDDATE,SUBSCRIPTION_ID,CHARGE_ID,DESCRIPTION A00000013,Each,200,7/15/2020,7/31/2020,A-S00000087,,License A00000013,Each,400,8/1/2020,8/31/2020,A-S00000087,,License
API operation
Request
POST: https://rest.apisandbox.zuora.com/v1/usage
The request must allow file consumption. The following information is a sample cURL command:
curl -X POST -H "Authorization: Bearer f21f017e4724445d8647b1f0de7ed6f1" -F "file=@UsageData.csv" "https://rest.apisandbox.zuora.com/v1/usage"
Response
{ "success" : true, "size" : 197, "checkImportStatus" : "/v1/usage/2c92c0fb72ff6f0501730193263716f8/status" }
If you have configured the notification, you’ll receive an email about the result of the import.
You can check the uploaded usage records by navigating to Billing > Usage through the Zuora UI.
Credit memos are legal documents used to correct charge mistakes on invoices and manage the balance on a particular invoice or customer account.
Credit memos can be generated in one of the following ways through the Zuora API:
The following API request retrieves all credit memos of the account (accountId
= 2c92c0f86a583eb9016a6b8873191a44). It also sets the zuora-version
header parameter to 257.0
to use the description
field. For information about REST API version control, see Minor Version.
After the credit memo is created, you can check the created credit memo by navigating to Billing > Credit and Debit Memos through the Zuora UI.
API operation
Create a credit memo from an invoice
Request
POST https://rest.apisandbox.zuora.com/v1/invoices/2c92c0996ade64b9016ae100ff683a28/creditmemos
Request body
{ "autoApplyToInvoiceUponPosting": false, "comment": "1st comment", "effectiveDate": "2020-06-15", "excludeFromAutoApplyRules": false, "items": [ { "amount": 50, "description": "item description", "invoiceItemId": "2c92c0856b26b267016b28cd20994b4a", "quantity": 1, "serviceEndDate": "2020-06-15", "serviceStartDate": "2020-06-15", "skuName": "SKU-30", "taxItems": [], "unitOfMeasure": "Each" } ], "reasonCode": "Charge Dispute" }
Response
{ "id": "2c92c0fb72a8521a0172bbe7cbb835a5", "number": "CM00000018", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "currency": "USD", "creditMemoDate": "2020-06-15", "targetDate": null, "postedById": null, "postedOn": null, "status": "Draft", "amount": 50.00, "taxAmount": 0.00, "totalTaxExemptAmount": 0.00, "unappliedAmount": 50.00, "refundAmount": 0.000000000, "appliedAmount": 0.000000000, "comment": "1st comment", "source": "AdhocFromInvoice", "sourceId": null, "referredInvoiceId": "2c92c0996ade64b9016ae100ff683a28", "reasonCode": "Charge Dispute", "createdDate": "2020-06-15 23:53:49", "createdById": "2c92c0f96a6e3c34016a70cc7fbf6730", "updatedDate": "2020-06-15 23:53:49", "updatedById": "2c92c0f96a6e3c34016a70cc7fbf6730", "cancelledOn": null, "cancelledById": null, "latestPDFFileId": null, "Custom_CM__c": "20", "transferredToAccounting": "No", "excludeFromAutoApplyRules": false, "autoApplyUponPosting": false, "taxStatus": null, "taxMessage": null, "success": true }
The following information is an example to create a credit memo (amount
= $20) from a product rate plan charge. The credit memo is credited back to an account with the ID 2c92c0f86a583eb9016a6b8873191a44. It also set the zuora-version
header parameter to 224.0
to use the amount
field. For information about REST API version control, see Minor Version.
API operation
Create credit memo from charge
Request
POST https://rest.apisandbox.zuora.com/v1/creditmemos
Request body
{ "accountId": "2c92c0f86a583eb9016a6b8873191a44", "charges": [ { "amount": 20, "chargeId": "2c92c0f96c74eee1016c78d16bb47221", "comment": "CM from Product Charges", "quantity": 1, "serviceEndDate": "2020-06-17", "serviceStartDate": "2020-06-17" } ], "comment": "Credit memo date", "effectiveDate": "2020-06-17", "reasonCode": "Correcting invoice error" }
Response
{ "id": "2c92c0fa72c087a90172c13184eb6481", "number": "CM00000019", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "currency": "USD", "creditMemoDate": "2020-06-17", "targetDate": null, "postedById": null, "postedOn": null, "status": "Draft", "amount": 20.00, "taxAmount": 0.00, "totalTaxExemptAmount": 0.00, "unappliedAmount": 20.00, "refundAmount": 0.000000000, "appliedAmount": 0.000000000, "comment": "Credit memo date", "source": "AdhocFromPrpc", "sourceId": null, "referredInvoiceId": null, "reasonCode": "Correcting invoice error", "createdDate": "2020-06-17 00:32:27", "createdById": "2c92c0f96a6e3c34016a70cc7fbf6730", "updatedDate": "2020-06-17 00:32:27", "updatedById": "2c92c0f96a6e3c34016a70cc7fbf6730", "cancelledOn": null, "cancelledById": null, "latestPDFFileId": null, "Custom_CM__c": "20", "transferredToAccounting": "No", "excludeFromAutoApplyRules": false, "autoApplyUponPosting": false, "taxStatus": "Complete", "taxMessage": null, "success": true }
The end subscriber might want to view the credits in their account. You can retrieve the credit memos or credit memo items through the Zuora API and view the details on the portal.
Depending on the level of details you need, you can retrieve all credit memos of an account, a particular credit memo (identified by ID), or all items of a credit memo. Deeper levels of details such as credit memo parts or credit memo item parts can also be retrieved by API operations.
Note: The credit memo ID is different from the credit memo number.
Using the Get credit memos operation, you can filter the results by using the accountId
query parameter. Otherwise, you’ll get information about all credit memos in your Zuora tenant.
The following API request retrieves all credit memos of the account (accountId
= 2c92c0f86a583eb9016a6b8873191a44).
API operation
Request
GET https://rest.zuora.com/v1/creditmemos?accountId=2c92c0f86a583eb9016a6b8873191a44
Response
{ "creditmemos": [ { "id": "2c92c0f96a6e3c35016a753dca702fa3", "number": "CM00000003", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "currency": "USD", "creditMemoDate": "2019-05-01", "targetDate": null, "postedById": "2c92c0f96a58497e016a6b5797d52fe6", "postedOn": "2019-05-01 16:38:50", "status": "Posted", "amount": 30.000000000, "taxAmount": 0.000000000, "totalTaxExemptAmount": 0.000000000, "unappliedAmount": 0.000000000, "refundAmount": 0.000000000, "appliedAmount": 30.000000000, "comment": "", "source": "AdhocFromPrpc", "sourceId": null, "referredInvoiceId": null, "reasonCode": "Correcting invoice error", "createdDate": "2019-05-01 14:12:24", "createdById": "2c92c0f96a58497e016a6b5797d52fe6", "updatedDate": "2019-05-01 16:39:11", "updatedById": "2c92c0f96a58497e016a6b5797d52fe6", "cancelledOn": null, "cancelledById": null, "latestPDFFileId": "2c92c08a6a6e055f016a75c3dd256b1a", "Custom_CM__c": null, "transferredToAccounting": "No", "excludeFromAutoApplyRules": false, "autoApplyUponPosting": false, "taxStatus": null, "taxMessage": null }, { "id": "2c92c0f86a6e0622016a704b481132c4", "number": "CM00000001", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "currency": "USD", "creditMemoDate": "2019-04-30", "targetDate": null, "postedById": "2c92c0f96a58497e016a6b5797d52fe6", "postedOn": "2019-04-30 15:09:03", "status": "Posted", "amount": 50.000000000, "taxAmount": 0.000000000, "totalTaxExemptAmount": 0.000000000, "unappliedAmount": 0.000000000, "refundAmount": 50.000000000, "appliedAmount": 0.000000000, "comment": "", "source": "AdhocFromInvoice", "sourceId": null, "referredInvoiceId": "2c92c09a6a6e0502016a703e6b915d79", "reasonCode": "Correcting invoice error", "createdDate": "2019-04-30 15:09:02", "createdById": "2c92c0f96a58497e016a6b5797d52fe6", "updatedDate": "2019-04-30 15:20:36", "updatedById": "2c92c0f96a58497e016a6b5797d52fe6", "cancelledOn": null, "cancelledById": null, "latestPDFFileId": "2c92c08a6a6e055f016a704b4aa5378d", "Custom_CM__c": null, "transferredToAccounting": "No", "excludeFromAutoApplyRules": false, "autoApplyUponPosting": true, "taxStatus": null, "taxMessage": null } ], "success": true }
This API request retrieves the data of a credit memo (memoId
= 2c92c0fa72c087a90172c13184eb6481).
API operation
Request
GET https://rest.zuora.com/v1/creditmemos/2c92c0fa72c087a90172c13184eb6481
Response
{ "id": "2c92c0fa72c087a90172c13184eb6481", "number": "CM00000019", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "currency": "USD", "creditMemoDate": "2020-06-17", "targetDate": null, "postedById": null, "postedOn": null, "status": "Draft", "amount": 20.000000000, "taxAmount": 0.000000000, "totalTaxExemptAmount": 0.000000000, "unappliedAmount": 20.000000000, "refundAmount": 0.000000000, "appliedAmount": 0.000000000, "comment": "Credit memo date", "source": "AdhocFromPrpc", "sourceId": null, "referredInvoiceId": null, "reasonCode": "Correcting invoice error", "createdDate": "2020-06-17 00:32:27", "createdById": "2c92c0f96a6e3c34016a70cc7fbf6730", "updatedDate": "2020-06-17 00:32:27", "updatedById": "2c92c0f96a6e3c34016a70cc7fbf6730", "cancelledOn": null, "cancelledById": null, "latestPDFFileId": "2c92c08a72c086ef0172c1318d4f08f6", "Custom_CM__c": "20", "transferredToAccounting": "No", "excludeFromAutoApplyRules": false, "autoApplyUponPosting": false, "taxStatus": "Complete", "taxMessage": null, "success": true }
In Zuora, you can refund fully or partially unapplied payments to your end subscribers by refunding from payment. You can also issue full or partial refunds for posted credit memos to your end subscribers by refunding credit memos.
When you issue a refund in either way, the following fields are always required:
totalAmount
: The total amount of the refund.type
: The type of refund.The total amount of the refund cannot exceed the unapplied amount of the associated payment or credit memo. If you want to refund the applied amount of the associated payment or credit memo, you must first unapply the applied amount from the invoices or debit memos, and then refund the unapplied amount to your end subscribers.
The refund type can be either External or Electronic. External refunds are performed outside of Zuora and electronic refunds are issued by using supported payment gateways.
If the refund type is Electronic, you cannot specify the refund date because the electronic refund will automatically refund money to the end subscriber’s credit card.
The following example uses the Refund payment operation to refund part of the unapplied amount ($25) from the payment. The total unapplied amount of the payment is $139.67. The payment ID is 2c92c0f96a6e3c3f016a702afb315193. This is an external refund, so the refund date is set to June 28, 2020. After the refund is applied, the unapplied amount of the payment is $114.67.
API operation
Request
POST https://rest.apisandbox.zuora.com/v1/payments/2c92c0f96a6e3c3f016a702afb315193/refunds
Request body
{ "comment": "Create a refund for unapplied payment.", "gatewayOptions": { "Comments": "test", "IPAddress": "192.168.1.1" }, "methodType": "CreditCard", "reasonCode": "Standard Refund", "refundDate": "2020-06-28", "totalAmount": 25.0, "type": "External" }
Response
{ "id": "2c92c0fb72e0de4f0172fec6a42e4581", "number": "R-00000005", "status": "Processed", "type": "External", "methodType": "CreditCard", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "amount": 25.000000000, "refundDate": "2020-06-28", "comment": "Create a refund for unapplied payment.", "paymentMethodId": "2c92c0f96a58497e016a6b57b4f83064", "paymentMethodSnapshotId": null, "paymentId": "2c92c0f96a6e3c3f016a702afb315193", "creditMemoId": null, "reasonCode": "Standard Refund", "gatewayId": null, "gatewayResponse": null, "gatewayResponseCode": null, "gatewayState": "NotSubmitted", "markedForSubmissionOn": null, "referenceId": null, "secondRefundReferenceId": null, "softDescriptor": null, "softDescriptorPhone": null, "submittedOn": null, "settledOn": null, "cancelledOn": null, "createdDate": "2020-06-28 23:32:10", "createdById": "2c92c0f96a6e3c34016a70cc7fbf6730", "updatedDate": "2020-06-28 23:32:10", "updatedById": "2c92c0f96a6e3c34016a70cc7fbf6730", "refundTransactionTime": null, "financeInformation": { "bankAccountAccountingCode": null, "bankAccountAccountingCodeType": null, "unappliedPaymentAccountingCode": null, "unappliedPaymentAccountingCodeType": null, "transferredToAccounting": "No" }, "success": true }
The following example uses the Refund credit memo operation to refund part of the unapplied amount ($10) from the credit memo. The total unapplied amount of the payment is $20. The payment ID is 2c92c0fa72c087a90172c13184eb6481. This is an external refund, so the refund date is set to June 28, 2020. After the refund is applied, the unapplied amount of the credit memo is $20.
API operation
Request
POST https://rest.apisandbox.zuora.com/v1/creditmemos/2c92c0fa72c087a90172c13184eb6481/refunds
Request body
{ "gatewayOptions": { "Comments": "Refund credit memo", "IPAddress": "192.168.1.1" }, "items": [ { "amount": 10, "creditMemoItemId": "2c92c0fa72c087a90172c13185026482" } ], "methodType": "CreditCard", "refundDate": "2020-06-28", "totalAmount": 10, "type": "External" }
Response
{ "id": "2c92c0fb72e0de460172fef61a590782", "number": "R-00000006", "status": "Processed", "type": "External", "methodType": "CreditCard", "accountId": "2c92c0f86a583eb9016a6b8873191a44", "amount": 10.000000000, "refundDate": "2020-06-28", "comment": null, "paymentMethodId": "2c92c0f96a58497e016a6b57b4f83064", "paymentMethodSnapshotId": null, "paymentId": null, "creditMemoId": "2c92c0fa72c087a90172c13184eb6481", "reasonCode": "Standard Refund", "gatewayId": null, "gatewayResponse": null, "gatewayResponseCode": null, "gatewayState": "NotSubmitted", "markedForSubmissionOn": null, "referenceId": null, "secondRefundReferenceId": null, "softDescriptor": null, "softDescriptorPhone": null, "submittedOn": null, "settledOn": null, "cancelledOn": null, "createdDate": "2020-06-29 00:24:00", "createdById": "2c92c0f96a6e3c34016a70cc7fbf6730", "updatedDate": "2020-06-29 00:24:00", "updatedById": "2c92c0f96a6e3c34016a70cc7fbf6730", "refundTransactionTime": null, "financeInformation": { "bankAccountAccountingCode": null, "bankAccountAccountingCodeType": null, "unappliedPaymentAccountingCode": null, "unappliedPaymentAccountingCodeType": null, "onAccountAccountingCode": null, "onAccountAccountingCodeType": null, "transferredToAccounting": "No" }, "success": true }