# API "Модуля сделок" системы учёта Bitcoin платежей. ## Общая информация * Базовая конечная точка (endpoint): [localhost:4999](http://localhost:4999) * Все конечные точки возвращают `JSON-объект` * Все поля, относящиеся ко времени и меткам времени, указаны в **миллисекундах**. ## HTTP коды возврата * HTTP `4XX` коды возврата применимы для некорректных запросов - проблема на стороне клиента. * HTTP `5XX` коды возврата используются для внутренних ошибок - проблема на стороне сервера. Важно **НЕ** рассматривать это как операцию сбоя. Статус выполнения **НЕИЗВЕСТЕН** и может быть успешным. ## Коды ошибок * Любая конечная точка может вернуть ошибку. **Пример ответа:** ```json { "error": { "code": 404, "message": "Not Found" } } ``` ## Общая информация о конечных точках * Для `GET` конечных точек параметры должны быть отправлены в виде `строки запроса (query string)` . * Для `POST` конечных точек, некоторые параметры могут быть отправлены в виде `строки запроса (query string)`, а некоторые в виде `тела запроса (request body)`: * При отправке параметров в виде `тела запроса` допустимы следующие типы контента: * `application/x-www-form-urlencoded` для `query string`; * `multipart/form-data` для `HTML-форм`; * `application/json` для `JSON`; * `text/plain` для `YAML` или `текста в произвольном формате`. * Параметры могут быть отправлены в любом порядке. ## Доступ к API Доступ к API возможен только при наличии _**маркера доступа**_ или **_цифровой подписи_** методом HMAC-SHA256. [Подробнее](https://github.com/ufocomp/db-platform/wiki/%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-API). ## Общие конечные точки ### Тест подключения ```http request GET /api/v1/ping ``` Проверить подключение к REST API. **Параметры:** НЕТ **Пример ответа:** ```json {} ``` ### Проверить время сервера ```http request GET /api/v1/time ``` Проверить подключение к REST API и получить текущее время сервера. **Параметры:** НЕТ **Пример ответа:** ```json { "serverTime": 1583495795455 } ``` ## Конечные точки Конечные точки разделены на две категории: `Пользователи (account)` и `Сделки (deal)`. Обработка запросов выполняется на стороне `Дополнительного сервера (ДС)`. Поэтому `Модуль сделок` формирует **транспортный пакет** в виде `JSON-объекта` и отправляет его на `ДС`. ###### ВАЖНО: Сетевой адрес `Дополнительного сервера (ДС)` можно указать в параметрах запроса в виде `строки запроса`. По умолчанию: `localhost` ### Формат транспортного пакета: **Запрос:** ```json { "id": "", "address": "", "action": "", "payload": "" } ``` **Ответ:** ```json { "id": "", "address": "", "action": "", "result": { "success": "", "message": "" }, "payload": "" } ``` **Описание:** Ключ | Тип | Значение | Описание ------------ | ------------ | ------------ | ------------ id | STRING | | Уникальный идентификатор запроса address | STRING | | Bitcoin адрес пользователя (учётной записи) `ДС`. По умолчанию: Адрес модуля action | STRING | help, status, new, add, update, delete | Действие result | JSON | | Результат выполнения запроса success | BOOLEAN | true, false | Успешно: Да/Нет message | STRING | | Сообщение (информация об ошибке) payload | BASE64 | | Полезная нагрузка (строка в формате Base64) `Полезная нагрузка` может содержать данные в виде: * `HTML-документа`; * `JSON-объекта`; * `Текста в произвольном формате`. ### Общие параметры #### Для последующих конечных точек можно указать **параметры** в виде `строки запроса (query string)`: Имя | Тип | Значение | Описание ------------ | ------------ | ------------ | ------------ payload | STRING | text, html, json, xml | Получить ответ в виде содержимого поля `payload` с указанием формата server | STRING | localhost | IP-адрес или Host имя сервера (ДС). По умолчанию: localhost pgp | BOOLEAN | false, off | Отключить PGP подпись модуля сделок address | STRING | | Bitcoin адрес пользователя (учётной записи) `ДС`. По умолчанию: Адрес модуля ## Параметры пользователя ### Параметры в виде `тела запроса (request body)`: Наименование | Тип | Действие | Описание ------------ | ------------ | ------------ | ------------ address | STRING | * | Bitcoin адрес bitmessage | STRING | New | Bitmessage адрес key | STRING | New, Add | Bitcoin ключ (публичный) pgp | STRING | New, Add | PGP ключ (публичный) url | STRING | New, Update | Список URL date | STRING | Update, Delete | Дата в формате: YYYY-MM-DD sign | STRING | Update, Delete | Bitcoin подпись flags | STRING | Delete | Флаги ## Параметры сделки ### Параметры в виде `тела запроса (request body)`: #### Для типов контента `application/x-www-form-urlencoded` и `multipart/form-data`: Наименование | Тип | Действие | Описание ------------ | ------------ | ------------ | ------------ type | STRING | * | Тип at | URL | * | URL сайта date | DATETIME | * | Дата сделки seller_address | STRING | * | Продавец: Bitcoin адрес seller_rating | STRING | Pay, Complete | Продавец: Рейтинг customer_address | STRING | * | Покупатель: Bitcoin адрес customer_rating | STRING | Pay, Complete | Покупатель: Рейтинг payment_address | STRING | Pay, Complete | Оплата: Bitcoin адрес payment_until | DATETIME | Pay, Complete | Оплата: Срок оплаты payment_sum | DOUBLE | * | Оплата: Сумма feedback_leave_before | DATETIME | Pay, Complete | Обратная связь: Срок до... feedback_status | STRING | Complete | Обратная связь: Статус feedback_comments | STRING | Complete | Обратная связь: Комментарий #### Для типа контента `application/json`: ```json { "order": "", "type": "", "at": "", "date": "", "seller": { "address": "", "rating": "" }, "customer": { "address": "", "rating": "" }, "payment": { "address": "", "until": "", "sum": "" }, "feedback": { "leave-before": "", "status": "", "comments": "" } } ``` #### Для типа контента `text/plain`: ```yaml deal: order: type: at: date: seller: address: rating: customer: address: rating: payment: sum: address: until: feedback: leave-before: status: comments: ``` ### Пользователь #### Помощь ```http request GET /api/v1/help ``` ```http request POST /api/v1/help ``` Получить справочную информацию по командам регистрации и обновления данных учётной записи. **Параметры:** [Строка запроса](#общие-параметры) **Пример:** Запрос: ```http request GET /api/v1/help?payload=html ``` Ответ (содержимое `payload`): ```html
Bitcoin Payment Service.

Usage: Send a message in accordance with the format.

Available actions: 

  help         : send this help
  status       : show account data
  new          : create account
  add          : adding data to a account (adding missing data)
  update       : updating account data
  delete       : delete account

The system has an AI and can determine the action itself.
But you can help the AI and indicate the action explicitly in the message subject.

Subject: [help|status|new|add|update|delete] | any text
Body:
Action         : Message format
  help         : <ignored>
  status       : <ignored>
  new          : <bitcoin><LF>
                 [<key><LF>] |
                 [<PGP><LF>] |
                 [{account:|trusted:}<LF>]
                 [<url><LF>]
  add          : [<key><LF>] |
                 [<PGP><LF>]
  update       : <yyyy-mm-dd><LF>
                 [<PGP><LF>] |
                 [{account:|trusted:}<LF>]
                 [<url><LF>] |
                 <signature>
  delete       : <yyyy-mm-dd><LF>
                 -account<LF>
                 <signature>
Arguments:
  account      : account URL list (default if not set "trusted")
  trusted      : trusted URL list
  -account     : delete account

Templates:
  <ignored>    : any text will be ignored
  <LF>         : line feed; format: 0x0a
  <string>     : single line text
  <bitcoin>    : bitcoin address; format: [bitcoin:]<string>
  <key>        : bitcoin public key
  <PGP>        : PGP public key
  <yyyy-mm-dd> : current date
  [+|-]<url>   : add(+) or delete(-) URL; format: http[s]://<string>
  <signature>  : bitcoin signature for message text (use private key)
``` ###### Этот HTML-документ содержит инструкцию к составлению данных в виде `текста в произвольном формате`. #### Статус ```http request GET /api/v1/account/status ``` ```http request POST /api/v1/account/status ``` Получить статус учётной записи пользователя. **Параметры:** [Строка запроса](#общие-параметры) **Пример:** Запрос: ```http request GET /api/v1/account/status?address=null ``` Ответ: ```json { "id": "A4406-PDF10-OE2BC-SF8AA-T918F-OC9BC-L9EB00", "action": "Status", "result": { "success": false, "message": "Invalid Bitcoin address: null" }, "payload": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJhdXRob3IiIGNvbnRlbnQ9IkJpdGNvaW4gUGF5bWVudCBTZXJ2aWNlIj4KPC9oZWFkPgo8Ym9keT4KPHByZT5IZWxsbyEKClNvcnJ5LCBzb21ldGhpbmcgd2VudCB3cm9uZyBhbmQgbGVkIHRvIGFuIGVycm9yOgoKPGZvbnQgY29sb3I9IiNDMDM5MkIiPjxiPkludmFsaWQgQml0Y29pbiBhZGRyZXNzOiBudWxsPC9iPjwvZm9udD4KCi0tLS0tClRoYW5rIHlvdSwKUGF5bWVudHMubmV0PC9wcmU+CjwvYm9keT4KPC9odG1sPgo=" } ``` #### Новый ```http request POST /api/v1/account/new ``` Зарегистрировать нового пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) #### Добавить ```http request POST /api/v1/account/add ``` Добавить данные в учётную запись пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) #### Обновить ```http request POST /api/v1/account/update ``` Обновить данные в учётной записи пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) #### Удалить ```http request POST /api/v1/account/delete ``` Удалить учётную запись пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) ### Сделка #### Создать ```http request POST /api/v1/deal/create ``` Создать сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) #### Оплатить ```http request POST /api/v1/deal/pay ``` Оплатить сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) #### Завершить ```http request POST /api/v1/deal/complete ``` Завершить сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) ## Примеры: * **HTTP Request:** ```http request POST /api/v1/account/new HTTP/1.1 Host: localhost:4999 Content-Type: application/x-www-form-urlencoded address=mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8&key=02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61 ``` * **curl command:** ```curl curl "http://localhost:4999/api/v1/account/new?payload=html" \ -X POST \ -d "address=mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8&key=02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61" \ -H "Content-Type: application/x-www-form-urlencoded" ``` * **HTTP Request:** ```http request POST /api/v1/account/new HTTP/1.1 Host: localhost:4999 Content-Type: application/json {"address": "mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8", "key": "02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61"} ``` * **curl command:** ```curl curl "http://localhost:4999/api/v1/account/new?payload=html" \ -X POST \ -d '{"address": "mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8", "key": "02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61"}' \ -H "Content-Type: application/json" ``` * **HTTP Request:** ```http request POST /api/v1/account/new?payload=html HTTP/1.1 Host: localhost:4999 Content-Type: text/plain mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8 02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61 ``` * **curl command:** ```curl curl "http://localhost:4999/api/v1/account/new?payload=html" \ -X POST \ -d "mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8\n02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61" \ -H "Content-Type: text/plain" ``` * **JavaScript:** ```javascript let headers = new Headers(); headers.append('Content-Type', 'multipart/form-data'); let body = new FormData(); body.append("address", "mynFyJJkRhsbB6y1Q5kTgDGckVz2m9NKH8"); body.append("key", "02ef68c191984433c8a730b8fa48a47ec016a0727e6d26cc0982c8900b39354f61"); const init = { method: 'POST', headers: headers, body: body, mode: "cors" }; fetch('http://localhost:4999/api/v1/account/new', init) .then((response) => { return response.json(); }) .then((json) => { console.log(json); console.log(window.atob(json['payload'])); }) .catch((e) => { console.log(e.message); }); ```