Online orders API

Transporting orders from e-shops or food delivery platforms to the PORTOS application.

Glossary

How it works

The online orders API is a mechanism that allows importing online orders from "external system" (such as e-shops or food delivery platforms) to the PORTOS system.

The PORTOS system acts as an "client" initiating HTTP requests targeting the external system, that acts as an "server" and handles the following requests:

  1. Fetch unprocessed orders

  2. Process order

After unprocessed order is fetched, cashier is requested to process (either accept or reject) the order trough the PORTOS application. After cashier confirms or rejects the order, PORTOS application will initiate second request (process order) to the external system.

The PORTOS system expects that responses from external system follows data format described below.

Fetch unprocessed orders

GET {external-system}{unprocessed-orders-url}

The PORTOS system will periodically fetch the unprocessed orders from the external system, by initiating GET HTTP request to the external system. External system returns the unprocessed orders for given venue. If the collection of orders is paginated by the external system (so response does not contain all unprocessed orders), the most oldest orders should be returned.

Query Parameters

[
  {
    "id": "b478396ad654",
    "type": "delivery",
    "delivery": {
      "address": {
        "line1": "Kresankova 12",
        "line2": "",
        "city": "Bratislava",
        "zipCode": 84105,
        "note": "Please knock twice"
      },
      "fee": 1.99
    },
    "createdAt": "2021-02-01T12:01:00.000Z",
    "scheduledAt": null,
    "customer": {
      "name": "John Doe",
      "phone": "+421 900 123 456",
      "email": "john.doe@example.com"
    },
    "products": [
      {
        "id": "1234",
        "name": "Burger",
        "quantity": 1,
        "baseUnitPrice": 8.99,
        "note": "",
        "additions": [
          {
            "id": "11002",
            "name": "No cheese",
            "quantity": 1,
            "unitPrice": 0.00,
            "note": ""
          },
          {
            "id": "11002",
            "name": "Extra bacon",
            "quantity": 1,
            "unitPrice": 1.99,
            "note": ""
          }
        ]
      }
    ],
    "currency": "EUR",
    "payment": {
      "isSettled": true,
      "method": "card"
    },
    "tip": 0,
    "totalPrice": 12.97,
    "note": null
  },
  {
    "id": "6a2ad048e32d",
    "type": "takeAway",
    "delivery": null,
    "createdAt": "2021-02-01T12:01:00.000Z",
    "scheduledAt": "2021-02-01T13:00:00.000Z",
    "customer": {
      "name": "John Doe",
      "phone": "+421 900 123 456",
      "email": "john.doe@example.com"
    },
    "products": [
      {
        "id": "2345",
        "name": "Fries",
        "quantity": 2,
        "baseUnitPrice": 4.99,
        "note": "",
        "additions": [
          {
            "id": "11024",
            "name": "Ketchup",
            "quantity": 1,
            "unitPrice": 1.99,
            "note": ""
          }
        ]
      }
    ],
    "currency": "EUR",
    "payment": {
      "isSettled": false,
      "method": null
    },
    "wrappingFee": 0,
    "packagingDeposit": 0,
    "tip": 0,
    "totalPrice": 13.96,
    "note": null
  }
]

Process order

POST {external-system}{process-order-url}

After the order is confirmed or rejected by Cashier trough the PORTOS cash register system user interface, the PORTOS system will initiate the POST HTTP request to the external system, to mark this specific order as processed.

Query Parameters

/* No response body is required by PORTOS. */

Data model

The data model of online orders exchange is described below.

All prices include taxes.

Order

Order represents purchase request made by customer trough the external system, containing data about products, delivery address, etc.

OrderDelivery

Order delivery information.

Address

The customer's address.

Customer

The customer's contact information.

Product

The product (such as food or drink).

ProductAddition

The product addition (option, modifier) that adds more information about how the product should be prepared.

Payment

The product payment information.

Configuration

To communicate with external system properly, the external system administrators must provide values stated below to the venue owners or PORTOS support.

Example

In all request examples below, we will assume following configuration:

  • external system unprocessed orders URL: https://the-foo-bar.sk/unprocessed_orders

  • external system process order URL: https://the-foo-bar.sk/process_order

  • API key is: my-token

Step 1: Fetching unprocessed orders

The PORTOS will request following URL:

GET https://the-foo-bar.sk/unprocessed_orders?version=1&key=my-token

The external system returns following payload as an response:

[
  {
    "externalId": "b478396ad654",
    "type": "delivery",
    "delivery": {
      "address": {
        "line1": "Kresankova 12",
        "line2": "",
        "city": "Bratislava",
        "zipCode": 84105,
        "note": "Please knock twice"
      },
      "fee": 1.99
    },
    "createdAt": "2021-02-01T12:01:00.000Z",
    "scheduledAt": null,
    "customer": {
      "name": "John Doe",
      "phone": "+421 900 123 456",
      "email": "john.doe@example.com"
    },
    "products": [
      {
        "id": "1234",
        "name": "Burger",
        "quantity": 1,
        "baseUnitPrice": 8.99,
        "note": "",
        "additions": [
          {
            "id": "11002",
            "name": "No cheese",
            "quantity": 1,
            "unitPrice": 0.00,
            "note": ""
          },
          {
            "id": "11002",
            "name": "Extra bacon",
            "quantity": 1,
            "unitPrice": 1.99,
            "note": ""
          }
        ]
      }
    ],
    "currency": "EUR",
    "payment": {
      "isSettled": true,
      "method": "card"
    },
    "wrappingFee": 0,
    "tip": 0,
    "totalPrice": 12.97,
    "note": null
  },
  {
    "externalId": "6a2ad048e32d",
    "type": "takeAway",
    "delivery": null,
    "createdAt": "2021-02-01T12:01:00.000Z",
    "scheduledAt": "2021-02-01T13:00:00.000Z",
    "customer": {
      "name": "John Doe",
      "phone": "+421 900 123 456",
      "email": "john.doe@example.com"
    },
    "products": [
      {
        "id": "2345",
        "name": "Fries",
        "quantity": 2,
        "baseUnitPrice": 4.99,
        "note": "",
        "additions": [
          {
            "id": "11024",
            "name": "Ketchup",
            "quantity": 1,
            "unitPrice": 1.99,
            "note": ""
          }
        ]
      }
    ],
    "currency": "EUR",
    "payment": {
      "isSettled": false,
      "method": null
    },
    "wrappingFee": 0,
    "packagingDeposit": 0,
    "tip": 0,
    "totalPrice": 13.96,
    "note": null
  }
]

As we can see, the external systems returns two unprocessed orders.

Step 2: Order acceptation

The PORTOS will mark first order as accepted by requesting following URL:

POST https://the-foo-bar.sk/process_order?version=1&key=my-token&externalId=b478396ad654&status=accepted&estimatedCompletionAt=2021-02-01T13%3A01%3A00.000Z

Please note that all query parameters are URL encoded. In URL above, the estimatedCompletionAt query parameter value 2021-02-01T13:01:00.000Z is URL encoded as 2021-02-01T13%3A01%3A00.000Z.

Step 3: Fetching unprocessed orders

The PORTOS will request unprocessed requests again:

GET https://the-foo-bar.sk/unprocessed_orders?version=1&key=my-token

The external system returns following payload as an response:

[
  {
    "externalId": "6a2ad048e32d",
    "type": "takeAway",
    "delivery": null,
    "createdAt": "2021-02-01T12:01:00.000Z",
    "scheduledAt": "2021-02-01T13:00:00.000Z",
    "customer": {
      "name": "John Doe",
      "phone": "+421 900 123 456",
      "email": "john.doe@example.com"
    },
    "products": [
      {
        "id": "2345",
        "name": "Fries",
        "quantity": 2,
        "baseUnitPrice": 4.99,
        "note": "",
        "additions": [
          {
            "id": "11024",
            "name": "Ketchup",
            "quantity": 1,
            "unitPrice": 1.99,
            "note": ""
          }
        ]
      }
    ],
    "currency": "EUR",
    "payment": {
      "isSettled": false,
      "method": null
    },
    "wrappingFee": 0,
    "packagingDeposit": 0,
    "tip": 0,
    "totalPrice": 13.96,
    "note": null
  }
]

The recently accepted order no longer appears in unprocessed orders collection.

Step 4: Order rejection

The PORTOS will mark remaining order as rejected by requesting following URL:

POST https://the-foo-bar.sk/process_order?version=1&key=my-token&externalId=6a2ad048e32d&status=rejected&rejectionReason=The%20food%20is%20out%20of%20stock.

Please note that all query parameters are URL encoded. In URL above, the rejectionReason query parameter value The food is out of stock. is URL encoded as The%20food%20is%20out%20of%20stock..

Step 5: Fetching unprocessed orders

The PORTOS will request unprocessed requests again:

GET https://the-foo-bar.sk/unprocessed_orders?version=1&key=my-token

All requests has been processed (rejected or accepted). The external system returns empty collection as an response.

[]

Changelog

Version 1.3 (2022-12-07)

  • New packagingDeposit field added.

  • Supported in PORTOS Pokladลˆa version 4.0.25 or later.

  • Supported in PORTOS Online Objednรกvky version 3.3.8 or later.

Version 1.2 (2022-08-12)

  • New tip field added.

  • Supported in PORTOS Pokladลˆa version 4.0.9 or later.

Version 1.1 (2022-03-17)

  • New note field added.

  • Supported in PORTOS Online Objednรกvky version 1.0.15 or later.

Version 1.0

  • Initial version

Last updated