PayKeeper API

Отрасль: Платежи и финансы. Актуально на 2026-10-24.

Протокол для автоматического управления приёмом платежей через платёжную платформу PayKeeper: выставление счетов и получение ссылок на оплату, информация о платежах, возвраты, списание авторизованных средств, работа с чеками 54-ФЗ. Подходит для интеграции с биллингом, бухгалтерскими системами, мобильными приложениями и самописными CMS. О каждом принятом платеже PayKeeper может сообщать POST-оповещением на сайт предприятия.

Сценарии

Выставить счёт и получить ссылку на оплату

Ссылка на оплату для клиента — в письмо, мессенджер или на страницу заказа.

  1. Все запросы — к адресу твоего сервера PayKeeper с заголовком Authorization: Basic (логин и пароль от личного кабинета в base64). Чтение — GET, изменения — POST в формате application/x-www-form-urlencoded.
  2. Получи токен безопасности: GET /info/settings/token/. Он нужен в каждом POST-запросе и меняется раз в сутки.
  3. Создай счёт: POST /change/invoice/preview/ с pay_amount, orderid, clientid, client_email, service_name и token. Срок действия счёта задаёт expiry.
  4. В ответе invoice_id и invoice_url — ссылка для оплаты. Добавь к ней ?pstype=sbp_default, чтобы сразу показать QR-код СБП.
  5. Чтобы PayKeeper сам отправил письмо со счётом, вызови POST /change/invoice/send/ с id счёта.
PK=https://<твой-сервер>.server.paykeeper.ru
AUTH='<логин>:<пароль>'
TOKEN=$(curl -s -u "$AUTH" "$PK/info/settings/token/" | jq -r .token)

curl -X POST "$PK/change/invoice/preview/" -u "$AUTH" \
  -d pay_amount=1500.00 -d orderid=1042 \
  --data-urlencode 'clientid=Иван Петров' -d client_email=ivan@example.ru \
  --data-urlencode 'service_name=Заказ №1042' \
  -d token=$TOKEN

Принять оповещение об оплате

Узнать об оплате с сервера и отметить заказ оплаченным.

  1. Укажи в личном кабинете адрес оповещений и секретное слово. О каждом платеже PayKeeper пришлёт POST с id, sum, clientid, orderid и key.
  2. Проверь подпись: key должен совпасть с md5 от id + sum (ровно два знака после точки) + clientid + orderid + секретное слово.
  3. Защитись от повторов: оповещение может прийти несколько раз — не зачисляй платёж с тем же id дважды.
  4. Ответь строкой OK и md5 от id + секретное слово. Без правильного ответа PayKeeper повторяет оповещение каждую минуту (по умолчанию до 50 раз).
  5. Если нужно перепроверить платёж, запроси его: GET /info/payments/byid/ с id.
import hashlib

SECRET = "<секретное слово>"

def handle(form: dict) -> str:
    sum_str = f"{float(form['sum']):.2f}"
    expected = hashlib.md5(f"{form['id']}{sum_str}{form['clientid']}{form['orderid']}{SECRET}".encode()).hexdigest()
    if expected != form["key"]:
        return "Error! Hash mismatch"
    mark_paid_once(order_id=form["orderid"], payment_id=form["id"])  # идемпотентно по id платежа
    return "OK " + hashlib.md5(f"{form['id']}{SECRET}".encode()).hexdigest()

Вернуть деньги покупателю

Полный или частичный возврат по платежу, в том числе с чеком возврата по 54-ФЗ.

  1. Получи токен: GET /info/settings/token/.
  2. Отправь возврат: POST /change/payment/reverse/ с id платежа, amount (разделитель — точка) и partial — строго true или false, значения 1 и 0 не принимаются. Для чека возврата передай refund_cart — JSON-строку с товарами.
  3. Ответ success означает только постановку в очередь. Через несколько минут проверь результат: GET /info/refunds/bypaymentid/.
  4. Возвраты доступны пользователям, у которых включена эта функция.
curl -X POST "$PK/change/payment/reverse/" -u "$AUTH" \
  -d id=<id платежа> -d amount=500.00 -d partial=true -d token=$TOKEN

Списать заблокированные деньги

Двухстадийная оплата: деньги заблокированы на карте, списываются после сборки заказа.

  1. Чтобы списать всю сумму сразу, не дожидаясь автосписания: POST /change/payment/capture/ с id платежа и token.
  2. Чтобы списать только часть (часть товара закончилась), используй POST /change/payment/reverse/ с нужной суммой — частичное списание выбирается автоматически по состоянию платежа.
  3. Если банк ответил status = queued, запрос лишь принят — проверь итог через несколько минут: GET /info/payments/byid/.
curl -X POST "$PK/change/payment/capture/" -u "$AUTH" -d id=<id платежа> -d token=$TOKEN

Сверить платежи за период

Ежедневная сверка с учётной системой: какие платежи прошли, отменены или возвращены.

  1. Запроси реестр: GET /info/payments/bydate/ с start и end (YYYY-MM-DD), status[] (например, success, canceled, refunded), payment_system_id[], from и limit — все параметры обязательны.
  2. Листай через from, пока не получишь меньше limit записей.
  3. Для счетов есть отдельная история: GET /info/invoice/list/ с status[] и датами, а данные одного счёта — GET /info/invoice/byid/.
curl -G -u "$AUTH" "$PK/info/payments/bydate/" \
  -d start=2026-10-01 -d end=2026-10-24 \
  -d 'status[]=success' -d 'status[]=refunded' \
  -d 'payment_system_id[]=<id платёжной системы>' \
  -d from=0 -d limit=100

Базовые URL

Авторизация

Тип: Basic Auth

Каждый запрос отправляется с заголовком Authorization: Basic — логин и пароль от личного кабинета PayKeeper в base64. Запросы на чтение выполняются GET, изменения — POST с заголовком Content-Type: application/x-www-form-urlencoded. Каждый POST-запрос дополнительно должен содержать параметр token — токен безопасности, полученный методом /info/settings/token/.

Методы

GET /info/settings/token/ — Получить токен безопасности

Токен нужен для всех POST-запросов (защита от CSRF). Меняется раз в 24 часа.

Пример ответа:

{
    "token" : "fd50e47596cff6c63c7ea0a633c0d2a8"
}

POST /change/invoice/preview/ — Подготовка счёта

Создаёт счёт по параметрам оплаты и возвращает его номер, полный URL для оплаты и HTML-предпросмотр письма. Созданный счёт получает служебный статус created и не попадает в историю счетов.

Параметр Где Тип Обяз. Описание
pay_amount body string да Сумма заказа к оплате
clientid body string нет Идентификатор клиента
orderid body string нет Номер заказа
service_name body string нет Наименование услуги; можно передать JSON-объект с корзиной cart и доп. атрибутами
client_email body string нет E-mail клиента
client_phone body string нет Телефон клиента
expiry body string нет Срок действия счёта: YYYY-MM-DD или YYYY-MM-DD H:i:s (не включительно)
token body string да Токен безопасности

Пример ответа:

{
  "invoice_id" : "20120229133742255",
  "invoice_url" : "https://pay.example.com/bill/20120229133742255",
  "invoice"    : "&lt;HTML&gt;&lt;HEAD&gt;&lt;META http-equiv=Content-Type ..."
}

POST /change/invoice/send/ — Отправить счёт клиенту

Отправляет клиенту письмо, созданное методом preview.

Параметр Где Тип Обяз. Описание
id body string да Идентификатор созданного счёта
token body string да Токен безопасности

Пример ответа:

{
  "result" : "success"
}

POST /change/invoice/revoke/ — Отменить счёт

Параметр Где Тип Обяз. Описание
id body string да Идентификатор счёта
token body string да Токен безопасности

POST /change/invoice/accept-cash/ — Отметить счёт оплаченным наличными

Параметр Где Тип Обяз. Описание
invoice_id body string да Идентификатор счёта
client_phone body string нет Телефон плательщика
token body string да Токен безопасности

GET /info/invoice/byid/ — Данные счёта

Статусы счёта: created, sent, paid, expired.

Параметр Где Тип Обяз. Описание
id query string да Номер счёта

Пример ответа:

[
      {
      "id"                : "20110115085347329",
      "clientid"          : "Ivanov Ivan Ivanovich",
       "orderid"          : "1337",
       "paymentid"        : "7331",
       "service_name"     : "Document delivery",
       "client_email"     : "ivanov@ivan.ivanovich.com",
       "client_phone"     : "+79254973590",
       "created_datetime" : "2011-01-15 08:53:47",
       "paid_datetime"    : "2011-01-16 14:12:00",
       "expiry_datetime"  : "2011-01-19 00:00:00",
       "pay_amount"       : "1205.98",
       "status"           : "paid",
       "user_id"           : 9
       }
]

GET /info/invoice/list/ — История счетов за период

Счета выводятся от новых к старым.

Параметр Где Тип Обяз. Описание
status[] query string нет Статусы: sent, paid, expired
start_date query string нет Счета, выставленные после даты YYYY-MM-DD
end_date query string нет Счета, выставленные до даты YYYY-MM-DD
from query integer нет Пропустить N результатов
limit query integer нет Не более N результатов

GET /info/payments/bydate/ — Реестр платежей за период

Параметр Где Тип Обяз. Описание
start query string да Начало периода YYYY-MM-DD
end query string да Конец периода YYYY-MM-DD
payment_system_id[] query integer да Идентификатор платёжной системы
status[] query string да Статусы: pending, obtained, canceled, success, failed, stuck, refunded, refunding, partially_refunded
from query integer да Пропустить первые N значений
limit query integer да Количество возвращаемых значений

Пример запроса:

/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

GET /info/payments/byid/ — Платёж по идентификатору

Параметр Где Тип Обяз. Описание
id query string да Идентификатор платежа в PayKeeper
advanced query string нет true — вернуть дополнительные опции платежа

GET /info/refunds/bypaymentid/ — Возвраты по платежу

Информация по возвратам для платежа.

POST /change/payment/reverse/ — Возврат платежа

Полный возврат, отмена авторизации, частичный возврат или частичное списание — выбирается автоматически по состоянию платежа. Доступно пользователям с включённой функцией возврата.

Параметр Где Тип Обяз. Описание
id body string да Идентификатор платежа в PayKeeper
amount body string да Возвращаемая сумма, разделитель точка
partial body string да Частичный возврат: только true или false
refund_cart body string нет JSON-строка товаров к возврату (для чека 54-ФЗ)
token body string да Токен безопасности

Пример ответа:

{
    "result" : "success"
}

POST /change/payment/capture/ — Списание по авторизации

Списывает средства по ранее авторизованному платежу, не дожидаясь автосписания. Для частичного списания используют /change/payment/reverse/.

Параметр Где Тип Обяз. Описание
id body string да Номер платежа к списанию
token body string да Токен безопасности

Нюансы

Примеры кода

Проверка POST-оповещения на PHP

<?php
  $secret_seed = "verysecretseed";
  $id = $_POST['id'];
  $sum = $_POST['sum'];
  $clientid = $_POST['clientid'];
  $orderid = $_POST['orderid'];
  $key = $_POST['key'];

  if ($key != md5 ($id.number_format($sum, 2, ".", "")
                   .$clientid.$orderid.$secret_seed))
  {
      echo "Error! Hash mismatch";
      exit;
  }

  echo "OK ".md5($id.$secret_seed);
?>

Источники


Если этого недостаточно — официальная документация: https://docs.paykeeper.ru/dokumentatsiya-json-api/ JSON: https://mcp-everything.ru/api/integrations/paykeeper. MCP: https://mcp-everything.ru/mcp