Skip to content

Интеграция на Python ​

Готовый, протестированный набор для серверной интеграции (Python 3.11+, только стандартная библиотека). Он реализует стабильный Idempotency-Key, безопасные повторы, проверку подписи вебхука, выдачу «ровно один раз», срок заказа и правило позднего платежа.

Скачать набор: eleven-pay-merchant-kit.zip (каталоги python/, node/, test-vectors/, curl/). Порядок — тот же, что в Счетах Cashier.

Пилотный режим

Реального приёма платежей через счета Cashier пока нет. Тесты и демонстрации набора работают на имитациях и ничего не отправляют в сеть. Базовый адрес API вам выдают при подключении.

Состав набора ​

ФайлНазначение
eleven_pay_client.pyHTTP-клиент: создание/чтение счёта, опрос; ключ идемпотентности обязателен
order_store.pyгде решается «оплачено один раз»: заказы, ключи, события, очередь разбора
checkout_service.pyадаптер сайта: настройки из окружения и CheckoutService
webhook_verify.py, webhook_receiver.pyпроверка подписи и приём вебхука
offline_demo.pyдемонстрация на имитациях, без сети и учётных данных
test_*.pyтесты (python -m unittest discover -s . -p "test_*.py")

order_store.py — набросок на SQLite: в продакшене это таблицы вашей базы, а важны сами механизмы (условное обновление WHERE status = 'awaiting_payment', запись event id, очередь выдачи).

Настройка (переменные окружения) ​

ПеременнаяОбязательнаЗначение
ELEVENPAY_BASE_URLдабазовый адрес API (https); значения по умолчанию нет
ELEVENPAY_API_KEYдаключ ep_live_… из секрет-хранилища сервера
ELEVENPAY_WEBHOOK_SECRETдасекрет подписи вебхука
ELEVENPAY_ORDER_TTL_SECONDSнет (1800)срок заказа на вашей стороне, 60–604800
ELEVENPAY_POLL_DEADLINE_SECONDSнет (600)предел ожидания опроса
ELEVENPAY_LATE_PAYMENT_POLICYнет (review)review — на ручной разбор; fulfil — выдать

Использование ​

python
import os

from checkout_service import OrderNotPayable, StartUncertain, build_service
from eleven_pay_client import ApiError
from order_store import OrderStore

service = build_service(os.environ, store=OrderStore("orders.sqlite3"))

# 1. Заказ создаёт ВАШ сайт: сумма из вашего каталога, срок — ваш.
service.place_order("order_1001", 1500)

# 2. Попросить Eleven Pay отправить счёт плательщику (телефон очищается только от оформления).
try:
    started = service.start_payment("order_1001", "+7 700 123 45 67")
    print(started.reference, started.payer_step, started.replayed)
except StartUncertain:
    # Ответа нет: счёт мог быть создан. Повторите ПОЗЖЕ тем же вызовом (тот же ключ).
    pass
except OrderNotPayable as error:
    print(error.reason)  # unknown_order | paid | expired
except ApiError as error:
    print(error.status, error.code)  # см. таблицу ошибок

# 3. Прогресс страницы (опционально): один запрос или ограниченный опрос.
result = service.refresh("order_1001")  # RefreshResult(outcome, payer_step)
result = service.await_payment("order_1001")  # "awaiting" по истечении предела = ещё не оплачено

# 4. Ваш срок: истёкшие неоплаченные заказы (ничего не отменяет в Eleven Pay).
expired = service.expire_stale()

payer_step — стабильный ключ для вашего интерфейса: sending_request, approve_in_kaspi, paid, not_sent, unconfirmed. Показывайте «подтвердите в приложении» только при approve_in_kaspi.

Приём вебхука ​

Вызывайте handle_webhook с сырыми байтами тела и заголовками. Верните его статус как HTTP-ответ: 401 — подпись неверна, 200 — принято (в том числе дубликат, поздний платёж, разбор), 500 — наша ошибка (Eleven Pay повторит).

python
# внутри вашего обработчика POST /webhooks/eleven-pay (любой фреймворк)
status, outcome = service.handle_webhook(dict(request_headers), raw_body_bytes)
return status  # тело ответа не требуется

Исходы: fulfilled, duplicate, already_paid, late_payment, needs_review, ignored_event_type. Выдачу выполняет ваш отдельный процесс по очереди fulfilment_outbox (запись делается в той же транзакции, что и смена статуса заказа).

Что проверять перед запуском ​

  • python -m unittest discover -s . -p "test_*.py" — зелёный; python offline_demo.py — проходит.
  • Тест на ваших данных: двойной клик, дубликат вебхука, поддельная подпись, просроченный заказ, поздний платёж (Чек-лист, Локальное тестирование).
  • Ваша база заменила SQLite-набросок, а ключ идемпотентности хранится вместе с заказом.