# Operator API (Quick Guide)

Base URL: `https://sandbox.playegamenow.com`

Auth: Processor Bearer token (Authorization header).
All responses are JSON.

---

## 1) Create customer + add money
**POST** `/operator/g/create/`

Creates a new customer and immediately adds money to their balance.

### Request Body
```json
{
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "payment_provider_id": "paypal",
  "operator_wallet_id": "1231",
  "player_wallet_id":  "123",
  "amount": "25.00",
  "operator_game_id": 42,
  "customer": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "date_of_birth": "1975-01-18"
  }
}
```

### Response (201)
```json
{
  "session_id": "uuid",
  "amount": "25.00",
  "operator_game_id": 42,
  "status": "pending"
}
```

---

## 2) Purchase (add money to existing customer)
**POST** `/operator/g/purchase/`

Adds money to an existing customer.

### Request Body
```json
{
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "payment_provider_id": "paypal",
  "operator_wallet_id": "1231",
  "player_wallet_id":  "123",
  "amount": "10.00",
  "operator_game_id": 42,
  "player_game_user_id": "1601-230020"
}
```

### Response (201)
```json
{
  "session_id": "uuid",
  "amount": "10.00",
  "operator_game_id": 42,
  "status": "pending"
}
```

---

## 3) Redeem (withdraw money from existing customer)
**POST** `/operator/g/redeem/`

Withdraws money from an existing customer.

### Request Body
```json
{
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "payment_provider_id": "paypal",
  "operator_wallet_id": "1231",
  "player_wallet_id":  "123",
  "amount": "5.00",
  "operator_game_id": 42,
  "player_game_user_id": "1601-230020"
}
```

### Response (201)
```json
{
  "session_id": "uuid",
  "amount": "5.00",
  "operator_game_id": 42,
  "status": "pending"
}
```

---

## 4) Create operator
**POST** `/operator/create/`

Creates a new operator account.

Auth: Processor Bearer token (Authorization header).

### Request Body
```json
{
  "username": "operator_demo_02",
  "email": "operator_demo_02@example.com",
  "business_name": "Fortune Hall",
  "contact_first_name": "John",
  "contact_last_name": "Doe",
  "address": "221B Baker Street, London",
  "contact_phone": "+380501112233",
  "operator_site_url": "https://operator.example.com"
}
```

### Response (201)
```json
{
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "username": "operator_demo_02"
}
```

### Notes
- Password is generated automatically.
- System sends password reset link to `email`.
- Returned `operator_id` is operator eWallet user id (UUID). Use it in `/operator/g/*` endpoints.

### Common Errors
- `400 Bad Request` — validation errors (for example, duplicate `username` or `email`).
- `401 Unauthorized` — missing or invalid processor token.

---

## Common Errors
- `400 Bad Request` — missing/invalid fields, amount < 0.01, invalid types.
- `401/403` — missing/invalid processor token, or service disabled.
- `404 Not Found` — operator or operator_game not found / not eligible.
- `500` — error (message: "Failed to process transaction").

---
### Fields
- `payment_provider_id` (string, required) payment provider
- `operator_id` (UUID string, required) operator id received when create operator
- `operator_wallet_id` (string, required) payment provider wallet id
- `player_wallet_id` (string, required) payment provider wallet id
- `amount` (decimal string, required, min 0.01)
- `operator_game_id` (integer, required) - each game will have it's unique, you will get it from operator admin
- `player_game_user_id` (string, required)
  This is `customerId` that you will receive from webhook after call /operator/g/create/ endpoint
- `customer` (object, required)
  - `first_name` (string)
  - `last_name` (string)
  - `email` (string)
  - `date_of_birth` (date string `YYYY-MM-DD`, optional, can be `null` or `""`)

### `player_game_user_id` Validation (purchase/redeem)
Validation depends on game platform name:

| Game platform | Regex pattern | Example |
|---|---|---|
| Golden Dragon | `^M-\d{3}-\d{3}-\d{3}$` | `M-290-204-128` |
| Golden Dragon City | `^M-\d{3}-\d{3}-\d{3}$` | `M-598-461-474` |
| Fortune 2 go (`f2go`) | `^\d{4}-\d{6}$` | `1601-230020` |
| River Sweeps | `^\d{2}(?:-\d{2}){5}$` | `95-72-66-97-03-07` |
| Magic City | `^M-\d{3}-\d{3}-\d{3}$` | `M-000-071-456` |
| Ultra Panda | `^[A-Za-z0-9]{1,64}$` | `DemoPlayer1` |

## Notes on Async Processing
These endpoints only initiate a transaction.
The returned `session_id` is the transaction UUID for later status checks (handled separately).

## Webhook (Session Result)
after you call create, redeem or purchase you will get session_id, after this you need to wait webhook in which 
we will send you information about status of this session(success, failed) and additional information, such as created customer id

Webhook details:
- We send a `POST` request to processor webhook URL configured in admin panel.
- Request body is JSON.
- Headers:
  - `Content-Type: application/json`
  - `Authorization: Bearer <processor.webhook_secret>`
  - `X-Idempotency-Key: tx:<session_id>`

Webhook payload example:
```json
{
  "event": "operator.transaction",
  "action": "purchase",
  "session_id": "5a1f6e95-4fb1-4fbe-ab03-4588f0f76c0f",
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "operator_api_user_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "operator_game_id": 42,
  "payment_provider_id": "paypal",
  "status": "success",
  "amount": "10.00",
  "fee": null,
  "player_wallet_id": "123",
  "player_game_user_id": "1601-230020",
  "game_name": "Fortune 2 go",
  "receipt": {
    "account_name": "John Doe",
    "purchase_amount": "10.00",
    "timestamp": "2026-05-23T12:30:45Z",
    "site_url": "www.fortune2go20.com",
    "game": "Fortune 2 go"
  },
  "error_message": null
}
```

Webhook `curl` example (for receiver-side testing):
```bash
curl -X POST "https://processor.example.com/webhook" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <processor.webhook_secret>" \
  -H "X-Idempotency-Key: tx:5a1f6e95-4fb1-4fbe-ab03-4588f0f76c0f" \
  -d '{
    "event": "operator.transaction",
    "action": "purchase",
    "session_id": "5a1f6e95-4fb1-4fbe-ab03-4588f0f76c0f",
    "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
    "operator_api_user_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
    "operator_game_id": 42,
    "payment_provider_id": "paypal",
    "status": "success",
    "amount": "10.00",
    "fee": null,
    "player_wallet_id": "123",
    "player_game_user_id": "1601-230020",
    "game_name": "Fortune 2 go",
    "receipt": {
      "account_name": "John Doe",
      "purchase_amount": "10.00",
      "timestamp": "2026-05-23T12:30:45Z",
      "site_url": "www.fortune2go20.com",
      "game": "Fortune 2 go"
    },
    "error_message": null
  }'
```

---

## 5) Get active operator games
**GET** `/operator/{operator_id}/games/`

Returns active operator games (`publish_site=true`) for the given operator id.
Only games that belong to the authenticated processor are returned.

Auth: Processor Bearer token (Authorization header).

### URL Param
- `operator_id` (UUID, eWallet user id)

### Response (200)
```json
[
  {
    "operator_game_id": 42,
    "display_name": "Fortune 2 go",
    "publish_site": true,
    "game_pos_url": "https://example.com/game-pos",
    "game_name": "Fortune 2 go"
  }
]
```

---

## 6) Get available games for authenticated processor
**GET** `/operator/games/`

Returns games assigned to the authenticated processor.

Auth: Processor Bearer token (Authorization header).

### Response (200)
```json
[
  {
    "game_id": "c55d8e02-e7db-41dc-a9d1-c9637d66c8b7",
    "name": "Fortune 2 go",
    "game_pos_url_box": "https://example.com/game-pos",
    "status": "active"
  }
]
```

`status` values:
- `active` if game is visible
- `inactive` if game is not visible

---

## 7) Create operator game for operator
**POST** `/operator/{operator_id}/games/`

Creates `OperatorGame` for operator from URL param.
Processor is taken from Bearer token.

Auth: Processor Bearer token (Authorization header).

### URL Param
- `operator_id` (UUID, eWallet user id)

### Request Body
```json
{
  "game_id": "c55d8e02-e7db-41dc-a9d1-c9637d66c8b7",
  "display_name": "Fortune 2 go",
  "pos_username": "cashier",
  "pos_password": "secret",
  "publish_site": true,
  "drawer": "1",
  "kiosk_number": "K-01",
  "station_number": 1,
  "order": 10,
  "pos_category": "casino"
}
```

### Response (201)
```json
{
  "operator_game_id": 42,
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "game_name": "Fortune 2 go",
  "game_pos_url": "https://example.com/game-pos",
  "display_name": "Fortune 2 go",
  "pos_username": "cashier",
  "pos_password": "secret",
  "publish_site": true,
  "drawer": "1",
  "kiosk_number": "K-01",
  "station_number": 1,
  "order": 10,
  "pos_category": "casino"
}
```

### Validation Notes
- `game_id` must be assigned to authenticated processor.
- if `OperatorGame` with same `game_id` already exists for this `operator_id` in scope of authenticated processor, API returns:
  - `400 Bad Request`
  - `{"game_id": ["Game already exists for this operator and processor."]}`

---

## 8) Update operator game for operator
**PATCH** `/operator/{operator_id}/games/{id}/`

Updates existing `OperatorGame` by id.
Record must belong to:
- operator from URL param
- authenticated processor from token

Auth: Processor Bearer token (Authorization header).

### URL Params
- `operator_id` (UUID, eWallet user id)
- `id` (integer, operator game id)

### Request Body (example)
```json
{
  "display_name": "Fortune 2 go Updated",
  "publish_site": true,
  "game_id": "6afeb970-2b45-4f00-ab6a-8f0938a067a2"
}
```

### Response (200)
```json
{
  "operator_game_id": 42,
  "operator_id": "0f6d7d8a-7e9a-4d95-9f73-5f7d9b8327a1",
  "game_name": "Fortune 2 go Updated",
  "game_pos_url": "https://example.com/game-pos",
  "display_name": "Fortune 2 go Updated",
  "pos_username": "cashier",
  "pos_password": "secret",
  "publish_site": true,
  "drawer": "1",
  "kiosk_number": "K-01",
  "station_number": 1,
  "order": 10,
  "pos_category": "casino"
}
```

---

## 9) Disable all operator games for authenticated processor
**POST** `/operator/{operator_id}/games/disable-all/`

Disables visibility of all operator games for this operator in scope of authenticated processor
(`processor_publish_site=false`).

Auth: Processor Bearer token (Authorization header).

### URL Param
- `operator_id` (UUID, eWallet user id)

### Response (200)
```json
{
  "detail": "All games for this operator were disabled by processor.",
  "updated": 2
}
```

### Notes
- Only records that belong to authenticated processor are affected.
- `updated` = number of rows actually changed.

---

## 10) Enable all operator games for authenticated processor
**POST** `/operator/{operator_id}/games/enable-all/`

Enables visibility of all operator games for this operator in scope of authenticated processor
(`processor_publish_site=true`).

Auth: Processor Bearer token (Authorization header).

### URL Param
- `operator_id` (UUID, eWallet user id)

### Response (200)
```json
{
  "detail": "All games for this operator were enabled by processor.",
  "updated": 2
}
```

### Notes
- Only records that belong to authenticated processor are affected.
- `updated` = number of rows actually changed.
