> For the complete documentation index, see [llms.txt](https://teamleader-sdk.mcore-services.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://teamleader-sdk.mcore-services.dev/api-reference/expenses/incoming-credit-notes.md).

# Incoming Credit Notes

Manage incoming credit notes from suppliers in Teamleader Focus.

```php
Teamleader::incomingCreditNotes()
```

|                          |                                                                      |
| ------------------------ | -------------------------------------------------------------------- |
| Class                    | `McoreServices\TeamleaderSDK\Resources\Expenses\IncomingCreditNotes` |
| Create / update / delete | ✓ / ✓ / ✓                                                            |
| Pagination               | No                                                                   |

## Endpoints

* `incomingCreditNotes.add`
* `incomingCreditNotes.approve`
* `incomingCreditNotes.delete`
* `incomingCreditNotes.info`
* `incomingCreditNotes.listPayments`
* `incomingCreditNotes.markAsPendingReview`
* `incomingCreditNotes.refuse`
* `incomingCreditNotes.registerPayment`
* `incomingCreditNotes.removePayment`
* `incomingCreditNotes.sendToBookkeeping`
* `incomingCreditNotes.update`
* `incomingCreditNotes.updatePayment`

## Filters

`list()` takes no filters.

## Accepted values

Public constants on the class. Body fields and enum values outside these lists throw before the request is sent.

| Constant                  | Values                                                                                                                                                          |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CURRENCIES`              | `BAM`, `CAD`, `CHF`, `CLP`, `CNY`, `COP`, `CZK`, `DKK`, `EUR`, `GBP`, `INR`, `ISK`, `JPY`, `MAD`, `MXN`, `NOK`, `PEN`, `PLN`, `RON`, `SEK`, `TRY`, `USD`, `ZAR` |
| `PAYMENT_STATUSES`        | `unknown`, `paid`, `not_paid`                                                                                                                                   |
| `REGISTER_PAYMENT_FIELDS` | `payment`, `paid_at`, `payment_method_id`, `remark`                                                                                                             |
| `REVIEW_STATUSES`         | `pending`, `approved`, `refused`                                                                                                                                |
| `TOTAL_KEYS`              | `tax_exclusive`, `tax_inclusive`                                                                                                                                |
| `UPDATE_PAYMENT_FIELDS`   | `payment_id`, `payment`, `paid_at`, `payment_method_id`, `remark`                                                                                               |
| `WRITE_FIELDS`            | `title`, `supplier_id`, `document_number`, `invoice_date`, `due_date`, `currency`, `total`, `company_entity_id`, `file_id`, `payment_reference`, `iban_number`  |

## Methods

### `getResponseStructure()`

```php
getResponseStructure(): array
```

Get response structure documentation

### `add()`

```php
add(array $data): array
```

Create a new expense document

`{base}.add` requires `title` and `currency.code`. Everything else — including `total` — is optional.

* `$data` — Document data

**Throws** `InvalidArgumentException` When a required field is missing, or a field or value is not accepted

### `create()`

```php
create(array $data): array
```

Alias for add()

* `$data` — Document data

### `update()`

```php
update(string $id, array $data): array
```

Update an expense document

* `$id` — Document UUID
* `$data` — Fields to update; null clears a nullable field

**Throws** `InvalidArgumentException` When the ID is empty, or a field or value is not accepted

### `info()`

```php
info(string $id, $includes = null): array
```

Get one expense document

* `$id` — Document UUID
* `$includes` — Not supported — the info endpoint takes no includes

**Throws** `InvalidArgumentException` When the ID is empty or includes are requested

### `delete()`

```php
delete(string $id): array
```

Delete an expense document

### `approve()`

```php
approve(string $id): array
```

Approve an expense document

### `refuse()`

```php
refuse(string $id): array
```

Refuse an expense document

### `markAsPendingReview()`

```php
markAsPendingReview(string $id): array
```

Put an expense document back to pending review

### `sendToBookkeeping()`

```php
sendToBookkeeping(string $id): array
```

Send an expense document to bookkeeping

### `listPayments()`

```php
listPayments(string $id): array
```

List the payments registered on an expense document

Returns `data[]` — id, payment {amount, currency}, paid\_at, payment\_method, remark — and `meta.total` with the amount paid and, since specification 1.221.0, its currency.

### `registerPayment()`

```php
registerPayment(string $id, array $payment, string $paidAt, ?string $paymentMethodId = null, ?string $remark = null): array
```

Register a payment

* `$id` — Document UUID
* `$payment` — \['amount' => float, 'currency' => 'EUR']
* `$paidAt` — ISO 8601 date-time
* `$paymentMethodId` — Payment method UUID
* `$remark` — Free text

**Throws** `InvalidArgumentException` When a required value is missing or invalid

### `removePayment()`

```php
removePayment(string $id, string $paymentId): array
```

Remove one payment

**Throws** `InvalidArgumentException` When either ID is empty

### `updatePayment()`

```php
updatePayment(string $id, string $paymentId, ?array $payment = null, ?string $paidAt = null, ?string $paymentMethodId = null, ?string $remark = null): array
```

Update one payment

Only the document and payment IDs are required: pass null for $payment to change only the date, method or remark. Before v2.2.8 the payment amount was required on every update.

* `$id` — Document UUID
* `$paymentId` — Payment UUID
* `$payment` — \['amount' => float, 'currency' => 'EUR'], or null to leave it
* `$paidAt` — ISO 8601 date-time
* `$paymentMethodId` — Payment method UUID
* `$remark` — Free text

**Throws** `InvalidArgumentException` When an ID is empty or the payment is invalid

### `list()`

```php
list(array $filters = [], array $options = []): array
```

Not available — there is no list endpoint for a single expense type

**Throws** `InvalidArgumentException` Always

### `getValidCurrencyCodes()`

```php
getValidCurrencyCodes(): array
```

### `getValidReviewStatuses()`

```php
getValidReviewStatuses(): array
```

### `getValidPaymentStatuses()`

```php
getValidPaymentStatuses(): array
```

## Examples

Create a basic incoming credit note:

```php
$creditNote = Teamleader::incomingCreditNotes()->add(['title' => 'Credit Note', 'currency' => ['code' => 'EUR'], 'total' => ['tax_exclusive' => ['amount' => 500.00]]]);
```

Approve a credit note:

```php
Teamleader::incomingCreditNotes()->approve('creditnote-uuid');
```

Refuse a credit note:

```php
Teamleader::incomingCreditNotes()->refuse('creditnote-uuid');
```

Send credit note to bookkeeping:

```php
Teamleader::incomingCreditNotes()->sendToBookkeeping('creditnote-uuid');
```

Delete a credit note:

```php
Teamleader::incomingCreditNotes()->delete('creditnote-uuid');
```

List all payments for a credit note:

```php
$payments = Teamleader::incomingCreditNotes()->listPayments('creditnote-uuid');
```

Register a payment for a credit note:

```php
$payment = Teamleader::incomingCreditNotes()->registerPayment('creditnote-uuid', ['amount' => 500.00, 'currency' => 'EUR'], '2024-01-20T10:00:00+00:00');
```

Remove a specific payment from a credit note:

```php
Teamleader::incomingCreditNotes()->removePayment('creditnote-uuid', 'payment-uuid');
```

Update an existing payment on a credit note:

```php
Teamleader::incomingCreditNotes()->updatePayment('creditnote-uuid', 'payment-uuid', ['amount' => 450.00, 'currency' => 'EUR']);
```
