{"id":39142342,"url":"https://github.com/arcsub/go-moysklad","last_synced_at":"2026-01-17T21:31:47.482Z","repository":{"id":197837764,"uuid":"698935979","full_name":"arcsub/go-moysklad","owner":"arcsub","description":"SDK для МойСклад JSON API v1.2","archived":false,"fork":false,"pushed_at":"2025-02-20T14:41:43.000Z","size":1981,"stargazers_count":8,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-20T15:37:51.615Z","etag":null,"topics":["api","api-client","golang","moysklad","sdk-go"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arcsub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-01T12:44:28.000Z","updated_at":"2025-02-20T14:40:29.000Z","dependencies_parsed_at":"2024-03-10T09:37:49.213Z","dependency_job_id":"f4a32c61-c6fb-4e17-a63a-68b08af8eeea","html_url":"https://github.com/arcsub/go-moysklad","commit_stats":null,"previous_names":["arcsub/go-moysklad"],"tags_count":74,"template":false,"template_full_name":null,"purl":"pkg:github/arcsub/go-moysklad","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsub%2Fgo-moysklad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsub%2Fgo-moysklad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsub%2Fgo-moysklad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsub%2Fgo-moysklad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arcsub","download_url":"https://codeload.github.com/arcsub/go-moysklad/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsub%2Fgo-moysklad/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28518627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T18:55:29.170Z","status":"ssl_error","status_checked_at":"2026-01-17T18:55:03.375Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-client","golang","moysklad","sdk-go"],"created_at":"2026-01-17T21:31:47.362Z","updated_at":"2026-01-17T21:31:47.446Z","avatar_url":"https://github.com/arcsub.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://dev.moysklad.ru/doc/api/remap/1.2/images/logo-e9f672b5.svg)\n\n[![](https://godoc.org/github.com/arcsub/go-moysklad?status.svg)](http://godoc.org/github.com/arcsub/go-moysklad)\n[![Go Report Card](https://goreportcard.com/badge/github.com/arcsub/go-moysklad)](https://goreportcard.com/report/github.com/arcsub/go-moysklad)\n![GitHub Tag](https://img.shields.io/github/v/tag/arcsub/go-moysklad?style=flat-square)\n![GitHub License](https://img.shields.io/github/license/arcsub/go-moysklad?style=flat-square)\n![GitHub commit activity](https://img.shields.io/github/commit-activity/t/arcsub/go-moysklad?style=flat-square)\n![GitHub last commit](https://img.shields.io/github/last-commit/arcsub/go-moysklad?style=flat-square)\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch2\u003ego-moysklad (МойСклад)\u003c/h2\u003e\n  \u003cdiv\u003eSDK для работы с \u003ca href=\"https://dev.moysklad.ru/doc/api/remap/1.2/#mojsklad-json-api\"\u003eМойСклад JSON API 1.2\u003c/a\u003e\u003c/div\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"https://github.com/arcsub/go-moysklad/assets/47686389/6bec5834-6eb9-442f-b1ee-efeaa85bb946\" width=\"200px\"\u003e\n\u003c/div\u003e\n\n\u003e\n\u003e **SDK находится в стадии разработки!**\n\u003e\n\u003e Некоторые методы могут отсутствовать или работать неправильно!\n\u003e\n\u003e **Подробная документация в процессе написания.**\n\n## Установка\n\n\u003e Требуемая версия go \u003e= 1.21\n\n```\ngo get -u github.com/arcsub/go-moysklad@HEAD\n```\n\n## Особенности\n\n### Используется [resty](https://pkg.go.dev/github.com/go-resty/resty/v2) как стандартный клиент\n\nМожно самостоятельно настроить resty-клиент, изучив его [документацию](https://pkg.go.dev/github.com/go-resty/resty/v2).\n\n### Возвращаемые аргументы\nКаждый запрос на создание/изменение/удаление возвращает 3 аргумента.\nРассмотрим объявление функции\n```go\nfunc (s *endpointCreate[T]) Create(ctx context.Context, entity *T, params ...func (*Params)) (*T, *resty.Response, error)\n```\nВ примере выше нас интересуют возвращаемые аргументы: `(*T, *resty.Response, error)`\n1. `*T` – указатель на сущность/документ, например *Product при вызове `Create()` (возвращает `bool` при вызове метода `Delete()`).\n2. `*resty.Response` – ответ на запрос, содержащий *http.Response и некоторую другую информацию.\n3. `error` – ошибки, если они были. При возникновении ошибок от API МойСклад в качестве ошибки будет заполненная структура `ApiErrors`\n\n### Указатели\nПоля структур сущностей и документов являются указателями.\n\n- Чтобы получить значение по указателю необходимо вызвать метод структуры `GetFieldName()`.\n  - `FieldName` - наименование поля.\n\nНапример:\n```go\nname := product.GetName()\nid := product.GetID()\n```\n\n- Чтобы установить значение необходимо передать значение в соответствующий метод `SetFieldName(value)`\n  - `FieldName` - наименование поля\n  - `value` - передаваемое значение.\n\n\u003e [!NOTE]\n\u003e Методы `SetFieldName()` возвращают указатель на объект, что позволяет вызывать методы по цепочке.\n\n\nНапример:\n```go\nproduct := new(moysklad.Product)\nproduct.SetName(\"iPhone 16 Pro Max\").SetCode(\"APPL16PM\")\n```\n\n- ~~Для безопасного разыменовывания указателя необходимо передать указатель в метод `Deref()`~~\n- ~~Чтобы установить указатель на примитивное значение поля также существуют вспомогательные методы:~~\n  - ~~`Bool()` возвращает *bool~~\n  - ~~`Int()` возвращает *int~~\n  - ~~`Uint()` возвращает *uint64~~\n  - ~~`Float()` возвращает *float64~~\n  - ~~`String()` возвращает *string~~\n\n## Использование\n### Создание экземпляра клиента\n```go\n// создание стандартного клиента (на базе resty.New())\nclient := moysklad.New(moysklad.Config{\n  // с использованием токена\n  Token: os.Getenv(\"MOYSKLAD_TOKEN\"),\n  \n  // или с использованием логина и пароля\n  Username: os.Getenv(\"MOYSKLAD_USERNAME\"),\n  Password: os.Getenv(\"MOYSKLAD_PASSWORD\"),\n})\n```\n\n### Создание экземпляра клиента со своим http клиентом\n\n```go\nhttpClient := \u0026http.Client{Timeout: 5 * time.Minute}\n\nclient := moysklad.New(moysklad.Config{\n  Token: os.Getenv(\"MOYSKLAD_TOKEN\"),\n  HTTPClient: httpClient,\n})\n```\n\n### Создание экземпляра клиента с resty клиентом\n\n```go\nrestyClient := resty.New()\nrestyClient.SetRetryCount(10) // количество повторных попыток\n\nclient := moysklad.New(moysklad.Config{\n  Token: os.Getenv(\"MOYSKLAD_TOKEN\"),\n  RestyClient: restyClient,\n})\n```\n### Параметры запроса\n\n#### Пример передачи параметров запроса в метод\n\nФункциональные параметры запроса можно передавать в методы, сигнатура которых это предусматривают.\n\n```go\nlist, _, err := client.Entity().Product().GetList(context.Background(),\n  moysklad.WithExpand(\"country\"),\n  moysklad.WithOrder(\"name\"),\n  moysklad.WithLimit(10),\n)\n```\n\n---\n#### Количество элементов на странице `limit=val`\nПример:\n```go\nmoysklad.WithLimit(100)\n```\n\n#### Смещение от первого элемента `offset=val`\nПример:\n```go\nmoysklad.WithOffset(100)\n```\n\n#### Контекстный поиск `search=val`\nПример:\n```go\nmoysklad.WithSearch(\"iPhone 16 Pro Max\")\n```\n#### Замена ссылок объектами\nПример:\n```go\nmoysklad.WithExpand(\"positions\").WithExpand(\"group\")\n```\n\n#### Фильтрация по значению `key=value`\nПример:\n```go\nmoysklad.WithFilterEquals(\"name\", \"Яблоко\")\n```\n\n#### Строго больше `key\u003evalue`\nПример:\n```go\nmoysklad.WithFilterGreater(\"sum\", \"100\")\n```\n\n#### Строго меньше `key\u003cvalue`\nПример:\n```go\nmoysklad.WithFilterLesser(\"sum\", \"1000\")\n```\n\n#### Больше или равно `key=\u003evalue`\nПример:\n```go\nmoysklad.WithFilterGreaterOrEquals(\"moment\", \"2023-06-01\")\n```\n\n#### Меньше или равно `key\u003c=value`\nПример:\n```go\nmoysklad.WithFilterLesserOrEquals(\"moment\", \"2023-06-01\")\n```\n\n#### Не равно `key!=value`\nПример:\n```go\nmoysklad.WithFilterNotEquals(\"name\", \"0001\")\n```\n\n#### Частичное совпадение (обычное подобие) `key~value`\nПример:\n```go\nmoysklad.WithFilterEquivalence(\"code\", \"ms\")\n```\n\n#### Полное совпадение в начале значения (левое подобие) `key~=value`\nПример:\n```go\nmoysklad.WithFilterEquivalenceLeft(\"code\", \"ms\")\n```\n\n#### Полное совпадение в конце значения (правое подобие) `key=~value`\nПример:\n```go\nmoysklad.WithFilterEquivalenceRight(\"code\", \"ms\")\n```\n\n#### Частичное совпадение не выводится `key!~value`\nПример:\n```go\nmoysklad.WithFilterNotEquivalence(\"code\", \"ms\")\n```\n\n#### Фильтрация по удалённым документам `isDeleted=val`\nПример:\n```go\nmoysklad.WithFilterDeleted(true)\n```\n\n#### Фильтрация по напечатанным документам `printed=val`\nПример:\n```go\nmoysklad.WithFilterPrinted(true)\n```\n\n#### Фильтрация по опубликованным документам `published=val`\nПример:\n```go\nmoysklad.WithFilterPublished(true)\n```\n\n#### Фильтрация по архивным сущностям `archived=val`\nПример:\n```go\nmoysklad.WithFilterArchived(true)\n```\n\n#### Группировка выдачи `groupBy=val`\nПример:\n```go\nmoysklad.WithGroupBy(moysklad.GroupByProduct)\n```\n\n#### Применение сохранённого фильтра `namedFilter=href`\nМетод принимает указатель на сохранённый фильтр.\n\nПример:\n```go\nmoysklad.WithNamedFilter(\u0026NamedFilter{...})\n```\n\n#### Сортировка по умолчанию `order=fieldName`\nПример:\n```go\nmoysklad.WithOrder(\"name\")\n```\n\n#### Сортировка по возрастанию `order=fieldName,asc`\nПример:\n```go\nmoysklad.WithOrderAsc(\"name\")\n```\n\n#### Сортировка по убыванию `order=fieldName,desc`\nПример:\n```go\nmoysklad.WithOrderDesc(\"name\")\n```\n\n#### Остатки и себестоимость в позициях документов `fields=stock`\nМетод устанавливает лимит позиций в 100 единиц, а также применяет замену ссылок объектами для поля `positions`\n\nПример:\n```go\nmoysklad.WithStockFiled()\n```\n\n#### Тип остатка `stockType=val`\n\nИспользуется в отчёте \"Остатки\"\n\nПример:\n```go\nmoysklad.WithStockType(moysklad.StockDefault)\n```\n\n#### Интервал, с которым будет построен отчет `interval=val`\nИспользуется в отчётах\n\nПример:\n```go\nmoysklad.WithInterval(moysklad.IntervalMonth)\n```\n\n#### Начало периода `momentFrom=val`\nМетод принимает `time.Time`\nПример:\n```go\nmoysklad.WithMomentFrom(time.Now())\n```\n\n#### Конец периода `momentTo=val`\nМетод принимает `time.Time`\nПример:\n```go\nmoysklad.WithMomentTo(time.Now())\n```\n\n### Сервисы\nДля перехода к определённому сервису необходимо вызвать цепочку методов, аналогично пути запроса.\n\n#### Пример: ProductService\nСервис для работы с товарами.\n\nОтносительный путь: `/entity/product`\nЦепочка вызовов от клиента будет выглядеть следующим образом:\n```go\n// `/entity/product`\n_ = client.Entity().Product()\n\n// `/entity/variant`\n_ = client.Entity().Variant()\n\n// `/context/companysettings`\n_ = client.Context().CompanySettings()\n\n// `/report/dashboard`\n_ = client.Report().Dashboard()\n```\n\n### Запрос по объекту `Meta`\n\nЕсли возникает необходимость точечно запросить информацию о сущности, имея только её `Meta`, можно использовать\nметод `FetchMeta`.\n\nЧтобы использовать данный функционал необходимо точно знать, какой тип данных мы ожидаем получить в ответ.\n\nМетод имеет следующую сигнатуру:\n\n```go\nfunc FetchMeta[T any](ctx context.Context, client *Client, meta Meta, params ...func (*Params)) (*T, *resty.Response, error)\n```\n\nПример:\n\n```go\nproduct, _, _ := moysklad.FetchMeta[moysklad.Product](ctx, client, product.GetMeta())\n```\n### Пример работы\n```go\npackage main\n\nimport (\n  \"context\"\n  \"fmt\"\n  \"github.com/arcsub/go-moysklad/moysklad\"\n  \"os\"\n)\n\nfunc main() {\n  // инициализируем простой клиент с аутентификацией по паре логин/пароль\n  client := moysklad.New(moysklad.Config{\n    Username:               os.Getenv(\"MOYSKLAD_USERNAME\"),\n    Password:               os.Getenv(\"MOYSKLAD_PASSWORD\"),\n    DisabledWebhookContent: true,\n  })\n\n  // сервис для работы с товарами\n  productService := client.Entity().Product()\n\n  // выполняем запрос на получение списка товаров без дополнительных параметров\n  products, _, err := productService.GetList(context.Background())\n  if err != nil {\n    panic(err)\n  }\n\n  // выводим названия полученных товаров\n  for _, product := range products.Rows {\n    fmt.Println(product.GetName())\n  }\n\n  // создадим новый товар\n  product := new(moysklad.Product)\n  product.SetName(\"Created Product\")\n\n  // отправим запрос на создание товара\n  // в качестве аргументов передадим контекст и товар\n  productCreated, _, err := productService.Create(context.Background(), product, \n    moysklad.WithExpand(\"country\", \"owner\", \"productFolder\"), // пример передачи параметров запроса\n  )\n  if err != nil {\n    panic(err)\n  }\n\n  // выведем название созданного товара\n  fmt.Println(productCreated.GetName())\n\n  // изменим название товара\n  productCreated.SetName(\"Updated Product\")\n\n  // отправим запрос на изменение товара\n  // в качестве аргументов передадим контекст, ID изменяемой сущности и изменённый товар\n  productUpdated, _, err := productService.Update(context.Background(), productCreated.GetID(), productCreated)\n  if err != nil {\n    panic(err)\n  }\n\n  // выведем название изменённого товара\n  fmt.Println(productUpdated.GetName())\n\n  // отправим запрос на удаление товара\n  // в качестве аргументов передадим контекст и удаляемую сущность, в которой содержится идентификатор\n  success, _, err := productService.Delete(context.Background(), productUpdated)\n  if err != nil {\n    panic(err)\n  }\n\n  // выведем состояние выполненного запроса, где true - успешно удалено, false – не удалено, см ошибки\n  fmt.Println(\"Deleted\", success)\n}\n```\n\n## Обратная связь\n\nБуду рад видеть ваши идеи и предложения в [Issues](https://github.com/arcsub/go-moysklad/issues).\n\n\u003c!--div align=\"center\"\u003e\n  \u003ca href=\"https://pay.cloudtips.ru/p/eac3797c\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://github.com/arcsub/go-moysklad/assets/47686389/6431baa5-28e4-48b6-8d97-0e50bb6646d2\" width=\"150px\"\u003e\n\u003cdiv align=\"center\"\u003eПоддержать проект\u003c/div\u003e\n\u003c/a\u003e\n\u003c/div--\u003e\n\u003cbr/\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcsub%2Fgo-moysklad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcsub%2Fgo-moysklad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcsub%2Fgo-moysklad/lists"}