The platform exposes APS type that allow external management systems receive deals from the platform.
In this document:
The considered APS type (download
)
extends the Resource APS type(s) and looks as follows:
{
"name": "DiscountManagement",
"id": "http://www.odin.com/oa/billing/discount-management/1.2",
"apsVersion": "2.0",
"implements": [
"http://aps-standard.org/types/core/resource/1.0"
],
"access": {
"public": true
},
"operations": {
"getSubscriptionResourceDiscountInfo": {
"path": "/discounts/resource-discount",
"verb": "GET",
"response": {
"type": "DiscountInfo"
},
"errorResponse": {
"type": "object"
},
"parameters": {
"accountUuid": {
"kind": "query",
"type": "string"
},
"subscriptionUuid": {
"kind": "query",
"type": "string"
},
"resourceUuid": {
"kind": "query",
"type": "string"
}
}
},
"getDealsForPlans": {
"path": "/deals/get-for-plans",
"verb": "POST",
"response": {
"type": "array"
},
"errorResponse": {
"type": "object"
},
"parameters": {
"includeParentPlanDiscountConditions": {
"kind": "query",
"type": "boolean"
},
"accountId": {
"kind": "query",
"type": "string"
},
"resellerId": {
"kind": "query",
"type": "string"
},
"plans": {
"kind": "body",
"type": "array",
"required": true
}
}
},
"getDealsPerUnit": {
"path": "/deals",
"verb": "POST",
"response": {
"type": "array"
},
"errorResponse": {
"type": "object"
},
"access": {
"public": true
},
"parameters": {
"providerCosts": {
"kind": "query",
"type": "boolean"
},
"accountId": {
"kind": "query",
"type": "string"
},
"resellerId": {
"kind": "query",
"type": "string"
},
"plans": {
"kind": "body",
"type": "array",
"required": true
}
}
}
},
"structures": {
"DiscountInfo": {
"type": "object",
"properties": {
"discountId": {
"type": "integer"
},
"discountPercent": {
"type": "number"
}
}
},
"PeriodDeals": {
"type": "object",
"properties": {
"period": {
"type": "Period",
"required": true
},
"parentPlanDiscountCondition": {
"type": "ParentPlanDiscountCondition"
},
"resources": {
"type": "array",
"items": {
"type": "ResourceDeals"
}
},
"effectiveFees": {
"type": "array",
"items": {
"type": "EffectiveFees"
}
}
}
},
"Period": {
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": [
"MONTHS",
"YEARS"
]
},
"duration": {
"type": "integer"
}
}
},
"ParentPlanDiscountCondition": {
"type": "object",
"properties": {
"planId": {
"type": "string",
"required": true
},
"planPeriod": {
"type": "Period"
}
}
},
"ResourceDeals": {
"type": "object",
"properties": {
"resourceId": {
"type": "string",
"required": true
},
"effectiveFees": {
"type": "array",
"items": {
"type": "EffectiveFees"
}
},
"effectiveCosts": {
"type": "array",
"items": {
"type": "EffectiveCosts"
}
},
"model": {
"type": "enum"
}
}
},
"EffectiveFees": {
"type": "object",
"properties": {
"name": {
"type": "string",
"required": true
},
"fee": {
"type": "Currency"
},
"salesFee": {
"type": "Currency"
},
"msrp": {
"type": "Currency"
},
"discount": {
"type": "Discount"
},
"salesDiscount": {
"type": "Discount"
},
"exchangeRate": {
"type": "number"
},
"quantity": {
"type": "number",
"description": "Deprecated"
},
"lowerLimit": {
"type": "number"
}
}
},
"Currency": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"code": {
"type": "string"
}
}
},
"Discount": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"PERCENT",
"FIXED"
]
},
"value": {
"type": "number"
},
"amount": {
"type": "number"
},
"amountCode": {
"type": "string"
}
}
},
"EffectiveCosts": {
"type": "object",
"properties": {
"name": {
"type": "string",
"required": true
},
"cost": {
"type": "Currency"
},
"lowerLimit": {
"type": "number"
}
}
},
"PlanDeals": {
"type": "object",
"properties": {
"planId": {
"type": "string",
"required": true
},
"periodDeals": {
"type": "array",
"required": true,
"items": {
"type": "PeriodDeals"
}
}
}
},
"Plan": {
"type": "object",
"properties": {
"planId": {
"type": "string",
"required": true
},
"periods": {
"type": "array",
"items": {
"type": "Period"
}
}
}
}
}
}
The APS type is used to create a singleton APS resource exposing its operations for API calls. The call syntax depends on the operation. For example, a call of an operation that accepts input parameters both in the URL string and in the body looks as follows:
POST /aps/2/services/discount-manager/<operation-path>?<query-params>
{/*<body params>*/}
In the above call, the verb can be either GET, PUT, POST, or DELETE as specified in the definition of the operation.
OPERATION |
VERB |
PATH |
RETURNS |
Description |
---|---|---|---|---|
GET |
/discounts/resource-discount |
|||
POST |
/deals/get-for-plans |
Deals for provided plan periods |
Deprecated. Gets collection of deals for a plan period. Every deal value contains plan period cost/price details. If a plan has resource rates configured, deal values for them will be returned too. |
|
POST |
/deals |
Deals for provided plan periods |
Gets collection of deals for a plan period. Every deal value contains plan period cost/price details for a one resource unit. If a plan has resource rates configured, deal values for them will be returned too. If resource rate has configured tiered prices, a lower limit will be returned for each tiered level. |
HTTP Request
GET /aps/2/services/discount-manager/discounts/resource-discount
Description
Parameters
PARAMETER |
TYPE |
DESCRIPTION |
---|---|---|
accountUuid |
String |
|
subscriptionUuid |
String |
|
resourceUuid |
String |
Returns
HTTP Request
POST /aps/2/services/discount-manager/deals/get-for-plans
Description
Deprecated. Gets collection of deals for a plan period. Every deal value contains plan period cost/price details. If a plan has resource rates configured, deal values for them will be returned too.
Parameters
PARAMETER |
TYPE |
DESCRIPTION |
---|---|---|
includeParentPlanDiscountConditions |
Boolean |
Boolean flag whether include PlanDeals with ParentPlanDiscountConditions |
accountId |
String |
|
resellerId |
String |
|
plans |
Array |
Collection of plans with periods to gets deals for |
Returns
Deals for provided plan periods
HTTP Request
POST /aps/2/services/discount-manager/deals
Description
Gets collection of deals for a plan period. Every deal value contains plan period cost/price details for a one resource unit. If a plan has resource rates configured, deal values for them will be returned too. If resource rate has configured tiered prices, a lower limit will be returned for each tiered level.
Parameters
PARAMETER |
TYPE |
DESCRIPTION |
---|---|---|
providerCosts |
Boolean |
|
accountId |
String |
|
resellerId |
String |
|
plans |
Array |
Collection of plans with periods to gets deals for |
Returns
Deals for provided plan periods
Discount Information.
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
discountId |
Integer |
Not Required |
Discount id. |
|
discountPercent |
Number |
Not Required |
Discount percent. |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
period |
Required |
Service plan period. |
||
parentPlanDiscountCondition |
Not Required |
Discount condition. |
||
resources |
Array of ResourceDeals |
Not Required |
Resource deals by service plan period. |
|
effectiveFees |
Array of EffectiveFees |
Not Required |
Effective fees for service plan periods. |
Resource identification structure.
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
unit |
Enum |
Not Required |
||
duration |
Integer |
Not Required |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
planId |
String |
Required |
Parent service plan APS ID. |
|
planPeriod |
Not Required |
Parent service plan period. |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
resourceId |
String |
Required |
Resource APS ID. |
|
effectiveFees |
Array of EffectiveFees |
Not Required |
Effective fees for the service plan resources. |
|
effectiveCosts |
Array of EffectiveCosts |
Not Required |
||
model |
Enum |
Not Required |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
name |
String |
Required |
Fee name. |
|
fee |
Not Required |
Fee value. |
||
salesFee |
Not Required |
Sales Fee value. |
||
msrp |
Not Required |
Manufacturer’s Suggested Retail Price. |
||
discount |
Not Required |
Applicable discount. |
||
salesDiscount |
Not Required |
Applicable discount in sales currency. |
||
exchangeRate |
Number |
Not Required |
Exchange rate from sales to billing currency. |
|
quantity |
Number |
Not Required |
Deprecated property. Quantity of resource units for which fee is indicated |
|
lowerLimit |
Number |
Not Required |
Lower limit for tiered price. |
Basic currency structure.
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
value |
String |
Not Required |
Amount. |
|
code |
String |
Not Required |
Currency Code |
The structure of applicable discount.
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
type |
Enum |
Not Required |
Specifies the discount type. |
|
value |
Number |
Not Required |
The discount value. |
|
amount |
Number |
Not Required |
The discount amount. |
|
amountCode |
String |
Not Required |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
name |
String |
Required |
Fee name. |
|
cost |
Not Required |
Cost value. |
||
lowerLimit |
Number |
Not Required |
Lower limit for tiered price. |
NAME |
TYPE |
ATTRIBUTES |
DEFAULT |
DESCRIPTION |
---|---|---|---|---|
planId |
String |
Required |
Service plan APS ID. |
|
periodDeals |
Array of PeriodDeals |
Required |
Plan period deals. See PeriodDeals. |
To check discounts provided by service plans, take into account the following specifics:
Discounts are calculated for the requester. Therefore, to check discounts for a particular customer, the external system must be authenticated as a staff member of this customer.
The staff member whose credentials are used to call the getDealsPerUnit
operation must be allowed to
send POST requests to the singleton resource based on the http://www.parallels.com/products/automation/billing
APS type as explained in the Set Up the User’s Credentials section.
In this section:
The following example shows a request for two periods of one plan and all available periods of another plan:
POST /aps/2/services/discount-manager/deals
[
{
"planId":"edb58c1d-3b0b-41ae-816c-f15fa25ff429",
"periods":[
{
"unit":"MONTHS",
"duration":1
},
{
"unit":"YEARS",
"duration":1
}
]
},
{
"planId":"267421f6-836e-4216-ac47-81d3c76c587f"
}
]
The response contains the price components for the requested service plans with discounts valid for the requester, for example:
HTTP/1.1 200 OK
[
{
"planId": "edb58c1d-3b0b-41ae-816c-f15fa25ff429",
"periodDeals": [
{
"period": {
"unit": "YEARS",
"duration": 1
},
"resources": [
{
"resourceId": "25bf1798-0fd1-438f-9e77-08284b3f7075",
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "1.0",
"code": "USD"
},
"lowerLimit": 0.0
},
{
"name": "recurring",
"fee": {
"value": "1.5",
"code": "USD"
},
"lowerLimit": 0.0
}
]
}
],
"effectiveFees": [
{
"name": "recurring",
"fee": {
"value": "1.5",
"code": "USD"
}
}
]
},
{
"period": {
"unit": "MONTHS",
"duration": 1
},
"resources": [
{
"resourceId": "25bf1798-0fd1-438f-9e77-08284b3f7075",
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "1.0",
"code": "USD"
},
"lowerLimit": 0.0
},
{
"name": "recurring",
"fee": {
"value": "1.5",
"code": "USD"
},
"lowerLimit": 0.0
}
]
}
],
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "1.0",
"code": "USD"
}
},
{
"name": "recurring",
"fee": {
"value": "1.5",
"code": "USD"
}
}
]
}
]
}
]
A “discount by parent” sales method matches the following formula:
If an account has a subscription on service plan A or purchases this plan and also purchases plan B, then a set discount is applied to plan B.
To make this discount type work through the API, follow these steps:
In the BSS provider control panel, configure a pair of service plans in the same sales category. One plan (“Service Plan A”) will be used as the parent in the discount, and the other plan (“Service Plan B”) as a child. In “Service Plan A”, add an up-sale category and add the sales category of “Service Plan B” to it.
In the BSS provider control panel, create a “Promotion By Parent Plans” promotion. In its configuration, add “Service Plan A” as a parent and “Service Plan B” as a promoted plan. For the added “Service Plan B”, configure the Promotion Prices.
Search for both service plans trough API to get their IDs:
GET /aps/2/collections/service-plans?select(name.en_US)&like(name.en_US,Service*)
The filters used in this request made the response shorter to include only the plan identification properties:
HTTP/1.1 200 OK
[
{
"aps": {
"modified": "2019-11-11T08:57:51Z",
"id": "0a1184ef-0099-4754-8260-9ebd295b71ab",
"type": "http://www.odin.com/billing/ServicePlan/1.1",
"status": "aps:ready",
"revision": 1
},
"name": {
"en_US": "Service B (used as a child)"
}
},
{
"aps": {
"modified": "2019-11-11T08:55:26Z",
"id": "350b97dd-ea4e-4ad7-a6e1-9c60d7143ec4",
"type": "http://www.odin.com/billing/ServicePlan/1.1",
"status": "aps:ready",
"revision": 1
},
"name": {
"en_US": "Service A (used as a parent in demos)"
}
}
]
Evaluate the discount by sending this request:
POST /aps/2/services/discount-manager/deals
[{
"planId": "0a1184ef-0099-4754-8260-9ebd295b71ab"
}]
The response contains prices for “Service Plan B” when it is ordered without a parent and when the specified parent is also ordered:
HTTP/1.1 200 OK
[
{
"planId": "0a1184ef-0099-4754-8260-9ebd295b71ab",
"periodDeals": [
{
"period": {
"unit": "MONTHS",
"duration": 1
},
"resources": [],
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "140.0",
"code": "USD"
}
},
{
"name": "recurring",
"fee": {
"value": "40.0",
"code": "USD"
}
}
]
},
{
"period": {
"unit": "MONTHS",
"duration": 1
},
"parentPlanDiscountCondition": {
"planId": "350b97dd-ea4e-4ad7-a6e1-9c60d7143ec4"
},
"resources": [],
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "84.0",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 40.0,
"amount": 56.0
}
},
{
"name": "recurring",
"fee": {
"value": "24.0",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 40.0,
"amount": 16.0
}
}
]
}
]
}
]
Note
When placing an order for the two service plans considered here, you must explicitly specify that “Service Plan A” is the parent of “Service Plan B”.
This example considers a service plan with two resources. One of them is sold using the tiered price (the unit price depends on the number of purchased resource units) and the price of the other is flat (the unit price does not depend on the number of purchased resource units).
The original price configuration is as follows:
Setup price for a subscription is 100.0.
One month subscription period costs 100.0.
The resource with the flat pricing costs 3.0 per unit.
The tiered prices for the other resource are presented in the following table:
Total number of purchased resource units ( |
Setup price per unit |
Recurring price per unit |
---|---|---|
0 - 5 |
1.0 |
3.0 |
6 - 10 |
0 |
3.0 |
11 and more |
0 |
2.8 |
The service plan is included in a promotion that provides the following discounts for the subscription period and for each resource unit:
Setup fee for the subscription: 10%
Recurring fee for the subscription period: 10%
Recurring fee per every resource unit: 20%
With that configuration, send a request to the discount manager:
POST /aps/2/services/discount-manager/deals
[{
"planId": "f69a9681-d74b-4f0a-a2f2-fd43a42ff175"
}]
The response contains separate prices for a resource unit on each resource tier (identified by lowerLimit
) and for
the subscription period:
HTTP/1.1 200 OK
[
{
"planId": "f69a9681-d74b-4f0a-a2f2-fd43a42ff175",
"periodDeals": [
{
"period": {
"unit": "MONTHS",
"duration": 1
},
"resources": [
{
"resourceId": "25bf1798-0fd1-438f-9e77-08284b3f7075",
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "1.0",
"code": "USD"
},
"lowerLimit": 0.0
},
{
"name": "recurring",
"fee": {
"value": "2.4",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 20.0,
"amount": 0.6
},
"lowerLimit": 0.0
}
]
},
{
"resourceId": "ef943ed8-e331-4beb-88cf-1284257adc2e",
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "1.0",
"code": "USD"
},
"lowerLimit": 0.0
},
{
"name": "recurring",
"fee": {
"value": "2.4",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 20.0,
"amount": 0.6
},
"lowerLimit": 0.0
},
{
"name": "recurring",
"fee": {
"value": "2.24",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 20.0,
"amount": 0.56
},
"lowerLimit": 11.0
}
]
}
],
"effectiveFees": [
{
"name": "setup",
"fee": {
"value": "80.0",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 20.0,
"amount": 20.0
}
},
{
"name": "recurring",
"fee": {
"value": "80.0",
"code": "USD"
},
"discount": {
"type": "PERCENT",
"value": 20.0,
"amount": 20.0
}
}
]
}
]
}
]