API v4.4 Panel de PublisherPanel
📡 Guía de integración para publishers

FastCoins API de Publisher
Documentación

Todo lo que necesitas para integrar anuncios PTC en tu sitio: notificaciones Postback S2S y referencia completa de la API.

Postback S2S PTC API Autenticación Bearer Token Ejemplos en PHP Gratis y público
Descripción general

FastCoins es una red de publishers PTC (Paid-To-Click). Inserta nuestros anuncios en tu sitio, tus usuarios ganan recompensas en tokens por verlos y tú recibes una parte de los ingresos automáticamente.

📡
Postback (S2S)
Tu servidor recibe una notificación vía HTTP GET cuando un usuario completa un anuncio. Ideal para acreditar recompensas automáticamente sin código en el lado del cliente.
🔌
PTC API
Obtén los anuncios disponibles por programación y muéstralos con tu propia interfaz. No requiere insertar ningún widget.
🪙
Tokens personalizados
Configura tu propio nombre de token y tasa de conversión. Las recompensas se convierten y se envían automáticamente vía postback.
💰
Reparto de ingresos
Tú controlas el porcentaje que se paga al usuario. El resto son tus ingresos como publisher, retirables cada mes (días 1–3).
🚀
Primeros pasos

Crea una cuenta de publisher, verifica que el dominio es tuyo y recibe tus credenciales de API una vez revisado.

  • 1
    Crea una cuenta de publisher en FastCoins.com/publisher_dashboard. Necesitarás un nombre de sitio y una URL.
  • 2
    Añade un dominio en la pestaña Dominios. Cada dominio tiene su propia API Key, Secret Key, Bearer Token, configuración de token y URL de postback.
  • 3
    Configura tu URL de postback: el endpoint de tu servidor que recibe las notificaciones de recompensas (ver la sección de Postback más abajo).
  • 4
    Genera un Bearer Token desde la pestaña Dominios. Es necesario para autenticar las llamadas a la API PTC.
  • 5
    Envía un postback de prueba desde la pestaña Dominios para verificar que tu endpoint responde correctamente antes de salir a producción.
ℹ️
Retiros: los saldos de publisher solo pueden retirarse del 1 al 3 de cada mes. Planifica tu flujo de caja en consecuencia.
📬
Integración por Postback (S2S)

Una notificación de servidor a servidor que se envía a tu sitio web cuando un usuario termina de ver un anuncio, para que puedas acreditar recompensas automáticamente sin código en el lado del cliente.

🔐 Requisitos de seguridad

⚠️
Valida siempre la IP de origen y la firma antes de acreditar cualquier recompensa. Nunca acredites basándote solo en los parámetros.
  • IP del servidor autorizadas: 62.171.140.250, 2a02:c207:2329:8601::1 — comprueba esto únicamente contra $_SERVER['REMOTE_ADDR']. Es una llamada directa de servidor a servidor, no una petición de navegador, así que no hay ningún proxy/CDN nuestro en medio; una cabecera como X-Forwarded-For la suministra el cliente y es trivial falsificarla, así que no confíes en ella para esta comprobación.
  • userIp es obligatorio, no es solo informativo: rechaza el callback si falta o no es una IP válida. Siempre resolvemos y enviamos la IP real del usuario que completó el anuncio (a través de Cloudflare en nuestro lado) precisamente para que puedas confiar en ella para detección de fraude, límites por IP y comprobaciones de usuarios duplicados; un endpoint que la ignora pierde por completo esa señal.
  • Respuesta HTTP obligatoria: exactamente ok — en minúsculas, sin espacios, sin HTML, HTTP 200
  • Algoritmo de firma (recomendado): signature_sha256 = HMAC-SHA256(subId + transId + reward, secret_key)secret_key es la clave HMAC, no se concatena en el mensaje. userIp no forma parte de ella.
  • Algoritmo de firma (antiguo, aún se envía en cada callback): signature = MD5(subId + transId + reward + secret_key) — valores concatenados sin separadores. Se mantiene funcionando indefinidamente para las integraciones creadas antes de que existiera signature_sha256; no tienes que cambiar nada si ya verificas esta.
  • ¿Necesitas más de 8 decimales? Cada callback también incluye reward_precise (10 decimales) con su propia signature_sha256_precise = HMAC-SHA256(subId + transId + reward_precise, secret_key) — totalmente opcional y aditivo, se calcula igual, solo que sobre la cadena de mayor precisión. reward/signature_sha256/signature siguen enviándose exactamente igual, uses o no esta opción.
  • Prevención de duplicados: comprueba siempre transId en tu base de datos antes de acreditar

📋 Parámetros del postback (GET)

Tu URL de postback recibe estos parámetros vía HTTP GET.

Parámetro Tipo Obligatorio Descripción
subIdstringOBLIGATORIOID único del usuario en tu sistema: el valor que pasaste en la llamada al widget/API
transIdstringOBLIGATORIOID único de transacción: compruébalo siempre para evitar acreditar duplicados
rewardfloatOBLIGATORIORecompensa en tu moneda de token (ya convertida usando tu token_rate configurado), con 8 decimales
reward_precisefloatOpcionalLa misma recompensa que reward, pero con 10 decimales en lugar de 8 — úsala cuando 8 decimales no te den suficiente precisión
reward_namestringOBLIGATORIONombre del token tal como está configurado para tu dominio (p. ej. POINTS, COINS)
reward_valuefloatOBLIGATORIOIgual que reward — se incluye por compatibilidad con bitcotasks
offer_namestringOpcionalTítulo del anuncio completado — útil para registros
offer_typestringOpcionalSiempre ptc para vistas de anuncios de FastCoins
payoutfloatOpcionalIgual que reward — se incluye por compatibilidad con terceros
userIpstringOBLIGATORIODirección IP real del usuario que completó la oferta, resuelta a través de Cloudflare en nuestro lado antes de enviar este callback: rechaza el callback si falta o no pasa FILTER_VALIDATE_IP. Úsala para detección de fraude, límites por IP, detección de usuarios duplicados, auditoría de conversiones y analítica.
statusintegerOBLIGATORIO1 = Acreditar recompensa  |  2 = Contracargo (deducir recompensa)
signature_sha256stringOBLIGATORIOHMAC-SHA256 de subId + transId + reward, con secret_key como clave — recomendado para integraciones nuevas
signature_sha256_precisestringOpcionalHMAC-SHA256 de subId + transId + reward_precise, con secret_key como clave — verifica esta en lugar de signature_sha256 solo si también lees reward_precise
signaturestringOBLIGATORIOAntiguo: MD5 de subId + transId + reward + secret_key concatenados (sin separadores). Aún se envía en cada callback, sin cambios — se mantiene para integraciones creadas antes de que existiera signature_sha256.
testintegerOpcional1 = postback de prueba desde el panel — no acredites recompensas reales

🧮 Ejemplo: construcción y verificación de una URL firmada

Un ejemplo completo resuelto para que puedas comprobar tu propio cálculo de firma contra el nuestro antes de salir a producción. La clave secreta usada es inventada, solo a modo de ilustración.

example
Secret Key (example only, never a real one): demo_secret_do_not_use_9f8e7d6c

Parameters for this conversion:
  subId   = user_12345
  transId = txn_987654321
  reward  = 0.50
  status  = 1
  userIp  = 127.0.0.1

signature_sha256 = HMAC-SHA256(subId + transId + reward, secret_key)
                  = HMAC-SHA256("user_12345" . "txn_987654321" . "0.50", demo_secret_do_not_use_9f8e7d6c)
                  = HMAC-SHA256("user_12345txn_9876543210.50", demo_secret_do_not_use_9f8e7d6c)
                  = df3eafaa3e8cf4fe8fb40c7bed633f34bc7b964bca58d2d691314771a042d59c

signature (legacy) = MD5(subId + transId + reward + secret_key)
                    = MD5("user_12345" . "txn_987654321" . "0.50" . "demo_secret_do_not_use_9f8e7d6c")
                    = MD5("user_12345txn_9876543210.50demo_secret_do_not_use_9f8e7d6c")
                    = d1eb68e41cbd5770de9384c5be8ebb39

Resulting callback URL:
https://yoursite.com/postback.php?subId=user_12345&transId=txn_987654321&reward=0.50&status=1&userIp=127.0.0.1&signature=d1eb68e41cbd5770de9384c5be8ebb39&signature_sha256=df3eafaa3e8cf4fe8fb40c7bed633f34bc7b964bca58d2d691314771a042d59c
⚠️
Nunca uses esta clave secreta de ejemplo para nada real — es pública, está impresa en esta documentación. Calcula tus firmas con la Secret Key real de tu pestaña Dominios y nunca pegues esa clave real en ningún sitio público (herramientas de chat, documentos, repositorios públicos): trátala exactamente como una contraseña. Este ejemplo también omite reward_name, reward_value, offer_name, offer_type, payout y test por brevedad — tu callback real incluye todos, según la tabla anterior.

📐 Opcional: precisión de 10 decimales (reward_precise)

Misma clave secreta, mismo callback — solo una recompensa con más precisión decimal de la que los 8 decimales de reward pueden contener. Totalmente aditivo: ignóralo si 8 decimales ya cubren tu caso de uso.

example-precise
Same secret key and subId/transId as above, but the underlying reward this
time carries more precision:

  reward          = 0.12345679   (8 decimals, rounded)
  reward_precise  = 0.1234567890 (10 decimals)

signature_sha256_precise = HMAC-SHA256(subId + transId + reward_precise, secret_key)
                          = HMAC-SHA256("user_12345" . "txn_987654321" . "0.1234567890", demo_secret_do_not_use_9f8e7d6c)
                          = 219d2101a528b8585161bd26c3bb80c5de8a6741d60d2f1778eb805a05f7a707

💻 Implementación en PHP — postback.php

Guarda esto en tu servidor, configura tu Secret Key de la pestaña Dominios y pega la URL completa en el campo Postback URL de tu dominio.

postback.php
// ── 1. YOUR SECRET KEY (from Domains tab → Secret Key) ─────
$secret = "";  // ← paste your secret key here

// ── 2. IP VALIDATION (callback source) ──────────────────────
// REMOTE_ADDR only — this call comes straight from our server to
// yours, no browser and no proxy of ours in between, so it's the
// one value here that can't be spoofed by whoever is calling you.
// X-Forwarded-For (or any other header) is attacker-controlled and
// must never be trusted for this check.
$allowed_ips = ['62.171.140.250', '2a02:c207:2329:8601::1'];
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (!in_array($ip, $allowed_ips, true)) {
    echo "ERROR: Invalid source IP";
    exit;
}

// ── 3. COLLECT PARAMETERS ───────────────────────────────────
$userId    = $_GET['subId']     ?? null;
$transId   = $_GET['transId']   ?? null;
$status    = $_GET['status']    ?? null;
$isTest    = isset($_GET['test']) && $_GET['test'] == 1;
$userIp    = $_GET['userIp']   ?? null;  // real IP of the ad viewer — required, see step 4

// ── 3b. DYNAMIC PRECISION ────────────────────────────────────
// Prefer reward_precise (10 decimals) when the callback carries it;
// fall back to the standard reward (8 decimals) otherwise. Whichever
// pair is picked, it's verified against its own matching signature in
// step 6 — if that signature is valid, the postback is accepted.
$hasPrecise = isset($_GET['reward_precise'], $_GET['signature_sha256_precise']);
$reward    = $hasPrecise ? $_GET['reward_precise']           : ($_GET['reward'] ?? null);
$signature = $hasPrecise ? $_GET['signature_sha256_precise'] : ($_GET['signature_sha256'] ?? null);

// ── 4. VALIDATE USER IP (required) ──────────────────────────
// userIp is mandatory — this is the real IP of the person who
// completed the offer, already resolved through Cloudflare on our
// end. Reject the callback outright rather than silently accepting
// one without it, since your fraud detection / IP-limit / duplicate-
// user checks depend on this value actually being present and valid.
if (!$userIp || !filter_var($userIp, FILTER_VALIDATE_IP)) {
    echo "ERROR: Invalid user IP";
    exit;
}

// ── 5. VALIDATE REQUIRED PARAMS ─────────────────────────────
if (!$userId || !$transId || $reward === null || !$signature) {
    echo "ERROR: Missing parameters";
    exit;
}

// ── 6. VERIFY SIGNATURE ─────────────────────────────────────
// Only subId + transId + reward go into this hash — userIp is NOT
// part of it. $secret is the HMAC key, not concatenated into the
// message. Don't add userIp here unless a different provider's docs
// explicitly say their signature scheme includes it.
$expected = hash_hmac('sha256', $userId . $transId . $reward, $secret);
if (!hash_equals($expected, $signature)) {
    echo "ERROR: Signature mismatch";
    exit;
}

// ── 7. HANDLE CHARGEBACK (status = 2) ───────────────────────
if ((int)$status === 2) {
    $reward = -abs((float)$reward);  // negative = deduct
}

// ── 8. TEST CALLBACK ─────────────────────────────────────────
// Authenticated and validated like any other callback, but must not
// touch a real balance.
if ($isTest) {
    echo "ok";
    exit;
}

// ── 9. PREVENT DUPLICATES, CREDIT REWARD & STORE USER IP ──────
// Replace with your actual DB logic.
if (!isTransactionProcessed($transId)) {
    creditUserReward($userId, $reward, $transId);
    // If your credit function only takes these 3 args, store $userIp
    // with the conversion separately, e.g.:
    //   saveConversionIp($transId, $userId, $userIp);
}

// ── 10. REQUIRED RESPONSE ───────────────────────────────────
echo "ok";  // MUST return exactly this, nothing else

🕓 Verificación antigua — MD5

💡
¿Ya verificas signature con MD5? Se sigue enviando en cada callback, exactamente igual — esto está aquí solo como referencia. No hay que hacer nada. Las integraciones nuevas deberían usar signature_sha256, más arriba.
postback-legacy.php
$signature = $_GET['signature'] ?? null;
$expected  = md5($userId . $transId . $reward . $secret);
if (!hash_equals($expected, $signature)) {
    echo "ERROR: Signature mismatch";
    exit;
}
// ...same IP check, userIp check, and crediting logic as the main example above.

🔀 Flujo del callback

  • 1
    Callback recibido
  • 2
    Comprueba REMOTE_ADDR contra la lista blanca de IP
  • 3
    Lee los parámetros, incluido userIp
  • 4
    Valida userIp — recházalo si falta o no es una IP válida
  • 5
    Valida los demás parámetros obligatorios
  • 6
    Verifica la firma
  • 7
    Comprueba status — aplícalo como contracargo si es 2
  • 8
    Si test=1, devuelve ok sin acreditar nada
  • 9
    Comprueba transId contra tu base de datos para evitar acreditar duplicados
  • 10
    Acredita o revierte la recompensa, y guarda userIp junto a la conversión
  • 11
    Devuelve ok

Respuestas posibles:

  • ok — callback procesado (o validado como callback de prueba)
  • ERROR: Invalid source IP
  • ERROR: Invalid user IP
  • ERROR: Missing parameters
  • ERROR: Signature mismatch
Respuesta obligatoria: devuelve HTTP 200 con el cuerpo exactamente ok — sin espacios, sin saltos de línea, sin HTML.
⚠️
Los postbacks fallidos pueden reenviarse desde la pestaña Registros de postback de tu panel. Haz siempre tu endpoint idempotente: debe ser seguro llamarlo varias veces con el mismo transId.
💡
Prueba primero: usa el botón Probar postback de la pestaña Dominios para verificar tu endpoint antes de salir a producción. Los postbacks de prueba incluyen test=1 — no acredites nada para ellos.
🔌
API PTC — Obtener anuncios por programación

Consulta los anuncios PTC disponibles mediante una API REST y muéstralos con tu propia interfaz. No requiere insertar ningún widget.

🌐 Endpoint

GET https://FastCoins.com/api/[API_KEY]/[USER_ID]/[USER_IP]/[DEVICE]
SegmentoDescripción
API_KEYLa API Key de tu dominio — se encuentra en la pestaña Dominios de tu Panel de Publisher
USER_IDIdentificador único del usuario en tu sistema. Se devuelve como subId en el postback
USER_IPDirección IP real del usuario — se usa para la segmentación de anuncios y la prevención de fraude. Pasa la IP real del cliente
DEVICEExactamente desktop o mobile — no existe un tercer valor. Las tabletas (iPad, tabletas Android) cuentan como mobile. El dispositivo real del visitante es obligatorio en cuanto algún advertiser tenga una campaña con segmentación por dispositivo: como llamas a esta API desde tu propio servidor, el User-Agent de tu servidor no es el del visitante, así que no podemos detectarlo por ti — debes detectarlo y pasarlo. Enviar cualquier cosa distinta de desktop/mobile (incluido un literal "tablet") se trata igual que omitirlo — conviértelo a mobile tú mismo. Una petición que lo omita o lo escriba mal devuelve HTTP 400 en ese caso.
⚠️
Cambio importante: si tu integración aún no envía [DEVICE], añádelo ya. Hoy se ignora silenciosamente, pero empezará a devolver HTTP 400 en cuanto la segmentación por dispositivo se active — no esperes a que eso rompa tu feed.

🔑 Autenticación — Bearer Token

⚠️
Cada petición a la API requiere un Bearer Token en la cabecera Authorization. Genera uno por dominio desde la pestaña Dominios (botón 🔄 junto a "Bearer Token").
Authorization: Bearer [YOUR_BEARER_TOKEN]
ℹ️
Si un dominio no tiene Bearer Token configurado, la autenticación se omite. Configura siempre uno en entornos de producción.

💻 Ejemplo en PHP

get-ads.php
// ── YOUR CREDENTIALS (from Domains tab) ─────────────────────
$apiKey      = 'YOUR_API_KEY';
$bearerToken = 'YOUR_BEARER_TOKEN';

// ── USER DATA ────────────────────────────────────────────────
$userId = $_SESSION['user_id'];  // your user's unique ID
// REMOTE_ADDR by default — it's the one value here that can't be
// spoofed by the visitor. Only read a proxy header instead (e.g.
// CF-Connecting-IP) if your own server sits behind a reverse proxy
// you control and trust — never a client-supplied header like
// X-Forwarded-For, which the visitor's own browser can set to
// anything.
$userIp = $_SERVER['REMOTE_ADDR'] ?? '';

// Required once any advertiser runs a device-targeted campaign — this
// script call happens during the visitor's own page load, so THIS
// server's incoming User-Agent is theirs. Don't skip this: a call from a
// background job/cron with no real visitor attached has no correct value
// to send here.
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$device    = preg_match('/Mobi|Android|iPhone|iPod|iPad|BlackBerry|IEMobile|Opera Mini/i', $userAgent)
    ? 'mobile' : 'desktop';

// ── BUILD URL ────────────────────────────────────────────────
$url = 'https://FastCoins.com/api/' . $apiKey
     . '/' . urlencode($userId)
     . '/' . urlencode($userIp)
     . '/' . $device;

// ── CURL REQUEST ─────────────────────────────────────────────
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 10,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $bearerToken,
        'Accept: application/json',
    ],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

// ── HANDLE RESPONSE ──────────────────────────────────────────
if ($httpCode === 200 && $data['status'] === '200') {
    foreach ($data['data'] as $ad) {
        // $ad['url'] already contains the user subId encoded
        echo '<a href="' . htmlspecialchars($ad['url']) . '" target="_blank">';
        echo htmlspecialchars($ad['title']);
        echo ' — ' . $ad['reward'] . ' ' . $ad['currency_name'];
        echo '</a><br>';
    }
} else {
    echo 'No ads available.';
}

📦 Formato de respuesta

Las respuestas correctas devuelven HTTP 200 con esta estructura JSON:

{ "status": "200", "message": "success", "data": [ { "id": "123", "image": "https://FastCoins.com/banners/ad.png", "title": "Visit Our Site & Earn", "description": "Watch this ad for 30 seconds", "duration": "30", "reward": "100.0000", "currency_name": "Coins", "url": "https://FastCoins.com/view/abc123", "boosted_campaign": false, "ad_type": "Iframe" } ] }
CampoTipoDescripción
idstringIdentificador único del anuncio
imagestringURL completa de la imagen del banner del anuncio — puede estar vacía
titlestringTítulo para mostrar — muéstraselo a tus usuarios
descriptionstringDescripción corta del anuncio
durationstringTiempo de visión requerido en segundos: 2, 30 o 60
rewardfloatImporte de la recompensa en la moneda de token de tu dominio (ya convertida)
currency_namestringNombre del token tal como está configurado para tu dominio (p. ej. COINS, USDT)
urlstringRedirige al usuario aquí para ver el anuncio. El postback se dispara automáticamente al completarse. Ya incluye el subId del usuario codificado.
boosted_campaignbooleanIndica si es un anuncio promocionado — considera destacarlos en tu interfaz
ad_typestringIframe = se reproduce dentro de un frame  |  Redirect = el usuario va a la página del advertiser

⚠️ Códigos de error

Las respuestas de error comparten la misma estructura JSON con un campo de estado distinto de 200.

HTTPstatusCausa y solución
401401API key inválida — revisa el segmento API_KEY de la URL, o falta el Bearer Token cuando el dominio exige uno
403403Bearer Token incorrecto — regenéralo y actualízalo en la pestaña Dominios
400400Formato de USER_ID inválido — debe ser alfanumérico (a-z, 0-9, _, -, .), máximo 255 caracteres
400400Segmento DEVICE ausente o inválido — solo se devuelve una vez que la segmentación por dispositivo esté activa. Debe ser exactamente desktop o mobile
500500Error interno del servidor — el campo message contiene detalles de depuración. Contacta con soporte si persiste.
🔄
Flujo de integración

El flujo completo, desde la llamada a la API hasta el crédito de la recompensa en tu sitio.

📡 Flujo de API + Postback

Tu sitio llama a
GET /api/…
El usuario hace clic en el url del anuncio
El usuario ve el anuncio en FastCoins.com
FastCoins dispara
GET postback.php
Valida y acredita la recompensa
Devuelve ok

🧩 Widget insertado (alternativa)

Si prefieres no usar la API, inserta el widget como un iframe — gestiona todo automáticamente y con estilos aislados del resto de tu página.

widget-embed.php
<iframe src="https://fastcoins.click/widget-embed.php?api_key=YOUR_API_KEY&sub_id={USER_ID}"
    style="width:100%;height:640px;border:none;" loading="lazy"></iframe>
ℹ️
Sustituye YOUR_API_KEY por la API Key de tu dominio y {USER_ID} por el ID del usuario actual (renderizado en el servidor). El widget muestra los anuncios y tareas disponibles en línea y dispara el postback automáticamente al completarse. Ajusta los 640px de style para hacer el iframe más alto o más bajo según tu diseño.
⚠️
Un único sub_id (= {USER_ID}) por usuario real — sin sufijos para multiplicar. Cada uno de tus usuarios debe identificarse con un único id estable. Tú eliges el formato — un id opaco, un nombre de usuario, un email (p. ej. ABD01230A23, [email protected]) — pero un usuario real se corresponde con exactamente un id, para siempre.

No está permitido: tomar un id base y añadirle un sufijo numérico para fabricar muchos "usuarios" a partir de una persona real. La detección es agnóstica al separador — elimina un -, _ o . final seguido de dígitos y trata el resto como la identidad del usuario. Cualquiera de estos pares se rechaza:
  • 123-1 & 123-2
  • ABC_1 & ABC_2
  • A23-23 & A23-24
  • order.1 & order.2
Un id continuo sin separador es una única identidad y nunca se divide (ABD01230A23, 1001, [email protected] son válidos).

Cuando se detecta el patrón, la API sigue respondiendo ok pero devuelve un mensaje explicando que el id no está permitido y no se acredita ninguna recompensa; el intento se registra como fraude.
Tareas (CPA) — para advertisers

Crea una tarea (p. ej. "regístrate en mi sitio"), fondea N finalizaciones y confirma cada una con un postback firmado de servidor a servidor. El usuario recibe la recompensa automáticamente en cuanto llega tu postback — sin aprobación manual ni retención de la plataforma.

📡 Cómo funciona

Creas la tarea
/create-task
El usuario abre tu URL con cka_cid
El usuario completa la acción
Tu servidor llama a nuestro postback
Usuario acreditado al instante

1) La URL del postback

GET https://fastcoins.click/webhooks/task-postback.php?cka_cid={CLICK_ID}&sign={SIGN}
  • cka_cid — el click id que añadimos a tu URL de destino cuando el usuario empezó (your-url?cka_cid=…). Devuélvelo sin cambios.
  • signhash_hmac('sha256', $cka_cid, $task_secret) (hex en minúsculas). El secreto de cada tarea se muestra en Create Task → My Tasks.

2) Firma

// PHP
$sign = hash_hmac('sha256', $cka_cid, $task_secret);

// Node.js
const sign = crypto.createHmac('sha256', taskSecret).update(ckaCid).digest('hex');

# Python
import hmac, hashlib
sign = hmac.new(task_secret.encode(), cka_cid.encode(), hashlib.sha256).hexdigest()
ℹ️
Solo tus IP de servidor incluidas en la lista blanca pueden llamar al postback (se configuran por tarea). Cualquier otra IP recibe 403 incluso con una firma válida. Esto más el HMAC es todo el modelo de autenticidad — guarda bien tu secreto.
⚠️
El crédito es inmediato y definitivo con tu postback — no hay contracargos. Una finalización se acredita en el instante en que tu postback firmado se verifica, porque tu postback ES la prueba de que el usuario hizo el trabajo. Asegúrate de ejecutar tus propias comprobaciones antifraude antes de llamar al postback: una vez enviado, no se puede revertir. Llámalo solo para finalizaciones de las que estés seguro de que son genuinas.

3) Píxel de analítica opcional

Coloca esto en tu página de conversión para tu propia analítica. Nunca acredita — el postback de arriba es lo único que acredita.

<img src="https://fastcoins.click/task-pixel.php?cid={CLICK_ID}" width="1" height="1" alt="">
💡
Buenas prácticas

Recomendaciones para una integración fiable, segura y con altos ingresos.

⚡ Rendimiento

  • Guarda en caché las respuestas de la API durante al menos 60 segundos por usuario. No llames a la API en cada carga de página — los anuncios cambian como mucho cada pocos minutos.
  • Pasa la IP real del usuario. Usa REMOTE_ADDR por defecto — es el único valor que el visitante no puede falsificar. Lee una cabecera de proxy en su lugar (p. ej. CF-Connecting-IP) solo si tu propio servidor está detrás de un proxy inverso que controlas y en el que confías; nunca una cabecera suministrada por el cliente como X-Forwarded-For. Las IP incorrectas reducen la calidad de la segmentación de anuncios.
  • Configura un timeout de 10 segundos en tus llamadas cURL para evitar cargas de página lentas si nuestra API va lenta temporalmente.

🔒 Seguridad

  • Nunca expongas tu Secret Key en código del lado del cliente ni en repositorios públicos. Solo se usa en el servidor para validar firmas.
  • Comprueba siempre transId contra tu base de datos antes de acreditar — esto evita recompensas duplicadas por reenvíos accidentales del postback.
  • Valida la IP de origen antes de procesar cualquier postback. Acepta únicamente peticiones de 62.171.140.250 o 2a02:c207:2329:8601::1.
  • Usa HTTPS en tu endpoint de postback. Los endpoints HTTP pueden bloquearse.
  • Envía un único sub_id por usuario real. No añadas sufijos numéricos a un id base (123-1/123-2, ABC_1/ABC_2, order.1/order.2) — cualquier separador (- _ .) se detecta como fraude y se rechaza sin acreditar recompensa. Ver la regla anterior.

💰 Ingresos

  • Los anuncios potenciados (boosted_campaign: true) pagan más — destácalos en tu interfaz para aumentar las tasas de clic.
  • Los anuncios largos (60 s) pagan bastante más que los cortos (2 s). Priorízalos cuando la participación de tus usuarios sea alta.
  • Equilibra el porcentaje del usuario — un pago mayor atrae más usuarios activos; un pago menor aumenta tu propio margen.
  • Los retiros están abiertos del 1 al 3 de cada mes — márcalo en tu calendario.

🐛 Depuración

  • Usa el botón Probar postback de la pestaña Dominios para verificar que tu endpoint devuelve exactamente ok con HTTP 200.
  • Consulta la pestaña Registros de postback para ver las respuestas HTTP completas de cada intento de postback — muestra los códigos de estado y las respuestas del servidor.
  • Los postbacks fallidos pueden reenviarse individualmente o en lote desde la pestaña de registros. Nunca se pierden datos de forma permanente.
  • Si la firma siempre falla: para signature_sha256, comprueba que secret_key se pasa como la clave HMAC (no concatenada en el mensaje) y que calculas el hash de subId + transId + reward sin separadores; para el signature antiguo, comprueba que concatenas subId + transId + reward + secret sin separadores. En cualquier caso, asegúrate de que reward coincide exactamente con la cadena del parámetro GET (sin redondear).
  • Si verificas signature_sha256_precise: se calcula sobre reward_precise, no sobre reward — mezclar los dos campos con la firma equivocada es el error más común aquí.

¿Listo para empezar a ganar?

Crea tu cuenta de publisher en menos de 2 minutos y luego verifica tu dominio para empezar.

Abrir el Panel de Publisher →
✓ Copiado al portapapeles