Affiliate
The five endpoints managing a partner's programme, earnings and payout requests.
Overview
The affiliate programme is where a customer takes a share of the business their own link brings in. These five endpoints manage one partner's own programme.
Earnings move in two stages: a commission clears first and then reaches the available balance. A payout is asked from the available amount alone.
Payouts are settled by hand. A request is opened, the operator approves it, and only one request stands open at a time.
Reference
Reading Where You Stand
Returns the programme, the earnings and the payout state in one call.
curl 'https://panel.example.com/api/v1/client/affiliate' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.example.com/api/v1/client/affiliate', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
if (! data.enrolled) showJoinButton(data.program);$ch = curl_init('https://panel.example.com/api/v1/client/affiliate');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// This read WRITES: it moves the cleared commissions into the available balance and is not read-only.
$aff = Kernel::internal('client:Affiliate/GetAffiliate', ['owner_id' => $uid])['data'];
$canAsk = $aff['payout']['ready'] ?? false;Joining the Programme
Signs the account up to the affiliate programme.
curl -X POST 'https://panel.example.com/api/v1/client/affiliate/enroll' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.example.com/api/v1/client/affiliate/enroll', {
method: 'POST',
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
shareLink(data.referral.link);$ch = curl_init('https://panel.example.com/api/v1/client/affiliate/enroll');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The partnership opens in THE ACCOUNT's currency and cannot be changed later; check the profile first.
$me = Kernel::internal('client:Account/GetMe', ['owner_id' => $uid])['data'];
if ($me['currency'] === $wanted)
Kernel::internal('client:Affiliate/EnrollAffiliate', ['owner_id' => $uid]);Listing the Commissions
Returns the commissions earned, newest first.
curl 'https://panel.example.com/api/v1/client/affiliate/commissions' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.example.com/api/v1/client/affiliate/commissions', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
const soon = data.filter((c) => c.state === 'clearing');$ch = curl_init('https://panel.example.com/api/v1/client/affiliate/commissions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A clearing commission CANNOT be paid yet: it reaches the available balance on its clearing day.
$rows = Kernel::internal('client:Affiliate/GetAffiliateCommissions', ['owner_id' => $uid])['data'];
$soon = array_filter($rows, fn ($c) => $c['state'] === 'clearing');Asking to Be Paid
Asks for the available earnings to be paid out.
curl -X POST 'https://panel.example.com/api/v1/client/affiliate/withdraw' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"amount":40,"gateway":"PayPal","gateway_info":"[email protected]"}'const res = await fetch('https://panel.example.com/api/v1/client/affiliate/withdraw', {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ amount, gateway, save_default: true }),
});
const { data } = await res.json();$ch = curl_init('https://panel.example.com/api/v1/client/affiliate/withdraw');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['amount' => 40, 'gateway' => 'PayPal']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Take the amount FROM THE DASHBOARD: what is available can move as commissions clear during the read.
$aff = Kernel::internal('client:Affiliate/GetAffiliate', ['owner_id' => $uid])['data'];
$max = $aff['balance']['available']['amount'];
Kernel::internal('client:Affiliate/WithdrawAffiliate',
['owner_id' => $uid, 'amount' => $max, 'gateway' => $gw]);Saving a Payout Destination
Saves or clears the destination detail of a payout road.
curl -X PUT 'https://panel.example.com/api/v1/client/affiliate/payment-method' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"gateway":"PayPal","info":"[email protected]"}'const res = await fetch('https://panel.example.com/api/v1/client/affiliate/payment-method', {
method: 'PUT',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ gateway, info }),
});
const { data } = await res.json();$ch = curl_init('https://panel.example.com/api/v1/client/affiliate/payment-method');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['gateway' => $gw, 'info' => $info]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A destination is kept PER ROAD: clearing one leaves the others alone and the map is managed one by one.
Kernel::internal('client:Affiliate/SaveAffiliatePayoutMethod',
['owner_id' => $uid, 'gateway' => $gw, 'info' => '']);Pitfalls
Reading where you stand moves the commissions whose clearing day arrived into the available balance. The endpoint is not read-only, and two calls in a row can show different balances. Call it right before a payout request to see the highest amount you may ask for.
A commission is not paid the moment it is earned: it waits out the clearing period the operator set. The clearing figure on the dashboard is part of what was earned and cannot be asked for. Adding the two figures and asking for the sum is refused.
A second request cannot be opened while one waits. A new one is refused until the operator settles it by hand. Read the pending field on the dashboard and close the request road in your interface, or the customer meets an error they cannot place.
The partnership record opens in the account's currency at the time of joining and the commissions build up in it. Changing the currency on the profile later does not move the earnings. Make sure the currency is right before joining.
Every payout road keeps a destination of its own, and clearing one leaves the others alone. Leaving the destination out of a request falls back to that road's saved detail, and the request is refused where none is saved.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.