# ITEC Pay — External API

Public, key-authenticated endpoints for outside applications. No session,
no login screen: every request carries the shared API key.

## Authentication

Add the key to your `.env`:

```
EXTERNAL_API_KEY=72ad618f31858fc8bf1d4ffb7e6c995c8e7f1ff33af50dba4318e78d67a654f9
```


Send it on every request, either as a header:

```
X-API-Key: 72ad618f31858fc8bf1d4ffb7e6c995c8e7f1ff33af50dba4318e78d67a654f9
```

...or as a `key` field in the request body (form or JSON).

> The API is POST-only. Parameters and the key must travel in the request
> body or the `X-API-Key` header — never in the URL, so they cannot leak
> into browser history, proxies or access logs.

A missing or wrong key returns `401`:

```json
{"status":401,"message":"Unauthorized."}
```

> Keep the key secret (use HTTPS — the site is served over
> `https://testing.itecpay.rw/`). Rotate it by changing
> `EXTERNAL_API_KEY` in `.env` — all old keys stop working immediately.

## Endpoints

### POST /api/external/reports/withdrawals

Base URL: `https://testing.itecpay.rw/`

Full endpoint: `https://testing.itecpay.rw/api/external/reports/withdrawals`

Duplicate of the internal staff report `GET /api/reports/withdrawals` —
every transfer out plus its charge in a date range.

#### Request body

Send as `application/json` (or form-encoded):

| Parameter  | Type     | Required | Description                                            |
|------------|----------|----------|--------------------------------------------------------|
| `from`     | `string` | yes      | Start date, `YYYY-MM-DD`                               |
| `to`       | `string` | yes      | End date, `YYYY-MM-DD`                                 |
| `client`   | `string` | no       | Client code; omit / `0` for General                    |
| `currency` | `string` | no       | Currency id; omit / `0` for all currencies             |
| `key`      | `string` | no       | API key if not sent in the `X-API-Key` header          |

#### Example

```bash
curl -X POST "https://testing.itecpay.rw/api/external/reports/withdrawals" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: 72ad618f31858fc8bf1d4ffb7e6c995c8e7f1ff33af50dba4318e78d67a654f9" \
  -d '{"from":"2026-08-01","to":"2026-08-11","client":"0","currency":"0"}'
```

#### Response

`200 OK`:

```json
{
  "status": 200,
  "rows": [
    {
      "trans_id": 12345,
      "req_ref": "9f17e356-2d5e-4e8d-9a92-3f7f9d12b1a4",
      "short_name": "ACME",
      "c_code": "ACME001",
      "out_amount": "500.00",
      "phone_number": "0788123456",
      "receiver_name": "",
      "symbol": "RWF",
      "transaction_type": "Transfer",
      "dueDate": "2026-08-05 09:41:12"
    }
  ]
}
```

| Field             | Description                                        |
|-------------------|----------------------------------------------------|
| `trans_id`        | Transaction id                                     |
| `req_ref`         | Internal request reference                         |
| `short_name`      | Client display name                                |
| `c_code`          | Client code                                        |
| `out_amount`      | Amount withdrawn                                  |
| `phone_number`    | Phone the money was sent to                       |
| `receiver_name`   | Receiver name (reserved; currently always `""`)  |
| `symbol`          | Currency symbol                                    |
| `transaction_type`| `Charge` (fee) or `Transfer`                      |
| `dueDate`         | Transaction timestamp                              |

`transaction_type` filters as `Charge` or `Transfer`; each withdrawal
consists of a `Transfer` row plus its `Charge` row.

#### Errors

| Code | Body                                          |
|------|-----------------------------------------------|
| 400  | `{"status":400,"message":"Missing API key."}` |
| 401  | `{"status":401,"message":"Unauthorized."}`    |

## Implementation notes

- Controller: `app/Api/ExternalController.php`
- Route: `routes/api.php` → `POST /api/external/reports/withdrawals`
- Data source: `App\Models\ManagerPortal::withdrawalsReport()` (same as the staff report)
- No session, CSRF or role middleware — the key check runs inside the controller.
