Sign up subscribers
Create a subscription with a customer account
Suppose that a new customer wants to subscribe to a service offered by you. You need to capture the following information:
- Basic information about your new customer
- The product or service you will be provisioning for them
- Price and frequency with which they will be charged
- The contract effective date from which the subscription becomes effective
By default the payment method will be authorized with the payment gateway you have configured for your tenant.
The following example shows how to create a subscription, passing the customer account and a reference to a plan. To learn about plans, see the Plans API operations.
curl -X POST "https://rest.test.zuora.com/v2/subscriptions"
-H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3"
-H "Content-Type: application/json"
-d '{
"account_data":{
"bill_to": {
"first_name": "Amy",
"last_name": "Lawrence",
"email": "amy.lawrence@zuora.com",
"address":{
"line1": "101 Redwood Shors Parkaway",
"city": "Redwood City",
"postal_code": "94065",
"state": "CA",
"country": "USA"
}
},
"name": "Amy Lawrence Account",
"currency": "USD"
},
"subscription_plans": [{
"plan_id": "8ad095b8813772670181383d05136860"
}],
"start_on":{
"contract_effective": "2022-08-01"
}
}'
AccountContactCreateRequest contactCreateRequest = new AccountContactCreateRequest()
.firstName("Amy")
.lastName("Lawrence")
.email("amy.lawrence@zuora.com")
.address(new Address()
.line1("101 Redwood Shors Parkaway")
.city("Redwood City")
.postalCode("94065")
.country("USA")
.state("CA"));
AccountCreateRequest accountCreateRequest = new AccountCreateRequest()
.name("Amy Lawrence's Account")
.billTo(contactCreateRequest)
.currency("USD");
PlanCreateRequest planRequest = new PlanCreateRequest()
.name('Monthly Plan')
.productId(newProduct.getId())
.startDate('2021-10-20')
.endDate('2031-10-19')
.description('Gold Product');
Plan newPlan = zuoraClient.plans().createPlan(planRequest);
LocalDate todayDate = LocalDate.now();
String todayDateStr = todayDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
SubscriptionCreateRequest subscriptionCreateRequest = new SubscriptionCreateRequest()
.accountData(accountCreateRequest)
.subscriptionPlans(Collections.singletonList(new SubscriptionChildPlanCreateRequest().planId(newPlan.getId())))
.startOn(new StartOn().contractEffective(todayDateStr));
Subscription createdSubscription = zuoraClient.subscriptions().createSubscription(subscriptionCreateRequest);
const date = new Date();
const todayDate = date.toISOString().split('T')[0];
const planId = '8ad095b8813772670181383d05136860';
const account = {
bill_to: {
first_name: 'Amy',
last_name: 'Lawrence',
email: 'amy.lawrence@zuora.com',
address:{
line1: '101 Redwood Shors Parkaway',
city: 'Redwood City',
postal_code: '94065',
state: 'CA',
country: 'USA',
}
},
name: 'Amy Lawrence Account',
currency: 'USD',
}
const subscriptionRequest = {
account_data: account,
subscription_plans: [
{
plan_id: planId,
}
],
start_on:{
contract_effective: todayDate,
},
};
const createdSubscription = await zuoraClient.subscriptions.createSubscription(subscriptionRequest);
Preview a subscription
You can use the "Preview a subscription" operation to generate a preview of billing documents and charge metrics of a subscription. This operation is only for preview, and no subscription or billing document is created. You can use this operation to the following metrics generated by the subscription:
- Metrics on the billing documents, including:
- Total amount
- Subtotal amount
- Tax amount
- Delta metrics of order actions, including:
- Gross amount of delta MRR
- Net amount of delta MRR
To preview a subscription, you must specify the following fields:
account_id
oraccount_data
metrics
subscription_plans
8ad09bce82aa84840182afab5e7b04fb
) where the ID of the associated account is 8ad09b7d8292b85d0182a4d6f875225a
:curl --request POST
--url 'https://rest.test.zuora.com/v2/subscriptions/preview'
--header 'Authorization: Bearer 2e4e1763af7d4cf5aaca1b519dfa3200'
--header 'Content-Type: application/json'
--data '{
"account_id": "8ad09b7d8292b85d0182a4d6f875225a",
"subscription_plans": [
{
"plan_id": "8ad09bce82aa84840182afab5e7b04fb"
}
],
"end_date": "2022-11-30",
"metrics": ["billing_documents"]
}'
LocalDate date = LocalDate.of(2022,11,30);
SubscriptionPreviewRequest previewRequest = new SubscriptionPreviewRequest()
.metrics(Collections.singletonList(SubscriptionPreviewRequest.MetricsEnum.BILLING_DOCUMENTS))
.endDate(date)
.accountId("8ad09b7d8292b85d0182a4d6f875225a")
.subscriptionPlans(Collections.singletonList(new SubscriptionPlanCreateRequest().planId("8ad09bce82aa84840182afab5e7b04fb")));
Map<String, Object> previewSubscription = zuoraClient.subscriptions().previewSubscription(previewRequest);
System.out.println(previewSubscription);
const previewRequest = {
account_id: '8ad09c4b84eac7870184ec0b170f1d87',
subscription_plans: [
{
plan_id: '8ad09bce82aa84840182afab5e7b04fb'
}
],
end_date: '2023-4-30',
metrics: ['billing_documents']
};
const previewSubscription = await zuoraClient.subscriptions.previewSubscription(previewRequest);
console.log(previewSubscription);
Update subscriptions
After you have created subscriptions, you can make modifications to the created subscriptions. This article provides common use cases on updating subscriptions and the corresponding code samples.
If you want to make changes to the subscription, you can use the Update a subscription operation to update the subscription. You can add subscription plans, remove subscription plans, change subscription plan details, or renew subscriptions by specifying the following fields, respectively:
add_subscription_plans
remove_subscription_plans
update_subscription_plans
renew
Add a subscription plan to a subscription
The following example provides an example of updating a subscription by adding a new plan to the created subscription.
curl -X PATCH "https://rest.test.zuora.com/v2/subscriptions/8ad08f74803a5e3e01803f340e3c2148"
-H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3"
-H "Content-Type: application/json"
-d '{
"description": "Updated subscription description",
"add_subscription_plans": [{
"subscription_plan":{
"plan_id": "8ad09bce8292b8480182a8ea00db35b3",
"prices":[{
"price_id": "8ad095b882aa84850182abbe78fd12f1"
}]
},
"start_on": {
"contract_effective": "2022-08-01",
"service_activation": "2022-08-01",
"customer_acceptance": "2022-08-01"
}
}]
}'
LocalDate date = LocalDate.of(2022,8,20);
String oldSubscriptionId = subscription.getId();
SubscriptionItemCreateRequest subscriptionItemCreateRequest = new SubscriptionItemCreateRequest().priceId("8ad095b882aa84850182abbe78fd12f1");
SubscriptionPlanCreateRequest subscriptionPlanRequest = new SubscriptionPlanCreateRequest()
.planId("8ad09bce8292b8480182a8ea00db35b3")
.prices(Collections.singletonList(subscriptionItemCreateRequest));
SubscriptionAddPlanPatchRequest addSubscriptionPlanRequest = new SubscriptionAddPlanPatchRequest()
.subscriptionPlan(subscriptionPlanRequest)
.startOn((new StartOn()
.contractEffective(date)
.customerAcceptance(date)
.serviceActivation(date)));
SubscriptionPatchRequest updateRequest = new SubscriptionPatchRequest()
.addSubscriptionPlans(Collections.singletonList(addSubscriptionPlanRequest));
Subscription updatedSubscription = zuoraClient.subscriptions().patchSubscription(oldSubscriptionId,updateRequest);
const updatedSubscription = await zuoraClient.subscriptions.patchSubscription('8ad08f74803a5e3e01803f340e3c2148',
{
description: 'Add a subscription plan',
add_subscription_plans: [{
subscription_plan:{
plan_id: '8ad09bce8292b8480182a8ea00db35b3',
prices:[{
price_id: '8ad095b882aa84850182abbe78fd12f1',
}],
},
start_on: {
contract_effective: '2022-12-31',
}
}],
}
);
Remove a subscription plan from a subscription
You can also remove a subscription plan from an existing subscription with the Update subscription API operation.
The following code samples provide an example of removing a subscription plan from a created subscription:
curl -X PATCH "https://rest.test.zuora.com/v2/subscriptions/8ad08f74803a5e3e01803f340e3c2148"
-H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3"
-H "Content-Type: application/json"
-d '{
"description": "Remove a subscription plan",
"remove_subscription_plans": [ {
"subscription_plan_id": "8ad08ccf82afa5d70182afdb2242002f",
"start_on": {
"contract_effective": "2022-08-20",
"service_activation": "2022-08-20",
"customer_acceptance": "2022-08-20"
}
}]
}'
LocalDate removePlanDate = LocalDate.of(2022,8,20);
String oldSubscriptionId = createdSubscription.getId();
SubscriptionRemovePlanPatchRequest removeSubscriptionPlanRequest = new SubscriptionRemovePlanPatchRequest()
.subscriptionPlanId("8ad09b7d80936cd1018098c227be79e4")
.startOn((new StartOn()
.contractEffective(removePlanDate)
.customerAcceptance(removePlanDate)
.serviceActivation(removePlanDate)));
SubscriptionPatchRequest updateRequest = new SubscriptionPatchRequest().removeSubscriptionPlans(Collections.singletonList(removeSubscriptionPlanRequest));
Subscription updatedSubscription = zuoraClient.subscriptions().patchSubscription(oldSubscriptionId,updateRequest);
const updatedSubscription = await zuoraClient.subscriptions.patchSubscription('8ad08f74803a5e3e01803f340e3c2148',
{
description: 'Remove a subscription plan',
remove_subscription_plans: [{
subscription_plan_id:'8ad08ccf82afa5d70182afdb2242002f',
start_on: {
contract_effective: '2022-12-31',
},
}],
}
);
Update the product quantity on a subscription
You can update the product quantity on a subscription only if the product uses the following prices:
- Per-unit
- Tiered
If you request to update the product quantity for other prices, the request will result in an error.
In this scenario, you need to specify the following fields in theupdate_subscription_plans
> subscription_plan
> subscription_items
nested object for the "Update a subscription" operation:quantity
start_date
quantity
field of a subscription item to 25
and the unit_amount
to 40
.curl --request PATCH \
--url 'https://rest.test.zuora.com/v2/subscriptions/A-S00013513' \
--header 'Authorization: Bearer 2d152847628046fca3ff3c63540933e3' \
--header 'Content-Type: application/json' \
--data '{
"update_subscription_plans": [
{
"subscription_plan": {
"subscription_plan_id": "8ad08e0183babdd00183c602861670cf",
"subscription_items": [
{
"id": "8ad08e0183babdd00183c602861670d0",
"quantity": 25,
"unit_amount": 40,
"start_date": "2022-10-10"
}
]
},
"start_on": {
"contract_effective": "2022-10-10",
"service_activation": "2022-10-10",
"customer_acceptance": "2022-10-10"
}
}
]
}'
LocalDate date = LocalDate.of(2022,10,10);
String subscriptionId = createdSubscription.getId();
SubscriptionItemPatchRequest subscriptionItemCreateRequest = new SubscriptionItemPatchRequest()
.id("8ad08e0183babdd00183c602861670d0")
.quantity(new BigDecimal(25))
.unitAmount(new BigDecimal(40))
.startDate(date);
List<SubscriptionItemPatchRequest> subscriptionItems = new ArrayList<>();
subscriptionItems.add(subscriptionItemCreateRequest);
SubscriptionPlanPatchRequest subscriptionPlanRequest = new SubscriptionPlanPatchRequest()
.subscriptionPlanId("8ad08e0183babdd00183c602861670cf")
.subscriptionItems(subscriptionItems);
SubscriptionUpdatePlanPatchRequest updateSubscriptionPlanRequest = new SubscriptionUpdatePlanPatchRequest()
.subscriptionPlan(subscriptionPlanRequest)
.startOn((new StartOn().contractEffective(date)));
List<SubscriptionUpdatePlanPatchRequest> subscriptionPlans = new ArrayList<>();
subscriptionPlans.add(updateSubscriptionPlanRequest);
SubscriptionPatchRequest updateRequest = new SubscriptionPatchRequest().updateSubscriptionPlans(subscriptionPlans);
Subscription updatedSubscription = zuoraClient.subscriptions().patchSubscription(subscriptionId,updateRequest);
System.out.println(updatedSubscription);
const updatedSubscription = await zuoraClient.subscriptions.patchSubscription('8ad08e0183babdd00183c60285e970ca',
{
description: "Remove a subscription plan",
update_subscription_plans: [{
subscription_plan:{
subscription_plan_id:'8ad08e0183babdd00183c602861670cf',
subscription_items:[
{
id: "8ad08e0183babdd00183c602861670d0",
quantity: 25,
unit_amount: 40,
start_date: '2022-10-10',
}
]
},
start_on: {
contract_effective: '2022-12-31',
}
}],
}
);
Cancel a subscription
When an end subscriber decides to terminate their subscription, there are three ways for the merchant to manage billing:
- Cancel the subscription and make the cancellation effective after the last invoiced periodAfter the cancellation, billing will stop immediately for the subscription. The cancellation is effective after the latest invoice through date.
To use this option for subscription cancellation, set the
cancel_at
field toinvoice_period_end
. - Cancel the subscription and make the cancellation effective at the end of the current subscription term.
This option is applicable only to termed subscriptions. After the cancellation, billing will continue until the end of the current subscription term and then stop. If the subscription is set to auto-renew when the subscription is created, the auto-renewal will be stopped when the subscription is canceled.
To use this option for subscription cancellation, set thecancel_at
field tosubscription_term_end
. - Cancel the subscription and make the cancellation effective on a specific date
- If the cancellation is made effective during a service period that has already been billed, Zuora will credit back the prorated amount from the cancellation effective date.
- If the cancellation is made effective after the billed through date, Zuora will continue to bill until the cancellation effective date. After that, billing will stop.
cancel_date
field to a specific date.The following code example demonstrates how to cancel a subscription at the end of billing period while specifying the processing option:
curl --request PATCH \
--url 'https://rest.test.zuora.com/v2/subscriptions/A-S00000035/cancel' \
--header 'Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3' \
--header 'Content-Type: application/json'\
--data '{
"cancel_at": "invoice_period_end",
"processing_options": {
"collection_method": "collect_payment",
"document_date": "2022-09-01"
}
}'
LocalDate documentDate = LocalDate.of(2022,9,1);
String subscriptionNumber = "A-S00013446";
CancelSubscriptionRequest cancelRequest = new CancelSubscriptionRequest()
.cancelAt(CancelAtEnum.INVOICE_PERIOD_END)
.processingOptions(new ProcessingOptions()
.documentDate(documentDate)
.collectionMethod(CollectionMethodEnum.COLLECT_PAYMENT));
Subscription canceledSubscription = zuoraClient.subscriptions().cancelSubscription(subscriptionNumber,cancelRequest);
const canceledSubscription = await zuoraClient.subscriptions.cancelSubscription('8ad0950c8480aa70018482ce8706460f',
{
cancel_at: 'invoice_period_end',
processing_options: {
document_date: '2022-09-01',
collection_method: 'create_invoice'
}
}
);
Update contact information for an account
Zuora requires two types of contacts to be associated with an account: bill-to contact and sold-to contact.
The bill-to contact determines where the invoice should be delivered, whereas the sold-to contact determines how taxes are calculated. If the invoice delivery preference is email, the bill-to contact must contain an email address.
In this use case, we will update the sold-to contact information of an account using the Update an account operation.
curl --request PATCH
--url https://rest.test.zuora.com/v2/accounts/2c92c0f86a8dd422016a9e7a70116b0d
--header 'Authorization: Bearer 06a297740b184fc384bc57cbe8a04e53'
--header 'Content-Type: application/json'
--data '{
"sold_to":{
"first_name": "Jane",
"last_name": "Doe",
"address": {
"line1": "No.111, Street ABC",
"city": "San Francisco",
"state": "CA",
"country": "United States"
}
}
}'
String accountId = "2c92c0f86a8dd422016a9e7a70116b0d";
Address soldToAddress = new Address()
.line1("No.123, Street ABC")
.city("San Francisco")
.state("CA")
.country("United States");
AccountPatchRequest accountPatchRequest = new AccountPatchRequest()
.soldTo(new AccountContactPatchRequest()
.firstName("Jane")
.lastName("Doe")
.address(soldToAddress));
Account updatedAccount = zuoraClient.accounts().updateAccount(accountId,accountPatchRequest);
const accountId = '2c92c0f86a8dd422016a9e7a70116b0d';
const accountPatchRequest = {
sold_to:{
first_name: 'John',
last_name: 'Doe',
address: {
country: 'United States',
state: 'CA',
city: 'San Francisco',
line1: 'No.111, Street ABC'
}
}
};
const updatedAccount = await zuoraClient.accounts.updateAccount(accountId, accountPatchRequest);