Below is the text of the page https://home.finance.ua/api stored 2013-09-21 by archive.org.ua. The original page over time could change. View as original html

Описание работы API для доступа к данным - Домашние Финансы | Ho

ukr [/ukr] rus forum.finance.ua Индексы FUDI Главная О системе Приложения Документация API Форум Вход E-MAIL ПАРОЛЬ Забыл пароль Зарегистрироваться API для доступа к данным Введение На этой странице публикуется описание работы серверного API. Обо всех ошибочных ситуациях или неточностях в описании сообщать на info@home.finance.ua или писать на форуме. Периодически документация пополняется описаниями новых методов. Для осуществления доступа к данным аккаунта Домашних Финансов используются POST-запросы типа « application/json » с json-содержанием. Для авторазиции возможно использование https. Для работы с данными аккаунта по https разрешена работа только для аккаунтов с ненулевым балансом. Все запросы должны направляться на адрес [PROTOCOL]://home.finance.ua/services/index.php В ответе сервера клиенту содержится строка с JSON-данными. Виды запросов-ответов и формат передаваемых данных рассмотрены ниже. Внимание! Согласно пункту 1.3 Cоглашения об использовании службы «API Домашние Финансы» , оно вступает в силу с момента первого использования Разработчиком любой функции API Домашних Финансов. Общая структура запросов и ответов Все запросы к серверу в качестве данных должны передавать JSON-объект следующего вида: { "id":ID_REQUEST, "service":SERVICE_NAME, "method":METHOD_NAME, "params":[] } Поле params используется для передачи параметров. Остальные поля носят служебный характер и являются либо идентификатором (ID_REQUEST), либо имеют одно из служебных предопределенных значений Содержание успешного ответа сервера будет таким: { "result":DATA, "id":ID_REQUEST } Содержание ответа с ошибкой - таким: { "error": { "message":SOME_TEXT, "code":ERROR_ID, "origin":2 }, "id":ID_REQUEST } ID_REQUEST — уникальный идентификатор запроса, который должен быть задан клиентом в теле запроса и будет возвращен в теле ответа на данный запрос. ERROR_ID - один из служебных идентификаторов ошибки, может принимать следующие значения: 50 — сессия невалидна 51 — у данного пользователя нет прав для совершения в данном бюджетном аккаунте запрашиваемого действия 52 — попытка работать по https протоколу в бесплатном аккаунте 53 — исчерпано количество сессионных дней для данного бесплатного аккаунта 54 — попытка работать в аккаунте (не своем) у которого нулевой баланс 55 — попытка сменить тип бюджетной сетки на бесплатном аккаунте 56 — попытка смотреть историю бюджетного аккаунта, недоступную для бесплатного аккаунта 57 — неверный E-mail или пароль при авторизации Авторизация в системе Для авторизации в системе клиент должен отправить на сервер запрос с такой структурой поля params: { "email":E-MAI, "password":PASSWORD } При успешной авторизации поле result ответа будет следующим: { "token":TOKEN, "idUser":ID_USER, "idAccount":ID_ACCOUNT, "role":ID_ROLE } E-MAIL — регистрационный E-mail пользователя PASSWORD — пароль пользователя TOKEN — ключ, который будет использоваться для идентификации сессии работы с бэк-ендом. После успешной авторизации в системе TOKEN не изменяется на протяжении всего сеанса работы с системой. Если на протяжении 3 суток в данном сеансе работы небыло активности — TOKEN становится невалидным. ID_USER — идентификатор пользователя ID_ACCOUNT — идентификатор бюджетного аккаунта. После авторизации возвращается номер дефолтового бюджетного аккаунта пользователя ID_ROLE — права доступа пользователя ID_USER к аккаунту ID_ACCOUNT Пример запроса на авторизацию: { "id":1, "service":"sauth", "method":"auth", "params":[ { "email":"info@home.finance.ua", "password":"123123" } ] } Пример ответа на запрос: { "result": { "token":"b6b7de813811acfa24d198adc4de0c6e", "idUser":"35", "idAccount":"35", "role":"5" }, "id":1 } После успешной авторизации данные ID_TOKEN, ID_USER и ID_ACCOUNT должны присутствовать в параметрах каждого запроса к серверу. На основании этих данных проверяется валидность текущего сеанса работы с бек-эндом, права пользователя ID_USER на произведение запрашиваемых действий в аккаунте ID_ACCOUNT и т. д. Поле “params” запросов в рабочем режиме является массивом из двух элементов, где в первом передаются сессионные данные, а во втором — пользовательские данные. Общая структура запросов в этом случае принимает вид: { /*Уникальный номер запроса*/ "id" : ID_REQUEST, /*Название сервиса*/ "service" : SERVICE_NAME, /*Название метода сервиса*/ "method" : METHOD_NAME, "params" : [ /*0-й элемент массива — служебные данные, которые должны быть всегда*/ { "token" : TOKEN, "idAccount" : ID_ACCOUNT, "idUser" : ID_USER }, /*Для каждого типа запросов структура этих данных своя*/ REQUEST_DATA ] } Получение настроек бюджетного аккаунта Для получения настроек бюджетного аккаунта поля запроса должны принимать следующие значения: SERVICE_NAME = ssettings METHOD_NAME = read REQUEST_DATA — массив, в котором в виде строк перечислены типы запрашиваемых настроек аккаунта. Возможные типы запрашиваемых настроек (для массива REQUEST_DATA): "ctgs" - категории расходов и доходов "scheta" - счета "budgetGrid" - настройки бюджетной сетки "userSettings" - настройки пользователя "finTargets" - финансовые цели "summaryBlocks" - виджеты "Итогов" "commonSettings" - разное "userAccounts" - бюджетные аккаунты пользователя "accountUsers" - пользователи бюджетного аккаунта "accountDate" - серверное "сегодня" Общая структура ответа на запрос описана выше. Структура поля result для данного запроса в общем выглядит так: { "SETTINGS_1_NAME" : DATA_1, "SETTINGS_2_NAME" : DATA_2, ... } Здесь [SETTINGS_I_NAME] - это название типа запрашиваемой настройки, DATA_I - данные, которые для каждого типа настроек имеют свою структуру. Для "ctgs" поле DATA_I будет следующим: { "ctgsCosts" : [ { /*Название категории*/ "title":CTG_1 TITLE, /*Плановое значение категории*/ "pred":CTG_1_PLAN, /*Временная метка даты, с которой категория считается отключенной. 0 - если категория включена*/ "disabledFrom":CTG_1_DISABLED_FROM }, { "title":CTG_2 TITLE, "pred":CTG_2_PLAN, "disabledFrom":CTG_2_DISABLED_FROM }, ... ], "ctgsRevenues" : [ { /*Название категории*/ "title":CTG_1 TITLE, /*Плановое значение категории*/ "pred":CTG_1_PLAN /*Временная метка даты, с которой категория считается отключенной. 0 - если категория включена*/ "disabledFrom":CTG_1_DISABLED_FROM }, { "title":CTG_2 TITLE, "pred":CTG_2_PLAN, "disabledFrom":CTG_2_DISABLED_FROM }, ... ] } Для "scheta" поле DATA_I будет следующим: [ { /*Название счета*/ "title":SCHET_1_TITLE, /*Временная метка даты, с которой счет считается отключенным. 0 - если счет включен*/ "disabledFrom":SCHET_1_DISABLED_FROM }, { "title":SCHET_2_TITLE, "disabledFrom":SCHET_2_DISABLED_FROM }, ... ] Для "budgetGrid" поле DATA_I будет следующим: { /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/ "periodType":PERIOD_TYPE_VALUE, /*Номер дня начала бюджетного периода для месячной сетки*/ "pstart":PSTART_VALUE, /*Дата первой операции аккаунта*/ "minDate":MINDATE_VALUE } Для "userSettings" поле DATA_I будет следующим: { /*E-mail авторизованного пользователя*/ "email":EMAIL_VALUE, /*Согласие пользователя получать новости системы на свой почтовый ящик, 0 - нет, 1 - да*/ "receiveNews":RECEIVE_NEWS_VALUE, /*Язык интерфейса приложения, 0 - русский, 1 - украинский*/ "lang":LANG_VALUE, /*Ник пользователя*/ "username":USERNAME_VALUE, /*Идентификатор основного бюджетного аккаунта пользователя, который активируется при авторизации*/ "mainAccount":MAIN_ACCOUNT_VALUE, /*Количество дней без активности в аккаунте, после которого пользователь получит напоминание на e-mail*/ "noActivityRemind":NO_ACTIVITY_REMIND_VALUE, } Для "finTargets" поле DATA_I будет следующим: [ { /*Название финансовой цели №1*/ "title":FIN_TARGET_1_TITLE}, /*Номер счета, используемый для финансовой цели №1*/ "idSchet":FIN_TARGET_1_ID_SCHET}, /*Номер валюты, остаток в которой идет в зачет финансовой цели №1*/ "idCurrency":FIN_TARGET_1_ID_CURRENCY}, /*Начальное значение остатков при старте выполнения финансовой цели №1*/ "startValue":FIN_TARGET_1_START_VALUE}, /*Конечное значение остатков, при котором финансовая цель №1 будет выполнена*/ "finishValue":FIN_TARGET_1_FINISH_VALUE}, /*Дата начала выполнения финансовой цели №1*/ "startDate":FIN_TARGET_1_START_DATE}, /*Дата окончания выполнения финансовой цели №1*/ "finishDate":FIN_TARGET_1_FINISH_DATE}, /*Текстовое описание финансовой цели №1*/ "description":FIN_TARGET_1_DESCRIPTION } ... ] Для "summaryBlocks" поле DATA_I будет следующим: [ { /*Название виджета №1*/ "title":BLOCK_1_TITLE}, /*Тип виджета №1, 0 - расходы, 1 - доходы, 2 - остатки на счетах*/ "type":BLOCK_1_TYPE}, /*Настройки блока №1, массив идентификаторов, соответствено, категорий расходов, категорий доходов, счетов*/ "data":BLOCK_1_ARRAY}, } ... ] Для "commonSettings" поле DATA_I будет следующим: { /*Номер основной валюты бюджетного аккаунта*/ "mainCurrency":MAIN_CURRENCY_VALUE}, /*Название бюджетного аккаунта*/ "accountTitle":ACCOUNT_TITLE_VALUE}, /*Массив из 3-х номеров телефонов (последние 7-м цифр номеров), используемых в SMS-сервисе*/ "smsNumbers":SMS_NUMBERS_ARRAY} } Для "userAccounts" поле DATA_I будет следующим: [ { /*Номер бюджетного аккаунта №1 пользователя */ "id":ACCOUNT_1_ID_VALUE}, /*Название бюджетного аккаунта №1 пользователя */ "title":ACCOUNT_1_TITLE_VALUE}, /*Права пользователя в бюджетном аккаунте №1, 0 - нет доступа, 1 - Администратор, 2 - Опытный редактор, 3 - Редактор, 4 - Пользователь, 5 - Гость*/ "role":ACCOUNT_1_ROLE_VALUE}, /*Флаг подтверждения участия пользователя в бюджетном аккаунте, 0 - нет, 1 - да*/ "accepted":ACCOUNT_1_ACCEPTED_VALUE} } ... ] Для "accountUsers" поле DATA_I будет следующим: [ { /*Номер пользователя №1 бюджетного аккаунта*/ "id":USER_1_ID_VALUE}, /*Имя пользователя №1 бюджетного аккаунта*/ "username":USER_1_USERNAME_VALUE}, /*Права пользователя №1 в бюджетном аккаунте , 0 - нет доступа, 1 - Администратор, 2 - Опытный редактор, 3 - Редактор, 4 - Пользователь, 5 - Гость*/ "role":USER_1_ROLE_VALUE}, /*E-mail пользователя №1 бюджетного аккаунта*/ "email":USER_1_EMAIL_VALUE} } ... ] Для "accountDate" поле DATA_I будет следующим: /*Метка 00:00:00 по GMT текущих суток сервера*/ ACCOUNT_DATE_MARK Пример запроса на получение только списка категорий и счетов: { "service":"ssettings", "method":"read", "id":3, "params":[ /*0-й элемент массива params - идентификаторы*/ { "token":"4f35fc9c0743e506108b13944b1d1291", "idUser":"1", "idAccount":"1" }, /*1-й элемент массива params - данные (перечисление типов запрашиваемых настроек)*/ ["ctgs","scheta"] ] } Пример ответа на запрос получения списка категорий и счетов: { "result":{ "ctgs":{ "ctgsCosts":[ {"title":"Продукты","pred":"0.00","disabledFrom":"0"}, {"title":"Проезд","pred":"0.00","disabledFrom":"1327449600"}, {"title":"Развлечения","pred":"0.00","disabledFrom":"0"} ], "ctgsRevenues":[ {"title":"Зарплата","pred":"0.00","disabledFrom":"0"}, {"title":"Подработка","pred":"0.00","disabledFrom":"0"}, ] }, "scheta":[ {"title":"Кошелек","disabledFrom":"0"}, {"title":"Конверт","disabledFrom":"1327449600"} ] }, "id":3 } Запись настроек бюджетного аккаунта Для записи настроек бюджетного аккаунта поля запроса должны принимать следующие значения: SERVICE_NAME = ssettings METHOD_NAME = write REQUEST_DATA — структура параметра описана ниже { "SETTINGS_1_NAME" : DATA_1, "SETTINGS_2_NAME" : DATA_2, ... } Как и при чтении настроек, разные типы настроек можно (и нужно) группировать и отправлять в одном запросе. Для сохранения изменений в списке категорий расходов, на сервер необходимо отправить полный список категорий расходов, который заменит хранящийся в текущий момент на сервере. Порядок категорий в структуре должен совпадать с порядком категорий при отображении. То же самое касается сохранения категорий доходов и счетов. Пример запроса на замещение списков категорий расходов, доходов и счетов: { "ctgs":{ "ctgsCosts":[ {"title":"Продукты бла-бла","pred":"0.00","disabledFrom":"0"}, {"title":"Проезд бла-бла","pred":"0.00","disabledFrom":"0"}, {"title":"Развлечения бла-бла","pred":"0.00","disabledFrom":"0"} ], "ctgsRevenues":[ {"title":"Зарплата бла-бла","pred":"0.00","disabledFrom":"0"} ] }, "scheta":[ {"title":"Кошелек бла-бла","disabledFrom":"0"}, {"title":"Конверт бла-бла","disabledFrom":"1327449600"}, {"title":"Карточка","disabledFrom":"1327449600"} ] } Если такой запрос на сохранение будет отправлен для данных, полученных в примере чтения настроек, то: Все три категории расходов будут переименованы Первая категория доходов будет переименована, а вторая удалена Два счета аккаунта будут переименованы, и к ним будет добавлен еще один Для сохранения настроек бюджетной сетки (budgetGrid) поле DATA_I должно быть следующим: { /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/ "periodType":PERIOD_TYPE_VALUE, /*Номер дня начала бюджетного периода для месячной сетки*/ "pstart":PSTART_VALUE, } Для сохранения настроек бюджетной сетки (budgetGrid) поле DATA_I должно быть следующим: { /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/ "periodType":PERIOD_TYPE_VALUE, /*Номер дня начала бюджетного периода для месячной сетки*/ "pstart":PSTART_VALUE, } Для сохранения настроек пользователя ("userSettings") поле DATA_I должно быть следующим: { /*E-mail авторизованного пользователя*/ "email":EMAIL_VALUE, /*Согласие пользователя получать новости системы на свой почтовый ящик, 0 - нет, 1 - да*/ "receiveNews":RECEIVE_NEWS_VALUE, /*Язык интерфейса приложения, 0 - русский, 1 - украинский*/ "lang":LANG_VALUE, /*Ник пользователя*/ "username":USERNAME_VALUE, /*Идентификатор основного бюджетного аккаунта пользователя, который активируется при авторизации*/ "mainAccount":MAIN_ACCOUNT_VALUE, /*Количество дней без активности в аккаунте, после которого пользователь получит напоминание на e-mail*/ "noActivityRemind":NO_ACTIVITY_REMIND_VALUE, /*Значение нового пароля пользователя. Пустая строка в параметре - пароль не будет изменен*/ "newPassword":NEW_PASSWORD_VALUE, } Для сохранения финансовых целей ("finTargets") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными каждой финансовой цели. Для сохранения настроек виджетов ("summaryBlocks") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому виджету. Для сохранения общих настроек ("сommonSettings") поле DATA_I должно быть таким же, как и при чтении. Для сохранения списка аккаунтов пользователя ("userAccounts") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому аккаунту пользователя. Для сохранения списка пользователей аккаунта ("аccountUsers") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому пользователю аккаунта. Чтение операций Для получения операций (расходов, доходов и переводов) бюджетного аккаунта поля запроса должны принимать следующие значения: SERVICE_NAME = soperations METHOD_NAME = read REQUEST_DATA — {"fromdate":FROM_DATE_VALUE, "todate":TO_DATE_VALUE, "today":TODAY_VALUE} FROM_DATE_VALUE и TO_DATE_VALUE определяют временной отрезок запрашиваемых операций. В ответе будут содержаться операции всех типов (расходы, доходы, переводы) и всех видов (совершонные, будущие, просроченные), дата которых находится в отрезка указанных дат. TODAY_VALUE - "сегодняшняя" дата клиента - дата актуальности учета. Даты должны быть указаны в формате временных меток (количество секунд с 00:00:00 01-01-1970 до 00:00:00 соответствующих суток по GMT) Поле result ответа будет иметь следующий формат: { /*Расходы*/ "costs":{ /*Массив идентификаторов операций*/ "id":[], /*Массив дат операций*/ "date":[], /*Массив комментариев операций*/ "comment":[], /*Массив типов операций (1 - совершенная, 2 - будущая)*/ "realtype":[], /*Массив сумм операций*/ "sum":[], /*Массив идентификаторов валют операций*/ "idCurrency":[], /*Массив идентификаторов категорий операций*/ "idCtg":[], /*Массив идентификаторов счетов операций*/ "idSchet":[], /*Массив идентификаторов авторов или последник редакторов операций*/ "idUser":[] }, /*Доходы*/ "revenues":{ "id":[], "date":[], "comment":[], "realtype":[], "sum":[], "idCurrency":[], "idCtg":[], "idSchet":[], "idUser":[] }, /*Переводы*/ "transfers":{ "id":[], "date":[], "comment":[], "realtype":[], /*Исходные суммы переводов*/ "sumFrom":[], /*Исходные валюты переводов*/ "idCurrencyFrom":[], /*Исходные счета переводов*/ "idSchetFrom":[], /*Конечные суммы переводов*/ "sumTo":[], /*Конечные валюты переводов*/ "idCurrencyTo":[], /*Конечные счета переводов*/ "idSchetTo":[], "idUser":[] }, /*Курсы валют для дней из запрашиваемого временного отрезка. Формат поля будет описан позже*/ "rates":[], /*Курсы валют сегодняшнего (для сервера) дня. Формат поля будет описан позже*/ "realtodayRates":[], /*Данные, необходимые для расчета начального сальдо запрашиваемого временного отрезка. Формат поля будет описан позже*/ "startSaldo":[] } Запись операций Для записи новых (добавленных) операций, сохранения изменений в уже существующих операциях и удаления существующих операций поля запроса должны принимать следующие значения: SERVICE_NAME = soperations METHOD_NAME = write REQUEST_DATA — структура параметра описана ниже [ { /*Тип действия, 0 - новая операция, 1 - редактирование операции, 2 - удаление операции*/ "operationActionType":OPERATION_ACTION_TYPE_VALUE, /*Объект данных операции*/ "operationObject":OPERATION_OBJECT }, ... ] В одном запросе могут (и должны) передаваться группы действий над операциями. Для операции "расхода" OPERATION_OBJECT имеет вид: { "id":OPERATION_ID_VALUE, "type":0, "date":OPERATION_DATE_VALUE, "comment":OPERATION_COMMENT_VALUE, "sum":OPERATION_SUM_VALUE, "idCurrency":OPERATION_ID_CURRENCY_VALUE, "idCtg":OPERATION_ID_CTG_VALUE, "idSchet":OPERATION_ID_SCHET_VALUE } Для операции "дохода" OPERATION_OBJECT имеет вид: { "id":OPERATION_ID_VALUE, "type":1, "date":OPERATION_DATE_VALUE, "comment":OPERATION_COMMENT_VALUE, "sum":OPERATION_SUM_VALUE, "idCurrency":OPERATION_ID_CURRENCY_VALUE, "idCtg":OPERATION_ID_CTG_VALUE, "idSchet":OPERATION_ID_SCHET_VALUE } Для операции "перевода" OPERATION_OBJECT имеет вид: { "id":OPERATION_ID_VALUE, "type":2, "date":OPERATION_DATE_VALUE, "comment":OPERATION_COMMENT_VALUE, "sumFrom":OPERATION_SOURCE_SUM_VALUE, "idCurrencyFrom":OPERATION_ID_SOURCE_CURRENCY_VALUE, "idSchetFrom":OPERATION_ID_SOURCE_SCHET_VALUE, "sumTo":OPERATION_TARGET_SUM_VALUE, "idCurrencyTo":OPERATION_ID_TARGET_CURRENCY_VALUE, "idSchetTo":OPERATION_ID_TARGET_SCHET_VALUE } Независимо от типа действия над операцией, в OPERATION_OBJECT передается полный набор полей операции. Для новых операций в поле OPERATION_ID_VALUE должен передаваться уникальный идентификатор операции, не совпадающий с идентификаторами уже существующих операций. Рекомендуется в качестве идентификаторов новых (еще не сохраненных на сервер) операций использовать целые отрицательные значения (-1, -2 и т.д.). В таком виде идентификатор будет существовать до сохранения операции на сервер, а после сохранения он должен быть заменен на "серверный" идентификатор, который приходит в ответе на запрос (см. ниже). Пример запроса на создание одного расхода, редактирование одного расхода, и удаление одного расхода: { "service":"soperations", "method":"write", "id":7, "params":[ { "token":"0c07c8ebd81d938e751c7304ae9ee908", "idUser":"35", "idAccount":"35" }, [ { "operationActionType":0, "operationObject": { "id":-1, "type":0, "date":1308528000, "comment":"ffff", "sum":123, "idCurrency":2, "idCtg":0, "idSchet":0 } }, { "operationActionType":1, "operationObject": { "id":961274, "type":0, "date":1304121600, "comment":"Магелан автоматы123", "sum":50, "idCurrency":1, "idCtg":6, "idSchet":0 } }, { "operationActionType":2, "operationObject": { "id":962561, "type":0, "date":1304208000, "comment": "посидели в клубе", "sum":200, "idCurrency":1, "idCtg":11, "idSchet":0 } } ] ] } В ответе сервера обязательно присутствует поле oldNewIds. Если в запросе присутствовали действия по созданию новых операций - в поле (массиве) oldNewIds будет передана информация определяющая соответствие между временными (отрицательными) идентификаторами операций на клиенте и постоянными (инициализированными на сервере) идентификаторами тех же операций. Пример ответа на запрос о создании одного нового расхода: { "result": { "oldNewIds": [ { /*Тип операции*/ "type":0, /*Клиентский "временный" идентификатор*/ "oldId":-1, /*Серверный "постоянный" идентификатор*/ "newId":32302 } ] ,"comment":"" }, "id":1 } В случае ошибок обработки действий по отдельным операциям (операция не может быть создана из-за превышения лимита, действие над операцией не может быть реализовано из-за ограничения прав пользователя, невозможно удаление операции из-за ее отсутствия и т.п.) - все остальные действия над операциями производятся без ограничений, а в поле comment передается комментарий о возникших проблемах. Подсчитывай свои возможности, cравнивай их со своими потребностями, рассчитывай и корректируй затраты и доходы вместе с Домашними Финансами Домашние Финансы: Стоимость услуг Школа Экономии Договор о предоставлении услуг ОФерта Cоглашение об использовании службы «API Домашние Финансы» Finance.ua: Валюта Кредит&Депозит Банковские металлы Фондовый рынок Новости Аудиоподкаст Видеоинтервью Форум Finance.ua Домашние финансы Индексы FUDI Конвертер валют Депозитный калькулятор Кредитный калькулятор Глоссарий Горячие предложения банков Корпоративный блог Контакты Реклама Карта портала Copyright © 2009-2013 Инфинсервис / Конфиденциальность / Правовая поддержка Integrites / Программинг Инфинсервис / Дизайн J.K.®Design