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.

cURLJavaNode
Copy
Copied
curl -X PATCH "https://rest.apisandbox.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"
          }
       }]
      }'
Copy
Copied
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);
Copy
Copied
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:

cURLJavaNode
Copy
Copied
curl -X PATCH "https://rest.apisandbox.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" 
            }
            }]
        }'
Copy
Copied
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);
Copy
Copied
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 the update_subscription_plans > subscription_plan > subscription_items nested object for the "Update a subscription" operation:

  • quantity
  • start_date

The following example updates the quantity field of a subscription item to 25 and the unit_amount to 40.

cURLJavaNode
Copy
Copied
curl --request PATCH \
  --url 'https://rest.apisandbox.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"
                }
		    }
	        ]
	    }'
Copy
Copied
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);
Copy
Copied
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',
      }
   }],
 }
);

Pause a subscription

If the end subscriber requests to suspend or pause a subscription, you can use the Pause a subscription operation to do it.

It is also required to specify the rules for pause a subscription. For example, the subscription can be paused on a specific date or after a certain number of periods from today.

To pause a date on a certain date, specify pause_date. To pause a date at the end of the current billing period, specify the following fields:

  • pause_at
  • pause_interval
  • pause_interval_count

You can optionally specify the resume_behavior field to define the behavior when the paused subscription resumes.

The following example pauses an active subscription for one month at the end of the current billing period. Subsequently, when the subscription is resumed, the subscription term is automatically extended by one month.

cURLJavaNode
Copy
Copied
curl --request POST 
     --url 'https://rest.apisandbox.zuora.com/v2/subscriptions/A-S00000035/pause' 
     --header 'Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3' 
     --header 'Content-Type: application/json' 
     --data '{
                "pause_at":"specific_period",
                "pause_interval": "month",
                "pause_interval_count": 1,
                "resume_behavior": {
                    "extend_term": true
                 }
              }
Copy
Copied
String subscriptionId = createdSubscription.getId();

PauseSubscriptionRequest pauseRequest = new PauseSubscriptionRequest()
    .pauseAt(PauseSubscriptionRequest.PauseAtEnum.SPECIFIC_PERIOD)
    .pauseInterval(PauseSubscriptionRequest.PauseIntervalEnum.MONTH)
    .pauseIntervalCount(new BigDecimal(1))
    .resumeBehavior(new ResumeSubscriptionRequest().extendTerm(true));

Subscription pausedSubscription = zuoraClient.subscriptions().pauseSubscription(subscriptionId, pauseRequest);
Copy
Copied
const pausedSubscription = await zuoraClient.subscriptions.pauseSubscription('8ad095b8844282ff0184528d63f3242f',
    {
      pause_date: '2022-12-20',
      pause_interval_count: '1',
      pause_interval: 'month',
      resume_behavior: {
        extend_term: true,
      },
    }
);

Resume a subscription

When a subscription is in the Suspended status, the only action you can take is to resume a suspended subscription with the Resume a subscription operation.

The resume date cannot be earlier than the suspend date and cannot be later than the subscription term end date.

The following example resumes the subscription that is suspended.

cURLJavaNode
Copy
Copied
curl --request POST      
     --url 'https://rest.apisandbox.zuora.com/v2/subscriptions/8ad08f74803a5e3e01803f340e3c2148/resume'      
     --header 'Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3'      
     --header 'Content-Type: application/json'      
     --data '{ 
                "extend_term": true,
                "resume_date": "2022-09-10"
             }' 
Copy
Copied
ResumeSubscriptionRequest resumeRequest = new ResumeSubscriptionRequest()
    .extendTerm(true)
    .resumeDate("2022-09-10");
 
Subscription resumedSubscription = zuoraClient.subscriptions().resumeSubscription(pausedSubscription.getId(), resumeRequest);
Copy
Copied
const resumedSubscription = await zuoraClient.subscriptions.resumeSubscription('8ad08ccf80efe77c0180f1f5f80d39c9',
    {
      extend_term: true,
      resume_date: '2022-09-10',
    }
);

Renew a subscription

The Update a subscription API operation allows you to renew a subscription that is about to expire.

Note that only termed subscriptions can be renewed.

The following code example renews the subscription (id = 8ad08f74803a5e3e01803f340e3c2148) on 2023-01-01. The renewal term is 12 months.

cURLJavaNode
Copy
Copied
curl -X PATCH "https://rest.apisandbox.zuora.com/v2/subscriptions/8ad08f74803a5e3e01803f340e3c2148"
  -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
  -H "Content-Type: application/json" 
  -d '{
         "description": "Renew a subscription", 
         "renew":{
            "start_on": {
                "contract_effective": "2023-01-01"
            }
          },
         "terms": { 
            "renewal_term": { 
                "interval": "month", 
                "interval_count": 12, 
                "type": "termed"
            }
         }
      }'
Copy
Copied
LocalDate renewStartDate = LocalDate.of(2023,1,1);
String subscriptionId = createdSubscription.getId();

SubscriptionTermPatchRequest renewalTerm = new SubscriptionTermPatchRequest()
    .renewalTerm(new Term()
        .type(Term.TypeEnum.TERMED)
        .interval(Term.IntervalEnum.MONTH)
        .intervalCount(12)

SubscriptionRenewPatchRequest renewSubscriptionRequest = new SubscriptionRenewPatchRequest()
    .startOn((new StartOn()
        .contractEffective(renewStartDate)));

SubscriptionPatchRequest updateRequest = new SubscriptionPatchRequest()
    .renew(renewSubscriptionRequest)
    .terms(renewalTerm)
    .description("Renew a subscription");

Subscription updatedSubscription = zuoraClient.subscriptions().patchSubscription(subscriptionId,updateRequest);
Copy
Copied
const renewRequest = {
  description: 'Renew a subscription',
  renew:{
    start_on: {
      contract_effective: '2023-01-01',
    }
  },
  terms: {
    renewal_term: {
      interval: 'month',
      interval_count: 12,
      type: 'termed',
    }
  }
};
  
const renewSubscription = await zuoraClient.subscriptions.patchSubscription('8ad092478455c5f3018460fd67d9444c',renewRequest);

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 period

    After 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 to invoice_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 the cancel_at field to subscription_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.

    To use this option for subscription cancellation, set the 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:

cURLJavaNode
Copy
Copied
curl --request PATCH \
     --url 'https://rest.apisandbox.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"
                }
             }'
Copy
Copied
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);
Copy
Copied
const canceledSubscription = await zuoraClient.subscriptions.cancelSubscription('8ad0950c8480aa70018482ce8706460f', 
    {
      cancel_at: 'invoice_period_end',
      processing_options: {
        document_date: '2022-09-01',
        collection_method: 'create_invoice'
      }
    }
);