# Affiliate Payout Requests

https://dev.wisecp.com/es/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

get/api/v1/admin/affiliates/withdrawals

`Affiliates/GetWithdrawals` admin

Returns the payout requests the partners opened.

Query 4

pageintWhich page.

limitintRecords per page. 100 at the most.

searchstringSearches the name, company, e-mail, payout method and request id.

statusstringThe status filter: `awaiting`, `process`, `completed`, `rejected` or `cancelled`.

Response fields data[] — 15 + meta — 4

idintThe request id.

affiliate_idintThe partner record that opened it.

owner_idintThe client behind the partner.

user_idintThe same client id. A second name coming from the query join.

full_namestringThe client's name.

company_namestringThe company name.

emailstringThe e-mail address.

amountstringThe amount asked for. Text with four decimals.

currencyintThe currency id of the amount.

gatewaystringThe payout method the partner picked.

gateway_infostringThe detail for that method. An account number or e-mail.

statusstringWhere the request stands.

status_msgstringThe note written on the status.

ctimestringWhen the request was opened.

updated_atstringWhen it last changed.

totalintHow many requests there are. It comes back under meta.

pageintThe page you are on.

limitintThe page size.

next_pageintThe next page. Zero on the last one.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/affiliates/withdrawals?status=awaiting' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
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);
```

```php
$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);
```

```php
// 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

post/api/v1/admin/affiliates/withdrawals/bulk

`Affiliates/BulkWithdrawals` admin touches the balance

Approves, refuses or removes several payout requests.

Body 2

actionstringreqWhat to do: `approve`, `reject` or `delete`.

idsint[]reqThe request ids to work on. An id that is not found gets skipped without a word.

Response fields data — 2

actionstringThe job applied.

processedint[]The ids you sent. Not the ones that truly changed.

Errors 3

action_invalid422The job name is none of the three values.

ids_required422No request id was given.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
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]}'
```

```javascript
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();
```

```php
$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);
```

```php
// 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

delete/api/v1/admin/affiliates/withdrawals/{wid}

`Affiliates/DeleteWithdrawal` admin

Removes one payout request and gives the amount back where needed.

Response fields data — 2

deletedboolWhether the delete ran.

idintThe id of the request removed.

Errors 2

not_found404No such request.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X DELETE 'https://panel.example.com/api/v1/admin/affiliates/withdrawals/3' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
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();
```

```php
$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);
```

```php
// The one difference from a bulk delete: a missing id gives 404 here and is skipped in bulk.
Api::Affiliates()->DeleteWithdrawal(['wid' => $wid]);
```

## Pitfalls

> **A refusal does not give the balance back**
> 
> 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.

> **Approve, refuse, approve again takes it twice**
> 
> 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 list that comes back does not say what was handled**
> 
> 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.

> **The balance never goes below zero**
> 
> 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.

> **Two ways to remove, one difference**
> 
> 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

- [Affiliate Partners](https://dev.wisecp.com/en/affiliate-partners)
- [Affiliate Assignments](https://dev.wisecp.com/en/affiliate-assignments)
- [Affiliate Program Settings](https://dev.wisecp.com/en/affiliate-program-settings)
