Skip to content

Instantly share code, notes, and snippets.

@lensgolda
Last active January 15, 2020 10:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lensgolda/281dcca19f464f6f037c4a98a58e40d6 to your computer and use it in GitHub Desktop.
Save lensgolda/281dcca19f464f6f037c4a98a58e40d6 to your computer and use it in GitHub Desktop.
Equipage External API

Внешнее API

Домен/базовый URL [тестовый сервер]: https://rest.myequipage-test.com/external

Домен/базовый URL [продакшн сервер]: https://rest.myequipage.com/external

Важно!

Сервер работает с временем UTC. При бронировании заказов, время подачи машины необходимо указывать в UTC.

Пример:

Москва. Необходимо заказать машину на 15:00МСК. Время UTC в данном случае это 12:00UTC, т.е. -3 часа. Если отправить время подачи 15:00, подразумевая МСК время, то заказ будет создан на 18:00МСК.

Информация о компании (о себе)

TODO: можно отдавать краткую статистику по заказам (кол-во/общая сумма)

GET "/me" - пока отключен

Тарифы

GET "/rates"

cURL example:
curl -X GET \
  'http://localhost:8080/external/rates?payment_method_id=corp-11&from=55.761303,37.614602&to=55.962710,37.404920' \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache'

Request

/rates:
    get:
      tags:
        - rate
      summary: Get all rates for given position
      parameters:
        - in: query
          name: from
          schema:
            type: string
          required: true
          description: Pickup position
          example: "55.748599,37.618994"
        - in: query
          name: to
          schema:
            type: string
          required: false
          description: Dropoff position
          example: "55.748599,37.618994"
        - in: query
          name: payment_method_id
          schema:
            type: string
          required: true
          description: API user Payment method ID
          example: "corp-11"
        - in: query
          name: flight_id
          schema:
            type: string
          format: int32
          description: Flight ID from GET /flights query
          example: ""23004626""

Response Example

{
    "route": {
        "duration": 4089.42917107,
        "distance": 32038.0932843,
        "from": [
            55.761303,
            37.6146
        ],
        "to": [
            55.96271,
            37.40492
        ],
        "polyline": [
            [
                55.76130111,
                37.61459365
            ],
            [
                55.96208007,
                37.40522251
            ]
        ]
    },
    "rates": [
        {
            "id": 1,
            "rate": "e_class",
            "title": "BUSINESS",
            "description": "Mercedes-Benz E-class",
            "passengers": 4,
            "photo_url": null,
            "baggage": 3,
            "price": 1079700,
            "time_unit_hour": 10500
        }
    ]
}
  • route - содержит данные о предварительном маршруте поездки от точки from до точки to
    • duration - длительность поездки (значение в секундах)
    • distance - расстояние (значение в метрах)
    • from - координаты точки подачи
    • to - координаты точки назначения (высадки)
    • polyline - координаты точек маршрута
  • rates - список доступных тарифов
    • title - название тарифа
    • rate - класс авто. Возможные значения: e_class, s_class, maybach, v_class
    • price - предварительная стоимость поездки по данному тарифу (значение в копейках)
    • time_unit_hour (опциональное) - стоимость часа поездки (для почасовых тарифов, значение в копейках)

Тарифы по городу

GET "/rates/:city"

Request

cURL example:
curl -X GET \
  http://localhost:8080/external/rates/moscow \
  -H 'Authorization: Bearer AUTH_TOKEN o' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache'

Структура запроса

/rates/{city}:
    get:
      tags:
        - rate
      summary: Get all rates for given city
      parameters:
        - in: path
          name: city
          schema:
            type: string
          required: true
          description: City
          example: "moscow"

Response Example

{
    "rates": [
        {
            "id": 1,
            "rate": "e_class",
            "title": "BUSINESS",
            "description": "Mercedes-Benz E-class",
            "passengers": 4,
            "photo_url": null,
            "baggage": 3
        }
    ]
}

Трансферы

GET /rates3/:id/transfers

Получение списка трансферов по тарифу :id.

Request example

curl 'http://rest.myequipage-test.com/external/rates3/9/transfers' \
  -X GET \
  -H 'Authorization: Bearer: AUTH_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache'

Errors

  • 404 - Not Found - не найдены трансферы по тарифу :id

Response example

{"transfers": [{"from":  {"type":         "airport",
                          "position":     [55.605688, 37.287003],
                          "city":         "Москва",
                          "display_name": "аэропорт Внуково"},
                "to":    {"type":         "railway",
                          "position":     [55.743131, 37.566944],
                          "city":         "Москва",
                          "display_name": "Киевский вокзал"},
                "price": 130000}]}
  • from - отправная точка трансфера
    • type - тип адресного элемента. Возможные значения: airport, railway, object
    • position - координаты точки
    • city - город
    • display_name - адрес (описание)
  • to - конечная точка трансфера
  • price - стоимость трансфера (значение в копейках)

Размещение заказа

POST "/orders"

  • Срочный заказ (менее 60 минут до подачи, без предварительного времени подачи) размещается без указания параметра времени подачи :pickup_at (поле не передается в запросе)
  • Предварительный заказ (на указанное предварительное время, более 60 минут, но не ранее чем за 5 дней) размещается с обязательным указанием параметра :pickup_at (обязательно передавать в запросе в указанном формате, время UTC)

Request

curl -X POST \
  http://localhost:8080/external/orders \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' \
  -d '{
  "payment_method_id": "corp-999",
  "rate_id": 1,
  "route": [
    {
      "position": [
        55.764334, 37.611842
      ],
      "address": "ул. Малая Дмитровка, 25"
    },
    {
      "position": [
        55.752792, 37.595133
      ],
      "address": "Новый Арбат ул., 8-10"
    }
  ],
  "pickup_at": "2019-05-21T18:00:00.511Z",
  "comment": "Please, wait me",
  "passenger_info": {
    "first_name": "John",
    "last_name": "Doe",
    "phone": "+79123456789"
  },
  "flight_id": "23004626"
}'

Структура запроса

type: object
      properties:
        payment_method_id:
          type: string
          required: true
          description: "Payment method's id"
          example: "card-123"
        rate_id:
          type: integer
          required: true
          format: int32
          description: "Rate id"
        route:
          type: array
          required: true
          items:
            type: object
            properties:
              position:
                type: array
                items:
                  type: number
                  format: float
                  example: "[55.76279, 37.59288]"
              address:
                type: string
                example: "проспект Защитников Москвы 10-184"
        pickup_at:
          type: string
          description: "Prebook time. Could be nil"
          format: datetime
          example: "2012-04-23T18:25:43.511Z"
        comment:
          type: string
          description: "Order's comment"
          example: "Please, wait me at first porch"
        passenger_info:
          type: object
          properties:
            first_name:
              type: string
              example: "Ivan"
            phone:
              type: string
              example: "+79999999187"
        flight_id:
          type: string
          description: Flight ID form /flights search request
          example: "23004626"

Response Example

{
    "order": {
        "id": 8173,
        "comment": "Please, wait me at first porch",
        "rate": {
            "id": 1,
            "title": "BUSINESS"
        },
        "passenger_info": {
            "phone": "+791234556789",
            "first_name": "John"
        },
        "pickup_at": "2019-06-26T23:00:00.511Z",
        "created_at": "2019-06-26T16:21:15.408Z"
    }
}

Получение списка заказов

GET "/orders"

Request

curl -X GET \
  http://localhost:8080/external/orders \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \

Структура запроса

get:
  summary: Return companie's orders
  parameters:
    - in: query
      name: skip
      schema:
        type: integer
        format: int32
      description: Pagination's skip, should be greater than 0. 0 by default
    - in: query
      name: limit
      schema:
        type: integer
        format: int32
      description: Pagination's limit should be greater than 0. 20 by default
  responses:
    '200':
      description: 'OK'
      content:
        application/json:
          schema:
            type: object
            properties:
              orders:
                type: array
    '400':
      description: "Skip/limit in wrong format"
      content:
        application/json:
          schema:
            type: object
            properties:
              errors:
                type: array
                items:
                  type: object
                  properties:
                    type:
                      type: string
                    message:
                      type: string
          example:
            errors:
              - type: "validation_error"
                message: "invalid_skip_limit"

Response Example

{
    "orders": [
        {
            "passenger_info": {
                "phone": "+79114650386",
                "first_name": "Alexey"
            },
            "pickup_charge_additional": 0,
            "min_price": 45000,
            "route": [
                {
                    "address": "проспект Защитников Москвы 10-184",
                    "position": [
                        55.76279,
                        37.59288
                    ]
                },
                {
                    "position": [
                        55.974283,
                        37.423107
                    ],
                    "go_to_pin": true
                }
            ],
            "rate": {
                "id": 1,
                "title": "BUSINESS"
            },
            "current_price": 0,
            "updated_at": "2019-07-25T16:40:57.489Z",
            "status": "new",
            "id": 8473,
            "paid": null,
            "estimated_price": 231000,
            "price": 0,
            "pickup_at": "2019-07-25T21:00:00.511Z",
            "estimated_price_discounted": null,
            "created_at": "2019-07-25T16:40:57.489Z"
        }
    ]
}

Описание некоторых полей заказа

Получение информации о заказе

GET "/orders/{:id}"

Request

curl -X GET \
  http://localhost:8080/external/orders/8472 \
  -H 'Authorization: Bearer ZeGE6prCBQ8l9O6K0UQPTfdkSm2ETo' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \

Структура запроса

get:
  summary: Return company's order
  parameters:
    - in: path
      name: id
      schema:
        type: integer
        format: int32
      required: true
      description: Order ID
      example: 1
  responses:
    '200':
      description: 'OK'
      content:
        application/json:
          schema:
            type: object
            properties:
              order:
                $ref: '#/components/schemas/FullOrder'
    '404':
      description: 'Order not found or belongs to another company'

Response Example

{
    "order": {
        "car": {
            "id": 2,
            "license_plate": "X777XX77",
            "color": "000000",
            "brand": "Mersedes-Benz",
            "model": "S-class",
            "heading": -28.789644,
            "position": [55.9695586,37.4437182]
        },
        "passenger_info": {
            "phone": "+79114650386",
            "first_name": "Alexey"
        },
        "pickup_charge_additional": 0,
        "min_price": 45000,
        "route": [
            {
                "address": "проспект Защитников Москвы 10-184",
                "position": [
                    55.76279,
                    37.59288
                ]
            },
            {
                "position": [
                    55.974283,
                    37.423107
                ],
                "go_to_pin": true
            }
        ],
        "rate": {
            "id": 1,
            "title": "BUSINESS"
        },
        "current_price": 0,
        "updated_at": "2019-07-25T17:34:22.238Z",
        "status": "new",
        "id": 8472,
        "comment": "Please, wait me at first porch",
        "paid": null,
        "estimated_price": 231000,
        "distance": 0,
        "driver": {
            "id": 550,
            "first_name": "Alexey",
            "rating": 5,
            "phone": "+79005629512",
            "photo_url": null
        },
        "price": 0,
        "pickup_at": "2019-07-25T18:25:00.511Z",
        "estimated_price_discounted": null,
        "created_at": "2019-07-25T16:37:12.833Z",
        "track": []
    }
}

Описание некоторых полей заказа

Отмена заказа

PATCH "/orders/{:id}/cancel"

Request

curl -X GET \
  http://localhost:8080/external/orders/8472/cancel \
  -H 'Authorization: Bearer ZeGE6prCBQ8l9O6K0UQPTfdkSm2ETo' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \

Структура запроса

patch:
  summary: Order cancel
  parameters:
    - in: path
      name: id
      schema:
        type: integer
        format: int32
      required: true
      description: Order ID
      example: 1
  responses:
    '200':
      description: 'OK'
      content:
        application/json:
          schema:
            type: object
            properties:
              order:
                $ref: '#/components/schemas/FullOrder'
    '404':
      description: 'Order not found or belongs to another company'
    '400':
      description: 'Order cant be cancelled'

Response Example

{
    "order": {
        "car": {
            "id": 2,
            "license_plate": "X777XX77",
            "color": "000000",
            "brand": "Mersedes-Benz",
            "model": "S-class"
        },
        "passenger_info": {
            "phone": "+79114650386",
            "first_name": "Alexey"
        },
        "pickup_charge_additional": 0,
        "min_price": 45000,
        "route": [
            {
                "address": "проспект Защитников Москвы 10-184",
                "position": [
                    55.76279,
                    37.59288
                ]
            },
            {
                "position": [
                    55.974283,
                    37.423107
                ],
                "go_to_pin": true
            }
        ],
        "rate": {
            "id": 1,
            "title": "BUSINESS"
        },
        "current_price": 0,
        "updated_at": "2019-07-25T17:34:22.238Z",
        "status": "cancelled",
        "id": 8472,
        "comment": "Please, wait me at first porch",
        "paid": null,
        "estimated_price": 231000,
        "distance": 0,
        "driver": {
            "id": 550,
            "first_name": "Alexey",
            "rating": 5,
            "phone": "+79005629512",
            "photo_url": null
        },
        "price": 0,
        "pickup_at": "2019-07-25T18:25:00.511Z",
        "estimated_price_discounted": null,
        "created_at": "2019-07-25T16:37:12.833Z",
        "track": []
    }
}

Описание некоторых полей заказа

  • new - новый заказ

  • pending - ожидает подтверждения водителем

  • on_the_way - водитель в пути/на пути к пассажиру

  • arrived - водитель прибыл, ожидает пассажира

  • no_show - пассажир не вышел

  • enroute - на маршруте / водитель с пассажиром

  • cancelled - заказ отменен

  • done - заказ завершен / выполнен

Когда будет назначен водитель на заказ, то в ответе будет появляться ключ driver, как в примере выше. Если водитель еще не назначен, то данный ключ в ответе будет отсутствовать.

Пояснения к некоторым полям о стоимости заказа:

  • price - Окончательная итоговая цена заказа если заказ выполнен (в статусе done)

  • min_price - Расчетная минимальная стоимость для заказа

  • current_price - Текущая стоимость на момент выполенения заказа

  • estimated_price - Расчетная стоимость заказа

  • estimated_price_discounted - Расчетную стоимость заказа со скидкой

  • pickup_charge_additional - Дополнительная стоимость подачи в заказе

  • paid - Флаг оплаты заказа

Эндпойнт изменения времени подачи предзаказа

POST /orders/:id/pickup_at

Request

curl -X POST \
  http://localhost:8080/external/orders/8472/pickup_at \
  -H 'Authorization: Bearer ZeGE6prCBQ8l9O6K0UQPTfdkSm2ETo' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
  "pickup_at": "2019-08-23T19:40:00.000Z"
}'

Примечание

Время UTC

Коды ошибок:

  • 404 - Not Found - Не найден заказ
  • 400 - {:type :invalid_operation :message :invalid_pickup_at} - неверный формат нового времени подачи
  • 400 - {:type :invalid_operation :message :only_preorders_supported} - менять время подачи можно только для предзаказов
  • 400 - {:type :invalid_operation :message :only_forward_change} - время подачи можно переводить только вперед
  • 400 - {:type :invalid_operation :message :too_late} - слишком поздно - уже началась (начинается) раздача предзаказа
  • 400 - {:type :invalid_operation :message :cant_change_pickup_at} - поменять не удалось, обратитесь в поддержку

В случае успешного изменения в ответ придет

Response Example

{
    "order": {
        "car": {
            "id": 2,
            "license_plate": "X777XX77",
            "color": "000000",
            "brand": "Mersedes-Benz",
            "model": "S-class"
        },
        "passenger_info": {
            "phone": "+79114650386",
            "first_name": "Alexey"
        },
        "pickup_charge_additional": 0,
        "min_price": 45000,
        "route": [
            {
                "address": "проспект Защитников Москвы 10-184",
                "position": [
                    55.76279,
                    37.59288
                ]
            },
            {
                "position": [
                    55.974283,
                    37.423107
                ],
                "go_to_pin": true
            }
        ],
        "rate": {
            "id": 1,
            "title": "BUSINESS"
        },
        "current_price": 0,
        "updated_at": "2019-07-25T17:34:22.238Z",
        "status": "new",
        "id": 8472,
        "comment": "Please, wait me at first porch",
        "paid": null,
        "estimated_price": 231000,
        "distance": 0,
        "driver": {
            "id": 550,
            "first_name": "Alexey",
            "rating": 5,
            "phone": "+79005629512",
            "photo_url": null
        },
        "price": 0,
        "pickup_at": "2019-07-25T18:25:00.511Z",
        "estimated_price_discounted": null,
        "created_at": "2019-07-25T16:37:12.833Z",
        "track": []
    }
}

Автоматическое отслеживание рейсов

Поиск рейсов

GET /flights?q=<query>&date_from=2019-10-02&date_to=2019-10-03

Параметры для запроса

  • q - обязательный, строка поиска, ищет по началу строки, регистронезависимо, например SU2011
  • date_from - опциональный, timestamp в UTC - фильтрует рейсы, не раньше указанного времени прибытия
  • date_to - опциональный, timestamp в UTC - фильтрует рейсы по дате, не позднее этого времени прибытия

Request

curl -X GET \
  'http://localhost:8080/external/flights?q=SU2011&date_from=2019-10-02&date_to=2019-10-03' \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'Cache-Control: no-cache'

Возвращает список рейсов в формате

{"flights":[
  {"flight":"SU1401",
   "dep_airport":"SVX",
   "dest_airport":"SVO",
   "scheduled_arrival":"2019-09-24T16:30:00.000+05:00",
   "estimated_arrival":"2019-09-24T16:10:32.000+05:00",
   }
]}

С полями

  • flight - название рейса
  • dep_airport - аэропорт отправления
  • dest_airport - аэропорт прибытия
  • scheduled_arrival - назначенное время прибытия
  • estimated_arrival - расчетное время прибытия

Для получения информации о маршруте и рекомендуемом времени подачи авто добавляется новый параметр flight_id для ендпойнда GET /rates (см выше)

Добавлена возможность привязать создаваемый заказ к рейсу

Для привязки заказа к полету требуется в запросе

POST /orders

добавить новое поле:

"flight_id": "<идентификатор рейса из поля id>"

Если такой рейс будет найден то заказ создастся с привязкой ко времени прибытия/отправления

В частности

  1. Будет произведена проверка того,что это предзаказ
  2. Будет произведена проверка времени подачи - чтобы подача была не сильно раньше и не сильно позже планируемого времени прибытия
  3. Будет производиться автоматическое отслеживание и корректировка времени прибытия такого рейса
  4. В информации о таком заказе появится дополнительное поле flight с данными о рейсе (в том же формате, что и для поиска)

Ошибки:

  • invalid_flight_data - рейс не найден
  • pickup_at_required - не указано время подачи
  • invalid_pickup_at - неверное время подачи
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment