Withdrawing service access at the end of the period for which the user has already paid
In the Bango Platform, entitlements describe a user's ability to access a service provided by a merchant. In some circumstances you might want a "soft ending" for the entitlement: to allow the user to access the service until the end of the period for which they have already paid, and then to deny access. For example, if a user chooses not to renew a subscription, you want to withdraw access when the current subscription ends. To do this, you cancel the entitlement by making a POST
request to the Bango Resale API. (To immediately withdraw access, revoke the entitlement instead.)
(You may cancel and revoke entitlements only in accordance with the merchant product descriptions and your commercial agreements.)
As part of the API request, you supply:
The API response is a structure that contains:
extensionData
property, and the status is ACTIVE-ENDING
or CANCELLED
depending on the use cases the merchant supports.extensionData
property, and the status won't be changed until the merchant sends an asynchronous notification to the Bango Platform.The Bango Platform automatically cancels entitlements when a merchant tells the Bango Platform to do so (for example, if the user cancels directly with the merchant, or if the merchant detects fraud).
Set an entitlement's notificationUrl
to receive a POST
notification when this happens.
Here's some sample code in a C/Java-like language: adapt this code to your needs. Use the same API endpoint prefix with test credentials and with production credentials.
function cancel_entitlement (entitlement_id, reason_category, reason_code, reason_desc, extra_custom_properties = {}) {
// *Always* use this endpoint prefix for the Bango Resale API.
const base_url = "https://resale.api.bango.net";
// This is what's returned with HTTP 2xx.
let entitlement = null;
const request_body_params = extra_custom_properties
.copy()
.set('cancelReasonCategory', reason_category)
.set('cancelReasonCode', reason_code)
.set('cancelReasonDescription', reason_desc);
try {
// POST UTF-8 JSON to the Bango Resale API and parse the JSON response
let response = rest_client_call({
method: "POST",
url: base_url + "entitlement/cancel/" + entitlement_id,
headers: {
"Authorization": get_authorization_header(),
"Content-Type": "application/json",
},
body: make_json_string(request_body_params),
}).from_json();
// The responseCode tells us the result.
switch (response.responseCode) {
// Success: entitlement is canceled
case "OK":
entitlement = response;
break;
// Failures
// These may indicate issues in your code, not the Bango Platform.
case "BAD_REQUEST": // Invalid request
case "UNAUTHORIZED": // Check your credentials
case "NOT_AVAILABLE": // Unable to cancel this entitlement
case "NOT_FOUND": // Invalid entitlement ID
case "TOO_MANY_REQUESTS": // Request limit reached: try again later
throw "Unable to cancel entitlement";
// Bango Platform issues
// These likely indicate transient problems.
// In production code, you might want to try the request again
// after a delay, ultimately falling back to an error state.
case "INTERNAL_ERROR":
case "SERVICE_UNAVAILABLE":
throw "Bango Platform unavailable";
// This might indicate Bango has added a new response code.
// Check the documentation again.
default:
throw "Unrecognized response code";
}
} catch (exception) {
// Production code might want to notify the reseller in some way,
// and/or log full details of the exception for later analysis,
// and degrade gracefully for the user.
output("An error occurred!");
output(exception);
}
// null if entitlement not canceled.
// if canceled, will have an entitlementId, status, and other properties:
// see API reference.
return entitlement;
}
In this section: