Skip to content

wild-paws/payment_checker

Repository files navigation

Payment Checker

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

Стек

  • Python 3.10+
  • Patchright (Playwright с обходом антибот-защиты, только Chromium)
  • pytest + pytest-retry
  • Allure

Установка с нуля на Windows

1. Установить Python

Скачать с https://python.org и установить. При установке отметить галку Add Python to PATH.

Проверить:

python --version

2. Клонировать репозиторий

git clone https://github.com/твой_юзер/payment_checker.git
cd payment_checker

3. Создать виртуальное окружение

python -m venv .venv
.venv\Scripts\activate

4. Установить зависимости

pip install -r requirements.txt

5. Установить Chromium

patchright install chromium

6. Создать credentials.json

copy credentials.example.json credentials.json

Открыть credentials.json и заполнить:

{
  "settings": {
    "headless": false,
    "slow_mo": 0,
    "known_wallets": []
  },
  "default": {
    "login": "твой_логин",
    "password": "твой_пароль"
  }
}

settings — настройки браузера и кошельки:

  • headless: false — браузер открывается с окном, удобно для наблюдения. true — без окна.
  • slow_mo: 0 — без задержек. Поставь 500-1000 если хочешь видеть каждый шаг.
  • known_wallets — список известных адресов кошельков, используется в паттерне 3.

"default" — креды для всех сайтов по умолчанию.

Если на каком-то сайте другие креды — добавь отдельную запись с доменом:

{
  "settings": { ... },
  "default": { "login": "...", "password": "..." },
  "other-site.com": { "login": "другой_логин", "password": "другой_пароль" }
}

Файл добавлен в .gitignore и не коммитится.

7. Установить Allure

# Установить Scoop если ещё нет
irm get.scoop.sh | iex

# Установить Allure
scoop install allure

Запуск тестов

# Все тесты
pytest --alluredir=reports/allure -v

# Один конкретный тест
pytest tests/test_site_365sms.py --alluredir=reports/allure -v

# Открыть отчёт после прогона
allure serve reports/allure

В отчёте для каждого теста:

  • Пошаговый лог с результатом каждого действия
  • Адрес крипто-кошелька в аттачменте
  • При падении — видео для разбора причины

История прогонов накапливается — allure показывает результаты за последние 30 дней. Видео очищаются перед каждым запуском — они уже сохранены в аттачментах allure.

При нестабильных падениях (капча, медленная загрузка) тест автоматически перезапускается до 2 раз.


Браузерный профиль и капча

Тесты используют persistent browser profile — фиксированный профиль в папке browser_profile/, который живёт между запусками. В отличие от чистого инкогнито, профиль накапливает историю, куки и кеш. Сайты видят "живой" профиль и не режут соединение как у бота.

При первом запуске на свежем профиле некоторые сайты с агрессивной защитой могут выдать капчу. Это нормально — тест перезапустится автоматически (до 2 раз), профиль постепенно насыщается.

Если тест упал после всех попыток — запусти его повторно вручную:

pytest --lf --alluredir=reports/allure -v

Папка browser_profile/ добавлена в .gitignore и не коммитится.


Маркер clear_session

Чтобы тест не заходил уже залогиненным из-за сохранённой сессии в профиле, добавь на класс теста маркер clear_session. Маркер всегда принимает BASE_URL — он импортируется из __init__.py пакета сайта.

Ставь по умолчанию без strategy= — чистятся только куки, этого достаточно в большинстве случаев. Добавляй strategy="full" только если тест всё равно заходит залогиненным после обычной очистки:

# Дефолт — чистит только куки домена
@pytest.mark.clear_session(BASE_URL)

# Если сайт помнит сессию даже после очистки куков — чистим всё
@pytest.mark.clear_session(BASE_URL, strategy="full")

Файл кошельков wallets_report.json

При падении теста адрес кошелька автоматически сохраняется в файл wallets_report.json в корне проекта. При успехе — сайт удаляется из файла. Файл живёт между запусками и накапливает данные.

Формат:

{
  "365sms.com": ["TXyz123abc"],
  "starzspins.com": ["TXyz456def", "TXyz789ghi"]
}

Несколько адресов на один сайт — нормально: кошельки могут меняться между прогонами, все уникальные адреса накапливаются до тех пор пока тест не пройдёт.

Файл передаётся в другой отдел для сверки с известными адресами. После сверки нужные адреса добавляются в known_wallets в credentials.json.

Файл добавлен в .gitignore и не коммитится.


Как читать отчёт при падении

Когда тест упал, Allure сохраняет видео с записью экрана.

Открой упавший тест в отчёте → вкладка Attachments → файл video. Видно что происходило на экране весь тест — где завис, что не кликнулось, когда страница не загрузилась.

Примечание: трейс Playwright отключён из-за несовместимости с Patchright — CDP команды трейсинга детектируются антибот-защитой сайтов. Для разбора падений используй только видео.


Как добавить новый сайт

Добавление нового сайта делается через Codex — ИИ-агент пишет код в отдельной ветке и создаёт Pull Request. Ты проверяешь локально, при необходимости просишь Codex починить, и только потом мержишь в main.

Шаг 1. Определить паттерн проверки

В проекте три паттерна — выбери подходящий до написания промта:

Паттерн 1 — по логотипу. Тест доходит до платёжной формы и проверяет наличие логотипа провайдера. Используй если провайдер визуально присутствует на странице оплаты.

Паттерн 2 — по API. Тест перехватывает API ответ в момент открытия платёжной формы и ищет провайдера в JSON. Используй если в DevTools видишь запрос к процессингу с JSON списком провайдеров.

Паттерн 3 — по адресу кошелька. Тест доходит до адреса кошелька и сверяет его со списком из credentials.json. Используй если определить провайдера невозможно, но кошелёк нужно проверить.

Шаг 2. Подготовить аккаунт

Зарегистрируй аккаунт на сайте вручную.

Если у сайта свои отдельные креды (не совпадают с default) — добавь их в credentials.json:

{
  "settings": { ... },
  "default": { "login": "...", "password": "..." },
  "new-site.com": { "login": "логин_для_этого_сайта", "password": "пароль_для_этого_сайта" }
}

Домен в ключе должен совпадать с доменом из BASE_URL нового сайта — без схемы и без www.

Шаг 3. Пройти путь руками

Войди в аккаунт и пройди весь путь до адреса крипто-кошелька:

  1. Открой DevTools (F12) → вкладка Network
  2. Авторизуйся
  3. Перейди в раздел пополнения / депозита
  4. Выбери криптовалюту (обычно USDT TRC-20)
  5. Дойди до экрана с адресом кошелька

По ходу пути собери:

  • URL каждой страницы и что происходит при переходе (ререндер SPA или полная перезагрузка с новым URL)
  • Есть ли возможность открыть нужные страницы напрямую по URL — это всегда лучше чем кликать кнопки
  • XPath или CSS селекторы всех элементов с которыми взаимодействуешь (кнопки, поля, дропдауны)
  • Паттерн 2: путь API запроса в Network в момент открытия платёжной формы и структуру JSON ответа
  • Паттерн 3: сам адрес кошелька — добавь его в known_wallets в credentials.json
  • Любые нюансы: модальные окна, iframe, редиректы

Шаг 4. Написать промт для Codex

Хороший промт описывает путь пошагово — каждый шаг это клик или ввод, каждый переход — что происходит со страницей (ререндер DOM или новый URL). Такое описание Codex переводит в page objects один к одному.

Примеры промтов для каждого паттерна:


Паттерн 1 — по логотипу:

Добавь новый сайт example-casino.com в проект payment_checker. Создай ветку site/example-casino и открой PR в main. Используй паттерн 1 — проверка по логотипу провайдера.

1) Страница логина:

Перехожу по ссылке: https://example-casino.com/ Жму кнопку входа: //a[@href='/login']

Открывается страница с формой входа, URL меняется на https://example-casino.com/login

Ввожу логин в поле: //input[@id='email'] Ввожу пароль в поле: //input[@name='password'] Жму кнопку подтверждения: //button[@data-test='submit']

Происходит ререндер DOM дерева, URL возвращается на https://example-casino.com/

2) Главная страница:

Жму кнопку депозита в шапке: //a[text()='Deposit']

Происходит ререндер DOM, URL меняется на https://example-casino.com/deposit

3) Страница депозита:

Жму кнопку Crypto: //button[text()='Crypto'] Жму кнопку USDT TRC-20: //button[text()='USDT TRC20'] Жму кнопку суммы 100: //button[text()='100']

Происходит полная перезагрузка страницы, URL меняется на домен провайдера

4) Страница с формой платежа:

Нахожу логотип провайдера на форме: //a[@href='https://provider.com'] Сохраняю адрес кошелька: //div[@class='wallet']/p — атрибут title

Смотри AGENTS.md для понимания архитектуры и паттернов.


Паттерн 2 — по API:

Добавь новый сайт example-casino.com в проект payment_checker. Создай ветку site/example-casino и открой PR в main. Используй паттерн 2 — проверка по API ответу.

1) Страница логина (модалка открывается сразу через URL):

Перехожу по ссылке: https://example-casino.com/?modal=login

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

Ввожу логин в поле: //input[@name='email'] Ввожу пароль в поле: //input[@name='password'] Жму кнопку подтверждения: //button[@data-test='submit']

Происходит ререндер DOM, URL меняется на https://example-casino.com/

2) Главная страница:

Жму кнопку кошелька в шапке: //button[@aria-label='wallet']

В момент клика уходит запрос /api/payments/methods — в ответе JSON список провайдеров, нужный провайдер называется CryptoProvider в поле code. URL меняется на ?modal=wallet&tab=deposit, открывается модальное окно с iframe платёжной формы

3) Форма платежа (внутри iframe, URL больше не меняется):

В модальном окне есть iframe: //iframe[@id='crypto-frame']

Жму дропдаун валюты: //div[@class='currency-select'] Выбираю USDT TRC-20: //li[text()='USDT TRC20'] Ввожу сумму в поле: //input[@id='amount'] Жму кнопку подтверждения: //button[@type='submit']

Происходит ререндер iframe, модальное окно и страница не ререндерятся, URL не меняется

Сохраняю адрес кошелька: //span[@class='wallet-address'] — текст элемента, нужен strip()

Смотри AGENTS.md для понимания архитектуры и паттернов.


Паттерн 3 — по адресу кошелька:

Добавь новый сайт example-casino.com в проект payment_checker. Создай ветку site/example-casino и открой PR в main. Используй паттерн 3 — проверка по адресу кошелька. Адрес кошелька уже добавлен в known_wallets в credentials.json.

1) Страница логина (форма открывается сразу по URL):

Перехожу по ссылке: https://example-casino.com/login

Форма входа доступна сразу — кнопку кликать не нужно

Ввожу логин в поле: //input[@id='login'] Ввожу пароль в поле: //input[@id='password'] Жму кнопку подтверждения: //button[@aria-label='sign in']

Происходит ререндер DOM, URL меняется на https://example-casino.com/

2) Главная страница:

Жму кнопку депозита в шапке: //a[text()='Deposit']

URL меняется на https://example-casino.com/account/cashier/deposit

3) Страница депозита:

Жму кнопку USDT: //div[text()='USDT']

После клика появляется адрес кошелька Сохраняю адрес кошелька: //div[@value] — атрибут value

Смотри AGENTS.md для понимания архитектуры и паттернов.


Шаг 5. Проверить локально

Codex создаст PR из ветки site/example-casino. До мержа проверь тест локально:

git fetch origin
git checkout site/example-casino

pytest tests/test_site_example_casino.py --alluredir=reports/allure -v
allure serve reports/allure

Если тест упал — смотри видео в отчёте (вкладка Attachments → video), пиши Codex что именно не работает. Он запушит фикс в ту же ветку:

git pull origin site/example-casino

Повторяй до зелёного теста.

Шаг 6. Смержить PR

Когда тест стабильно проходит — принимай PR на GitHub. main обновится.

Подтяни изменения локально:

git checkout main
git pull origin main

Структура проекта

payment_checker/
├── credentials.json                # все настройки и креды (не коммитить!)
├── credentials.example.json        # шаблон для credentials.json
├── .gitignore
├── README.md
├── AGENTS.md                       # инструкция для Codex
├── requirements.txt                # зависимости с зафиксированными версиями
├── pytest.ini                      # настройки pytest (retries, markers)
├── conftest.py                     # фикстуры: браузер, страница, креды, allure хуки
├── wallet_log.py                   # запись кошельков упавших тестов в wallets_report.json
├── browser_profile/                # персистентный профиль браузера (не коммитится)
├── reports/
│   ├── allure/                     # данные allure отчётов — хранятся 30 дней
│   └── videos/                     # временный буфер видео — очищается перед каждым запуском
├── config/
│   ├── __init__.py
│   └── settings.py                 # загрузка настроек из credentials.json
├── pages/
│   ├── __init__.py
│   ├── base_page.py                # базовый класс с общими методами
│   ├── site_365sms/                # паттерн 1 — проверка по логотипу
│   │   ├── __init__.py
│   │   ├── login_page.py
│   │   ├── home_page.py
│   │   ├── deposit_page.py
│   │   └── payment_page.py
│   ├── site_starzspins/            # паттерн 2 — проверка по API
│   │   ├── __init__.py
│   │   ├── login_page.py
│   │   ├── home_page.py
│   │   └── payment_page.py
│   └── site_bet25/                 # паттерн 3 — проверка по адресу кошелька
│       ├── __init__.py
│       ├── login_page.py
│       ├── home_page.py
│       └── deposit_page.py
└── tests/
    ├── __init__.py
    ├── base_test.py
    ├── test_site_365sms.py
    ├── test_site_starzspins.py
    └── test_site_bet25.py

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages