БэкендPython

ЮKassa API на Python: создаём тестовый платёж и принимаем webhook

Создаём тестовый платёж ЮKassa на Python, получаем confirmation URL, принимаем webhook в FastAPI и безопасно сверяем итоговый статус оплаты.

Кодик

Автор

6 мин чтения

ЮKassa API можно освоить на одном небольшом проекте, если сразу видеть вход, действие и результат. Тестовый магазин позволяет пройти полный цикл платежа без реального списания: создание, переход по ссылке, уведомление и проверка статуса. Ниже вы соберёте работающий пример и проверите обычный и граничный сценарии.

Опасно считать оплату успешной только после возврата браузера или доверять любому JSON, который пришёл на webhook. Поэтому отделим настройку, входные данные, основное действие и проверку. В этой статье вы соберёте FastAPI-приложение, которое создаёт платёж с idempotence key и принимает событие payment.succeeded. Проверка: два повтора одной операции не создают дубликат, confirmation URL открывается, а webhook сверяет платёж через API.

1Соберите минимум

передать сумму, валюту и confirmation. Не расширяйте проект до первого успешного запуска.

2Увидьте данные

повтор не создаёт второй платёж. Проверяйте значение, а не отсутствие ошибки.

3Измените правило

После успеха добавьте локальную таблицу заказов и защиту от повторной выдачи. Так копирование станет практикой.

Как устроен учебный проект ЮKassa API

ЮKassa API разделяет подготовку, основное действие, проверку ответа и сохранение результата. Держите ввод, логику и отображение раздельно: тогда каждый этап можно проверить отдельно.

ЭтапДействиеПроверяемый результат
Созданиепередать сумму, валюту и confirmationAPI возвращает payment id и URL
Идемпотентностьиспользовать UUID для операцииповтор не создаёт второй платёж
Webhookпринять событие и извлечь object.idendpoint быстро отвечает 200
Проверказапросить платёж по id через SDKзаказ меняется только при succeeded

Контрольные точки: создание, идемпотентность, webhook и проверка. Следующий шаг начинается после совпадения с ожидаемым результатом.

Путь данных в проекте ЮKassa API
От входных данных до видимого результата. Сначала проверяется вход, затем действие и только потом интерфейс.

Зафиксируйте первый успех Работайте с тестовым магазином и суммой. Не используйте боевой secret key в учебном проекте. Сохраните команду запуска и ожидаемый вывод.

Собираем рабочий пример шаг за шагом

Материал сверялся с официальной документацией сервиса 21 октября 2026 года. Установите yookassa, fastapi и uvicorn. SHOP_ID и SECRET_KEY задайте через окружение. Проверьте текущую папку через pwd или Get-Location. Вставьте пример целиком, выполните один раз, затем разбирайте по частям.

import os
import uuid
from fastapi import FastAPI, Request
from yookassa import Configuration, Payment

Configuration.account_id = os.environ["YOOKASSA_SHOP_ID"]
Configuration.secret_key = os.environ["YOOKASSA_SECRET_KEY"]
app = FastAPI()

@app.post("/payments")
def create_payment():
    payment = Payment.create({
        "amount": {"value": "100.00", "currency": "RUB"},
        "confirmation": {"type": "redirect", "return_url": "https://example.test/thanks"},
        "capture": True,
        "description": "Учебный заказ CODIK-101",
        "metadata": {"order_id": "CODIK-101"},
    }, str(uuid.uuid4()))
    return {"id": payment.id, "url": payment.confirmation.confirmation_url}

@app.post("/webhook/yookassa")
async def webhook(request: Request):
    event = await request.json()
    payment_id = event.get("object", {}).get("id")
    if event.get("event") == "payment.succeeded" and payment_id:
        payment = Payment.find_one(payment_id)
        if payment.status == "succeeded":
            print("paid order:", payment.metadata.get("order_id"))
    return {"ok": True}
Что должно произойти после запуска
  • POST /payments возвращает id и ссылку confirmation_url для тестовой оплаты.
  • После уведомления приложение повторно получает платёж и видит статус succeeded.
  • Повторный запуск даёт тот же предсказуемый результат.
  • Пустой ввод получает понятное сообщение вместо падения.

Код держит подготовку отдельно от внешнего действия, поэтому ошибку можно найти на конкретном шаге. Найдите в примере вход, проверку и место формирования результата.

Хрупкий и проверяемый вариант ЮKassa API
Что отличает устойчивый проект от случайного запуска. Явные границы делают ошибку локальной и понятной.

Что происходит внутри и почему это работает

Ключ идемпотентности связывает повтор запроса с одной операцией. Redirect нужен пользователю, webhook сообщает серверу событие, а финальная проверка API подтверждает состояние. Логику держите отдельно от вывода: функция получает аргумент и возвращает значение, а интерфейс показывает его. Секреты и персональные данные не должны попадать в репозиторий, журнал или публичный скриншот.

ЧастьЗа что отвечаетЧто проверить
Payment.createсоздаёт операцию с суммой и описаниемключ идемпотентности уникален
Confirmationпереводит пользователя на оплатуreturn_url не считается доказательством
Webhookсообщает об изменениистатус сверяется через API

Webhook может прийти повторно или не по порядку. Храните payment id и текущий статус заказа, делайте обновление идемпотентным и не выдавайте товар повторно. Не прячьте поток в одном обработчике: сохраните вход, проверьте его, вызовите операцию и только затем обновите интерфейс.

Проверьте границу Отправьте одно и то же тестовое событие дважды. Заказ должен перейти в paid только один раз. Меняйте одно условие за прогон, чтобы видеть причину.

Проверяем проект и добавляем свою функцию

Добавьте таблицу заказов со статусами pending и paid, затем свяжите metadata.order_id с конкретной записью. До правки запишите ожидаемое поведение одним предложением. После граничного теста повторите обычный сценарий.

Проверка своими руками
  1. Сохраните ожидаемый результат: два повтора одной операции не создают дубликат, confirmation URL открывается, а webhook сверяет платёж через API.
  2. Измените правило: добавьте локальную таблицу заказов и защиту от повторной выдачи. Сначала предскажите итог.
  3. Передайте граничное значение и убедитесь, что приложение не падает.
  4. Верните корректные данные и объясните роли трёх основных частей.
Готово, если выполняются все пункты
  • API возвращает payment id и URL
  • повтор не создаёт второй платёж
  • endpoint быстро отвечает 200
  • заказ меняется только при succeeded

Полезное улучшение сохраняет исходный сценарий и добавляет одну новую проверяемую возможность. Полезная правка проходит от нового ввода до видимого результата.

Четыре контрольные точки ЮKassa API
Четыре проверки перед следующим шагом. Каждый следующий этап начинается после наблюдаемого результата.

Что запомнить и куда двигаться дальше

Перед боевым запуском настройте HTTPS, журнал событий без секретов, возвраты и сверку суммы, валюты и order_id. Для закрепления откройте в первом API на FastAPI, в REST API на Express и в проверке JSON через Pydantic.

Как изучить тему в Кодике

Сначала разберите входные данные и один успешный вызов, затем изучайте дополнительные параметры. Сначала восстановите главную функцию и проверьте её на трёх значениях.

ШагЧто разобратьМини-проверка
1. ОсноваHTTP, JSON, UUID и переменные окружения PythonОбъясните вход и выход функции.
2. ИнструментSDK ЮKassa, Payment и confirmationПовторите команду по памяти.
3. ПроектFastAPI webhook и статусы заказаПроверьте два сценария.
4. РефакторингИдемпотентность, хранение и сверку платежейРазделите ввод, логику и вывод.

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

Доверие return_url

Пользователь может не вернуться или открыть URL вручную. Смотрите серверный статус.

Новый UUID при ретрае

Повтор создаёт вторую операцию. Сохраняйте ключ вместе с заказом.

Webhook выдаёт товар сразу

Сначала подтвердите payment id и статус через API.

Секрет в логе

Ключ магазина нельзя печатать или возвращать клиенту.

Сверяйтесь с первичной документацией. Команды и ограничения примера проверены по официальному источнику 1. Если версия инструмента изменилась, официальный источник важнее старого скриншота.

Что получится в итоге

Готовый результат проекта: ЮKassa API на Python: создаём тестовый платёж и принимаем webhook
Финальный экран показывает результат, состояние запроса и понятное сообщение об ошибке без раскрытия секретов.

Короткие ответы
Зачем нужен Idempotence-Key?

Чтобы безопасный повтор одного запроса не создавал новую платёжную операцию.

Почему одного webhook JSON недостаточно?

Сервер должен связать событие с заказом и подтвердить итоговый статус.

Что проверять первым, если ЮKassa API не запускается?

Версию среды, текущую папку, команду запуска и первую строку ошибки.

Как понять, что проект ЮKassa API работает?

Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай.

Можно ли начать с готового кода?

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

Сделайте один осознанный шаг дальше

Выберите одно улучшение и проведите его от ввода до результата.

Если не хватает основы, перейдите курс Python, затем восстановите ключевую функцию без подсказки.