Copy of Renew a Manual Renewal Subscription Ahead of Schedule

Overview

This guide shows you how to implement the Update Subscription Item and the Renew Subscription API endpoints to renew a subscription ahead of schedule.

Use case

  1. A customer buys a Cloudify subscription selecting manual renewal at the end of the billing period.
  2. After seeing the expiration notice, the customer clicks a Renew Subscription button in the Self-Service area.
  3. The Renew Subscription API endpoint is then used to renew the customer's subscription immediately.
  4. The Cleverbridge platform bills the customer the full price for the next billing interval starting immediately.

Implement the API Endpoints

Before you start

🚧

Important

Get the customer's consent before making changes to a subscription.

To avoid chargebacks and customer inquiries, it is also essential that you coordinate all price increases with Client Experience.

In the European Economic Area (EEA), Strong Customer Authentication (SCA) is required for recurring electronic payments when the amount changes. This means that some of your customers will have to authenticate their payment, which in turn might impact the renewal success rate.

For more information, see Best Practices: Obtain Customer Consent.

Make sure that:

  • The subscription renewal type is Manual.
  • The subscription status is Active.
  • The renewal date has not yet passed.
  • The renewal is not combined with an alignment of the subscription. For more information, see Alignment Settings.

Billing interval

By default, the Cleverbridge platform bills the customer the full price for the next billing interval, which starts immediately. Any remaining time from the current billing interval is added to the next billing interval, moving the next billing date further into the future.
If you want to suppress this behavior, set ResetBillingInterval to true.

Step 1: Preview price and new expiration date

Implement the Update Subscription Item endpoint.

If the API call is formatted as described below, it will:

  • Calculate the next billing date if the renewal is made
  • Return the next billing date in the NextBillingDate parameter so it can be displayed to the customer.
  • Not change any data in the Cleverbridge system

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

No

AlignToCurrentInterval: false

GetCustomerPricePreviewOnly: true

Alignment settings used for the price preview calculation.

ProductId

int

Yes

292973

Product ID of the subscription item.

RunningNumber

int

Yes

1

Running number of the item in the subscription.

Quantity

int

Yes

1

Total number of items in the subscription after the update.

SubscriptionId

str

Yes

S67531904

The unique identifier of the subscription.

UpdateAction

str

No

upgrade (or 1 for JSON)

The value set does not affect transaction processing.
See the note below.

TriggerImmediateRenewal

bool

Yes

true

Triggers a renewal immediately.

JSON Payload

{
  "ProductId": 292973,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67531904",
  "UpdateAction": 0,
  "TriggerImmediateRenewal": true,
  "AlignmentSettings": {
    "AlignToCurrentInterval": false,
    "GetCustomerPricePreviewOnly": true
  }

📘

Note

The UpdateAction parameter is currently used for documentation and tracking only. The value set does not affect transaction processing.

The supported values are as follows:

  • For upgrades, set the parameter to upgrade(or 1 for JSON)
  • For downgrades, set the parameter to downgrade, (or 2 for JSON)
  • For all other changes, set the parameter to update (or 0 for JSON)

Request

curl --location 'https://rest.cleverbridge.com/subscription/updatesubscriptionitem' 
--header 'Content-Type: application/json' 
--header 'Accept: application/json' 
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS' 
--data '{
  "ProductId": 292973,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67531904",
  "UpdateAction": 0,
  "TriggerImmediateRenewal": true,
  "AlignmentSettings": {
    "AlignToCurrentInterval": false,
    "GetCustomerPricePreviewOnly": true
  }
}'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "ProductId": 292973,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67531904",
  "UpdateAction": 0,
  "TriggerImmediateRenewal": True,
  "AlignmentSettings": {
    "AlignToCurrentInterval": False,
    "GetCustomerPricePreviewOnly": True
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Basic Basic YOUR_BASE64_ENCODED_CREDENTIALS',
}
conn.request("POST", "/subscription/updatesubscriptionitem", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'rest.cleverbridge.com',
  'path': '/subscription/updatesubscriptionitem',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS',
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "ProductId": 292973,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67531904",
  "UpdateAction": 0,
  "TriggerImmediateRenewal": true,
  "AlignmentSettings": {
    "AlignToCurrentInterval": false,
    "GetCustomerPricePreviewOnly": true
  }
});

req.write(postData);

req.end();
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://rest.cleverbridge.com/subscription/updatesubscriptionitem")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
  .body("{\n  \"ProductId\": 292973,\n  \"Quantity\": 1,\n  \"RunningNumber\": 1,\n  \"SubscriptionId\": \"S67531904\",\n  \"UpdateAction\": 0,\n  \"TriggerImmediateRenewal\": true,\n  \"AlignmentSettings\": {\n    \"AlignToCurrentInterval\": false,\n    \"GetCustomerPricePreviewOnly\": true\n  }\n}")
  .asString();

Response

{
    "NextBillingDate": "2026-05-09T15:54:58.419961",
    "NextRenewalDate": "2026-05-09T15:54:58.419961",
    "AlignmentCustomerGrossPrice": 0.0,
    "AlignmentCustomerNetPrice": 0.0,
    "AlignmentCustomerVatPrice": 0.0,
    "NextBillingCustomerGrossPrice": 5.0,
    "NextBillingCustomerNetPrice": 4.20,
    "NextBillingCustomerVatPrice": 0.80,
    "NextRenewalCustomerGrossPrice": 5.0,
    "NextRenewalCustomerNetPrice": 4.20,
    "NextRenewalCustomerVatPrice": 0.80,
    "PriceCurrencyId": "USD",
    "ResultMessage": "OK"
}

Step 2: Renew subscription for another billing interval

The Renew Subscription API endpoint must be called after the current billing interval starts and before the next billing date.

If the API call is formatted as described below, it will update the customer's subscription data in the Cleverbridge platform.

Parameters

ParameterTypeRequiredExampleNotes
SubscriptionIdstrYesS67531904The unique identifier of the subscription.
ResetBillingIntervalboolYesfalseSet to true to immediately start the new billing interval
📘

Note

Because the renewal occurs before the current interval ends, the remaining time is added to the new billing interval.

Request

curl -X POST "https://rest.cleverbridge.com/subscription/renewsubscription?SubscriptionId=S67531904" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS" \
  -d '{
    "SubscriptionId": "S67531904",
    "ResetBillingInterval": false
  }'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "SubscriptionId": "S67531904",
  "ResetBillingInterval": False
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS',
}
conn.request("POST", "/subscription/renewsubscription?SubscriptionId=S67670740", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
const https = require('https');

const data = JSON.stringify({
  SubscriptionId: "S67531904",
  ResetBillingInterval: false
});

const options = {
  hostname: 'rest.cleverbridge.com',
  port: 443,
  path: '/subscription/renewsubscription?SubscriptionId=S67670740',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS',
    'Content-Length': Buffer.byteLength(data)
  }
};

const req = https.request(options, (res) => {
  let responseData = '';

  res.on('data', (chunk) => {
    responseData += chunk;
  });

  res.on('end', () => {
    console.log(responseData);
  });
});

req.on('error', (error) => {
  console.error(error);
});

req.write(data);
req.end();
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class RenewSubscription {

    public static void main(String[] args) throws Exception {

        String jsonBody = """
        {
          "SubscriptionId": "S67531904",
          "ResetBillingInterval": false
        }
        """;

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://rest.cleverbridge.com/subscription/renewsubscription?SubscriptionId=S67670740"))
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

        HttpResponse<String> response =
                client.send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}

Response

{
    "ContinueUrl": "https://www.cleverbridge.com/864/p/534580479-qm7W2NZh8ZvkVJ7MFLMn",
    "NextBillingDate": "2026-05-09T15:54:58.419961",
    "TransactionStatus": "Success",
    "ResultMessage": "OK"
}

Diagram

flowchart LR
  classDef mainColor fill:#ffffff,color:#555555,stroke:#96C34B,stroke-width:2px;

  A(["&nbsp;&nbsp;<br/>A customer buys an annual subscription selecting manual renewal&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> B(["&nbsp;&nbsp;<br/><i>Renew Subscription API</i> endpoint is used to renew the customer's subscription immediately&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> C(["&nbsp;&nbsp;<br/>Cleverbridge bills the customer the full price&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor