Python · SDK + algoritmo Luhn

Gerador de Cartão para Testes em Python

SDK oficial fakeforge-br gera números sintéticos de cartão que passam validação Luhn (mod-10). Cobre Visa, Mastercard, Elo, Hipercard, Amex. Snippets pra pytest, Django, FastAPI. Ambiente de desenvolvimento apenas.

Ferramenta para desenvolvedores. Os cartão de crédito gerados são sintéticos e não pertencem a nenhuma pessoa real. Uso restrito a testes de software, seed de banco de dados de desenvolvimento e fixtures de QA. Usar em cadastro real ou apresentar como documento verdadeiro configura falsidade ideológica (art. 299 CP).

TL;DR

pip install fakeforge-br

from fakeforge import FakeForge
ff = FakeForge()

cartoes = ff.credit_card(100)  # 100 cartões sintéticos válidos Luhn

SDK oficial

from fakeforge import FakeForge

ff = FakeForge()

# 1 cartão sintético
[cartao] = ff.credit_card(1)
print(cartao)
# {
#   "number": "4532 8891 2947 6103",
#   "brand": "visa",
#   "cvv": "428",
#   "expiry": "07/29",
#   "holder": "MARINA SOUZA OLIVEIRA"
# }

# 100 cartões pra popular tabela de testes
cartoes = ff.credit_card(100)

# Preset fintech: customer + PIX + banco + cartão coerentes
[cliente] = ff.preset("fintech", 1)
print(cliente["credit_card"]["number"])

Algoritmo Luhn local (offline)

# luhn.py - implementação pura
import random

BIN_TESTE = {
    "visa": "4",
    "mastercard": "5",
    "elo": "6362",
}

def luhn_checksum(numero_sem_dv: str) -> int:
    """Calcula dígito Luhn (mod-10)."""
    digitos = [int(d) for d in numero_sem_dv][::-1]
    total = 0
    for i, d in enumerate(digitos):
        if i % 2 == 0:
            dobrado = d * 2
            total += dobrado if dobrado < 10 else dobrado - 9
        else:
            total += d
    return (10 - (total % 10)) % 10

def gerar_cartao(bandeira: str = "visa") -> str:
    """Gera número de cartão sintético que passa validação Luhn."""
    prefixo = BIN_TESTE.get(bandeira, "4")
    tam_prefixo = len(prefixo)
    aleatorios = "".join(str(random.randint(0, 9)) for _ in range(15 - tam_prefixo))
    numero_parcial = prefixo + aleatorios
    dv = luhn_checksum(numero_parcial)
    return f"{numero_parcial}{dv}"

Uso em pytest — teste de checkout

# tests/test_checkout.py
import pytest
from fakeforge import FakeForge
from myapp.checkout import CheckoutService

@pytest.fixture(scope="session")
def ff():
    return FakeForge()

@pytest.fixture(scope="session")
def cartoes_teste(ff):
    return ff.credit_card(50)

class TestCheckout:
    @pytest.mark.parametrize("indice", range(20))
    def test_aceita_cartao_com_luhn_valido(self, cartoes_teste, indice):
        cartao = cartoes_teste[indice]
        service = CheckoutService()
        resultado = service.validar_cartao(cartao["number"])
        assert resultado.valido

    def test_rejeita_luhn_invalido(self):
        service = CheckoutService()
        assert not service.validar_cartao("1234 5678 9012 3456").valido

Uso em Django (seed de teste)

# myapp/management/commands/seed_cartoes_teste.py
from django.core.management.base import BaseCommand
from django.conf import settings
from fakeforge import FakeForge
from myapp.models import CartaoTeste

class Command(BaseCommand):
    """Popula tabela cartao_teste em ambiente DE DESENVOLVIMENTO apenas."""

    def handle(self, *args, **options):
        if not settings.DEBUG:
            self.stderr.write("Refuso rodar em production.")
            return

        ff = FakeForge()
        dados = ff.credit_card(200)

        CartaoTeste.objects.bulk_create([
            CartaoTeste(
                numero=c["number"],
                bandeira=c["brand"],
                titular=c["holder"],
                validade=c["expiry"],
                cvv=c["cvv"],
            )
            for c in dados
        ])
        self.stdout.write("200 cartões sintéticos seeded (dev only)")

Nota importante

Cartões gerados aqui são sintéticos, não pertencem a ninguém e não têm saldo em conta bancária real. Passam validação Luhn (mod-10) do lado do cliente, mas gateway de pagamento real (Stripe, Mercado Pago, PagSeguro, Cielo) vai rejeitar em transação verdadeira. Uso restrito a testes de front-end, seed de banco de desenvolvimento e fixtures de QA. Nunca use em cadastro real, contrato ou compra. Ver guia LGPD + Código Penal art. 299.

Próximos passos