🎰 Test Card Generator 2030 — Offline, GUI, Beyond Namso

:high_voltage: Test Cards + Tokens + 3DS + DIDs — One Desktop Tool Does It All

Generate Luhn-valid test cards with tokens, 3DS codes, biometrics, and DIDs — all from a desktop app you can run offline.


If you’ve ever tested a payment form, you’ve probably hit Namso Gen. It works. But it’s online-only, limited in features, and you’re trusting someone else’s server with your workflow. This tool runs locally, generates more data types, and gives you a proper GUI.


🧠 What Even Is a Test Card Generator?

Payment forms need testing. Real cards = real charges = real problems. Test cards = fake numbers that look valid to the form but can’t actually charge anyone.

How it works:

  • Every card number follows the Luhn algorithm (a.k.a. Mod 10) — a checksum that catches typos
  • The first 6-8 digits are the BIN/IIN — they identify the card network (Visa, Mastercard, etc.) and issuing bank
  • Generators create numbers that pass Luhn validation but aren’t linked to real accounts

What you use them for:

  • Testing checkout flows without risking real money
  • Validating that your payment form rejects bad numbers
  • Stress-testing payment systems with bulk data
  • Learning how card validation actually works

What they DON’T do:

  • Generate real card numbers with real balances
  • Work for actual purchases (they’ll fail at the bank level)
  • Give you anything illegal — these are test numbers, not stolen data
⚡ The Tool — Test Card Generator 2030

This is a Python + PyQt6 desktop app. You run it locally. No servers, no tracking, no rate limits.

What It Does

Feature What You Get
BIN input Enter any 6-8 digit IIN, generates matching card type
Auto-detection Visa, Mastercard, Amex, Discover, UnionPay, Crypto — detected from BIN
Correct lengths Visa: 16 or 19, Amex: 15, Mastercard: 16 — handled automatically
CVV generation 3 digits (most cards) or 4 digits (Amex) — auto-selected
Expiry dates 2026+ with 1-10 year validity
Cardholder names Random English names for realistic test data
Batch generation Up to 200 cards at once
Save to file Export everything to .txt

Advanced Features (Checkboxes)

Checkbox What It Adds
Add tokens Simulates Apple Pay / Google Pay / stablecoin tokenization
Add 3DS codes 6-digit codes for 3D Secure authentication testing
Add biometric tokens SHA-256 hash mimicking fingerprint/face ID tokens
Add dynamic CVV Changes hourly (shows seed + explanation)
Add DID Decentralized identifiers (did:ethr:..., did:key:..., did:web:...)

Screenshots

📋 The Full Script (Copy-Paste Ready)

Requirements: Python 3.9+ and PyQt6 (pip install pyqt6)

Save this as card_generator.py and double-click to run:

import sys
import random
import hashlib
from datetime import datetime
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit,
    QPushButton, QTextEdit, QSpinBox, QFileDialog,
    QMessageBox, QCheckBox
)

def luhn_checksum(number_str):
    digits = [int(d) for d in number_str]
    for i in range(len(digits) - 2, -1, -2):
        digits[i] = sum(divmod(digits[i] * 2, 10))
    total = sum(digits)
    return (10 - (total % 10)) % 10

def generate_card_number(iin_prefix):
    iin_str = str(iin_prefix)
    if len(iin_str) < 6 or len(iin_str) > 8:
        raise ValueError("IIN must be 6-8 digits")
    
    card_type, length_range, _ = determine_card_type(iin_prefix)
    
    if isinstance(length_range, int):
        length = length_range
    else:
        length = random.choice(length_range)
    
    remaining_length = length - len(iin_str) - 1
    random_digits = ''.join(str(random.randint(0, 9)) for _ in range(remaining_length))
    partial_number = iin_str + random_digits
    checksum = luhn_checksum(partial_number + '0')
    return partial_number + str(checksum), length

def generate_expiry_date():
    base_year = 2026
    current_year = datetime.now().year
    start_year = max(current_year, base_year)
    expiry_year = start_year + random.randint(1, 10)
    expiry_month = random.randint(1, 12)
    return f"{expiry_month:02d}/{expiry_year % 100:02d}"

def generate_static_cvv(length=3):
    return ''.join(str(random.randint(0, 9)) for _ in range(length))

def generate_dynamic_cvv(seed, length=3):
    current_time = datetime.now().strftime("%Y%m%d%H")
    hash_input = f"{seed}{current_time}"
    hashed = hashlib.sha256(hash_input.encode()).hexdigest()
    return hashed[:length].upper()

def generate_biometric_token():
    bio_data = ''.join(random.choices('0123456789ABCDEF', k=32))
    return hashlib.sha256(bio_data.encode()).hexdigest()

def generate_did():
    method = random.choice(['ethr', 'key', 'web'])
    identifier = ''.join(random.choices('0123456789abcdef', k=40))
    return f"did:{method}:{identifier}"

def generate_cardholder_name():
    first_names = ["John", "Jane", "Alex", "Emily", "Michael", "Sophia", "David", "Olivia", "James", "Emma"]
    last_names = ["Doe", "Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Martinez"]
    return f"{random.choice(first_names)} {random.choice(last_names)}"

def generate_token(card_number):
    token_length = random.randint(16, 19)
    token_prefix = random.choice(['9', '8'])
    remaining = token_length - 1 - 4
    random_part = ''.join(str(random.randint(0, 9)) for _ in range(remaining))
    return token_prefix + random_part + card_number[-4:]

def generate_3ds_code():
    return ''.join(str(random.randint(0, 9)) for _ in range(6))

def determine_card_type(iin_prefix):
    iin_str = str(iin_prefix)
    if iin_str.startswith('4'):
        return 'Visa', [16, 19], 3
    elif iin_str.startswith('5') or iin_str.startswith('2'):
        return 'Mastercard', 16, 3
    elif iin_str.startswith('34') or iin_str.startswith('37'):
        return 'American Express', 15, 4
    elif iin_str.startswith('6'):
        return 'Discover', [16, 19], 3
    elif iin_str.startswith('62') or iin_str.startswith('81'):
        return 'UnionPay', [16, 19], 3
    elif iin_str.startswith('7'):
        return 'Crypto/Stablecoin', [16, 19], 3
    else:
        return 'Unknown', 16, 3

def generate_cards(iin_prefix, count, include_token=False, include_3ds=False, include_biometric=False, include_dynamic_cvv=False, include_did=False):
    card_type, length_range, default_cvv = determine_card_type(iin_prefix)
    cards = []
    for _ in range(count):
        card_number, actual_length = generate_card_number(iin_prefix)
        expiry = generate_expiry_date()
        cvv_seed = random.randint(100000, 999999)
        cvv_length = default_cvv
        cvv = generate_dynamic_cvv(cvv_seed, cvv_length) if include_dynamic_cvv else generate_static_cvv(cvv_length)
        name = generate_cardholder_name()
        card = {
            'type': card_type,
            'number': card_number,
            'length': actual_length,
            'expiry': expiry,
            'cvv': cvv,
            'name': name
        }
        if include_dynamic_cvv:
            card['cvv_note'] = f"Dynamic (seed: {cvv_seed}, changes hourly)"
        if include_token:
            card['token'] = generate_token(card_number)
        if include_3ds:
            card['3ds_code'] = generate_3ds_code()
        if include_biometric:
            card['biometric_token'] = generate_biometric_token()
        if include_did:
            card['did'] = generate_did()
        cards.append(card)
    return cards

class CardGeneratorGUI(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Test Card Generator 2030")
        self.resize(720, 640)
        self.layout = QVBoxLayout()

        self.iin_label = QLabel("IIN (6–8 digits):")
        self.iin_input = QLineEdit()
        self.iin_input.setPlaceholderText("Example: 411111")
        self.layout.addWidget(self.iin_label)
        self.layout.addWidget(self.iin_input)

        self.count_label = QLabel("Number of cards:")
        self.count_input = QSpinBox()
        self.count_input.setMinimum(1)
        self.count_input.setMaximum(200)
        self.count_input.setValue(10)
        self.layout.addWidget(self.count_label)
        self.layout.addWidget(self.count_input)

        self.token_cb = QCheckBox("Add tokens (digital wallets / stablecoins)")
        self.threeds_cb = QCheckBox("Add 3DS codes")
        self.bio_cb = QCheckBox("Add biometric tokens")
        self.dyn_cvv_cb = QCheckBox("Add dynamic CVV")
        self.did_cb = QCheckBox("Add DID (decentralized identity)")

        for cb in [self.token_cb, self.threeds_cb, self.bio_cb, self.dyn_cvv_cb, self.did_cb]:
            self.layout.addWidget(cb)

        self.generate_btn = QPushButton("Generate Cards")
        self.generate_btn.clicked.connect(self.generate)
        self.layout.addWidget(self.generate_btn)

        self.output = QTextEdit()
        self.output.setReadOnly(True)
        self.layout.addWidget(self.output)

        self.save_btn = QPushButton("Save to File")
        self.save_btn.clicked.connect(self.save_result)
        self.layout.addWidget(self.save_btn)

        self.setLayout(self.layout)

    def generate(self):
        try:
            iin_text = self.iin_input.text().strip()
            if not iin_text:
                QMessageBox.warning(self, "Error", "Please enter IIN")
                return
            if not iin_text.isdigit():
                QMessageBox.warning(self, "Error", "IIN must contain only digits")
                return
            iin = int(iin_text)
            if len(str(iin)) < 6 or len(str(iin)) > 8:
                QMessageBox.warning(self, "Error", "IIN must be between 6 and 8 digits")
                return

            count = self.count_input.value()

            cards = generate_cards(
                iin, count,
                include_token=self.token_cb.isChecked(),
                include_3ds=self.threeds_cb.isChecked(),
                include_biometric=self.bio_cb.isChecked(),
                include_dynamic_cvv=self.dyn_cvv_cb.isChecked(),
                include_did=self.did_cb.isChecked()
            )

            out = ""
            for idx, card in enumerate(cards, 1):
                out += f"Card {idx}\n"
                out += f"Type: {card['type']}\n"
                out += f"Number: {card['number']}  (length: {card['length']})\n"
                out += f"Expiry: {card['expiry']}\n"
                out += f"CVV: {card['cvv']}"
                if 'cvv_note' in card:
                    out += f" ({card['cvv_note']})"
                out += "\n"
                out += f"Name: {card['name']}\n"
                if 'token' in card:
                    out += f"Token: {card['token']}\n"
                if '3ds_code' in card:
                    out += f"3DS Code: {card['3ds_code']}\n"
                if 'biometric_token' in card:
                    out += f"Biometric Token: {card['biometric_token']}\n"
                if 'did' in card:
                    out += f"DID: {card['did']}\n"
                out += "─" * 60 + "\n\n"

            self.output.setPlainText(out)

        except ValueError as ve:
            QMessageBox.warning(self, "Input Error", str(ve))
        except Exception as e:
            QMessageBox.critical(self, "Error", f"{type(e).__name__}\n{str(e)}")

    def save_result(self):
        text = self.output.toPlainText().strip()
        if not text:
            QMessageBox.information(self, "Nothing to save", "Generate some cards first")
            return
        path, _ = QFileDialog.getSaveFileName(self, "Save As", "", "Text Files (*.txt);;All Files (*.*)")
        if path:
            try:
                with open(path, "w", encoding="utf-8") as f:
                    f.write(text)
                QMessageBox.information(self, "Success", "File saved successfully")
            except Exception as e:
                QMessageBox.critical(self, "Save Error", str(e))

def main():
    app = QApplication(sys.argv)
    window = CardGeneratorGUI()
    window.show()
    sys.exit(app.exec())

if __name__ == "__main__":
    main()

To run:

  1. Install Python 3.9+ from python.org
  2. Open terminal/cmd → pip install pyqt6
  3. Save the script → double-click to run
🌐 Alternatives — Online Generators

If you don’t want to run Python locally, these web tools do similar things:

Tool What It Does Link
Namso Gen The OG. BIN-based generation, Luhn-valid, bulk export namso.net
Multi-CC Gen Multiple BINs at once, simpler interface multi-cc-gen.web.app
BinCodes Generator Generator + validator + BIN lookup combined bincodes.com
TheNamsoGen Bulk generation, CSV/JSON export, region-specific data thenamsogen.com

Why the desktop tool is still better:

  • Works offline (no internet required after install)
  • No rate limits or captchas
  • Advanced features (tokens, 3DS, biometrics, DIDs) not available elsewhere
  • Your data stays on your machine
🔧 GitHub Repos — Build Your Own

Want to modify or integrate this into your workflow? Here are open-source alternatives:

Repo Language Stars What It Does
python-cc-num-gen Python Simple class-based generator, Visa/MC/Amex/Discover
CreditCardGenerator Swift CLI tool with batch generation + file export
credit-card-generator (Node) Node.js npm package, Triple-DES CVV generation
CCGenerator Python Interactive CLI with performance modes
reNamso HTML/JS 31★ Modern rewrite of Namso, no jQuery, clean code
🔍 BIN Lookup APIs — Know Your Numbers

Before generating, you might want to look up what a BIN actually represents:

API Free Tier What It Returns
binlist.net 5/hour Card brand, type, bank, country
HandyAPI BIN Free with key Updated weekly, 6-8 digit support
BinCodes API Limited XML/JSON, card validation
BINTable 100/month REST API, detailed issuer data
API-Ninjas BIN Free tier Brand, type, country, validity check
❓ Common Questions

Q: Will these cards work for real purchases?
No. They pass Luhn validation (the checksum check) but fail at the bank level. There’s no account behind them.

Q: Is this legal?
Generating test numbers = yes. Using them for fraud = no. These are for testing payment forms, not stealing.

Q: What’s a BIN/IIN?
The first 6-8 digits of a card number. They identify the card network (Visa starts with 4, Mastercard with 5, etc.) and the issuing bank.

Q: Why do some Visa cards have 19 digits?
Visa supports both 16 and 19-digit numbers. The generator handles this automatically.

Q: What’s a dynamic CVV?
Some modern cards change their CVV periodically (often hourly) for security. The generator simulates this with a seed-based hash.

Q: What’s a DID?
Decentralized Identifier — a Web3/blockchain identity format. Useful for testing systems that use verifiable credentials.


New to BINs and how they actually work? This breaks it down from zero:

:skull: Working BIN Masterclass


One script. Offline. More features than Namso. No excuses.

11 Likes

The program works, thank you.

There will be a lot more software on this topic ahead :+1:

2 Likes

@Edgar Your next posts?? :fire::fire::fire:

1 Like

:heart_eyes: thank you

1 Like

@Edgar
How to use the software without using python?

Python is too complex to use

thanks you

Python is just the simplest of such solutions, because its environment is very easy and fast to set up, it takes about 5-10 minutes even for a beginner, and it is cross-platform, which means that by installing python, you can run it on mac, linux or any versions of Windows, as well as if someone you will need it urgently, they can assemble the installation file if you have python installed, for the most part it allows you to open programs by double-clicking on the py file, and if you do not like the graphical interface, you can always run it from the terminal

I think OneHack should posts a step by step tutorials with video how to install and use python. I know nothing in Python…Experts in VPN only

How do you know about cybersecurity and OPSEC While you don’t know how to use python ?