Manage Orders

The BSS API allows an external system to issue and activate various types of orders to perform certain commercial operations, including the creation and cancellation of subscriptions, ordering of more resources, and so on.

APS Type and Operations

The platform uses the OrderManagementApplication APS type to create a singleton APS resource presenting the order management service that provides several custom operations to manage orders in BSS. This document covers the following custom operations:

  • orderInfo: gets a list of orders or some data of a specified order by sending a GET request.

  • placeOrder: creates an order by sending a POST request. The type of a new order must be specified by the mandatory type property in the request body.

  • estimateOrder: allows the provider or a reseller to estimate price details of an order without placing that order.

  • estimateCosts: enables a reseller to estimate the cost of an order without placing that order.

  • termsConditions: returns a list of Terms and Conditions that a customer must accept when purchasing specified service plans.

  • reasonCodes: gets a list of pre-defined reasons to be used in a cancellation order.

The APS controller returns the APS ID of the new order if the request is processed successfully, regardless of the order type in a placeOrder request. For example:

{
   "orderId": "f0817852-282c-4047-a4d3-f6501939d5a6"
}

Sales Orders

A sales order is the only order type that creates a subscription from a service plan for a specified customer. In a POST request body, this is defined as "type":"SALES".

../../_images/order-sequence-customer.png ../../_images/order-sequence-plan.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-sales.png ../../_images/order-sequence-status.png

The procedure consists of the following steps:

  1. Identify a customer. Find the APS ID of the account that you want to subscribe to the selected service plans.

  2. Identify service plans. Find the APS IDs of the required service plans, subscription periods, and add-on resources to purchase.

  3. Identify a payment method. From the available payment methods that the chosen account owns, select the one that will be applied to the new order.

  4. Create a sales order. Request a new sales order with input parameters discovered in the previous steps. If everything is OK, the platform creates a sales order and starts the order processing.

  5. Verify the order status. Get the order details to verify if the ordered services are provisioned for the customer.

Other Order Types

There are several order types that change a subscription. In a POST request body, an order type is specified by the type property:

  • RENEWAL: creates a renewal order for a specified subscription and starts the renewal process for the next subscription period.

  • CHANGE: creates a change order to switch a subscription to another period of a specified service plan or to change resource limits in the subscription.

  • CANCELLATION: creates a cancellation order to cancel a specified subscription.

Since the main object in those orders is an existing subscription, the order management sequence is slightly different from the case with a sales order.

../../_images/order-sequence-customer.png ../../_images/order-sequence-subscription.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales.png ../../_images/order-sequence-status.png

The procedure consists of the following steps:

  1. Identify a customer. Find the APS ID of the account whose subscription to be changed.

  2. Identify a subscription. Find the APS ID of the subscription to be changed, and, if necessary, the subscription period to be changed.

  3. Identify a payment method. From the available payment methods that the chosen account owns, select the one that will be applied to the new order.

  4. Create an order. Request a new order with the input parameters discovered in the previous steps. If everything is OK, the platform creates the order and starts the order processing.

  5. Verify the order status. Get the order details to verify if the ordered updates in the specified subscription are completed.

Security

To be able to call the above-mentioned custom operations, an external system must be authorized to use the GET and POST methods on the OrderManagementApplication APS type whose APS ID is http://www.odin.com/billing/order-management. To add this permission, follow the instructions in the Set Up the User’s Credentials section.

Order Processing

After an order that requires payment from an account (a customer or reseller) is placed in BSS, the latter starts the order processing, which consists of at least the following two phases:

  1. Order payment.

    This phase requires the account to have an automated payment method, for example, a bank card. The paymentMethodId property, if used, specifies a payment method explicitly. Otherwise, the platform will seek the default payment method (marked as Auto Payments) for that account. When you verify an order status, pay attention to the returned paymentStatus property that shows whether the order is payed for or there are any issues with it.

    Warning

    If the platform cannot find a relevant payment method, it places the required order without a payment attached.

  2. Order provisioning.

    BSS creates a subscription and requires the provisioning system, usually OSS, to perform a required operation, for example, provisioning of the services marked as “auto-provisioning”. When you verify an order status, pay attention to the returned provisioningStatus property that shows whether the ordered services were provisioned successfully or whether there were any issues with it.

When creating an order, it might be necessary to pass the following optional properties:

  • paymentMethodId is the platform internal ID of a payment method belonging to the customer for whom an order is requested. This method will be used to pay for the requested order. If this property is omitted, the platform will be seeking a method declared as the default for the customer.

  • attributes is an array of BSS specific order attributes preliminary configured by the provider as custom attributes in the platform. Each entry is a pair of attributeID and value properties.

  • parameters are also known as activation parameters. Send such parameters when creating a sales order in a case the ordered services require those parameters at the provisioning stage.

Source Data

Depending on the order type, an external system must preliminary collect the following data before sending REST requests:

  • The following properties of the service plan if you want to order it:

    • The APS ID of the service plan

    • A subscription period identified by its length consisting of the measurement unit, typically “MONTHS” or “YEARS”, and the number of the units

    • The APS ID of the resources if you want to order more of those resources than the service plan includes

  • The APS ID of the account if you want to subscribe the latter to a service plan

  • The APS ID of the subscription if you want to manage a subscription, for example, to renew, switch or cancel it

Identify and Configure Accounts

Identify an account that you want to subscribe to service plans or an account whose subscription you are going to change.

../../_images/order-sequence-customer-b.png ../../_images/order-sequence-plan.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-sales.png ../../_images/order-sequence-status.png

An order must specify the APS ID of the account to be subscribed to service plans or the account whose subscription must be changed.

Find the APS ID of the account as explained in the Account Lookup section, for example:

GET /aps/2/collections/accounts?eq(id,1000001)

Pay attention to the aps section in the response:

HTTP/1.1 200 OK

[{
   "aps": {
      "id": "3fef9702-b2ad-419a-9924-a56882e5f06c",
      "type": "http://parallels.com/aps/types/pa/account/1.2",
      "status": "aps:ready",
      /* ... */
   },
   /* ... */
}]

If you want the order to be paid for automatically, ensure the account has an automatic payment method such as a bank card, configured as the default method (marked as Auto Payments):

../../_images/customer-default-method.png

Note

If a request for order creation does not specify a payment method, the order management service will try to apply the payment method configured as default (marked as Auto Payments). This requires the customer to have a payment method configured as default.

Identify Service Plans

To subscribe an account to service plans, identify them first.

../../_images/order-sequence-customer.png ../../_images/order-sequence-plan-b.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-sales.png ../../_images/order-sequence-status.png

Get a list of service plans as explained in the Service Plans section, for example:

GET /aps/2/collections/service-plans

In the response, find the service plans and subscription periods you want to order as well as the resources that you can buy in addition to the included amount:

HTTP/1.1 200 OK

[
   /* ... */
   {
      "aps": {
         "id": "ae0e6e84-0d37-4b17-8f6c-5709633529ab",
         "type": "http://www.odin.com/billing/ServicePlan/1.0",
         "status": "aps:ready",
         /* ... */
      },
      "name": {
         "en_US": "Offer-Counter-User Management Project"
      },
      "billingTerms": {
         "pricingModel": "PM_FIXED_PRICE",
         "period": {
            "duration": 1,
            "unit": "MONTHS"
         },
         "autorenewal": {
            "days": 0,
            "type": "DISABLED"
         },
         "model": "CHARGE_BEFORE_BILLING_PERIOD",
         "recurringPricesEvery": "MONTH"
      },
      "subscriptionPeriods": [
         {
            "autoRenewalPeriod": {
               "unit": "MONTHS",
               "duration": 1
            },
            "numberOfBillingPeriods": 1,
            "trial": false,
            "defaultPeriod": false,
            "fees": {
               "setup": {
                  "price": {
                     "value": "10.0",
                     "code": "USD"
                  },
                  /* ... */
               },
               "recurring": {
                  "price": {
                     "value": "4.25",
                     "code": "USD"
                  },
                  /* ... */
               },
               "renewal": {
                  "price": {
                     "value": "0.0",
                     "code": "USD"
                  },
                  /* ... */
               },
               "deposit": { /* ... */ },
            },
            "refund": { /* ... */ }
         },
         /* ... */
      ],
      "resourceRates": [
         {
            "resourceId": "1c3ab0be-3160-45a1-a9b4-7824f74673ff",
            /* ... */
            "units": {
               "included": 20.0,
               "min": 0.0,
               "max": -1.0
            },
            "fees": {
               "setup": {
                  "price": {
                     "value": "0.0",
                     "code": "USD"
                  },
                  /* ... */
               },
               "recurring": {
                  "price": {
                     "value": "1.5",
                     "code": "USD"
                  },
                  "chargePerUnit": true,
                  /* ... */
               }
            },
            /* ... */
         },
         {
            "resourceId": "7205fd93-9768-480c-956b-58f54aac7247",
            /* ... */
            "units": {
               "included": 10.0,
               "min": 0.0,
               "max": -1.0
            },
            "fees": {
               "setup": {
                  "price": {
                     "value": "0.0",
                     "code": "USD"
                  },
                  /* ... */
               },
               "recurring": {
                  "price": {
                     "value": "1.5",
                     "code": "USD"
                  },
                  "chargePerUnit": true,
                  /* ... */
               }
            },
            /* ... */
         },
         /* ... */
      ],
      /* ... */
   },
   /* ... */
]

The returned service plan representation contains the APS ID (aps.id) of the plans as well as the subscription periods identified by the measurement unit (subscriptionPeriods.autoRenewalPeriod.unit) and the number of the units (subscriptionPeriods.autoRenewalPeriod.duration). A list of resource rates allows a customer or a system to order more amount of resources than the service plan includes.

Identify Payment Methods

Find a payment method to pay for a new order.

../../_images/order-sequence-customer.png ../../_images/order-sequence-plan.png ../../_images/order-sequence-payment-b.png ../../_images/order-sequence-sales.png ../../_images/order-sequence-status.png

Get a list of the payment methods owned by the account as explained in the Get Payment Methods section, for example:

GET /aps/2/services/payment-method-manager/paymentMethods?accountId=3fef9702-b2ad-419a-9924-a56882e5f06c

In the response, find the id property of the payment method to be applied to the new order:

[
   {
      "id": 3,
      "paymentSystemId": "Demo.Redirect",
      "paymentSystem": "Demo Payment Gateway",
      "ownerAccountId": null,
      "number": null,
      "name": "Demo Payment Gateway",
      "type": "EXTERNAL",
      "perCustomer": false,
      "status": "ACTIVE",
      "ratified": "NOT_REQUIRED",
      "defaultMethod": true
   },
   {
      "id": 0,
      "paymentSystemId": "Check/Cash",
      "paymentSystem": "Check/Cash",
      "ownerAccountId": null,
      "number": null,
      "name": "Check/Cash",
      "type": "MANUAL",
      "perCustomer": false,
      "status": "ACTIVE",
      "ratified": "NOT_REQUIRED",
      "defaultMethod": false
   }
]

Get the Terms and Conditions of Service Plans

Since service plans are generally accompanied by certain terms and conditions that must be accepted by a customer, a requester can get the contents of those terms and conditions before subscribing that customer to the service plan. The request must contain the APS IDs of the service plans and the customer as in the following example:

POST /aps/2/services/order-manager/orders/termsconditions

{
   "type": "SALES",
   "accountId": "3fef9702-b2ad-419a-9924-a56882e5f06c",
   "products": [
      {
         "planId": "ebf17799-6a39-4133-ab9c-0afa40dcd6ae",
         "period": {
               "unit": "MONTHS",
               "duration": 1
         }
      }
   ]
}

If the requested terms and conditions are included, the platform returns their IDs and contents:

[
   {
      "termId": "1",
      "name": "Terms and Conditions",
      "content": "<h1>Cloud SaaS</h1>\r\n<h2>Introduction</h2>\r\n
            Lorem ipsum ut porttitor sagittis.\r\n
            <h2>Intellectual Properties</h2>\r\n
            Convallis interdum porttitor ante hendrerit.\r\n
            <h2>Restrictions</h2>\r\n
            Ac auctor duis curae magna."
   }
]

When placing a sales order to subscribe a customer to the service plans, the request must confirm the acceptance of the respective terms and conditions.

Sales Orders

To subscribe a customer to a list of service plans, an external management system must request the creation of a sales order in the platform.

../../_images/order-sequence-customer.png ../../_images/order-sequence-plan.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-sales-b.png ../../_images/order-sequence-status.png

In a request, specify the parameters you have collected in the previous steps. Optionally, the request can contain the following groups of properties:

  • If you want your customer to have more resources than assigned by the units.included values in the resourceRates array of a service plan, add the resources array containing a pair of the APS ID and total amount for every such resource.

  • To pass the activation parameters required by the ordered application services, add them to the parameters array.

  • To assign order attributes, send those attributes in the attributes array.

  • To accept the terms and conditions required by the service plans, send the acceptedTerms array containing the IDs of the accepted terms and conditions.

The following example illustrates how to subscribe a specified customer to a list of specified service plans and demonstrates a request for an extended amount of a resource:

POST /aps/2/services/order-manager/orders

{
   "type": "SALES",
   "accountId" : "3fef9702-b2ad-419a-9924-a56882e5f06c",
   "promoCode": "123",
   "paymentMethodId": "3",
   "products" : [{
         "planId" : "ae0e6e84-0d37-4b17-8f6c-5709633529ab",
         "period" : {
            "unit" : "MONTHS",
            "duration" : 1
         },
         "resources" : [{
            "resourceId" : "1c3ab0be-3160-45a1-a9b4-7824f74673ff",
            "amount" : 40
         }],
         "parameters": [
            {
               "aps": {
               "type": "http://aps-standard.org/samples/vpsdemo/management/1.0"
            },
               "client": "1st APS, inc.",
               "mail": "jsmith@aps.test"
            }
         ],
         "childProducts": [
            { // Another service plan - upsell
            }
         ]
      },
      { // Another service plan
      }
   ],
   "attributes": [
      {
         "attributeID": "comments",
         "value": "Requested by the ERP system."
      }
   ],
   "acceptedTerms": [
      "1"
   ],
   "specialPricing" : { // See the "Set Special Prices" section for details
   }
}

Key:

  • For every service plan specified in the request, a separate subscription must be created on completion of the order processing.

  • In the resources set, a required resource amount must be higher than the included amount of the resource, since the former includes the latter plus the additional amount.

  • An entry in the parameters array contains a set of properties required by an auto-provisioning APS resource whose APS type is specified by the aps section.

  • Refer to the Set Special Prices section for details about special prices.

The response must contain the APS ID of the created order, as specified earlier in the APS Type and Operations section.

If all is configured correctly, the platform will process the created sales order, including:

  • Order payment

  • Creation of the customer subscription

  • Provisioning of the services

In BSS, you can verify if a subscription is created from the requested service plan for the specified account:

../../_images/ordered-subscription.png

The total amount of the ordered resource in the subscription is the same as requested (20):

../../_images/ordered-resource.png

To get the APS IDs of the subscriptions related to a particular order, refer to the Get List of Orders process.

Identify Subscriptions

To change a subscription, find its APS ID, subscription period and resources to be changed.

../../_images/order-sequence-customer.png ../../_images/order-sequence-subscription-b.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales.png ../../_images/order-sequence-status.png

Note

Typically, subscription services are provisioned by OSS (one of exceptions are subscriptions providing the reseller status). In this case, the platform keeps two coupled subscriptions: one in OSS (OSS subscription) and the other in BSS (BSS subscription). Use the APS ID of the latter when managing these subscriptions through the orders.

You can search for a subscription in various ways, as shown in the following examples.

  • Get the full list of subscriptions:

    GET /aps/2/collections/bss-subscriptions
    
  • Get all subscriptions of a customer using the subscriptions link of the account APS type:

    GET /aps/2/collections/bss-subscriptions?eq(account.aps.id,d7dd06ef-20a0-41f5-b89f-768ef373ae44)
    

Find the subscription you want to process (for example, to renew or cancel) in the response that will look similar to the following:

HTTP/1.1 200 OK

[
   {
      "aps": {
      "id": "456808a0-b5a6-4092-ab67-b77e33743a07",
      "type": "http://www.odin.com/billing/Subscription/1.0",
                     "status": "aps:ready",
         /* ... */
      },
      "billingTerms": {
         "billingPeriod": {
            "duration": 1,
            "unit": "MONTHS"
         },
         "billingModel": "CHARGE_BEFORE_BILLING_PERIOD",
         "freezePrices": false,
         "autoRenewal": {
            "type": "DISABLED"
         }
      },
      "serviceGate": "PEMGATE",
      "trial": false,
      "nextBillDate": "2019-04-12",
      "subscriptionPeriod": {
         "duration": 1,
         "unit": "MONTHS"
      },
      "serviceStatus": "ACTIVE",
      "name": "VPS Demo Services",
      "lastBillDate": "2019-03-12",
      "subscriptionId": 1000001,
      "autoRenewEnabled": false,
      "startDate": "2019-03-12",
      "expirationDate": "2019-04-12",
      "status": "ACTIVE"
   } /*,
   ...other subscriptions */
]

Renewal Orders

When a subscription is close to its expiration date, the platform will renew it automatically for the next subscription period if the subscription configuration inherited from the service plan allows it. Alternatively, a staff member or an external management system can renew the subscription period including the upgrade of the subscription from a trial to a paid period.

../../_images/order-sequence-customer.png ../../_images/order-sequence-subscription.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales-b.png ../../_images/order-sequence-status.png

To renew a subscription, an external management system must call the placeOrder custom operation as in the following example:

POST /aps/2/services/order-manager/orders

{
   "type": "RENEWAL",
   "subscriptionId": "456808a0-b5a6-4092-ab67-b77e33743a07",
   "paymentMethodId": "11",
   "period": {
      "unit": "MONTHS",
      "duration": 1
   }
}

Note

The period structure is needed only if you are going to change the period, otherwise the subscription will be renewed for the next period equal the current period.

The response must contain the APS ID of the created order, as specified earlier in the APS Type and Operations section.

../../_images/ordered-subscription-renewed.png

Change Orders

A change order allows a requester to switch a subscription and change resource limits in a subscription as explained in the following two sections.

Note

A change request can combine both of the above operations: switching a subscription and changing resource limits.

../../_images/order-sequence-customer.png ../../_images/order-sequence-subscription.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales-b.png ../../_images/order-sequence-status.png

Switching Subscriptions

The platform allows a customer to switch a subscription from their current service plan to another one or to another subscription period within the current service plan. Alternatively, an external management system can call the placeOrder custom operation to start a switching process.

POST /aps/2/services/order-manager/orders

{
   "type": "CHANGE",
   "subscriptionId": "456808a0-b5a6-4092-ab67-b77e33743a07",
   "planId": "ae0e6e84-0d37-4b17-8f6c-5709633529ab",
   "paymentMethodId": "11",
   "period": {
      "unit": "MONTHS",
      "duration": 3
   }
}

If successful, the response contains the APS ID of the created order, as specified earlier in the APS Type and Operations section.

Changing Resource Limits

To buy an additional amount of resources within a subscription, an external management system can call the placeOrder custom operation as in the following example:

POST /aps/2/services/order-manager/orders

{
   "type": "CHANGE",
   "subscriptionId": "4c867c87-fbf7-49e8-9f7e-0d06e8f7a003",
   "paymentMethodId": "11",
   "resources": [
      {
         "resourceId": "bf8ea705-3f2b-4f3c-b445-a11ec100da82",
         "amount": 10
      }
   ]
}

Every entry in the resources array corresponds to a resource rate in the respective service plan and consists of the resource APS ID and a new limit (amount) for the resource.

If successful, the response contains the APS ID of the created order, as specified earlier in the APS Type and Operations section.

Cancellation Orders

Requesting Subscription Cancellation

A cancellation order is used to request the termination of a subscription.

../../_images/order-sequence-customer.png ../../_images/order-sequence-subscription.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales-b.png ../../_images/order-sequence-status.png

If there is unused time, the subscriber’s balance must be adjusted by the refundType property:

  • "refundType":"CREDIT_MEMO" - create a credit memo to be used by the subscriber to pay for other services.

  • "refundType":"REFUND" - refund directly using the specified payment method.

To cancel a subscription, an external management system must call the placeOrder custom operation as in the following example:

POST /aps/2/services/order-manager/orders

{
   "type": "CANCELLATION",
   "subscriptionId": "456808a0-b5a6-4092-ab67-b77e33743a07",
   "refundType": "CREDIT_MEMO"
}

If successful, the response must contain the APS ID of the created order, as specified earlier in the APS Type and Operations section.

Pushing Order Processing

If the customer must be paid for the unused period of time, whether by creating a credit memo or by refund, the new cancellation order will be in the “New” status waiting for further action. If you request the Get Order Details, pay attention to the ofStatus (order flow status) property in the response; it will be "NW". In the BSS control panel, the canceled subscription must look as follows:

../../_images/ordered-subscription-cancelled.png

To continue the normal order processing and make it finally “completed”, the external system must open the order by sending a push request for the order to transition to the "OP" status (meaning “Open” status) as in the following example:

POST /aps/2/services/order-manager/orders/4449abb3-f760-4bd8-98cc-c8e36352c3a7/push

{
   "ofStatus": "OP"
}

If successful, the response only contains the header HTTP/1.1 200 OK (without body). If you request the order details, the returned order flow status will be "ofStatus":"CP" (“Completed”). The respective subscription is now terminated.

Cancellation Reasons

When a customer or their sales vendor cancels a subscription in a user panel (whether in the reseller or customer panel), they must choose a reason for this operation. A reason is selected from the list of available reasons configured in the platform by the provider.

An external system can request the platform to provide the list of possible reasons for all operations or for a specific one as in the following examples.

  • Get the full list of the configured reasons:

    GET /aps/2/services/order-manager/reasonCodes
    

    The response will be as follows:

    HTTP/1.1 200 OK
    
    [
      {
        "reasonId": 1,
        "description": {
          "en_US": "Customer Request"
        },
        "operationType": "START_SERVICE"
      },
      {
        "reasonId": 2,
        "description": {
          "en_US": "Released from Credit Hold"
        },
        "operationType": "START_SERVICE"
      },
      {
        "reasonId": 3,
        "description": {
          "en_US": "Other"
        },
        "operationType": "START_SERVICE"
      },
      {
        "reasonId": 4,
        "description": {
          "en_US": "Not Applicable"
        },
        "operationType": "START_SERVICE"
      },
      {
        "reasonId": 5,
        "description": {
          "en_US": "Customer Request"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 6,
        "description": {
          "en_US": "Fraud"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 7,
        "description": {
          "en_US": "Account overdue"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 8,
        "description": {
          "en_US": "AUP Violation"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 9,
        "description": {
          "en_US": "Other"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 10,
        "description": {
          "en_US": "Not Applicable"
        },
        "operationType": "STOP_SERVICE"
      },
      {
        "reasonId": 17,
        "description": {
          "en_US": "Cost"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 18,
        "description": {
          "en_US": "Poor Performance"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 19,
        "description": {
          "en_US": "Poor Service"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 20,
        "description": {
          "en_US": "No Longer Used"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 21,
        "description": {
          "en_US": "New Provider"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 22,
        "description": {
          "en_US": "Change in Company Circumstance"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 23,
        "description": {
          "en_US": "Other"
        },
        "operationType": "CANCEL_BY_CUSTOMER"
      },
      {
        "reasonId": 13,
        "description": {
          "en_US": "Customer Request"
        },
        "operationType": "CANCEL_BY_VENDOR"
      },
      {
        "reasonId": 14,
        "description": {
          "en_US": "Other"
        },
        "operationType": "CANCEL_BY_VENDOR"
      },
      {
        "reasonId": 15,
        "description": {
          "en_US": "Customer Request"
        },
        "operationType": "ACCOUNT_CANCELLATION"
      },
      {
        "reasonId": 16,
        "description": {
          "en_US": "Other"
        },
        "operationType": "ACCOUNT_CANCELLATION"
      },
      {
        "reasonId": 61,
        "description": {
          "en_US": "Account overdue"
        },
        "operationType": "DESTROY_SERVICE"
      },
      {
        "reasonId": 69,
        "description": {
          "en_US": "Other"
        },
        "operationType": "DESTROY_SERVICE"
      },
      {
        "reasonId": 107,
        "description": {
          "en_US": "Automatical Synchronization: Stop Service"
        },
        "operationType": "AUTOMATIC_SYNCHRONIZATION"
      },
      {
        "reasonId": 161,
        "description": {
          "en_US": "Automatical Synchronization: Destroy Service"
        },
        "operationType": "AUTOMATIC_SYNCHRONIZATION"
      }
    ]
    
  • Get the list of reasons applicable for the cancellation operation:

    GET /aps/2/services/order-manager/reasonCodes?operationType=CANCEL_BY_VENDOR
    

    With the default platform configuration, the response will be as follows:

    HTTP/1.1 200 OK
    
    [
      {
        "reasonId": 13,
        "description": {
          "en_US": "Customer Request"
        },
        "operationType": "CANCEL_BY_VENDOR"
      },
      {
        "reasonId": 14,
        "description": {
          "en_US": "Other"
        },
        "operationType": "CANCEL_BY_VENDOR"
      }
    ]
    

Note

Using the BSS control panel, the provider can navigate to
System > Settings > Order Processing > Reason Codes and change the list of reasons.

When creating a cancellation order, an external system can specify a reason for it and a comment, for example:

POST /aps/2/services/order-manager/orders

{
   "type": "CANCELLATION",
   "refundType":"CREDIT_MEMO",
   "subscriptionId" : "a63078fb-7af8-417e-88c3-e7af37e08e59",
   "reasonId": 14,
   "comment": "Requested through the ERP system."
}

If the comment is not specified in the request, the default string is assigned to the order comment field based on the following conditions:

  • “No comment”: if a reason is specified

  • “Cancelled from API”: if no reason is specified

Get List of Orders

Typically, an external management system verifies whether the placed orders were processed successfully.

../../_images/order-sequence-subscription.png ../../_images/order-sequence-customer.png ../../_images/order-sequence-payment.png ../../_images/order-sequence-notsales.png ../../_images/order-sequence-status-b.png

Get All Orders

An external management system can get a list of all orders by calling the listOrders custom operation:

GET /aps/2/services/order-manager/orders

The response contains the list of orders:

HTTP/1.1 200 OK

[
   {
      "orderId": "18131926-c152-4652-8a29-3fe076929f4b",
      "internalId": 1000024,
      "orderNumber": "SO000014",
      "type": "SO",
      "total": 308.0,
      "taxTotal": 0.0,
      "exclusiveTaxTotal": 0.0,
      "subTotal": 308.0,
      "status": "COMPLETED",
      "paymentStatus": "FINISHED",
      "provisioningStatus": "COMPLETED",
      "ofStatus": "CP",
      "sellerId": "c0d43087-da72-472a-a176-84a34608979f",
      "buyerId": "d7dd06ef-20a0-41f5-b89f-768ef373ae44",
      "orderDate": "2019-04-04T21:00:00Z",
      "expirationDate": "2019-04-07T21:00:00Z",
      "creationTime": "2019-04-05T13:22:14Z"
      "orderAttributes": [],
      "accountAttributes": [],
      "endCustomerName": "John Smith",
      "endCustomerType": "CUSTOMER"
   },
   { // Another order
   }
]

A returned order representation contains the results of the two order processing steps (paymentStatus and provisioningStatus) and the status of the order.

Similar to other requests for a collection of resources, by default, the returned Content-Range header contains the total number of found orders in accordance with the pagination rules. This calculation requires a substantial amount of time when the orders number several million. To turn off this calculation, send the header APS-Skip-Content-Range.

Note

The orderAttributes and accountAttributes arrays show only those attributes whose configuration parameter Show in the List of Resellers is checked in the provider control panel.

Get Filtered Orders

To select the list of orders by particular criteria, the listOrders operation provides custom filters similar to Resource Query Language. In this case, a request will look as follows:

GET /aps/2/services/order-manager/orders?in({property},{value}),select({linkToResources}),ge(creationDate,{fromDate}),le(creationDate,{toDate}),like(number,*000001),limit({from},{to})

The following functions can be used:

  • in verifies whether a property is in a specified list, for example, request only sales orders and billing orders:

    in(type,(SO,BO))
    

    The following properties are allowed in the function:

    • resellerId is the APS ID of the reseller that provides the ordered services.

    • customerId is the APS ID of the customer that placed the order.

    • endCustomerName is a customer name.

    • endCustomerType is an account type (“PROVIDER”, “RESELLER”, or “CUSTOMER”).

    • ID of an order or account attribute.

    • internalId is and integer showing an order unique ID in the platform.

    • orderId is a string showing an order unique APS ID.

    • orderNumber is a string ID assigned by the platform to an order, for example, “SO000004”.

    • status is an order status.

    • type is an order type. The most common types for API are in the following list:

      • BO is a billing order generated at the end of a billing period usually to bill an account for resources consumed during the passed billing period.

      • CL is a cancellation order generated when a subscription is cancelled and the sales vendor owns money to the customer.

      • CF is a cancellation order generated when a subscription is cancelled and the customer owns money to the sales vendor.

      • RN is a renewal order created when a subscription must be renewed for the next period.

      • SO is a sales order that contains a request for certain service plans.

      • CH is a change order that a subscriber uses to change a subscription.

    • provisioningStatus is an order provisioning status.

    • paymentStatus is the payment status of an order.

    • subscriptionId is the APS ID of the subscription whose orders are requested.

    Note

    A list of order attribute IDs and account attribute IDs is created by the provider using the control panel. Those IDs are unique within the platform.

  • like verifies if a property matches a wildcard mask that uses the wildcard symbols * and ?. Currently, this function is applicable to orderNumber, endCustomerName, and attribute IDs (either account or order attributes).

    Example of filtering by order number:

    like(orderNumber,*00001)
    

    Example of filtering by attribute ID:

    like(ORDER_ID1,test1234)
    
  • ge and le (respectively “Greater or Equal” and “Lower or Equal”) functions are applicable to the internal ID and the date-time properties to select the orders in a certain date and time interval:

    • internalId

    • creationTime

    • orderDate

    • expirationDate

    For example, seek for orders created in the specified time period:

    ge(creationTime,2018-04-26T16:00:00Z),le(creationTime,2018-04-26T18:00:00Z)
    
  • limit fetches orders in a range of numbers, for example get orders in the range of 0 to 9:

    limit(0,9)
    

Note

limit(0,0) requires the APS controller to return only the total number of orders matching the requested filters. In this case, the response contains the Content-Range header that shows the requested number and does not contain the body.

Get Order Details

To get the full JSON representation of an order, a request must specify the order APS ID in the URL as in the following example:

GET /aps/2/services/order-manager/orders/18131926-c152-4652-8a29-3fe076929f4b

If successful, the response looks similar to the following:

HTTP/1.1 200 OK

{
   "orderId": "18131926-c152-4652-8a29-3fe076929f4b",
   "internalId": 1000002,
   "orderNumber": "SO000001",
   "type": "SO",
   "total": {
      "value": 308.0,
      "code": "USD"
   },
   "taxTotal": {
      "value": 0.0,
      "code": "USD"
   },
   "exclusiveTaxTotal": {
      "value": 0.0,
      "code": "USD"
   },
   "subTotal": {
      "value": 308.0,
      "code": "USD"
   },
   "status": "COMPLETED",
   "subscriptions": [
      "4c867c87-fbf7-49e8-9f7e-0d06e8f7a003"
   ],
   "bssSubscriptions": [
      "456808a0-b5a6-4092-ab67-b77e33743a07"
   ],
   "paymentStatus": "FINISHED",
   "provisioningStatus": "COMPLETED",
   "ofStatus": "CP",
   "sellerId": "8265e3d7-cdf5-4acc-8ca4-267268a79aae",
   "buyerId": "9d086478-d00b-40c2-86df-7bc9b862e667",
   "orderDate": "2019-02-26",
   "expirationDate": "2019-03-01",
   "creationTime": "2019-02-26T10:01:17Z",
   "orderAttributes": [],
   "endCustomerAttributes": [
      {
         "attributeID": "external_id",
         "value": "Smith-123"
      }
    ],
   "details": [
      {
         "type": "RESOURCE_RECURRING",
         "planId": "67216414-6490-4588-bef9-7f6acf5e6a63",
         "period": {
            "unit": "YEARS",
            "duration": 1
         },
         "resourceId": "6cc3ccc6-0571-4c16-8e41-3916e1136284",
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "Disk Space Recurring",
         "quantity": 90.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "GB",
         "unitPrice": {
            "value": 1.0,
            "code": "USD"
         },
         "extendedPrice": {
            "value": 90.0,
            "code": "USD"
         }
         "discount": {
            "type": "PERCENT",
            "value": 0.0,
            "amount": 0.0
         },
         "taxAmount": {
            "value": 0.0,
            "code": "USD"
         }
         "exclusiveTaxAmount": {
            "value": 0.0,
            "code": "USD"
         }
      },
      {
         "type": "PLAN_RECURRING",
         "planId": "67216414-6490-4588-bef9-7f6acf5e6a63",
         "period": {
            "unit": "YEARS",
            "duration": 1
         },
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "VIP Maintenance and Support Recurring",
         "quantity": 1.0,
         "unitOfMeasure": "item",
         "unitPrice": {
            "value": 199.0,
            "code": "USD"
         }
         "extendedPrice": {
            "value": 199.0,
            "code": "USD"
         }
         "discount": {
            "type": "PERCENT",
            "value": 0.0,
            "amount": 0.0
         },
            "taxAmount": {
               "value": 0.0,
               "code": "USD"
            }
            "exclusiveTaxAmount": {
               "value": 0.0,
               "code": "USD"
            }
         },
         {
            "type": "PLAN_SETUP",
            "planId": "67216414-6490-4588-bef9-7f6acf5e6a63",
            "period": {
               "unit": "YEARS",
               "duration": 1
            },
         "description": "VIP Maintenance and Support Setup",
         "quantity": 1.0,
         "unitOfMeasure": "item",
         "unitPrice": {
            "value": 19.0,
            "code": "USD"
         }
         "extendedPrice": {
            "value": 19.0,
            "code": "USD"
         }
         "discount": {
            "type": "PERCENT",
            "value": 0.0,
            "amount": 0.0
         },
         "taxAmount": {
            "value": 0.0,
            "code": "USD"
         }
         "exclusiveTaxAmount": {
            "value" 0.0,
            "code": "USD"
         }
      }
   ],
   "endCustomerName": "John Smith",
   "endCustomerType": "CUSTOMER"
}

From the response, the external management system will get the following data that it can subject to further processing:

  • The APS ID of the order;

  • The order status (“NOT_STARTED”, “IN_PROGRESS”, “PROBLEM”, “CANCELED”, or “COMPLETED”);

  • The order number generated by the platform internally. This attribute allows a staff member to find an order in the user panel;

  • A list of subscriptions (APS IDs) the order is bound to. As it was mentioned earlier, when managing subscriptions through orders, use the BSS

Estimate Prices and Costs

The order management API allows an external system to estimate prices and costs using the following custom operations:

  • estimateOrder: provides detailed structured pricing for a customer’s order.

  • estimateCosts: given a similar customer’s order, returns the detailed structured cost of that order for the customer’s reseller.

An estimation request sends the same payload as the creation operation for the same order type. An external system can estimate the following order types:

  • Sales

  • Renewal

  • Change

  • Cancellation

The following examples are based on the provider-reseller-customer chain:

../../_images/provider-reseller-customer.png

The configuration of such a sales scheme is similar to the one described in concepts. In addition, it requires configuration of discounts and taxes (which we suppose is already done).

Estimate the Order Price

The estimateOrder custom operation calculates the price details for an order without the order creation. Typically, resellers use it to estimate the price for a customer whose APS ID must be in the request.

The estimation operation takes into account the discounts, promos, and taxes valid for a specified customer. It is possible to exclude the tax calculation by adding the includeTaxes=false input query parameter.

POST /aps/2/services/order-manager/orders/estimate

{
   "type": "SALES",
   "accountId" : "00b60056-8b0a-4981-8ca4-d114346cd652",
   "promoCode" : "123",
   "products" : [{
      "planId" : "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
      "period" : {
         "unit" : "MONTHS",
         "duration" : 1
      },
      "resources" : [{
         "resourceId" : "2f8905f8-4302-49d7-ab7f-65c9036addf0",
         "amount" : 20
      }]
   }]
}

Note

Refer to the Set Special Prices section for details about special prices.

A response looks like this:

HTTP/1.1 200 OK

{
   "promoResult": "APPLIED",
   "total": 20.839999999999996,
   "subTotal": 18.939999999999998,
   "taxTotal": 1.9,
   "exclusiveTaxTotal": 1.9,
   "details": [
      {
         "type": "PLAN_SETUP",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "description": "Cloud VPSes Setup",
         "quantity": 1.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "item",
         "unitPrice": 2.0,
         "extendedPrice": 1.5,
         "discount": {
            "type": "PERCENT",
            "value": 25.0,
            "amount": 0.5
         },
         "taxAmount": 0.15,
         "exclusiveTaxAmount": 0.15
      },
      {
         "type": "PLAN_RECURRING",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "Cloud VPSes Recurring",
         "quantity": 1.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "item",
         "unitPrice": 4.25,
         "extendedPrice": 3.19,
         "discount": {
            "type": "PERCENT",
            "value": 25.0,
            "amount": 1.06
         },
         "taxAmount": 0.32,
         "exclusiveTaxAmount": 0.32
      },
      {
         "type": "RESOURCE_RECURRING",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "resourceId": "2f8905f8-4302-49d7-ab7f-65c9036addf0",
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "null Recurring",
         "quantity": 19.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "unit",
         "unitPrice": 1.0,
         "extendedPrice": 14.25,
         "discount": {
            "type": "PERCENT",
            "value": 25.0,
            "amount": 4.75
         },
         "taxAmount": 1.43,
         "exclusiveTaxAmount": 1.43
      }
   ]
}

Note

1. There are two types of taxes, those that are included in the initial price (inclusive taxes) and those that are added to the initial price (exclusive taxes).

  1. In the response, the total estimated price total is the sum of subtotal and exclusiveTaxTotal.

Estimate the Order Cost

The estimateCosts operation is similar to the estimateOrder operation: it accepts the same input data, that is, a structured order for a customer, and returns data using the same output structure as estimateOrder. The difference is that estimateCosts returns data that shows how much the customer’s reseller pays to its direct parent reseller or the provider, whereas estimateOrder returns the price for the specified customer.

Set Special Prices

When calling a custom operation that creates a Sales Orders or estimates an order as described in the Estimate the Order Price section, it is possible to add the specialPricing structure inside the main input OrderRequest structure. The added structure is applicable to the list of specified order types and it redefines some spot prices of the service plans specified in those order types:

"specialPricing" : {
   "applicableTo" : [ /* "RENEWAL" or empty */ ],
   "products" : [ /* One or more service plans with redefined prices and costs */ ]
}

Note

The applicableTo property must comply with Special Pricing.

If at least one special price is applicable to a subscription, the final prices in that subscription are adjusted by automatically creating a promo bound to the subscription. Unlike other promos, such a promo is not included in the marketing configuration (Products > Marketing) and it is applicable only to its bound subscription.

For example, when creating a sales order with special prices applicable to RENEWAL, the auto-generated new promo will influence both the price of the first period and all subsequent subscription periods.

An entry in the products list is a service plan with the new spot (special) prices and costs. The general format of an entry is:

{
   "planId": "<UUID>",
   "period": {
       "unit": "<string>", // DAYS   MONTHS   YEARS
       "duration": "<int>",
   },
   "prices": {
       "setup": "<number>",
       "recurring": "<number>",
       "renewal": "<number>",
       "transfer": "<number>"
   },
   "costs": {
       "setup": "<number>",
       "recurring": "<number>",
       "renewal": "<number>",
       "transfer": "<number>"
   }
   "resources": [
       {
           "resourceId": "<UUID>",
           "prices": {
               "setup": "<number>",
               "recurring": "<number>",
               "overuse": "<number>"
           },
           "costs": {
               "setup": "<number>",
               "recurring": "<number>",
               "overuse": "<number>"
           }
       },
       /* ... more resource rates */
   ]
}

The cost is the price that a reseller pays their parent for a delegated service plan. For example, an L1 reseller delegates a service plan to an L2 reseller and gives a 10% discount for every spot price in that service plan. So, if a subscription price for a customer of the L2 reseller is $100, it will cost $90 for the L2 reseller.

Note

The cost of a service plan for a reseller (for example, an L2 reseller) can be changed only by the reseller’s ancestors (L1 reseller or the provider).

In the example below, the provider estimates the cost of a service plan delegated to a reseller and the price for a customer of the reseller. This is assuming a sales order contains special prices for the customer and special costs for the reseller:

POST /aps/2/services/order-manager/orders/estimate

{
   "type": "SALES",
   "accountId" : "00b60056-8b0a-4981-8ca4-d114346cd652",
   "promoCode" : "123",
   "products" : [{
      "planId" : "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
      "period" : {
         "unit" : "MONTHS",
         "duration" : 1
      },
      "resources" : [{
         "resourceId" : "2f8905f8-4302-49d7-ab7f-65c9036addf0",
         "amount" : 20
      }]
   }],
   "specialPricing": {
      "applicableTo" : [ ],
      "products": [
         {
            "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
            "period": {
               "unit": "MONTHS",
               "duration": 1
            },
            "prices": {
               "setup": 1.2
            },
            "costs": {
               "setup": 1.0,
               "recurring": 14.0
            },
            "resources": [
               {
                  "resourceId": "2f8905f8-4302-49d7-ab7f-65c9036addf0",
                  "prices": {
                     "recurring": 0.5
                  },
                  "costs": {
                     "recurring": 0.3
                  }
               }
            ]
         }
      ]
   }
}

The response looks as follows:

HTTP/1.1 200 OK

{
   "promoResult": "APPLIED",
   "total": 16.45,
   "subTotal": 14.95,
   "taxTotal": 1.5,
   "exclusiveTaxTotal": 1.5,
   "details": [
      {
         "type": "PLAN_SETUP",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "description": "Cloud VPSes Setup",
         "quantity": 1.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "item",
         "unitPrice": 1.2,
         "extendedPrice": 1.2,
         "discount": {
            "type": "FIXED",
            "value": 1.2,
            "amount": 0.8
         },
         "taxAmount": 0.12,
         "exclusiveTaxAmount": 0.12
      },
      {
         "type": "PLAN_RECURRING",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "Cloud VPSes Recurring",
         "quantity": 1.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "item",
         "unitPrice": 4.25,
         "extendedPrice": 4.25,
         "taxAmount": 0.43,
         "exclusiveTaxAmount": 0.43
      },
      {
         "type": "RESOURCE_RECURRING",
         "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
         "period": {
            "unit": "MONTHS",
            "duration": 1
         },
         "resourceId": "2f8905f8-4302-49d7-ab7f-65c9036addf0",
         "duration": {
            "unit": "MONTHS",
            "duration": 1.0
         },
         "description": "null Recurring",
         "quantity": 19.0,
         "lowerBound": 0.0,
         "unitOfMeasure": "unit",
         "unitPrice": 0.5,
         "extendedPrice": 9.5,
         "discount": {
            "type": "FIXED",
            "value": 0.5,
            "amount": 9.5
         },
         "taxAmount": 0.95,
         "exclusiveTaxAmount": 0.95
      }
   ]
}

Once the order estimation satisfies the requesting system, the latter can place a sales order with the same configuration, that is:

POST /aps/2/services/order-manager/orders

{
   "type": "SALES",
   "accountId" : "00b60056-8b0a-4981-8ca4-d114346cd652",
   "promoCode" : "123",
   "products" : [{
      "planId" : "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
      "period" : {
         "unit" : "MONTHS",
         "duration" : 1
      },
      "resources" : [{
         "resourceId" : "2f8905f8-4302-49d7-ab7f-65c9036addf0",
         "amount" : 20
      }]
   }],
   "specialPricing": {
      "applicableTo" : [ "RENEWAL" ],
      "products": [
         {
            "planId": "6b64da9a-f8e6-4cbd-8aef-de304a27b627",
            "period": {
               "unit": "MONTHS",
               "duration": 1
            },
            "prices": {
               "setup": 1.2
            },
            "costs": {
               "setup": 1.0,
               "recurring": 14.0
            },
            "resources": [
               {
                  "resourceId": "2f8905f8-4302-49d7-ab7f-65c9036addf0",
                  "prices": {
                     "recurring": 0.5
                  },
                  "costs": {
                     "recurring": 0.3
                  }
               }
            ]
         }
      ]
   }
}

As usual, the response must contain the ID of the created order. On completion of the order processing, you can find the new customer subscription with a special promo attached to it:

../../_images/special-price-subscription.png ../../_images/special-price-promo.png

Note

When the provider has an agreement with a service vendor on discount for a certain service, the agreed price can be registered in the platform by adding the providerCosts to sales orders as described in Specify Provider Costs.

Warning

The order management API does not accept an empty specialPricing structure. If you are not going to use special prices, do not pass an empty specialPricing structure.

Resource Dependency Validation

The platform rejects sales orders and change orders which do not comply with resource dependencies when the dependency type is REQUIRES or PROVIDED_BY. When an order is rejected, the response code is “500 Internal Server Error” and the error message contains the cause of rejection and the solution. This is valid when creating, upgrading, or downgrading a subscription.

REQUIRES Dependency

If a resource called ‘Child Resource’ requires two units of a resource called ‘Parent Resource’, the error message contains:

The order cannot be accepted: Resource 'Child Resource' requires resource 'Parent Resource'.
Please add necessary resource(s) to the order. Lack of resource 'Parent Resource': 2.0.

In a downgrade request, if there is an attempt to remove a resource required by another resource, the error message contains:

The order cannot be accepted: Resource 'Parent Resource' is required for
resource 'Child Resource'. Please downgrade necessary resource(s).

PROVIDED_BY Dependency

If a resource called ‘Child Resource’ is provided by a resource called ‘Parent Resource’, the platform does not fulfill an order that requests a creation, upgrade, or downgrade of the ‘Child Resource’. It rejects such a request with an error message containing:

The order cannot be accepted: Resource 'Child Resource' is provided by Resource 'Parent Resource'.
Amount of resource 'Parent Resource' cannot be less than amount of resource 'Child Resource'.