Documentation du renvoi

Notifications en temps réel des récompenses des éditeurs

Utilisez un renvoi éditeur lorsque vous voulez que CPAlead notifie votre serveur en temps réel après une offre complétée. Ceci est généralement utilisé pour créditer des points ou de l'argent, débloquer du contenu, mettre à jour vos propres rapports, ou synchroniser les conversions vers une plateforme externe. Ajoutez votre point de terminaison sous "Renvoi" -> "Configuration", et CPAlead lui enverra une requête HTTP GET lorsqu'une conversion éligible est enregistrée.

What This Postback Is For

Use a publisher postback when you want CPAlead to notify your server each time a user completes an offer. Most publishers use it to reward users, unlock content, keep an internal conversion ledger, or sync their own analytics and reporting.

The safest starting pattern is to pass your own reference in {subid}, store {lead_id} for idempotency, and reward based on {payout}. Expand from there only if your workflow actually needs more fields.

Common Uses

Credit points, cash, or in-app rewards to your users after a completed offer.

Unlock premium content, gated files, or paid features inside your own product.

Write each conversion into your own ledger so finance or support can reconcile payouts later.

Forward conversion data into your own tracker, CRM, analytics stack, or BI pipeline.

Quick Start

Pass your own user ID, wallet ID, or click reference in {subid}.

Save a postback URL that includes {lead_id} so you can ignore duplicates safely.

Reward from {payout} first. Add extra macros only when you actually need them.

Test the URL, confirm a fast HTTP 2xx response, then review Postback Logs.

Recommended starter macros: {subid}, {lead_id}, {campaign_id}, {campaign_name}, {payout}, {password}.

Configuration de l'URL de suivi

Transmettez votre propre ID utilisateur, ID de portefeuille, ID de transaction ou référence de clic dans notre URL de suivi afin que la même valeur vous revienne plus tard dans le renvoi..

https://{tracking_domain}/view.php?id=1234&pub=1234&subid={Tracking_or_Subid}&subid2={Additional_Subid}&subid3={Additional_Subid}

Pour les flux d'applications mobiles, vous pouvez également transmettre l'IDFA (Apple) ou le GAID (Google) avec vos sous-IDs:

https://{tracking_domain}/view.php?id=1234&pub=1234&subid={Tracking_or_Subid}&subid2={Additional_Subid}&subid3={Additional_Subid}&idfa={Your_Users_IDFA}&gaid={Your_Users_GAID}

Configuration de l'URL de renvoi

Dans la configuration du renvoi, enregistrez l'URL qui doit recevoir vos notifications de conversion. Commencez avec le minimum de macros dont vous avez réellement besoin, puis ajoutez d'autres champs uniquement si votre système les utilise.:

https://example.com/postback/cpalead.php?subid={subid}&lead_id={lead_id}&campaign_id={campaign_id}&campaign_name={campaign_name}&payout={payout}&password={password}

Si vous voulez tous les champs canoniques actuellement pris en charge, votre URL de renvoi peut ressembler à ceci:

https://example.com/postback/cpalead.php?campaign_id={campaign_id}&campaign_name={campaign_name}&subid={subid}&subid2={subid2}&subid3={subid3}&payout={payout}&ip_address={ip_address}&gateway_id={gateway_id}&lead_id={lead_id}&country_iso={country_iso}&password={password}&virtual_currency={virtual_currency}

CPAlead peut envoyer des renvois éditeur vers des points de terminaison HTTP et HTTPS.

Start with {subid}, {lead_id}, {campaign_id}, {campaign_name}, and {payout}. In the current publisher postback flow, {virtual_currency} is typically 0.

Paramètres de macro

Voici les principales macros CPAlead que vous pouvez placer dans votre URL. Elles seront remplacées par des valeurs de conversion en direct lorsque votre renvoi sera envoyé:

Paramètre de macro Description

{campaign_id}

CPAlead campaign or offer ID for the conversion.

{campaign_name}

CPAlead campaign or offer name.

{subid}

Your primary user ID or click/reference ID passed on the tracking URL.

{subid2}

Optional secondary tracking value passed on the tracking URL.

{subid3}

Optional tertiary tracking value passed on the tracking URL.

{idfa}

iOS advertising ID if you passed it on the tracking URL.

{gaid}

Android advertising ID if you passed it on the tracking URL.

{payout}

CPAlead payout amount for the conversion.

{ip_address}

Visitor IP captured on the converting click.

{gateway_id}

Locker or offer-wall tool ID when a CPAlead tool generated the conversion.

{lead_id}

Unique CPAlead lead/conversion ID. Best macro for deduping retries.

{country_iso}

Two-letter country code such as US.

{password}

Your saved postback password, if you include {password} in the URL.

{virtual_currency}

Virtual-currency amount from the event. In the standard publisher flow this is typically 0.

Helpful Compatibility Aliases

{offer_id} Alias of {campaign_id}.

{offer_name} Alias of {campaign_name}.

{amount} Alias of {payout}.

{transaction_id} Alias of {lead_id}.

{ip} Alias of {ip_address}.

{country_code} Alias of {country_iso}.

Configuration de l'URL de liste blanche

Si votre point de terminaison restreint le trafic entrant, ajoutez l'IP de relais CPAlead indiquée ci-dessous à la liste blanche afin que votre serveur accepte la livraison des renvois.

34.69.179.33

Exemple de script

Cet exemple montre un point de départ plus sûr pour une intégration personnalisée : validez le mot de passe, utilisez lead_id pour l'idempotence, stockez la charge utile brute, et ne récompensez l'utilisateur qu'une seule fois.

<?php
declare(strict_types=1);

/*
 * CPAlead publisher postback example.
 *
 * Recommended CPAlead URL:
 * https://example.com/postback/cpalead.php?subid={subid}&lead_id={lead_id}&campaign_id={campaign_id}&campaign_name={campaign_name}&payout={payout}&password={password}
 *
 * Notes:
 * - {subid} should usually be your internal user ID or click/reference ID.
 * - {lead_id} should be stored uniquely so retries do not double-credit a user.
 * - {payout} is the most reliable reward input in the current publisher flow.
 * - {virtual_currency} is currently sent as 0 in the standard publisher postback flow.
 */

const DB_HOST = '127.0.0.1';
const DB_PORT = '3306';
const DB_NAME = 'your_database';
const DB_USER = 'your_user';
const DB_PASS = 'your_password';
const POSTBACK_PASSWORD = 'replace_with_your_secret';

$subid = trim((string) ($_GET['subid'] ?? ''));
$leadId = (int) ($_GET['lead_id'] ?? 0);
$campaignId = (int) ($_GET['campaign_id'] ?? 0);
$campaignName = trim((string) ($_GET['campaign_name'] ?? ''));
$payout = (float) ($_GET['payout'] ?? 0);
$countryIso = strtoupper(substr((string) ($_GET['country_iso'] ?? ''), 0, 2));
$ipAddress = trim((string) ($_GET['ip_address'] ?? ''));
$password = (string) ($_GET['password'] ?? '');

if (POSTBACK_PASSWORD !== '' && !hash_equals(POSTBACK_PASSWORD, $password)) {
    http_response_code(403);
    exit('Invalid postback password.');
}

if ($subid === '' || $leadId <= 0) {
    http_response_code(400);
    exit('Missing subid or lead_id.');
}

$dsn = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', DB_HOST, DB_PORT, DB_NAME);
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$pdo->beginTransaction();

try {
    /*
     * Create a table like:
     * CREATE TABLE cpalead_postbacks (
     *   id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
     *   lead_id BIGINT UNSIGNED NOT NULL UNIQUE,
     *   user_id VARCHAR(100) NOT NULL,
     *   campaign_id BIGINT UNSIGNED NOT NULL,
     *   campaign_name VARCHAR(255) NOT NULL,
     *   payout DECIMAL(10,4) NOT NULL DEFAULT 0,
     *   country_iso CHAR(2) NULL,
     *   ip_address VARCHAR(45) NULL,
     *   raw_query TEXT NULL,
     *   created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
     * );
     */
    $insert = $pdo->prepare(
        'INSERT INTO cpalead_postbacks
            (lead_id, user_id, campaign_id, campaign_name, payout, country_iso, ip_address, raw_query, created_at)
         VALUES
            (:lead_id, :user_id, :campaign_id, :campaign_name, :payout, :country_iso, :ip_address, :raw_query, NOW())'
    );
    $insert->execute([
        ':lead_id' => $leadId,
        ':user_id' => $subid,
        ':campaign_id' => $campaignId,
        ':campaign_name' => $campaignName,
        ':payout' => $payout,
        ':country_iso' => $countryIso ?: null,
        ':ip_address' => $ipAddress ?: null,
        ':raw_query' => json_encode($_GET, JSON_UNESCAPED_SLASHES),
    ]);
} catch (PDOException $e) {
    // MySQL duplicate-key error: the lead was already processed.
    if (($e->errorInfo[1] ?? null) === 1062) {
        $pdo->rollBack();
        http_response_code(200);
        exit('Duplicate lead ignored.');
    }

    $pdo->rollBack();
    throw $e;
}

/*
 * Example reward logic:
 * - If you run a cash-back system, you may choose to credit $payout directly.
 * - If you run a points system, convert $payout to your own point value here.
 */
$rewardAmount = $payout;

$updateUser = $pdo->prepare('UPDATE users SET balance = balance + :amount WHERE id = :user_id');
$updateUser->execute([
    ':amount' => $rewardAmount,
    ':user_id' => $subid,
]);

if ($updateUser->rowCount() !== 1) {
    $pdo->rollBack();
    http_response_code(404);
    exit('User not found.');
}

$pdo->commit();

http_response_code(200);
echo sprintf(
    'OK lead_id=%d user=%s campaign_id=%d payout=%.4f',
    $leadId,
    $subid,
    $campaignId,
    $payout
);