{"name":"PayKeeper","vendor":"PayKeeper","industry":"finance","summary":"Протокол для автоматического управления приёмом платежей через платёжную платформу PayKeeper: выставление счетов и получение ссылок на оплату, информация о платежах, возвраты, списание авторизованных средств, работа с чеками 54-ФЗ. Подходит для интеграции с биллингом, бухгалтерскими системами, мобильными приложениями и самописными CMS. О каждом принятом платеже PayKeeper может сообщать POST-оповещением на сайт предприятия.","docsUrl":"https://docs.paykeeper.ru/dokumentatsiya-json-api/","coverage":{"included":[],"excluded":[]},"scenarios":[{"id":"vystavit-schet-i-poluchit-ssylku","title":"Выставить счёт и получить ссылку на оплату","summary":"Ссылка на оплату для клиента — в письмо, мессенджер или на страницу заказа.","steps":["Все запросы — к адресу твоего сервера PayKeeper с заголовком Authorization: Basic (логин и пароль от личного кабинета в base64). Чтение — GET, изменения — POST в формате application/x-www-form-urlencoded.","Получи токен безопасности: GET /info/settings/token/. Он нужен в каждом POST-запросе и меняется раз в сутки.","Создай счёт: POST /change/invoice/preview/ с pay_amount, orderid, clientid, client_email, service_name и token. Срок действия счёта задаёт expiry.","В ответе invoice_id и invoice_url — ссылка для оплаты. Добавь к ней ?pstype=sbp_default, чтобы сразу показать QR-код СБП.","Чтобы PayKeeper сам отправил письмо со счётом, вызови POST /change/invoice/send/ с id счёта."],"code":"PK=https://<твой-сервер>.server.paykeeper.ru\nAUTH='<логин>:<пароль>'\nTOKEN=$(curl -s -u \"$AUTH\" \"$PK/info/settings/token/\" | jq -r .token)\n\ncurl -X POST \"$PK/change/invoice/preview/\" -u \"$AUTH\" \\\n  -d pay_amount=1500.00 -d orderid=1042 \\\n  --data-urlencode 'clientid=Иван Петров' -d client_email=ivan@example.ru \\\n  --data-urlencode 'service_name=Заказ №1042' \\\n  -d token=$TOKEN","language":"bash","methods":["GET /info/settings/token/","POST /change/invoice/preview/","POST /change/invoice/send/"]},{"id":"prinyat-opoveschenie-ob-oplate","title":"Принять оповещение об оплате","summary":"Узнать об оплате с сервера и отметить заказ оплаченным.","steps":["Укажи в личном кабинете адрес оповещений и секретное слово. О каждом платеже PayKeeper пришлёт POST с id, sum, clientid, orderid и key.","Проверь подпись: key должен совпасть с md5 от id + sum (ровно два знака после точки) + clientid + orderid + секретное слово.","Защитись от повторов: оповещение может прийти несколько раз — не зачисляй платёж с тем же id дважды.","Ответь строкой OK и md5 от id + секретное слово. Без правильного ответа PayKeeper повторяет оповещение каждую минуту (по умолчанию до 50 раз).","Если нужно перепроверить платёж, запроси его: GET /info/payments/byid/ с id."],"code":"import hashlib\n\nSECRET = \"<секретное слово>\"\n\ndef handle(form: dict) -> str:\n    sum_str = f\"{float(form['sum']):.2f}\"\n    expected = hashlib.md5(f\"{form['id']}{sum_str}{form['clientid']}{form['orderid']}{SECRET}\".encode()).hexdigest()\n    if expected != form[\"key\"]:\n        return \"Error! Hash mismatch\"\n    mark_paid_once(order_id=form[\"orderid\"], payment_id=form[\"id\"])  # идемпотентно по id платежа\n    return \"OK \" + hashlib.md5(f\"{form['id']}{SECRET}\".encode()).hexdigest()","language":"python","methods":["GET /info/payments/byid/"]},{"id":"vernut-dengi-pokupatelyu","title":"Вернуть деньги покупателю","summary":"Полный или частичный возврат по платежу, в том числе с чеком возврата по 54-ФЗ.","steps":["Получи токен: GET /info/settings/token/.","Отправь возврат: POST /change/payment/reverse/ с id платежа, amount (разделитель — точка) и partial — строго true или false, значения 1 и 0 не принимаются. Для чека возврата передай refund_cart — JSON-строку с товарами.","Ответ success означает только постановку в очередь. Через несколько минут проверь результат: GET /info/refunds/bypaymentid/.","Возвраты доступны пользователям, у которых включена эта функция."],"code":"curl -X POST \"$PK/change/payment/reverse/\" -u \"$AUTH\" \\\n  -d id=<id платежа> -d amount=500.00 -d partial=true -d token=$TOKEN","language":"bash","methods":["GET /info/settings/token/","GET /info/refunds/bypaymentid/","POST /change/payment/reverse/"]},{"id":"spisat-zablokirovannye-dengi","title":"Списать заблокированные деньги","summary":"Двухстадийная оплата: деньги заблокированы на карте, списываются после сборки заказа.","steps":["Чтобы списать всю сумму сразу, не дожидаясь автосписания: POST /change/payment/capture/ с id платежа и token.","Чтобы списать только часть (часть товара закончилась), используй POST /change/payment/reverse/ с нужной суммой — частичное списание выбирается автоматически по состоянию платежа.","Если банк ответил status = queued, запрос лишь принят — проверь итог через несколько минут: GET /info/payments/byid/."],"code":"curl -X POST \"$PK/change/payment/capture/\" -u \"$AUTH\" -d id=<id платежа> -d token=$TOKEN","language":"bash","methods":["GET /info/payments/byid/","POST /change/payment/reverse/","POST /change/payment/capture/"]},{"id":"sverit-platezhi-za-period","title":"Сверить платежи за период","summary":"Ежедневная сверка с учётной системой: какие платежи прошли, отменены или возвращены.","steps":["Запроси реестр: GET /info/payments/bydate/ с start и end (YYYY-MM-DD), status[] (например, success, canceled, refunded), payment_system_id[], from и limit — все параметры обязательны.","Листай через from, пока не получишь меньше limit записей.","Для счетов есть отдельная история: GET /info/invoice/list/ с status[] и датами, а данные одного счёта — GET /info/invoice/byid/."],"code":"curl -G -u \"$AUTH\" \"$PK/info/payments/bydate/\" \\\n  -d start=2026-10-01 -d end=2026-10-24 \\\n  -d 'status[]=success' -d 'status[]=refunded' \\\n  -d 'payment_system_id[]=<id платёжной системы>' \\\n  -d from=0 -d limit=100","language":"bash","methods":["GET /info/invoice/byid/","GET /info/invoice/list/","GET /info/payments/bydate/"]}],"baseUrls":[{"label":"Боевой","url":"https://<адрес вашего сервера PayKeeper>"}],"auth":{"type":"basic","description":"Каждый запрос отправляется с заголовком `Authorization: Basic` — логин и пароль от личного кабинета PayKeeper в base64. Запросы на чтение выполняются GET, изменения — POST с заголовком `Content-Type: application/x-www-form-urlencoded`. Каждый POST-запрос дополнительно должен содержать параметр `token` — токен безопасности, полученный методом `/info/settings/token/`.","example":""},"methods":[{"id":"GET /info/settings/token/","title":"Получить токен безопасности","httpMethod":"GET","path":"/info/settings/token/","description":"Токен нужен для всех POST-запросов (защита от CSRF). Меняется раз в 24 часа.","params":[],"requestExample":"","responseExample":"{\n    \"token\" : \"fd50e47596cff6c63c7ea0a633c0d2a8\"\n}","docsUrl":""},{"id":"POST /change/invoice/preview/","title":"Подготовка счёта","httpMethod":"POST","path":"/change/invoice/preview/","description":"Создаёт счёт по параметрам оплаты и возвращает его номер, полный URL для оплаты и HTML-предпросмотр письма. Созданный счёт получает служебный статус `created` и не попадает в историю счетов.","params":[{"name":"pay_amount","in":"body","type":"string","required":true,"description":"Сумма заказа к оплате"},{"name":"clientid","in":"body","type":"string","required":false,"description":"Идентификатор клиента"},{"name":"orderid","in":"body","type":"string","required":false,"description":"Номер заказа"},{"name":"service_name","in":"body","type":"string","required":false,"description":"Наименование услуги; можно передать JSON-объект с корзиной cart и доп. атрибутами"},{"name":"client_email","in":"body","type":"string","required":false,"description":"E-mail клиента"},{"name":"client_phone","in":"body","type":"string","required":false,"description":"Телефон клиента"},{"name":"expiry","in":"body","type":"string","required":false,"description":"Срок действия счёта: YYYY-MM-DD или YYYY-MM-DD H:i:s (не включительно)"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"{\n  \"invoice_id\" : \"20120229133742255\",\n  \"invoice_url\" : \"https://pay.example.com/bill/20120229133742255\",\n  \"invoice\"    : \"&lt;HTML&gt;&lt;HEAD&gt;&lt;META http-equiv=Content-Type ...\"\n}","docsUrl":""},{"id":"POST /change/invoice/send/","title":"Отправить счёт клиенту","httpMethod":"POST","path":"/change/invoice/send/","description":"Отправляет клиенту письмо, созданное методом preview.","params":[{"name":"id","in":"body","type":"string","required":true,"description":"Идентификатор созданного счёта"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"{\n  \"result\" : \"success\"\n}","docsUrl":""},{"id":"POST /change/invoice/revoke/","title":"Отменить счёт","httpMethod":"POST","path":"/change/invoice/revoke/","description":"","params":[{"name":"id","in":"body","type":"string","required":true,"description":"Идентификатор счёта"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /change/invoice/accept-cash/","title":"Отметить счёт оплаченным наличными","httpMethod":"POST","path":"/change/invoice/accept-cash/","description":"","params":[{"name":"invoice_id","in":"body","type":"string","required":true,"description":"Идентификатор счёта"},{"name":"client_phone","in":"body","type":"string","required":false,"description":"Телефон плательщика"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"GET /info/invoice/byid/","title":"Данные счёта","httpMethod":"GET","path":"/info/invoice/byid/","description":"Статусы счёта: `created`, `sent`, `paid`, `expired`.","params":[{"name":"id","in":"query","type":"string","required":true,"description":"Номер счёта"}],"requestExample":"","responseExample":"[\n      {\n      \"id\"                : \"20110115085347329\",\n      \"clientid\"          : \"Ivanov Ivan Ivanovich\",\n       \"orderid\"          : \"1337\",\n       \"paymentid\"        : \"7331\",\n       \"service_name\"     : \"Document delivery\",\n       \"client_email\"     : \"ivanov@ivan.ivanovich.com\",\n       \"client_phone\"     : \"+79254973590\",\n       \"created_datetime\" : \"2011-01-15 08:53:47\",\n       \"paid_datetime\"    : \"2011-01-16 14:12:00\",\n       \"expiry_datetime\"  : \"2011-01-19 00:00:00\",\n       \"pay_amount\"       : \"1205.98\",\n       \"status\"           : \"paid\",\n       \"user_id\"           : 9\n       }\n]","docsUrl":""},{"id":"GET /info/invoice/list/","title":"История счетов за период","httpMethod":"GET","path":"/info/invoice/list/","description":"Счета выводятся от новых к старым.","params":[{"name":"status[]","in":"query","type":"string","required":false,"description":"Статусы: sent, paid, expired"},{"name":"start_date","in":"query","type":"string","required":false,"description":"Счета, выставленные после даты YYYY-MM-DD"},{"name":"end_date","in":"query","type":"string","required":false,"description":"Счета, выставленные до даты YYYY-MM-DD"},{"name":"from","in":"query","type":"integer","required":false,"description":"Пропустить N результатов"},{"name":"limit","in":"query","type":"integer","required":false,"description":"Не более N результатов"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"GET /info/payments/bydate/","title":"Реестр платежей за период","httpMethod":"GET","path":"/info/payments/bydate/","description":"","params":[{"name":"start","in":"query","type":"string","required":true,"description":"Начало периода YYYY-MM-DD"},{"name":"end","in":"query","type":"string","required":true,"description":"Конец периода YYYY-MM-DD"},{"name":"payment_system_id[]","in":"query","type":"integer","required":true,"description":"Идентификатор платёжной системы"},{"name":"status[]","in":"query","type":"string","required":true,"description":"Статусы: pending, obtained, canceled, success, failed, stuck, refunded, refunding, partially_refunded"},{"name":"from","in":"query","type":"integer","required":true,"description":"Пропустить первые N значений"},{"name":"limit","in":"query","type":"integer","required":true,"description":"Количество возвращаемых значений"}],"requestExample":"/info/payments/bydate/?limit=100&from=0&start=2016-04-14&end=2017-03-14&status[]=success&status[]=canceled&status[]=failed&payment_system_id[]=9&payment_system_id[]=1","responseExample":"","docsUrl":""},{"id":"GET /info/payments/byid/","title":"Платёж по идентификатору","httpMethod":"GET","path":"/info/payments/byid/","description":"","params":[{"name":"id","in":"query","type":"string","required":true,"description":"Идентификатор платежа в PayKeeper"},{"name":"advanced","in":"query","type":"string","required":false,"description":"true — вернуть дополнительные опции платежа"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"GET /info/refunds/bypaymentid/","title":"Возвраты по платежу","httpMethod":"GET","path":"/info/refunds/bypaymentid/","description":"Информация по возвратам для платежа.","params":[],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /change/payment/reverse/","title":"Возврат платежа","httpMethod":"POST","path":"/change/payment/reverse/","description":"Полный возврат, отмена авторизации, частичный возврат или частичное списание — выбирается автоматически по состоянию платежа. Доступно пользователям с включённой функцией возврата.","params":[{"name":"id","in":"body","type":"string","required":true,"description":"Идентификатор платежа в PayKeeper"},{"name":"amount","in":"body","type":"string","required":true,"description":"Возвращаемая сумма, разделитель точка"},{"name":"partial","in":"body","type":"string","required":true,"description":"Частичный возврат: только true или false"},{"name":"refund_cart","in":"body","type":"string","required":false,"description":"JSON-строка товаров к возврату (для чека 54-ФЗ)"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"{\n    \"result\" : \"success\"\n}","docsUrl":""},{"id":"POST /change/payment/capture/","title":"Списание по авторизации","httpMethod":"POST","path":"/change/payment/capture/","description":"Списывает средства по ранее авторизованному платежу, не дожидаясь автосписания. Для частичного списания используют `/change/payment/reverse/`.","params":[{"name":"id","in":"body","type":"string","required":true,"description":"Номер платежа к списанию"},{"name":"token","in":"body","type":"string","required":true,"description":"Токен безопасности"}],"requestExample":"","responseExample":"","docsUrl":""}],"codeExamples":[{"title":"Проверка POST-оповещения на PHP","language":"php","code":"<?php\n  $secret_seed = \"verysecretseed\";\n  $id = $_POST['id'];\n  $sum = $_POST['sum'];\n  $clientid = $_POST['clientid'];\n  $orderid = $_POST['orderid'];\n  $key = $_POST['key'];\n\n  if ($key != md5 ($id.number_format($sum, 2, \".\", \"\")\n                   .$clientid.$orderid.$secret_seed))\n  {\n      echo \"Error! Hash mismatch\";\n      exit;\n  }\n\n  echo \"OK \".md5($id.$secret_seed);\n?>"}],"errors":[],"limits":"","gotchas":["Параметр `token` обязателен в каждом POST-запросе, хотя в описании методов его часто не упоминают; токен меняется раз в 24 часа.","В `partial` передавайте именно `true`/`false` — значения 1/0 система не воспринимает.","Возврат выполняется асинхронно: успешный ответ означает только постановку в очередь. Результат проверяют через `/info/refunds/bypaymentid/` или реестр платежей со статусом `refunding`, обычно через несколько минут.","При ответе `status = queued` на capture (Промсвязьбанк) запрос лишь принят банком; итог проверяют через несколько минут.","POST-оповещение о платеже содержит `id`, `sum`, `clientid`, `orderid`, `key` и доп. поля. `key` — md5 от конкатенации id, sum (2 знака после точки), clientid, orderid и секретного слова из личного кабинета.","На оповещение нужно ответить строкой `OK <md5(id + секретное слово)>`. Без корректного ответа PayKeeper повторяет запрос каждую минуту, по умолчанию до 50 раз, после чего платёж получает статус «Совершён без оповещения».","Оповещение может прийти несколько раз — обработчик должен защищаться от повторного зачисления по `id` платежа.","К ссылке счёта можно добавить `?pstype=sbp_default`, чтобы показать QR-код СБП, и `&returnFormat=json`, чтобы получить содержимое QR-кода."],"slug":"paykeeper","version":2,"updatedAt":"2026-10-24T17:05:34.874Z","sources":[{"title":"JSON API","url":"https://docs.paykeeper.ru/dokumentatsiya-json-api/","kind":"research","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"Безопасность и авторизация","url":"https://docs.paykeeper.ru/dokumentatsiya-json-api/token-bezopasnosti/","kind":"research","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"Счета","url":"https://docs.paykeeper.ru/dokumentatsiya-json-api/scheta/","kind":"research","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"Платежи","url":"https://docs.paykeeper.ru/dokumentatsiya-json-api/platezhi/","kind":"research","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"Приём POST-оповещений","url":"https://docs.paykeeper.ru/metody-integratsii/priyom-post-opoveshhenij/","kind":"research","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"Вставленный текст","url":"","kind":"import","addedAt":"2026-10-12T08:20:21.097Z"},{"title":"scenarios-paykeeper.md","url":"","kind":"import","addedAt":"2026-10-24T17:05:25.856Z"}],"logoUrl":null}