How to use Reactor APIs

Short summary of Reactor engine: it is designed to be a full functional Order Capture and Validation engine, which means it is a kind of shopping cart solution. You may read the more detailed summary of Reactor here: Reactor.

Turning to the use cases. The following sections will describe step by step the usage of the interfaces. The use cases are going through operations in a transaction. To allow multiple environments and multiple users to work independently, Reactor is prepared to work in multi-tenant mode. Tenants are identified by apiKey, which can be requested using the generateAPIKey interface.


Using the Swagger UI you should open API Key handling tag first, then select requestAPIKeybyMail interface. Then, as the picture shows, you press Try it out button, which activates the input fields on the form and allows you to execute the operation.

This interface has an email address input parameters. Here you should add your email address and Reactor will send you the generated apiKey dedicated for you. One thing rest, pressing the Execute button.

The response will contain a standard response called reactorResponse (each interface contains this).

                    "reactorStatus": "REACTOR_API_KEY_SENT",
                    "reactorErrorLevel": "SUCCESSFUL",
                    "value": 201,
                    "reasonPhrase": "API key sent to email given.",
                    "reasonDetails": "The generated API key was sent to the email address given.",
                    "reasonProductOfferings": null,
                    "httpStatus": "OK"

Using the apiKey with no additional configuration steps mean, that the tenant will use the default configuration, which is the basis of the rule examples below in this article.

In the first few rounds when you work with Reactor it is suggested to use the defaults. Later we will come back to describe the configurability of a tenant.

Start playing with transactions aka the shopping carts

Each and every case must be started with an openTransaction call, which creates a shopping cart instance, called transaction. Transaction ID in the response will be used in each following steps to address the transaction instance.


Using the Swagger UI you should open Transaction handling tag first on the page, and select openTransaction operation. Then, as the picture shows, you press the Try it out button, which activates the input fields on the form and allows you to execute the operation. Just as the case of apiKey request.

For a simple test you should not change anything on the input structure, but simply to press the blue Execute button that just came up.

On the other hand two of the fields have functions behind, which are working already:

The response will look like this:

                "transactionID": "REACTOR-001-000000000000293",
                "productOfferings": {
                    "reactorResponse": {
                    "reactorStatus": "REACTOR_OK",
                    "reactorErrorLevel": "SUCCESSFUL",
                    "value": 200,
                    "reasonPhrase": "Reactor OK",
                    "reasonDetails": "Everything OK, no error happened.",
                    "reasonProductOfferings": null,
                    "httpStatus": "OK"
                    "currentPortfolio": [
                        "recordID": 1,
                        "productOfferingItem": {
                        "productOfferingID": "demoproduct4",
                        "shortDescription": "Something to demonstrate the product structure in current portfolio.",
                        "longDescription": "REACTOR-001-000000000000293",
                        "productOfferingType": "Additional",
                        "imageLink": "/",
                        "multiservice": false,
                        "onetimePrice": 2000,
                        "recurringPrice": 4000,
                        "activateOnKind": "nextCycleCloseDate",
                        "deactivateOnKind": "nextCycleCloseDate"
                        "productOfferingStatus": "A",
                        "effectiveDate": "2018-06-11T00:00:00.000+0000",
                        "expirationDate": null,
                        "listofAvailableActions": [

The first field is the above mentioned transactionID. The next item is a productOfferings structure that contains reactorResponse, currentPortfolio (it has data if you selected currentPortfolio or both at input), availableProductOffering (if you selected availableProductOfferings or both above).

Detailed description of the data structure can be found in the Model section of the Swagger UI!

currentPortfolio and availableProductOfferings lists

CurrentPortfolio contains all items that are already active in the cart, indicating their status and showing those data, which is interesting on a UI. AvailableProductOffering list contains the product offerings that can be ordered in the given moment, using the addProductOffering interface. To simplify the manual testing and trials, the demo Product Offerings have the transaction ID shown in the longDescription field too!


The first step is to find this interface on Swagger UI. It is behind Product offering manipulations, or you can also find it under Reactor tag, where all the interfaces are listed.

The usage starts with the Try it out button as before. The input parameters are the TransactionID and the POChangesBody structure. The following request will activate demoproduct1 and the response will contain both the currentPortfolio and the availableProductOffering lists.

                "productOfferingID": "demoproduct1",
                "responseType": "both",
                "effectiveDate": "2018-11-08T19:06:53.442Z",
                "expirationDate": "2018-11-08T19:06:53.442Z"

Currentportfolio will contain demoproduct1 with NA status, but it be missing from availableProductOfferings, since it is not a MultiService, therefore it cannot be ordered in multiple instances (but demoproduct301 can be). The expirationDate field is skipped in this operation.


The interface is similar to addProductOffering, the same input structure is used, while there is one more input field called currentPortfolioRecordID. This field identifies exactly the item that would be deleted, since the productOfferingID is not unique because of Multiservices (see below). Although the request body uses the same POChangesBody structure to keep things simple and common, only the responseType and the effectiveDate field has a meaning, the value of productOfferingID and effectiveDate will be skipped.

Demo rule set

The following simple rule set is configured in the demo environment:

Activate on cycle change

Some Product Offerings are configured with activateOnKind: nextCycleCloseDate. Activating these products, the effective date in the currentPortfolio list will have the calculated next cycle start day. Cycle is a monthly period by the engine ending with the calendar day indicated by the cycleCloseDay parameter on Customer at transaction opening. Assuming the current date is 10th of October, the cycleCloseDay is 15, then the calculated effective date will be 16th of October; if the cycleCloseDay parameter is 5, then the calculated result will be 6th of November.


Some Product Offerings are configured with multiservice: true. This means they can be activated at multiple times, having multiple instances in parallel in the currentPortfolio list. Product Offerings, which are set to false, can be ordered only once, like demoproduct1 as mentioned above.

Hard Precondition

This rule means, that a Product Offering is shown on the availableProductOffering list only, if its precondition Product Offering is on the currentPortfolio list.

Currently demoproduct2 is Hard Precondition of demoproduct3, therefore you will not see demoproduct3 at transaction opening but only after you activated demoproduct2.

In case of deleting Product Offering, Reactor checks if Precondition criteria is still met and if not, the affected consequence currentPortfolioItems will also be deleted, using the same expiration date, which was calculated to the record deleted by the operation directly.

Soft Precondition

By this rule a Product Offering is orderable only if its precondition item exists in the currentPortfolio list, but still if precondition is not there, the ProductOffering will be shown on the availableProductOfferings list. It is for a kind of marketing trick to show a product, which you want to sell, but requires something else to order before. Either the Product Offering is shown in the availableProductOfferings list, it is not orderable; trying to order you will get an error as in the example below!

Currently demoproduct300 is Soft Precondition of demoproduct301. Both are shown on the availableProductOffering list after transaction opening, but demoproduct301 cannot be ordered. If you try adding it using addProductOffering interface, you will get the following response:

            "reactorResponse": {
                "reactorStatus": "REACTOR_SOFT_PRECONDITION_COLLISION",
                "reactorErrorLevel": "REACTOR_CLIENT_ERROR",
                "value": 1430,
                "reasonPhrase": "Soft Precondition Collision happened!",
                "reasonDetails": "This code is to indicate if an availableProductOffering item is not Orderable, because its precondition item is not active. This is the only case when item from the available list cannot be ordered. The list of preconditional POs are indicated in the reasonPOs substructure to show to the client, what to order before.",
                "reasonProductOfferings": [
                    "productOfferingID": "demoproduct300",
                    "shortDescription": "Something to demonstrate the product structure.",
                    "longDescription": "REACTOR-001-000000000000293",
                    "productOfferingType": "Additional",
                    "imageLink": "/",
                    "multiservice": false,
                    "onetimePrice": 2000,
                    "recurringPrice": 4000,
                    "activateOnKind": "immediate",
                    "deactivateOnKind": "nextCycleCloseDate"
                "httpStatus": "OK"

It tells you, that REACTOR_SOFT_PRECONDITION_COLLISION error happened, with its detailed description, which potentially can be shown to the end user directly. Important to highlight, that reasonProductOfferings list inside the response contains those Product Offerings, which causes the error. To allow ordering the original Product Offering, all of them should be ordered first, since preconditions are in logical AND relation. The structure of this data is the same as a Product Offering represented on the availableProductOffering list. Beyond the structure, this list contains only Product Offerings, which are really orderable and exists in the availableProductOffering list too. Practically, this part of the response enables a simple UI function to have a pop-up with "Would you like to order now?" message.

In case of deleting product offering, Reactor checks if Precondition criteria is still met and if not, the affected consequence currentPortfolioItems will also be deleted, using the same expiration date, which was calculated to the record deleted by the operation directly.

Hard Exclusion

Practically the logic of exclusion is the opposite of the precondition. Product Offering will be represented on the availableProductOfferings list only if its excluding item is not on the currentPortfolio list.

Currently demoproduct1 Hard Excludes demoproduct2, means ordering demoproduct1, demoproduct2 will be dropped out from the availableProductOffering list.

Soft Exclusion (change)

In case of Soft Exclusion Product Offering can be ordered even if its excluding item is on the currentPortfolio list, but the excluding item will be deactivated by this order step.

Currently demoproduct300 Soft Excludes demoproduct1, therefore ordering demoproduct300 will delete demoproduct1 from the currentPortfolio.


Compatibility is a similar to the Precondition rule, but here multiple preconditional Product Offering may be defined for one rule and if any of them is active on the currentPortfolio list, then the conditional Product Offering becomes orderable. By other words, the preconditional Product Offerings in a Compatibility rule instance are in logical OR condition, while the Compatibility rule instances are in logical AND relation to EACH other.

Currently demoproduct9 is Compatible with demoproduct7 and demoproduct8 and by another rule instance it is Compatible with demoproduct301. Testing this situation, you have to activate demoproduct7 or demoproduct8 and afterwards demoproduct301 (don't forget to activate demoproduct300 before since demoproduct300 and demoproduct301 are in Soft Precondition relation!).

In case of deleting product offering, Reactor checks if Compatibility criterion are still met and in case no, the affected consequence currentPortfolioItems will also be deleted, using the same expiration date, which was calculated to the record deleted by the operation directly.

Hard Move Together

Hard Move Together activates and/or deactivates additional Product Offerings in case of moving (adding or deleting) of one other. For example you activate a Product Offering, which is in moving together relation with a second one, then the second one will also be activated. It is the same for deletion. All consecutive Product Offerings will get the same status, change date values as control Product Offering. Move Together rules can be directional, or bidirectional. Directional means, that a given rule is active only for activation or deactivation. The move together is mandatory, which means if any of the consecutive activations are not possible, then it fails with REACTOR_MOVE_TOGETHER_CANNOT_ACTIVATE or REACTOR_MOVE_TOGETHER_CANNOT_DEACTIVATE error.

Currently demoproduct20 is Hard Move Together with demoproduct21 bidirectionally and with demoproduct30 for deactivation. Activating demoproduct20 will activate demoproduct21 if possible and in case of deactivation it will deactivate demoproduct21 and also demoproduct30.

Soft Move Together

Very similar to the Hard Move Together, but it does not fail if consecutive Product Offerings cannot be changed.

Currently demoproduct24 Soft Move Together with demoproduct25 for activation and demoproduct26 with demoproduct27 for deactivation.

Configuration of tenant identified by apiKey

Be aware that adding anything by the configureAPIkeyProductOfferings, configureAPIKeyProductRelationRules or configureAPIKeyCurrentPortfolio is overriding the default configuration, while configureAPIKeyRulesOrder can be used separately to try the effect of changing rule type order on the well-known default configuration. Each transaction loads the actual configuration of apiKey and will use this setup for its entire lifetime. Practically you can open a transaction, then reorder the rule sequence by configureAPIKeyRulesOrder and test the difference via executing the same steps in two parallel transactions. With no other changes, all new transaction opening will use the same setup as the second one in the example.

The configureAPIkeyProductOfferings, configureAPIKeyProductRelationRules or configureAPIKeyCurrentPortfolio interfaces can be called multiple times and each call will add the data entered on top of the previous calls. The interfaces do not validate data consistency, which means it is you can load rule instances or current portfolio items, without product offerings defined. Finally, be aware of loading consistent data to avoid unexpected strange situations.

There is no way to reset or change the manual configurations. If you need different setup, open a new apiKey!