View attachment 53318
Creating Your Own Checker Via Stripe
Checker services are in
absolute shambles right now. Their services are
dropping like flies - either going completely offline or becoming so unreliable they might as well be. The working ones? Theyre either
slow as shit or spitting out more
false declines than actual results. No wonder my inbox is flooded with the same question "How do I make my own checker?"
Well Im finally going to break it all down. Creating your own checker is a complex beast with multiple approaches but were going to tackle it step by step. This guide is the first in a series where well explore different methods starting with the most straightforward one: checking cards via
Stripes API.
Right now youre working with the bare essentials a
Stripe checker that can check a single card at a time; the next guide will amp things up with mass-checking techniques 3DS checks and explorations into other merchant integrations.
Why Stripe Though?
If youve been following my writeups you already know my stance on this: checking via
Stripe is
bad. Not because it "kills" cards - thats technically not true. The real issue is
Stripe's Radar system blacklisting (generic_decline) your cards. Every single card you run through a
Stripe checker gets
flagged as part of a "card testing" attack and good fucking luck using that card on any
Stripe-powered site afterward.
But desperate times call for desperate measures. Maybe youre hitting non-
Stripe sites anyway or you just need a quick validity check. The method still works - just understand what you're getting yourself into.
Stripe API And Binners
View attachment 53321
Those binners we roasted earlier? Turns out theyre the same ones running these "SK checker services" - mostly operated by tech-savvy
Indians whove figured out how to automate their garbage strategy. They manually generate and test bulk cards by scraping e-commerce sites for public
Stripe keys. Same monkey-typewriter approach just with fancier tools.
And its not just
Stripe they're targeting.
Braintree Square any payment processor with public keys exposed on websites gets hammered by these scripts. But we're focusing on
Stripe today because it's the most widespread and their API is actually decent to work with even if these clowns are abusing it.
Here's how Stripe checking works under the hood:
- Tokenization: Your card details get converted into a one-time token
- Payment Method Creation: That token becomes a "payment method"
- Auth Options: You can either just bind the card (no charge) or run a small auth charge ($0.50-$1) to verify funds
Building Your Own Checker
Alright lets get you set up with
Stripe in a way that doesnt leave you looking like a clueless rookie.
1. Prep Your Gear:
- Premium US proxy - Stripes fraud detection will flag cheap proxies instantly. Residential proxies are your best bet here.
- Legit identity details (SSN + DOB). Half-assed fake info is a one-way ticket to account termination.
- Business front browse Flippa.com for a small established e-commerce site. Copy their business model and details - this helps you sail through Stripe's verification process.
- Banking info any plausible routing and account numbers will work since were not actually processing payments. Just make sure the numbers follow the correct format.
2. Setting Up Your Stripe Account:
- Quality fullz (SSN DOB address etc). Bender-Search is my current go-to - their data is accurate and cheap at 50 cents per set. While other vendors exist Benders quality has been consistently solid.View attachment 53323
- Register at stripe.com using an email that you have access to.
- Personal info use the name and DOB from your fullz. The SSN needs to match perfectly.
View attachment 53325
- Business details:
- Bank details:
- When prompted for bank details select "Enter Bank Details Manually" - not doing so will prompt Plaid which we dont want
- Look up a real routing number from a bank in your fullz's city
- Generate a random 10-12 digit account number
- Use the same name as your personal info
- Once verified grab your API keys from the dashboard - youll need these for the checker
3. Configuración del verificador:
Antes, simplemente podías usar tu clave sk_live y ejecutar un script
de Python para generar un token y verificar una tarjeta. Hoy en día,
Stripe no es tan tonto: si intentas enviar directamente números de tarjeta de crédito sin procesar, recibirás un error como este:
[código]
{
"carga": nulo,
"código": nulo,
"código de rechazo": nulo,
"doc_url": nulo,
"mensaje": "Enviar números de tarjetas de crédito directamente a la API de Stripe generalmente no es seguro. Para continuar el procesamiento, utilice Stripe.js, los enlaces móviles de Stripe o Stripe Elements. Para obtener más información, consulte
https://dashboard.stripe.com/account/integration/settings. Si está cualificado para gestionar datos de tarjetas directamente, consulte
https://support.stripe.com/questions/enabling-access-to-raw-card-data-apis."
"parámetro": nulo,
"intención_de_pago": nulo,
"método_de_pago": nulo,
"url_registro_de_solicitud": "
https://dashboard.stripe.com/logs/req_21941209",
"intención_de_configuración": nulo,
"fuente": nulo,
"tipo": "error_de_solicitud_inválida"
}
[/código]
En lugar de usar una llamada directa a la API, ahora debe usar el frontend
JavaScript de Stripes para recopilar y tokenizar los datos de la tarjeta. Existen soluciones alternativas (las analizaré con más detalle en una próxima guía), pero para este enfoque superficial, cambiamos a una configuración de servidor
PHP sencilla.
Esto es lo que tienes que hacer:
- Coloque los siguientes archivos en una carpeta:
- índice.html
- validar.php
- compositor.json
- Ejecute "composer install" para instalar el módulo PHP de Stripe .
- Aloje la carpeta localmente (usando XAMPP WAMP o cualquier servidor PHP simple ).
- Abra index.html en su navegador. Le solicitará sus claves sk_live y pk_live y luego mostrará un campo de pago seguro de Stripe .
- Ingrese los detalles de su tarjeta; una vez enviados, el backend (validate.php) utiliza una intención de pago para validar la legitimidad de las tarjetas y devuelve una respuesta.
A continuación se muestra el código completo para esta configuración. (En serio, no modifiques nada).
[código]index.html:[/código]
[código]
<!DOCTYPE html>
<html lang="es">
<cabeza>
<meta charset="UTF-8">
<meta name="viewport" content="ancho=ancho-del-dispositivo, escala-inicial=1.0">
Validador de tarjetas
<script src="
https://js.stripe.com/v3/"></script>
<estilo>
cuerpo {
familia de fuentes: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
relleno: 20px;
fondo: #f0f0f0;
}
.validador de tarjetas {
ancho máximo: 500px;
margen: 0 auto;
fondo: blanco;
relleno: 20px;
radio del borde: 8px;
caja-sombra: 0 2px 4px rgba(0,0,0,0.1);
}
h2 {
color: #32325d;
alinear texto: centro;
margen inferior: 24px;
}
.grupo de formularios {
margen inferior: 16px;
}
etiqueta {
pantalla: bloque;
margen inferior: 8px;
color: #32325d;
}
aporte {
ancho: 100%;
relleno: 8px 12px;
borde: 1px sólido #e4e4e4;
radio del borde: 4px;
tamaño de fuente: 16px;
margen inferior: 16px;
}
.elemento-tarjeta {
relleno: 12px;
borde: 1px sólido #e4e4e4;
radio del borde: 4px;
margen inferior: 16px;
}
botón {
fondo: #5469d4;
color: blanco;
relleno: 12px 24px;
borde: ninguno;
radio del borde: 4px;
tamaño de fuente: 16px;
cursor: puntero;
ancho: 100%;
}
botón:deshabilitado {
fondo: #93a3e8;
cursor: no permitido;
}
.estado {
margen superior: 16px;
relleno: 12px;
radio del borde: 4px;
alinear texto: centro;
}
.error {
fondo: #tarifa;
color: #ff0000;
}
.éxito {
fondo: #e8ffe8;
color: #008000;
}
</estilo>
</cabeza>
<cuerpo>
<div class="validador de tarjetas">
Validador de tarjetas
<div id="formulario-de-configuración">
<div class="grupo-de-formularios">
<label>Clave secreta (sk_live):</label>
<tipo de entrada="texto" id="sk_live" requerido>
</div>
<div class="grupo-de-formularios">
<label>Clave pública (pk_live):</label>
<tipo de entrada="texto" id="pk_live" requerido>
</div>
<button onclick="setupStripe()">Continuar</button>
</div>
<div id="tarjeta-forma" estilo="mostrar: ninguno;">
<form id="formulario-de-pago">
<div class="grupo-de-formularios">
<label>Detalles de la tarjeta:</label>
<div id="elemento-de-tarjeta" class="elemento-de-tarjeta"></div>
</div>
Validar tarjeta
</form>
<div id="estado" clase="estado" estilo="mostrar: ninguno;"></div>
</div>
</div>
<guión>
dejar raya;
dejar elementos;
dejar tarjeta;
deja que sk_live;
función setupStripe() {
constante pk_live = document.getElementById('pk_live').value;
sk_live = documento.getElementById('sk_live').valor;
si (!pk_live || !sk_live) {
alert('Por favor ingrese ambas claves');
devolver;
}
raya = Raya(pk_live);
elementos = stripe.elements();
tarjeta = elementos.crear('tarjeta');
document.getElementById('setup-form').style.display = 'none';
document.getElementById('tarjeta-formulario').style.display = 'bloque';
tarjeta.mount('#elemento-tarjeta');
}
document.getElementById('formulario-de-pago').addEventListener('enviar', función asíncrona(e) {
e.preventDefault();
const submitButton = document.getElementById('boton-de-envío');
const statusDiv = document.getElementById('estado');
submitButton.disabled = verdadero;
submitButton.textContent = 'Procesando...';
statusDiv.style.display = 'bloque';
statusDiv.textContent = 'Validando tarjeta...';
statusDiv.className = 'estado';
intentar {
const { métodoDePago, error } = await stripe.createPaymentMethod({
tipo: 'tarjeta',
tarjeta: tarjeta,
});
si (error) {
arrojar error;
}
constante respuesta = await fetch('validate.php', {
método: 'POST',
encabezados: {
'Tipo de contenido': 'application/json',
},
cuerpo: JSON.stringify({
payment_method_id: métododepago.id,
clave secreta: sk_live,
}),
});
const resultado = await respuesta.json();
si (resultado.error) {
lanzar nuevo Error(resultado.error);
}
// Manejar la autenticación 3D Secure si es necesario
si (resultado.requiere_acción) {
statusDiv.textContent = 'Se requiere autenticación adicional...';
const { error: confirmError } = await stripe.confirmCardSetup(
resultado.secreto_del_cliente
);
si (confirmarError) {
lanzar confirmError;
}
statusDiv.textContent = '¡La tarjeta está activa!

';
statusDiv.className = 'estado exitoso';
devolver;
}
deje mensaje = '';
cambiar (resultado.estado) {
caso 'exitoso':
mensaje = '¡La tarjeta está activa!

';
romper;
caso 'procesando':
mensaje = 'La validación de la tarjeta aún está procesándose...';
romper;
caso 'requiere_acción':
mensaje = 'La tarjeta requiere verificación adicional.';
romper;
por defecto:
mensaje = `Estado de validación de la tarjeta: ${result.status}`;
}
statusDiv.textContent = mensaje;
statusDiv.className = result.success ? 'estado exitoso' : 'estado error';
} captura (error) {
statusDiv.textContent = `

Rechazado: ${error.message}`;
statusDiv.className = 'error de estado';
} finalmente {
submitButton.disabled = falso;
submitButton.textContent = 'Validar tarjeta';
}
});
</script>
</cuerpo>
</html>
[/código]
[código]validate.php:[/código]
[código]
<?php
header('Control-de-Acceso-Permitir-Origen: *');
header('Tipo de contenido: aplicación/json');
header('Control de acceso: permitir métodos: POST');
header('Control de acceso-Permitir-encabezados: Tipo-de-contenido');
si ($_SERVER['MÉTODO_DE_SOLICITACIÓN'] === 'OPCIONES') {
código_de_respuesta_http(200);
exit();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit();
}
require_once '../vendor/autoload.php';
// Ensure the input is valid JSON before decoding
$rawInput = file_get_contents('php://input');
if (!isValidJson($rawInput)) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON input']);
exit();
}
$input = json_decode($rawInput, true);
$payment_method_id = $input['payment_method_id'] ?? null;
$secret_key = $input['secret_key'] ?? null;
if (!$payment_method_id || !$secret_key) {
http_response_code(400);
echo json_encode(['error' => 'Missing required parameters']);
exit();
}
// Helper function to validate JSON
function isValidJson($string) {
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
try {
\Stripe\Stripe::setApiKey($secret_key);
// Create a SetupIntent and confirm it with the payment method
$setup_intent = \Stripe\SetupIntent::create([
'payment_method' => $payment_method_id,
'confirm' => true,
'usage' => 'off_session',
'return_url' => '
https://crdpro.cc',
'automatic_payment_methods' => [
'enabled' => true,
'allow_redirects' => 'never'
]
]);
// Check the status
$status = $setup_intent->status;
$success = in_array($status, ['succeeded', 'requires_action', 'processing']);
// If 3D Secure authentication is required
if ($status === 'requires_action' || $status === 'requires_source_action') {
echo json_encode([
'success' => false,
'status' => $status,
'setup_intent' => $setup_intent->id,
'client_secret' => $setup_intent->client_secret,
'requires_action' => true
]);
exit();
}
echo json_encode([
'success' => $success,
'status' => $status,
'setup_intent' => $setup_intent->id
]);
} catch (\Exception $e) {
http_response_code(400);
echo json_encode([
'error' => $e->getMessage(),
'type' => get_class($e)
]);
}
Code:
{
"require": {
"stripe/stripe-php": "^13.0"
}
}
*** Hidden text: cannot be quoted. ***
Once everything's setup properly:
Some Other Stuff To Remember
The whole deal with
binding versus
auth is simple. Binding merely creates a payment method which is like filing away your card details without much fanfare. Auth on the other hand actually attempts to charge a tiny amount (think $0 or a few bucks) to verify the card. It gives you better clarity on whether a card is active but it also leaves a more noticeable trace and risk of killing the card.
En cuanto a la gestión de cuentas,
Stripe es
implacable . En cuanto empieces a ejecutar patrones sospechosos, frenarán de golpe y eliminarán tu cuenta. ¿La mejor opción? Alterna entre varias cuentas
de Stripe , usa direcciones IP diferentes para cada una y mantén el volumen de verificación de tarjetas dentro de límites razonables. No seas el idiota que piensa que realizar un montón de pruebas en una sola cuenta es buena idea.
Finalmente, la gestión de errores es tu salvavidas. Aprende a analizar cada mensaje de error: a veces significa que la tarjeta está dañada; otras veces, simplemente es que
Stripe se está poniendo terco. En cualquier caso, comprender estos mensajes te permitirá ajustar tu enfoque sobre la marcha.
No es ciencia espacial, pero si ignoras estos consejos, te encontrarás dando tumbos como un novato. Usa estas estrategias para ir un paso por delante y recuerda: el diablo está en los detalles.
Más por venir
Este es solo el comienzo de nuestra serie sobre cómo crear comprobadores, ya que es extremadamente básico y sencillo. Empezamos con la versión básica: la comprobación de la API
de Stripe . En próximas guías, profundizaremos en el tema principal: crear tus propios sistemas de autenticación y comprobadores masivos que funcionen con diferentes procesadores de pago, crear tu propio bot de verificación de CC de Telegram, etc., y crear comprobadores que realmente te proporcionen información útil más allá de "válido/inválido".
Recuerda: Un verificador es tan bueno como su operador. No seas el imbécil que procesa 10,000 tarjetas con una sola cuenta
de Stripe y se pregunta por qué la banearon. Empieza poco a poco, entiende la mecánica y crece con inteligencia.
Estén atentos a la próxima guía de esta serie. Vamos a profundizar en los detalles de cómo construir fichas que realmente merecen ser llamadas herramientas, no juguetes. Doctrina fuera.