# 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 GET /api/v1/ping HTTP/1.1 ``` Проверить подключение к REST API. **Параметры:** НЕТ **Пример ответа:** ```json {} ``` ### Проверить время сервера ```http GET /api/v1/time HTTP/1.1 ``` Проверить подключение к 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`, `token`, `delete` | Действие token | JSON | | Маркер доступа 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 or JSON array | `new` | Bitmessage адрес или массив адресов email | STRING | `new` | Почтовый адрес password | STRING | `new` | Пароль key | STRING | `new`, `add` | Bitcoin ключ (публичный) pgp | STRING | `new`, `add` | PGP ключ (публичный) url | STRING | `new`, `update` | Список URL date | STRING | `update`, `delete` | Дата в формате: YYYY-MM-DD code | STRING | `token` | Произвольная строка которую нужно подписать. sign | STRING | `update`, `token`, `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: ``` ### Новая сделка (ордер) Ордер создается без указания адреса платежа (поле `payment`). Адрес платежа связан с исходными данными ордера. Зная исходные данные ордера можно вычислить адрес платежа. Адрес платежа создается модулем сделок. **Пример:** Минимально необходимый набор данных для создания ордера (в формате JSON) предоставлен ниже: Запрос: ```http POST /api/v1/deal HTTP/1.1 ``` Тело запроса ```json { "order": "create", "type": "Prepaid", "at": "http://placard.zr-code.com", "date": "2022-04-11 11:14:46 UTC", "seller": { "address": "n2f3cbeUUFhbz6mFLpDUzMnrt72sPu7WQK" }, "customer": { "address": "2N3oefVeg6stiTb5Kh3ozCSkaqmx91FDbsm" }, "payment": { "until": "2022-04-12 11:14:46 UTC", "sum": 0.00001 } } ``` Ответ: ```json { "id": "AEEAB-PEE95-O6F30-S68A8-TC55A-O3B7D-L98370", "action": "Created", "result": { "success": true, "message": "New deal submitted" }, "payload": "LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEE1MTIKCmRlYWw6CiAgb3JkZXI6IENyZWF0ZWQKICB0eXBlOiBQcmVwYWlkCiAgYXQ6IGh0dHA6Ly9wbGFjYXJkLnpyLWNvZGUuY29tCiAgZGF0ZTogMjAyMi0wNC0xMSAxMToxNDo0NiBVVEMKICBzZWxsZXI6CiAgICBhZGRyZXNzOiBuMmYzY2JlVVVGaGJ6Nm1GTHBEVXpNbnJ0NzJzUHU3V1FLCiAgICByYXRpbmc6IDAsIDAlCiAgY3VzdG9tZXI6CiAgICBhZGRyZXNzOiAyTjNvZWZWZWc2c3RpVGI1S2gzb3pDU2thcW14OTFGRGJzbQogICAgcmF0aW5nOiAwLCAwJQogIHBheW1lbnQ6CiAgICB1bnRpbDogMjAyMi0wNC0xMiAxMToxNDo0NiBVVEMKICAgIGFkZHJlc3M6IDJONmFidjNxaGdIUXh2bnRmRHptbWk0a0htMTRUYWRvQnB1CiAgICBzdW06IDAuMDAwMDEgdEJUQwogIGZlZWRiYWNrOgogICAgbGVhdmUtYmVmb3JlOiAyMDIyLTA0LTEyIDExOjE0OjQ2IFVUQwotLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLQpWZXJzaW9uOiBjYwoKd3B3RUFRRUtBQVlGQW1KVURid0FDZ2tRN0lqUjIwSkJpemVCckFRQWp0UlU5R3IySm1qdUhLTHhaejQrVWMzQwp2cUFzem1JcjhZRUdRUWZKS3o3SjJsd1U0ZkNOaVByZ29yQTdIdVRGa1Bqd0JrN0N0MHBOZlQwWmpxYTVYWXk5Cml1d01hRkVsM1dmVUQ0MlQxQVFWUDhCbUp6RmtxUXdVSE81dWtDS1RpaTViK3VHVVIvZzJETStFOXVBb3ZYWEYKZ3M5NldWVlJzNGg5YWdCektPTT0KPW4razcKLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0t" } ``` Расшифровка `payload`: ```yaml -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 deal: order: Created type: Prepaid at: http://placard.zr-code.com date: 2022-04-11 11:14:46 UTC seller: address: n2f3cbeUUFhbz6mFLpDUzMnrt72sPu7WQK rating: 0, 0% customer: address: 2N3oefVeg6stiTb5Kh3ozCSkaqmx91FDbsm rating: 0, 0% payment: until: 2022-04-12 11:14:46 UTC address: 2N6abv3qhgHQxvntfDzmmi4kHm14TadoBpu sum: 0.00001 tBTC feedback: leave-before: 2022-04-12 11:14:46 UTC -----BEGIN PGP SIGNATURE----- Version: cc wpwEAQEKAAYFAmJUDbwACgkQ7IjR20JBizeBrAQAjtRU9Gr2JmjuHKLxZz4+Uc3C vqAszmIr8YEGQQfJKz7J2lwU4fCNiPrgorA7HuTFkPjwBk7Ct0pNfT0Zjqa5XYy9 iuwMaFEl3WfUD42T1AQVP8BmJzFkqQwUHO5ukCKTii5b+uGUR/g2DM+E9uAovXXF gs96WVVRs4h9agBzKOM= =n+k7 -----END PGP SIGNATURE----- ``` ## Пользователь ### Помощь ```http GET /api/v1/help HTTP/1.1 ``` ```http POST /api/v1/help HTTP/1.1 ``` Получить справочную информацию по командам регистрации и обновления данных учётной записи. **Параметры:** [Строка запроса](#общие-параметры) **Пример:** Запрос: ```http GET /api/v1/help?payload=html HTTP/1.1 ``` Ответ (содержимое `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
  token        : get access token
  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>
  token        : <code><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
  <code>       : unique string
  [+|-]<url>   : add(+) or delete(-) URL; format: http[s]://<string>
  <signature>  : bitcoin signature for message text (use private key)
``` ###### Этот HTML-документ содержит инструкцию к составлению данных в виде `текста в произвольном формате`. ### Статус ```http GET /api/v1/account/status HTTP/1.1 ``` ```http POST /api/v1/account/status HTTP/1.1 ``` Получить статус учётной записи пользователя. **Параметры:** [Строка запроса](#общие-параметры) **Пример:** Запрос: ```http GET /api/v1/account/status?address=null HTTP/1.1 ``` Ответ: ```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 POST /api/v1/account/new HTTP/1.1 ``` Зарегистрировать нового пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) ### Добавить ```http POST /api/v1/account/add HTTP/1.1 ``` Добавить данные в учётную запись пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) ### Обновить ```http POST /api/v1/account/update HTTP/1.1 ``` Обновить данные в учётной записи пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) ### Удалить ```http POST /api/v1/account/delete HTTP/1.1 ``` Удалить учётную запись пользователя. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-пользователя) ## Сделка ### Создать ```http POST /api/v1/deal/create HTTP/1.1 ``` Создать сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) ### Оплатить ```http POST /api/v1/deal/pay HTTP/1.1 ``` Оплатить сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) ### Завершить ```http POST /api/v1/deal/complete HTTP/1.1 ``` Завершить сделку. **Параметры:** [Строка запроса](#общие-параметры), [Тело запроса](#параметры-сделки) ## Примеры: * **HTTP Request:** ```http 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 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 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); }); ```