Affiliate Payout Requests
The three endpoints that see and settle the payout requests partners open.
Overview
A partner cannot take the commission they earn straight away; they open a payout request and the team approves it. This article covers the three endpoints that see and settle those requests.
A request sits in one of five states: waiting, in process, completed, refused or cancelled. Only completed is the moment the money truly leaves, and it comes off the partner's balance.
What happens to the balance matters here: an approval takes the money down, a removal gives it back, and a refusal leaves the balance alone. Reading the three as one shows the partner a wrong figure.
Reference
Listing the Payout Requests
Returns the payout requests the partners opened.
awaiting, process, completed, rejected or cancelled.curl 'https://panel.example.com/api/v1/admin/affiliates/withdrawals?status=awaiting' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/affiliates/withdrawals?status=awaiting', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data, meta } = await res.json();
const owed = data.reduce((s, w) => s + Number(w.amount), 0);$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/withdrawals?status=awaiting');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The amounts sit in EACH REQUEST's own currency; convert before adding them up.
$rows = Api::Affiliates()->GetWithdrawals([], ['status' => 'awaiting'])['data'];
$byCurrency = [];
foreach ($rows as $w) $byCurrency[$w['currency']] = ($byCurrency[$w['currency']] ?? 0) + (float) $w['amount'];Handling Requests in Bulk
Approves, refuses or removes several payout requests.
approve, reject or delete.curl -X POST 'https://panel.example.com/api/v1/admin/affiliates/withdrawals/bulk' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"action":"approve","ids":[3,5]}'const res = await fetch('https://panel.example.com/api/v1/admin/affiliates/withdrawals/bulk', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ action: 'approve', ids: [3, 5] }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/withdrawals/bulk');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['action' => 'approve', 'ids' => [3, 5]]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// APPROVE takes it off the balance and REJECT DOES NOT give it back; delete is the one job that refunds.
Api::Affiliates()->BulkWithdrawals(['action' => 'approve', 'ids' => [3, 5]]);
// approved by mistake: delete rather than reject
Api::Affiliates()->BulkWithdrawals(['action' => 'delete', 'ids' => [3]]);Removing One Request
Removes one payout request and gives the amount back where needed.
curl -X DELETE 'https://panel.example.com/api/v1/admin/affiliates/withdrawals/3' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/affiliates/withdrawals/${wid}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/withdrawals/' . $wid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The one difference from a bulk delete: a missing id gives 404 here and is skipped in bulk.
Api::Affiliates()->DeleteWithdrawal(['wid' => $wid]);Pitfalls
An approval takes the amount off the partner's balance. A refusal writes the status alone and does not put the amount back, so refusing a request you approved leaves the money short on that balance for good. The way back from a wrong approval is removal and not refusal.
An approval takes from the balance only while the request is not already completed. Refusing an approved request and approving it again drops the state out of completed, so it takes a second time and the partner loses twice for one payout. Check the balance by hand after a round like that.
The processed field is the same set of ids you sent. A request that is not found gets skipped without a word, while its id still shows in that list. Read the statuses back from the listing endpoint to see that bulk work landed.
Every job that takes from the balance stops at zero. Approving a request larger than the balance leaves it at zero and the difference disappears with no error. Compare the request amount against the partner's balance before approving.
Removing one request and removing many do the same job, and both give the amount back on a completed request. The one difference is a missing id: the single endpoint answers 404 while the bulk one skips quietly. The single endpoint is safer for an id you are unsure of.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.