AoyTasks Integration Guide
Connect AoyTasks to your website, credit members for completed activities, or advertise your own CPA campaign.
Create an account on AoyTasks first. Publishers register and verify an app under My Apps; advertisers use the CPA Advertising workspace.
Add your Website
Before integrating our offerwall or APIs, register your website in the dashboard. Once registered, you'll receive an API KEY and a SECRET KEY required for the next steps.
Integrate Offerwall
Our offerwall displays website visits, videos, tasks, and supported offers or surveys. Its layout adapts automatically to any screen size.
Website Integration
Use JavaScript to open the offerwall in a new tab, or embed it directly in your approved HTTPS website using an iFrame.
JavaScript Integration
window.open("https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]", "_blank", "noopener");
iFrame Integration
<iframe scrolling="yes" frameborder="0"
src="https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]"></iframe>
Replace [API_KEY] with the app API key from My Apps and [USER_ID] with your own stable user identifier. Keep the app Secret Key on your server.
PTC API Integration
Fetch PTC and video campaigns from AoyTasks and enabled partners to display them in your own UI. Open the returned url when the user clicks Start — no second API request is needed.
Endpoint
curl -X GET "https://aoytasks.com/api/v1/publisher/ptc?user_id=[USER_ID]&user_ip=[USER_IP]" \
-H "Authorization: Bearer [BEARER_TOKEN]" \
-H "User-UA: [USER_AGENT]"
JSON response
{
"status": 200,
"message": "success",
"data": [
{
"id": "[STABLE_ITEM_ID]",
"source": "native",
"provider": "AoyTasks",
"category": "ptc",
"title": "Visit and earn rewards!",
"description": "View this website to earn your reward.",
"image": "",
"reward": "80.00000",
"payout": "0.08000000",
"currency_name": "Points",
"url": "https://aoytasks.com/publisher-api/launch/[VISITOR_LINK_FROM_RESPONSE]",
"duration": 15,
"ad_type": "iframe"
},
{
"id": "[STABLE_VIDEO_ID]",
"source": "makeyoutask",
"provider": "MakeYouTask",
"category": "video",
"title": "Watch video",
"description": "View this website to earn your reward.",
"image": "",
"reward": "80.00000",
"payout": "0.08000000",
"currency_name": "Points",
"url": "https://aoytasks.com/publisher-api/launch/[VISITOR_LINK_FROM_RESPONSE]",
"duration": 30,
"ad_type": "video"
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 2,
"has_more": false,
"url_expires_in": 600
}
}
PHP example
function requestWithFileGetContents($url, $token) {
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
$options = [
'http' => [
'header' => "Authorization: Bearer $token\r\nUser-UA: $userAgent\r\nAccept: application/json\r\n",
]
];
return file_get_contents($url, false, stream_context_create($options));
}
function requestWithCurl($url, $token) {
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
"User-UA: $userAgent",
"Accept: application/json"
],
]);
$response = curl_exec($ch);
if (curl_errno($ch)) $response = false;
curl_close($ch);
return $response;
}
$url = 'https://aoytasks.com/api/v1/publisher/ptc?user_id=[USER_ID]&user_ip=[USER_IP]';
$token = '[BEARER_TOKEN]';
$response = requestWithFileGetContents($url, $token) ?: requestWithCurl($url, $token);
if ($response) {
$data = json_decode($response, true);
if (isset($data['status']) && $data['status'] == 200) {
foreach ($data['data'] as $ptc) {
echo $ptc['title'] . " — " . $ptc['reward'] . "\n";
}
} else {
echo $data['message'] ?? 'Error';
}
} else {
echo "Request Failed";
}
Replace [BEARER_TOKEN] with your Bearer token (generate it in My Apps → Edit → Offerwall Integration), [USER_ID] with the user's unique identifier on your site, and [USER_IP] with the user's IP address.
Shortlink API Integration
Fetch shortlink campaigns managed on AoyTasks to display them in your own UI. Open the returned url when the user clicks Start — no second API request is needed.
Endpoint
curl -X GET "https://aoytasks.com/api/v1/publisher/shortlinks?user_id=[USER_ID]&user_ip=[USER_IP]" \
-H "Authorization: Bearer [BEARER_TOKEN]" \
-H "User-UA: [USER_AGENT]"
JSON response
{
"status": 200,
"message": "success",
"data": [
{
"id": "[STABLE_ITEM_ID]",
"source": "native",
"provider": "AoyTasks",
"category": "shortlinks",
"title": "Shortlink #1",
"description": "Complete the shortlink to earn.",
"image": "",
"reward": "80.00000",
"payout": "0.08000000",
"currency_name": "Points",
"url": "https://aoytasks.com/publisher-api/launch/[VISITOR_LINK_FROM_RESPONSE]",
"available": 2,
"limit": 2
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 1,
"has_more": false,
"url_expires_in": 600
}
}
PHP example
$url = 'https://aoytasks.com/api/v1/publisher/shortlinks?user_id=[USER_ID]&user_ip=[USER_IP]';
$token = '[BEARER_TOKEN]';
$response = requestWithFileGetContents($url, $token) ?: requestWithCurl($url, $token);
if ($response) {
$data = json_decode($response, true);
if (isset($data['status']) && $data['status'] == 200) {
foreach ($data['data'] as $shortlink) {
echo $shortlink['title'] . " — " . $shortlink['reward'] . "\n";
}
} else {
echo $data['message'] ?? 'Error';
}
} else {
echo "Request Failed";
}
Replace [BEARER_TOKEN] with your Bearer token (generate it in My Apps → Edit → Offerwall Integration), [USER_ID] with the user's unique identifier on your site, and [USER_IP] with the user's IP address.
Offer API Integration
Fetch hosted offerwalls, approved AoyTasks CPA offers, and individual partner offers to display them in your own UI. Open the returned url when the user clicks Start — no second API request is needed.
Endpoint
curl -X GET "https://aoytasks.com/api/v1/publisher/offers?user_id=[USER_ID]&user_ip=[USER_IP]" \
-H "Authorization: Bearer [BEARER_TOKEN]" \
-H "User-UA: [USER_AGENT]"
JSON response
{
"status": 200,
"message": "success",
"data": [
{
"id": "[STABLE_ITEM_ID]",
"source": "aoytasks_cpa",
"provider": "AoyTasks CPA",
"category": "offers",
"title": "Download and try this app",
"description": "Create an account and complete the required step.",
"image": "",
"reward": "80.00000",
"payout": "0.08000000",
"currency_name": "Points",
"url": "https://aoytasks.com/publisher-api/launch/[VISITOR_LINK_FROM_RESPONSE]",
"cpa_type": "offer",
"goals": [
{
"id": "register",
"name": "Create an account",
"reward": "80.00000",
"payout": "0.08000000"
}
],
"devices": [
"desktop",
"android",
"ios"
],
"estimated_minutes": 0
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 1,
"has_more": false,
"url_expires_in": 600
}
}
PHP example
$url = 'https://aoytasks.com/api/v1/publisher/offers?user_id=[USER_ID]&user_ip=[USER_IP]';
$token = '[BEARER_TOKEN]';
$response = requestWithFileGetContents($url, $token) ?: requestWithCurl($url, $token);
if ($response) {
$data = json_decode($response, true);
if (isset($data['status']) && $data['status'] == 200) {
foreach ($data['data'] as $offer) {
echo $offer['title'] . " — " . $offer['reward'] . "\n";
}
} else {
echo $data['message'] ?? 'Error';
}
} else {
echo "Request Failed";
}
Replace [BEARER_TOKEN] with your Bearer token (generate it in My Apps → Edit → Offerwall Integration), [USER_ID] with the user's unique identifier on your site, and [USER_IP] with the user's IP address.
Survey API Integration
Fetch approved AoyTasks CPA surveys and individual partner surveys to display them in your own UI. Open the returned url when the user clicks Start — no second API request is needed.
Endpoint
curl -X GET "https://aoytasks.com/api/v1/publisher/surveys?user_id=[USER_ID]&user_ip=[USER_IP]" \
-H "Authorization: Bearer [BEARER_TOKEN]" \
-H "User-UA: [USER_AGENT]"
JSON response
{
"status": 200,
"message": "success",
"data": [
{
"id": "[STABLE_ITEM_ID]",
"source": "aoytasks_cpa",
"provider": "AoyTasks CPA",
"category": "surveys",
"title": "Share your shopping habits",
"description": "Answer a few questions about your shopping habits.",
"image": "",
"reward": "80.00000",
"payout": "0.08000000",
"currency_name": "Points",
"url": "https://aoytasks.com/publisher-api/launch/[VISITOR_LINK_FROM_RESPONSE]",
"cpa_type": "survey",
"goals": [
{
"id": "complete",
"name": "Complete the survey",
"reward": "80.00000",
"payout": "0.08000000"
}
],
"devices": [
"desktop",
"android",
"ios"
],
"estimated_minutes": 0
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 1,
"has_more": false,
"url_expires_in": 600
}
}
PHP example
$url = 'https://aoytasks.com/api/v1/publisher/surveys?user_id=[USER_ID]&user_ip=[USER_IP]';
$token = '[BEARER_TOKEN]';
$response = requestWithFileGetContents($url, $token) ?: requestWithCurl($url, $token);
if ($response) {
$data = json_decode($response, true);
if (isset($data['status']) && $data['status'] == 200) {
foreach ($data['data'] as $survey) {
echo $survey['title'] . " — " . $survey['reward'] . "\n";
}
} else {
echo $data['message'] ?? 'Error';
}
} else {
echo "Request Failed";
}
Replace [BEARER_TOKEN] with your Bearer token (generate it in My Apps → Edit → Offerwall Integration), [USER_ID] with the user's unique identifier on your site, and [USER_IP] with the user's IP address.
Android Integration
Open the URL in the device browser, or embed it in a WebView inside your Android app.
Offerwall URL
https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]
WebView Example
WebView myWebView = new WebView(activityContext);
setContentView(myWebView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]");
Replace [API_KEY] with the app API key from My Apps and [USER_ID] with your own stable user identifier. Keep the app Secret Key on your server.
iOS Integration
Open the URL in Safari, or use WKWebView inside your iOS app.
Offerwall URL
https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]
WebView Example
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func loadView() {
let configuration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: configuration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]") else { return }
webView.load(URLRequest(url: url))
}
}
Replace [API_KEY] with the app API key from My Apps and [USER_ID] with your own stable user identifier. Keep the app Secret Key on your server.
React Native
Use Linking to open the offerwall in the device browser, or embed it using react-native-webview.
import { Linking } from 'react-native';
Linking.openURL('https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]');
// Install react-native-webview for your application platform.
import { WebView } from 'react-native-webview';
return <WebView source={{ uri: 'https://aoytasks.com/offerwall/[API_KEY]/[USER_ID]' }} />;
Replace [API_KEY] with the app API key from My Apps and [USER_ID] with your own stable user identifier. Keep the app Secret Key on your server.
Offerwall Parameters
Replace these placeholders with your approved app credentials and the signed-in member's exact identifier.
| Parameter | Description | Value |
|---|---|---|
[API_KEY] | Unique API code provided when you registered your website | App API key from My Apps |
[USER_ID] | Unique identifier code of the user on your site | 1–64 ASCII letters or digits, with single _ . @ - separators inside the identifier |
[USER_IP] | Public IPv4 or IPv6 address of the user (for Publisher API requests) | Visitor's public IP address |
[BEARER_TOKEN] | Private API token generated in My Apps → Edit → Offerwall Integration | Authorization: Bearer [BEARER_TOKEN] header |
Ready-Made Website Scripts
Follow the steps below to connect AoyTasks to VieFaucet 4.3, VieFaucet 4.4, or CryptoFaucet / ClaimBits.
VieFaucet 4.3 Integration
Four quick steps to integrate the AoyTasks offerwall into VieFaucet 4.3.
Step 1 — Open application/controllers/wh.php and add this before the last closing bracket (}):
Enter your publisher app Secret Key under the $secret variable. Without it, postbacks will not credit users.
public function aoytasks()
{
$secret = ""; // YOUR SECRET KEY
$hold = 3; // Hold days (0 = instant)
$minHold = 0.5; // Rewards below this are not held
$userId = isset($_POST['subId']) ? $this->db->escape_str($_POST['subId']) : null;
$transactionId = isset($_POST['transId']) ? $this->db->escape_str($_POST['transId']) : null;
$reward = isset($_POST['reward']) ? $this->db->escape_str($_POST['reward']) : null;
$action = isset($_POST['status']) ? $this->db->escape_str($_POST['status']) : null;
$debug = isset($_POST['debug']) ? $this->db->escape_str($_POST['debug']) : "0";
$userIp = isset($_POST['userIp']) ? $this->db->escape_str($_POST['userIp']) : "0.0.0.0";
$signature = isset($_POST['signature']) ? $this->db->escape_str($_POST['signature']) : null;
$expected = hash_hmac('sha256', ($_POST['transId'] ?? '') . ($_POST['subId'] ?? '') . ($_POST['reward'] ?? ''), $secret);
if (!is_string($signature) || !hash_equals($expected, $signature)) {
echo "ERROR: Signature doesn't match";
return;
}
if ($debug == 1) {
echo "ok";
return;
}
$reward = $reward * $this->data['settings']['currency_rate'];
$trans = $this->m_offerwall->getTransaction($transactionId, 'aoytasks');
if ($action == 2) {
$this->m_offerwall->reduceUserBalance($userId, abs($reward));
$this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 1, time());
echo "ok";
} else {
if (!$trans) {
$hold = ($reward > $minHold) ? 3 : 0;
if ($hold == 0) {
$offerId = $this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 2, time());
$this->m_offerwall->updateUserBalance($userId, $reward);
$this->m_core->addNotification($userId, currency($reward, $this->data['settings']['currency_rate']) . " from AoyTasks Offer #$offerId was credited.", 1);
$user = $this->m_core->get_user_from_id($userId);
$this->m_core->addExp($user['id'], $this->data['settings']['offerwall_exp_reward']);
if (($user['exp'] + $this->data['settings']['offerwall_exp_reward']) >= ($user['level'] + 1) * 100) {
$this->m_core->levelUp($user['id']);
}
} else {
$availableAt = time() + $hold * 86400;
$offerId = $this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 0, $availableAt);
$this->m_core->addNotification($userId, "Your AoyTasks Offer #$offerId is pending approval.", 0);
}
echo "ok";
} else {
echo "DUP";
}
}
}
Step 2 — Open application/controllers/offerwall.php and add before the last }:
public function aoytasks()
{
$api_key = ""; // YOUR API KEY
$this->data['page'] = 'AoyTasks Offerwall';
$this->data['iframe'] = '<iframe style="width:100%;height:800px;border:0;" scrolling="yes" frameborder="0"
src="https://aoytasks.com/offerwall/' . $api_key . '/' . $this->data['user']['id'] . '"></iframe>';
$this->data['wait'] = 3; // Hold days
$this->render('offerwall', $this->data);
}
Step 3 — Add a menu link in application/views/user_template/template.php:
<li><a href="<?= site_url('offerwall/aoytasks') ?>" key="t-aoytasks">AoyTasks</a></li>
Step 4 — Open application/config/config.php, find $config['csrf_exclude_uris'] and add:
'wh/aoytasks',
Set your Postback URL in the AoyTasks dashboard to: https://yourdomain.com/wh/aoytasks
VieFaucet 4.4 Integration
Integration for VieFaucet 4.4 follows the same steps as 4.3 with a minor difference in the notification helper function name.
Step 1 — Open application/controllers/wh.php and add this function:
public function aoytasks()
{
$secret = ""; // YOUR SECRET KEY
$hold = 3;
$minHold = 0.5;
$userId = isset($_POST['subId']) ? $this->db->escape_str($_POST['subId']) : null;
$transactionId = isset($_POST['transId']) ? $this->db->escape_str($_POST['transId']) : null;
$reward = isset($_POST['reward']) ? $this->db->escape_str($_POST['reward']) : null;
$action = isset($_POST['status']) ? $this->db->escape_str($_POST['status']) : null;
$debug = isset($_POST['debug']) ? $this->db->escape_str($_POST['debug']) : "0";
$userIp = isset($_POST['userIp']) ? $this->db->escape_str($_POST['userIp']) : "0.0.0.0";
$signature = isset($_POST['signature']) ? $this->db->escape_str($_POST['signature']) : null;
$expected = hash_hmac('sha256', ($_POST['transId'] ?? '') . ($_POST['subId'] ?? '') . ($_POST['reward'] ?? ''), $secret);
if (!is_string($signature) || !hash_equals($expected, $signature)) {
echo "ERROR: Signature doesn't match";
return;
}
if ($debug == 1) {
echo "ok";
return;
}
$reward = $reward * $this->data['settings']['currency_rate'];
$trans = $this->m_offerwall->getTransaction($transactionId, 'AoyTasks');
if ($action == 2) {
$this->m_offerwall->reduceUserBalance($userId, abs($reward));
$this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 1, time());
echo "ok";
} else {
if (!$trans) {
$hold = ($reward > $minHold) ? 3 : 0;
if ($hold == 0) {
$offerId = $this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 2, time());
$this->m_offerwall->updateUserBalance($userId, $reward);
// Note: 4.4 uses currencyDisplay() instead of currency()
$this->m_core->addNotification($userId, currencyDisplay($reward, $this->data['settings']) . " from AoyTasks Offer #$offerId was credited.", 1);
$user = $this->m_core->getUserFromId($userId);
$this->m_core->addExp($user['id'], $this->data['settings']['offerwall_exp_reward']);
if (($user['exp'] + $this->data['settings']['offerwall_exp_reward']) >= ($user['level'] + 1) * 100) {
$this->m_core->levelUp($user['id']);
}
} else {
$availableAt = time() + $hold * 86400;
$offerId = $this->m_offerwall->insertTransaction($userId, 'AoyTasks', $userIp, $reward, $transactionId, 0, $availableAt);
$this->m_core->addNotification($userId, "Your AoyTasks Offer #$offerId is pending approval.", 0);
}
echo "ok";
} else {
echo "DUP";
}
}
}
Steps 2, 3 & 4 — Identical to VieFaucet 4.3. See the section above.
Postback URL: https://yourdomain.com/wh/aoytasks
CryptoFaucet / ClaimBits Integration
Create the file system/gateways/aoytasks.php and configure your publisher app Secret Key:
<?php
define('BASEPATH', true);
require('../init.php');
$secret = "YOUR_SECRET_KEY";
$userId = $_POST['subId'] ?? null;
$transId = $_POST['transId'] ?? null;
$reward = $_POST['reward'] ?? null;
$status = $_POST['status'] ?? null;
$debug = $_POST['debug'] ?? "0";
$signature = $_POST['signature'] ?? null;
$userIp = $_POST['userIp'] ?? "0.0.0.0";
$expected = hash_hmac('sha256', (string) $transId . (string) $userId . (string) $reward, $secret);
if (!is_string($signature) || !hash_equals($expected, $signature)) {
echo "ERROR: Signature doesn't match";
exit;
}
if ($debug == 1) {
echo "ok";
exit;
}
if ($status == 2) {
// Reversal / Chargeback — subtract reward
// Your reversal logic here
} else {
// Credit reward to user
// Your crediting logic here
}
echo "ok";
Currency must match your site balance unit in your publisher app settings.
Postback URL: https://yourdomain.com/system/gateways/aoytasks.php
S2S Postback
When a user completes an action, AoyTasks sends an HTTPS POST request with a URL-encoded body to your registered Postback URL. Verify its signature before crediting the user.
Postback Parameters
| Parameter | Description | Example |
|---|---|---|
subId | Unique identifier code of the user who completed the action on your platform. | user123 |
transId | Unique identification code of the transaction made by your user. | XX-12345678 |
offer_name | Name of the completed offer. | AoyTasks - Register and Earn |
offer_type | Completion type (ptc, video, task, shortlink, offer, or survey); test deliveries use test. | ptc |
reward | Amount of your virtual currency to be credited to your user. | 1.25 |
reward_name | The name of your currency set when you registered your website. | Points |
reward_value | Amount of your virtual currency credited for $1 worth of payout (Exchange Rate). | 1000.00 |
payout | Publisher payout in USD. | 0.100000 |
userIp | The user's IP address who completed the action. | 192.168.1.0 |
country | Country (ISO2 form) where the completion came from. | US |
status | 1 = credit 2 = reversal / chargeback | 1 |
debug | Check if this is a test or live postback call. | 0 (live) / 1 (test) |
signature | HMAC-SHA256 signature authenticated with your app Secret Key. | 64 lowercase hexadecimal characters |
Rewards and payouts are nonnegative decimal strings. For status=2, reverse the matching original credit once. A test postback (debug=1) must never change a balance.
Postback Security
Always verify the signature parameter and sender IP to confirm the postback originates from AoyTasks servers, and match subId to the exact identifier of an existing user on your site.
Server IPs to Allowlist
Accept requests only from our server IPv4 or IPv6 address over HTTPS:
187.127.209.238 2a02:4780:5e:494e::1
Signature Formula
Calculate hash_hmac('sha256', $transId . $subId . $reward, $secretKey) using the received string values in that exact order, then compare with signature using hash_equals:
hash_hmac('sha256', $transId . $subId . $reward, $secretKey)
<?php
$secret = ""; // Your Secret Key from My Apps
$subId = $_POST['subId'] ?? '';
$transId = $_POST['transId'] ?? '';
$reward = $_POST['reward'] ?? '';
$signature = $_POST['signature'] ?? '';
$expected = hash_hmac('sha256', $transId . $subId . $reward, $secret);
if (!is_string($signature) || !hash_equals($expected, strtolower($signature))) {
http_response_code(400);
echo "ERROR: Signature doesn't match";
exit;
}
?>
Delivery uses a 15-second total timeout and a 5-second connection timeout, with up to 12 attempts. Record (transId, status) with a unique database constraint to prevent duplicate credits.
Respond to Postback
Return an HTTP 2xx response (for example outputting ok) after the authenticated event has been recorded and its reward applied atomically. A duplicate authenticated event should also return 2xx without applying the reward again.
http_response_code(200);
echo "ok";
Postback Example
Below is a complete PHP postback example that verifies the sender IP and HMAC-SHA256 signature, acknowledges test postbacks (debug=1) without changing balances, deduplicates events by (transId, status), and processes both credits (status=1) and reversals (status=2):
<?php
$secret = ""; // Your Secret Key from My Apps
// Verify direct connection IP from AoyTasks servers
$allowed_ips = ['187.127.209.238', '2a02:4780:5e:494e::1'];
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (!in_array($ip, $allowed_ips, true)) {
http_response_code(403);
echo "ERROR: Invalid source";
exit;
}
// Read postback parameters
$userId = (string) ($_POST['subId'] ?? '');
$transId = (string) ($_POST['transId'] ?? '');
$reward = (string) ($_POST['reward'] ?? '');
$rewardName = (string) ($_POST['reward_name'] ?? '');
$offerName = (string) ($_POST['offer_name'] ?? '');
$offerType = (string) ($_POST['offer_type'] ?? '');
$payout = (string) ($_POST['payout'] ?? '0');
$userIp = (string) ($_POST['userIp'] ?? '0.0.0.0');
$country = (string) ($_POST['country'] ?? '');
$status = (int) ($_POST['status'] ?? 1);
$debug = (int) ($_POST['debug'] ?? 0);
$signature = (string) ($_POST['signature'] ?? '');
// Validate HMAC-SHA256 signature
$expected = hash_hmac('sha256', $transId . $userId . $reward, $secret);
if (!hash_equals($expected, strtolower($signature))) {
http_response_code(400);
echo "ERROR: Signature doesn't match";
exit;
}
// Acknowledge test postbacks without changing balances
if ($debug === 1) {
http_response_code(200);
echo "ok";
exit;
}
// Handle reversal (status = 2) or credit (status = 1)
if ($status === 2) {
$rewardAmount = -abs((float) $reward);
} else {
$rewardAmount = abs((float) $reward);
}
// Prevent duplicates — check if (transId, status) already exists in your database
if (isNewTransaction($transId, $status)) {
processTransaction($userId, $rewardAmount, $transId, $status);
}
http_response_code(200);
echo "ok";
?>
Use Send Test Postback in your app settings to test your endpoint without crediting a user.
CPA Advertising — Overview
CPA means Cost Per Action. You pay only when your backend confirms a real action — such as creating an account or completing a purchase. Opening a page alone does not earn a CPA reward.
To get started, open Advertiser → CPA Advertising → CPA Balance and transfer at least $10.00 from your Purchase Balance. A minimum CPA balance of $10.00 is required to create or resume a campaign.
Choose the right integration: An advertiser sends conversions to AoyTasks using a CPA campaign secret and click_id. A publisher receives rewards from AoyTasks using an app Secret Key and transId. These credentials are not interchangeable.
How It Works
click_id.click_id with the user's account or order, then verifies the required action.https://aoytasks.com/api/v1/cpa/postback.Campaign Fields & Click Tracking
Step 1 — Campaign Details
| Field | What to enter | Who sees it |
|---|---|---|
Internal name / note | Required name up to 128 characters. Optional private note up to 5,000 characters. | You and administrators. |
Offerwall category | Offers or Surveys. | Matching offerwall category. |
Destination URL |
Public HTTPS URL (up to 2,048 characters, port 443). If {click_id} is omitted, AoyTasks appends ?click_id=....Supported destination macros: {click_id} — Unique 32-character lowercase hex token (valid for 30 days).{sub_id} — Publisher's user identifier.{campaign_id} — Campaign UUID.{ip_address} / {country_code} — Click-time IP address and ISO2 country code.
|
Users visit this URL. |
Public title / description | Required title up to 128 characters; description up to 250 characters explaining eligibility and steps. | Users and publishers. |
Offer image / icon URL | Optional upload (250×250 px, JPG/PNG/GIF, up to 500 KB) or public HTTPS square icon URL. | Users and publishers. |
Example Destination URL
https://your-site.example/signup?click_id={click_id}&member={sub_id}&campaign={campaign_id}&ip={ip_address}&cc={country_code}
Postback / S2S Integration
Endpoint: https://aoytasks.com/api/v1/cpa/postback. Send over HTTPS from your backend or measurement provider (MMP). A browser pixel or page visit does not confirm a conversion.
Method A — Secret Header (Recommended for your own backend)
Copy your secret from Campaign → Integration and send it in the X-Postback-Secret HTTP header. No sender IP allowlist is required for Method A.
curl --get "https://aoytasks.com/api/v1/cpa/postback" \
--data-urlencode "click_id=SAVED_32_HEX_CLICK_ID" \
--data-urlencode "event=register" \
--header "X-Postback-Secret: YOUR_CPA_SECRET"
Method B — Secret Query/Body Parameter (For MMPs)
If your measurement provider cannot send custom HTTP headers, pass secret=YOUR_CPA_SECRET and configure the provider's sending IPv4/IPv6 addresses or CIDRs in Campaign → Integration → Advertiser IP allowlist (up to 100 entries).
https://aoytasks.com/api/v1/cpa/postback?click_id=SAVED_CLICK_ID&event=register&secret=YOUR_CPA_SECRET
Postback Parameters
| Parameter | Requirement | Description |
|---|---|---|
click_id | Required | Exact saved 32-character lowercase hexadecimal token from the click. |
event | Required | Exact configured event name (e.g. register, first_purchase). |
status | Optional | Defaults to approved. Send rejected to log a nonbillable rejection, or reversed (alias chargeback) to refund a paid conversion. |
payout | Dynamic only | Positive decimal USD within your campaign's configured min/max range (ignored for fixed-payout events). |
secret | Method B only | 40-character hexadecimal CPA secret (requires Advertiser IP allowlist). |
ip_address | Optional | User's public conversion-time IP for optional VPN/proxy and country comparison checks. |
country_code | Optional | Uppercase 2-letter ISO country code at conversion time for country comparison against the click country. |
Reversing a Paid Conversion (Chargeback)
curl --get "https://aoytasks.com/api/v1/cpa/postback" \
--data-urlencode "click_id=ORIGINAL_SAVED_CLICK_ID" \
--data-urlencode "event=first_purchase" \
--data-urlencode "status=reversed" \
--header "X-Postback-Secret: YOUR_CPA_SECRET"
Measurement Providers (MMPs)
When using a measurement provider, pass {click_id} into your provider's passthrough parameter on the destination URL, then map that saved token back to click_id in the provider's callback configuration (AppsFlyer, Adjust, Branch).
Secret Keys & IP Allowlist
Every CPA postback is authenticated with a 40-character lowercase hexadecimal secret key found in Campaign → Integration:
| Secret Type | Scope | Notes |
|---|---|---|
| Campaign Secret | One campaign | Authenticates postbacks only for that specific campaign. Rotating it does not affect other campaigns. |
| Global Secret | All your CPA campaigns | Authenticates postbacks across all campaigns in your advertiser account. |
When using secret= in the query/body (Method B), the sending server's IPv4/IPv6 address or CIDR range must be listed in your Advertiser IP allowlist (up to 100 entries; /0 catch-all ranges are not permitted).
Events & Payouts
Add 1–50 events per campaign. Event names start with a lowercase letter and use lowercase letters, digits, and underscores (up to 64 characters). Each click_id + event combination can be approved once.
| Event | Label | Example Gross Payout | When to send |
|---|---|---|---|
register | Create an account | $0.10 | After the account meets your stated requirements. |
reach_level_10 | Reach level 10 | $0.50 | After your server confirms the user reached level 10. |
first_purchase | Make your first purchase | $2.00 | After a qualifying payment is confirmed. |
Fixed Payout: Uses the saved event price (with optional Tier 1 / Tier 2 / Tier 3 regional overrides).
Dynamic Payout: Pass payout on each approval as a positive USD decimal string (up to 8 decimal places, e.g. 1.50000000) within the campaign's saved min/max range.
Caps & Budget Management
Purchase Balance and CPA Balance are separate. Transfers into CPA Balance are one-way (minimum $10.00) and cannot be reversed.
| Control | Counts | When reached |
|---|---|---|
| Daily Cap | Approved events per day (0 = unlimited) | Further approvals return HTTP 429 until the next day (UTC). |
| Lifetime Cap | Total approved events (0 = unlimited) | Campaign status becomes Completed. Reversals do not reopen cap slots. |
| CPA Balance | Must cover each gross event payout | Insufficient funds reject approval and pause the campaign. Fund and click Resume manually. |
Devices & Countries
Choose All devices or select specific platforms (Desktop, Android, iOS). For countries, choose Worldwide, allow selected countries, or block selected countries. Current minimum gross payouts by tier:
| Tier | Minimum Gross Payout |
|---|---|
| Tier 1 | $0.00500000 |
| Tier 2 | $0.00200000 |
| Tier 3 | $0.00100000 |
Platform Fees
Approval debits the gross payout from your CPA Balance. The platform fee comes out of that gross amount (not added on top), and the publisher receives the remainder. Reversals (status=reversed) refund the original gross charge into your CPA Balance.
| Gross payout band | Current fee |
|---|---|
| Up to $1.00000000 | 20% |
| Above $1.00000000, up to $5.00000000 | 15% |
| Above $5.00000000, up to $20.00000000 | 10% |
| Above $20.00000000 | 7% |
Workspace & Campaign Status
| Status | Meaning | New approvals? |
|---|---|---|
| Pending | Awaiting admin review. | No. |
| Active | Approved and running. | Yes, subject to all checks. |
| Paused | Stopped manually or for insufficient funding. | No; fund if needed (≥ $10.00) and resume. |
| Completed | Lifetime cap reached. | No. |
| Rejected | Admin rejected campaign. | No; review reason or contact support. |
Postback Response Codes
| HTTP | Meaning | Next action |
|---|---|---|
| 200 | Accepted event, logged rejection, or reversal. | Inspect JSON action; a logged rejection is not a paid approval. |
| 400 / 413 / 426 | Invalid input, oversized request, or non-HTTPS. | Use exact endpoint, scalar parameters, and form-encoded POST or GET query. |
| 401 | No authentication provided. | Send X-Postback-Secret header or secret parameter. |
| 403 | Wrong secret, unapproved sender IP, or failed network/country check. | Check secret scope, Advertiser IP allowlist, and conversion IP/country values. |
| 404 | Unknown click_id. | Ensure {click_id} is in your destination URL and returned unchanged. |
| 409 | Duplicate event, expired click (30 days), inactive campaign, or insufficient balance. | Inspect reason in Postback Log. |
| 422 | Unknown event name or invalid dynamic payout. | Match exact configured event name and decimal payout limits. |
| 429 | Rate limit (120 req/min) or conversion cap reached. | Back off or check daily/lifetime caps. |
| 500 / 503 | Temporary verification or processing issue. | Retain event and retry with backoff using the same click_id and event. |
Troubleshooting
click_id was saved with the user's account/order and not sent as a literal macro string.event name and valid CPA secret (plus IP allowlist if using Method B).Before Launch Checklist
- Public title, description, devices, and countries match your actual offer requirements.
{click_id}attribution is saved in your database across signup, redirects, and payment.- Your backend verifies the completed action before sending the exact configured
eventname. - CPA secrets remain server-side, and any Method B sender IPs are added to your Advertiser IP allowlist.
- Retries use the same
click_idandeventso duplicate protection prevents double charges.
Brand Assets
Download the official AoyTasks logos and AT icon for your website, app, or integration.
All files have transparent backgrounds; the preview backgrounds are not part of the artwork. Keep the original colors and aspect ratio. Use SVG for crisp website logos and the AT icon at favicon sizes. The complete ZIP includes the supplied PNG sizes and usage notes.