Disclaimer

This document is only collection of author’s notes, experiences and point of views. It is not, in any meaning, either complete description of the topic nor official RTB documentation. It may be inaccurate, incomplete, obsolete, misleading or completely wrong. It may even cause loss of data or damage system integrity. It may not comply with company codex, values, presentation style or economic interests or may reveal company secrets.

As such, it is absolutely prohibited to distribute this document outside of RTB & Co. GmbH. Such an action may result into legal acts against both the sender and the company. It is only intended, after review of technical and presentational correctness and accuracy, to be used as an information source for official documentation.

Always contact documentation department for information about current presentation style and allowed formats before creating customer’s documentation.

1. What is RAO

RAO d.o.o., aka PtGateway, aka Park-IS is a croatian company for parking management.

2. Integration with PDM

2.1. Article index

Use real time request 53 to obtain index of articles for all companies.

Request type description
type ArticleIndex = {
  REQ: 53,
  filter?: {
    property: "ZONE" | "ZONENAME" | "ZONECOLOR",
    value: string
  }
}

The command optionally accept filter parameter.

It filter is not provided the filter set in PDM.control is used.

Example request without explicit filter
{
    "REQ":53
}

If filter is provided the property filter defined in PDM.control will be replaced by provided one. Please note, that only property filter is overwritten. Town filter stays untouched no matter of what is set here.

Example request without explicit filter
{
    "REQ":53,
    "filter": {
      "property": "ZONENAME",
      "value": "1."
    }
}

If we remove technical details, response is located in body part. There is a list of articles IDs which may be sold on the place where PDM stays. The response has same structure for both variants or the request.

Example response (zone '1.')
{
   "httpStatus":200,
   "body":{
      "status":"OK", (1)
      "error":null,
      "companies":[
         {
            "companyId":"402880a825447882012544788b750002",
            "companyName":"ZAGREBAČKI HOLDING d.o.o.",
            "articleIds":[
               "EFA2F4755FFA280EE05314B2A8C0C864",
               "EFA2F4756066280EE05314B2A8C0C864"
            ]
         }
      ]
   },
   "REQ":53
}
1 See RAO statuses for full list of existing status codes.

2.2. Article list

PDM may request one ore more article details based on articleIds.

Sample request
{
   "filter":{
      "companyId":"402880a825447882012544788b750002",
      "articlesIds":[
         "EFA2F4755FF9280EE05314B2A8C0C864",
         "EFA2F4756062280EE05314B2A8C0C864"
      ]
   },
   "REQ":54
}
Sample response
{
   "httpStatus":200,
   "body":{
      "status":"OK",
      "error":null,
      "articles":[
         {
            "id":"EFA2F4755FFA280EE05314B2A8C0C864",
            "name":"DPK 2. ZONA RP",
            "description":"POSTAVITE KARTU NA VIDNO MJESTO SA UNUTRAŠNJE STRANE VJETROBRANSKOG STAKLA! HVALA!",
            "price":8.0,
            "vat":0.25,
            "period":"DNEVNA",
            "quantity":{
               "min":1,
               "max":1,
               "required":true
            },
            "lpn":{
               "min":3,
               "max":15,
               "required":true
            }
         },
         {
            "id":"EFA2F4756066280EE05314B2A8C0C864",
            "name":"PK 2.ZONA 1 SAT",
            "description":"POSTAVITE KARTU NA VIDNO MJESTO SA UNUTRAŠNJE STRANE VJETROBRANSKOG STAKLA! HVALA!",
            "price":0.7,
            "vat":0.25,
            "period":"SATNA",
            "quantity":{
               "min":1,
               "max":3,
               "required":true
            },
            "lpn":{
               "min":3,
               "max":15,
               "required":true
            }
         }
      ]
   },
   "REQ":54
}

2.3. Init sale

Method for initiating the sale of an item. Use real time request 55 to start sale process.

Example request
{
    "REQ":55,
    "body": {
        "companyId":"402880a825447882012544788b750002",
        "articleId":"EFA2F4755FF9280EE05314B2A8C0C864",
        "quantity":1,
        "lpn":"PB123456",
        "penaltyNumber": "123" (1)
    }
}
1 optional, used only if penalty is payed. Leave lpn empty in such a case.
Example response
{
   "httpStatus":200,
   "body":{
      "from":"2023-12-27T00:00:00",
      "to":"2023-12-28T00:00:00",
      "status":"OK",
      "price":13.3,
      "ticketNumber":"6878453",
      "transactionId":"ff8080818a224345018ca71fe8e177ab" (1)
   },
   "REQ":55
}
1 Field transactionId is optional. PDM may provide its own transaction number. If omitted RAO will generate some ID.

2.4. Confirm sale

Method for confirming purchases, initiated with the initSale method Use real time request 56 to confirm sale process.

Example request
{
    "REQ":56,
    "body": {
        "transactionId":"ff8080818a224345018ca71fe8e177ab",
        "billNumber": "12-122-12", (1)
        "paymentMode": "GOTOVINA" (2)
    }
}
1 Optional. It represents custom bill number which may be sent to RAO as well.
2 Optional. Text description how was the payment done (e.g. GOTOVINA KREDITNA KARTICA).
Example response
{
   "httpStatus":200,
   "body":{
      "status":"OK"
   },
   "REQ":56
}

3. Abort sale

Termination of transaction processing. Abort sale indicates the termination of the sale of a parking ticket for the specified license plate. AbortSale is invoked, otherwise, with some types of tickets (e.g. SATNE), the transaction remains for some time in the status initiated, and the controller does not issue an order for such types. Use real time request 57 to abort sale process.

Example request
{
   "REQ":57,
   "body": {
      "transactionId":"ff8080818a224345018ca71fe8e177ab"
   }
}
Example response
{
   "httpStatus":200,
   "body":{
      "detailsMessage": "TRANSACTION ABORTED",
      "status": "OK"
   },
   "REQ":57
}

4. Cancel sale

Reverse transactions. A confirmed transaction can be reversed in some cases, but the call method for a particular transaction is limited to 5 minutes. Use real time request 58 to abort sale process.

Example request
{
   "REQ":58,
   "body": {
      "transactionId":"ff8080818a224345018ca71fe8e177ab",
      "reason": "Reason why the sale was canceled"
   }
}
Example response
{
   "httpStatus":200,
   "body":{
      "detailsMessage": "TRANSACTION CANCELED",
      "status": "OK"
   },
   "REQ":58
}

4.1. Complete examples

Article index
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{REQ:53}];DPA2;
Article list
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{filter:{companyId:"402880a825447882012544788b750002",articleIds:["EFA2F4755FFA280EE05314B2A8C0C864","EFA2F4756066280EE05314B2A8C0C864"]},REQ:54}];DPA2;
Init sale
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{REQ:55,body:{"companyId":"402880a825447882012544788b750002","articleId":"EFA2F4755FF9280EE05314B2A8C0C864","quantity":1,"lpn":"PB123456"}}];DPA2;
Confirm sale
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{REQ:56,body:{transactionId:"ff8080818a224345018caadee8bd77e4",billNumber:"12-122-12"}}];DPA2;
Abort sale
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{REQ:57,body:{transactionId:"ff8080818a224345018cf796369b7f98"}}];DPA2;
Cancel sale
PSA10027;GAC11;DTM2023-12-26T11:03:33;VER7.5.5.114;PID7625EFE11;MRQ[{REQ:58,body:{transactionId:"ff8080818a224345018cf7a607f17fa7", reason:"Test"}}];DPA2;

5. Configuration

5.1. Application

Install applejack and configure it. It in necessary to configure URI and credential to it for PDM.control. Please provide them to application configuration like in sample below.

pcon:
  partner:
    rao:
      url: http://192.168.100.18:20000
      user: user
      password: password

5.2. User interface

Partner can be configured for each Area independently. There is few options to set.

5.2.1. Town name, Town ID

Town name, Town ID - each article returned by RAO service contains also field Town name and Town ID. So far every article contains

<cityId>402880c7215e4c6501215e549b391b7a</cityId>
<cityName>ZAGREB</cityName>

It is not clear if RAO pre-filter list just for the town where we are or it if sends all articles. To be able to filter-in just articles valid in the town, please provide either Town Name or Town ID. Normally would be enough to filter just by name of town. But I do not know how a case where there are multiple towns with same name (e.g. Nova Vas) therefore I left also an option to filter by ID. Please do not fill both fields simultaneously. They are evaluated as AND which may filter out everything.

5.2.2. Zone property name

Here it is necessary to set which RAO property is used to map PDM.control zones. Every article contains multiple of them and it is not clear which one to use. The ones mentioned bellow are good candidates.

<key>CONSTANTID</key><value>1RP1DNEVNA</value>
<key>ZONECOLOR</key><value>CRVENA</value>
<key>ZONENAME</key><value>1.</value>
<key>ZONE</key><value>1</value>
// cSpell: enable

Please specify a property name key which will be taken as zone. A value needs to be filled to every zone in grid below to express desired mapping.

Appendix A: RAO statuses

Status can have one of following values (at 2024-01-01):

public enum ResponseStatus {
    OK,
    ALREADY_INITIALIZED,
    MAX_AMMOUNT_REACHED,
    ERROR_AMMOUNT,
    ERROR_LENGTH,
    ERROR_PARAMETERS,
    ERROR_SERVICE_PROVIDER,
    PAYMENT_PROVIDER_DISABLED,
    PAYMENT_ITEM_NOT_EXISTS,
    PAYMENT_ITEM_PARTIALY_PAID,
    SERVICE_PROVIDER_AVAILABLE,
    PAYMENT_ITEM_NOT_ALLOWED,
    NO_DATA_TO_PROCESS,
    SERVICE_PROVIDER_NOT_AVAILABLE,
    SERVICE_PROVIDER_DISABLED,
    SERVICE_PROVIDER_NOT_DEFINED,
    NO_SERVICE_PROVIDERS_DEFINED,
    NO_RESELLERS_DEFINED,
    RESELLER_NOT_DEFINED,
    RESELLER_REBATE_MISMATCH,
    TRANSACTION_DOES_NOT_EXIST,
    INVALID_CREDENTIALS,
    EXISTING_PPT,
    NO_AUTHORIZATION_FOR_USER,
    ENDDATE_EXCEEDS_AUTHORIZATION,
    REJECTED_DEBT,
    PAYMENT_ITEM_NOT_ALLOWED_DPK,
    PAYMENT_ITEM_NOT_ALLOWED_PPK,
    PAYMENT_ITEM_NOT_ALLOWED_IPPK,
    PAYMENT_ITEM_NOT_ALLOWED_KPK,
    PAYMENT_ITEM_NOT_ALLOWED_PARKING_PROVIDER,
    FOREGIN_PRICE_NOT_DEFINED,
    EXISTING_KPK,
    ERROR_PARSING_BEGIN_DATE,
    ERROR_PERIOD,
    INVALID_TICKET_DATE,
    LIMIT_EXCEEDED,
    MISSING_POS,
    ERROR_RTN,
    UNKNOWN_PARKING_LOT,
    NOT_ENOUGH_ASSETS;
}

Additionally there are included error from Applejack. They are just string prefixed by AJ: text.