2026-03-12 06:54:38 +00:00
2026-03-12 06:54:38 +00:00
2026-03-12 06:54:38 +00:00
2026-03-12 06:54:38 +00:00
2026-03-12 06:54:38 +00:00
2026-03-12 06:54:38 +00:00

YooKassa Mock v2

Легковесный mock-сервер для эмуляции базового сценария работы YooKassa.

Что умеет

  • создавать платеж
  • возвращать confirmation_url
  • показывать checkout-страницу
  • завершать платеж как:
    • succeeded
    • canceled
  • отправлять webhook
  • повторять webhook при ошибке
  • поддерживать Idempotence-Key
  • отдавать статус платежа по payment_id

Файлы

  • main.py — FastAPI приложение
  • requirements.txt — зависимости
  • Dockerfile — образ
  • docker-compose.yml — запуск контейнера
  • .env — переменные окружения

Запуск

1. Сборка и старт

docker compose up -d --build

2. Проверка здоровья

curl -s http://127.0.0.1:${YMK_PUBLIC_PORT}/health

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

{"status":"ok","payments_total":0,"idempotence_keys_total":0}

Переменные окружения

Пример .env:

YMK_PUBLIC_PORT=8083

WEBHOOK_URL=http://192.168.149.101:8000/api/tickets/webhook/yookassa

MOCK_HOST=192.168.149.101
MOCK_PORT=8083

MOCK_REQUIRE_AUTH=0
MOCK_SHOP_ID=test_shop
MOCK_SECRET_KEY=test_secret

WEBHOOK_RETRY_COUNT=3
WEBHOOK_RETRY_DELAY_SEC=1
WEBHOOK_DELAY_SEC=0

Описание

YMK_PUBLIC_PORT

Внешний порт хоста, на который публикуется контейнер.

WEBHOOK_URL

URL для отправки webhook после смены статуса платежа.

MOCK_HOST

Хост, который будет подставляться в confirmation_url.

MOCK_PORT

Порт, который будет подставляться в confirmation_url.

MOCK_REQUIRE_AUTH

  • 0 — Basic Auth не обязателен
  • 1 — Basic Auth обязателен

MOCK_SHOP_ID

Логин для Basic Auth, если auth включен.

MOCK_SECRET_KEY

Пароль для Basic Auth, если auth включен.

WEBHOOK_RETRY_COUNT

Количество попыток отправки webhook.

WEBHOOK_RETRY_DELAY_SEC

Пауза между retry webhook.

WEBHOOK_DELAY_SEC

Искусственная задержка перед первой отправкой webhook.


API

1. POST /v3/payments

Создание платежа.

Обязательное

  • заголовок Idempotence-Key
  • confirmation.return_url
  • amount.value

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

curl -s -X POST http://127.0.0.1:8083/v3/payments \
  -H 'Content-Type: application/json' \
  -H 'Idempotence-Key: test-001' \
  -d '{
    "amount": {
      "value": "100.00",
      "currency": "RUB"
    },
    "confirmation": {
      "type": "redirect",
      "return_url": "http://192.168.149.101:3000/payment/return"
    },
    "capture": true,
    "description": "Заказ №1"
  }'

Пример успешного ответа

{
  "id": "fdb332f8-bb1d-4def-bc1d-d5b00a7e287a",
  "status": "pending",
  "paid": false,
  "amount": {
    "value": "100.00",
    "currency": "RUB"
  },
  "confirmation": {
    "type": "redirect",
    "confirmation_url": "http://192.168.149.101:8083/checkout?payment_id=fdb332f8-bb1d-4def-bc1d-d5b00a7e287a"
  },
  "created_at": "2026-03-12T06:35:47.512Z",
  "description": "Заказ №1",
  "metadata": {},
  "capture": true,
  "recipient": {
    "account_id": "test_shop",
    "gateway_id": "100700"
  },
  "refundable": false,
  "test": true
}

Идемпотентность

Если повторно вызвать POST /v3/payments с тем же Idempotence-Key, мок вернет тот же платеж, а не создаст новый.


2. GET /v3/payments/{payment_id}

Получение статуса платежа.

Пример

curl -s http://127.0.0.1:8083/v3/payments/fdb332f8-bb1d-4def-bc1d-d5b00a7e287a

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

{
  "id": "fdb332f8-bb1d-4def-bc1d-d5b00a7e287a",
  "status": "succeeded",
  "paid": true,
  "amount": {
    "value": "100.00",
    "currency": "RUB"
  },
  "confirmation": {
    "type": "redirect",
    "confirmation_url": "http://192.168.149.101:8083/checkout?payment_id=fdb332f8-bb1d-4def-bc1d-d5b00a7e287a"
  },
  "created_at": "2026-03-12T06:35:47.512Z",
  "description": "Заказ №1",
  "metadata": {},
  "capture": true,
  "recipient": {
    "account_id": "test_shop",
    "gateway_id": "100700"
  },
  "refundable": true,
  "test": true
}

3. GET /checkout?payment_id=<id>

HTML-страница оплаты.

Что показывает:

  • payment_id
  • статус
  • сценарий
  • описание
  • сумму

На странице есть три кнопки:

  • Оплатить успешно
  • Отменить оплату
  • Ошибка оплаты

4. POST /process/{payment_id}

Меняет статус платежа, отправляет webhook, делает redirect на return_url.

Входные варианты

Через form-data / x-www-form-urlencoded поле action:

  • success
  • cancel
  • fail

Пример success

curl -i -X POST http://127.0.0.1:8083/process/fdb332f8-bb1d-4def-bc1d-d5b00a7e287a \
  -d 'action=success'

Пример cancel

curl -i -X POST http://127.0.0.1:8083/process/294ec8cd-c1fb-44b4-91cc-04d669343390 \
  -d 'action=cancel'

Поведение

  • success → статус succeeded, paid=true
  • cancel → статус canceled, paid=false
  • fail → статус canceled, paid=false

После этого сервис делает:

  • webhook на WEBHOOK_URL
  • 303 See Other на return_url

5. GET /health

Проверка состояния сервиса.

Пример

curl -s http://127.0.0.1:8083/health

Ответ

{
  "status": "ok",
  "payments_total": 2,
  "idempotence_keys_total": 2
}

Webhook

После success:

{
  "event": "payment.succeeded",
  "type": "notification",
  "object": {
    "id": "payment_id",
    "status": "succeeded",
    "paid": true,
    "amount": {
      "value": "100.00",
      "currency": "RUB"
    },
    "description": "Заказ №1",
    "metadata": {}
  }
}

После cancel / fail:

{
  "event": "payment.canceled",
  "type": "notification",
  "object": {
    "id": "payment_id",
    "status": "canceled",
    "paid": false,
    "amount": {
      "value": "250.00",
      "currency": "RUB"
    },
    "description": "Заказ №2",
    "metadata": {
      "mock_scenario": "cancel"
    }
  }
}

Retry webhook

Если endpoint webhook отвечает ошибкой или недоступен:

  • мок делает повторные попытки
  • количество попыток задается WEBHOOK_RETRY_COUNT
  • задержка между попытками задается WEBHOOK_RETRY_DELAY_SEC

Логи смотреть так:

docker logs --tail 100 yookassa-mock

Сценарии через metadata

При создании платежа можно задать сценарий по умолчанию:

"metadata": {
  "mock_scenario": "cancel"
}

Допустимые значения:

  • success
  • cancel
  • fail

Если в POST /process/{payment_id} не передать action, будет использован mock_scenario.


Basic Auth

Если включить:

MOCK_REQUIRE_AUTH=1

Тогда endpoints /v3/payments и /v3/payments/{payment_id} будут требовать Basic Auth.

Логин/пароль берутся из:

  • MOCK_SHOP_ID
  • MOCK_SECRET_KEY

Ограничения

Это мок, не полная копия YooKassa.

Сейчас нет:

  • persistent storage
  • списка платежей
  • ручного cancel endpoint в стиле реального API
  • полной схемы YooKassa
  • реальной проверки секретов YooKassa
  • capture/authorize flow с отдельным подтверждением списания
  • рефандов

Текущее состояние проверки

Проверено вручную:

  • создание платежа — OK
  • confirmation_url — OK
  • GET /v3/payments/{id} — OK
  • идемпотентность — OK
  • pending -> succeeded — OK
  • pending -> canceled — OK
  • redirect на return_url — OK
  • retry webhook — OK

Проблема сейчас только одна:
WEBHOOK_URL отвечает 404 Not Found, значит endpoint на основном backend отсутствует или указан неверно.

Description
No description provided
Readme 33 KiB
Languages
Python 97.6%
Dockerfile 2.4%