# Connection
URL: /docs/lan/connection

Enable local communication on the device, discover it, open a TCP connection and authenticate.

## Enable on the device

Local communication is **off by default**. On the POS+ device:

1. Open **Settings → Local communication** (the screen is protected by the
   settings PIN).
2. Turn on **LAN**.
3. Note the IPv4 address and the TCP port shown on the screen. The default port
   is `8471`; you can change it to any value between `1024` and `65535` except
   `8470`.

The same screen lists the clients that are connected right now, which is useful
while you develop.

## Discovery

If you do not know the device address, broadcast a UDP datagram to port `8470`:

```json title="UDP → 255.255.255.255:8470"
{ "type": "PLUSPAY_DISCOVER" }
```

Every POS+ device with local communication enabled answers to the sender:

```json title="UDP ← 192.168.1.40"
{ "type": "PLUSPAY_POS", "serial_no": "PBD522C630205", "port": 8471, "name": "Kasa 1" }
```

Connect to the **address the answer came from** and the `port` in it. To find
one specific device, add `"serial_no"` to the discovery message; only that device
answers.

Discovery is optional. In a fixed installation, store the IP address and serial
number in your configuration instead.

## Framing

* One message is **one line of UTF-8 JSON** followed by `\n` (`\r\n` is also
  accepted). Do not pretty-print.
* The reply comes back on the **same connection**, also as one line.
* There is **no correlation id**. Replies arrive in the order of the requests;
  a connection processes requests one after another.
* You may keep the connection open for several requests or open a new one each
  time. Set `TCP_NODELAY` for snappier small writes.

Every message has the same shape:

```json
{
  "header": { "transaction_type": "POST_PAYMENT_START", "order_code": "SIP-1042", "api_key": "…", "secret_key": "…" },
  "data": { "payment_type": "POS", "payment_method": "CC", "total_amount": 410 }
}
```

| Header field       | Required    | Description                                                 |
| ------------------ | ----------- | ----------------------------------------------------------- |
| `transaction_type` | yes         | The operation. See [Commands](/docs/lan/commands).          |
| `api_key`          | yes         | From the Credentials page.                                  |
| `secret_key`       | yes         | From the Credentials page.                                  |
| `order_code`       | per command | Your order code.                                            |
| `transaction_id`   | per command | A POS+ transaction id.                                      |
| `lang`             | no          | UI language while POS+ handles the request (`tr`, `en`, …). |

## Authentication

Before running a request the device checks, in order:

1. POS+ has finished starting up. Otherwise → `PP_A2A_017`.
2. Someone has logged in to POS+ on the device. Otherwise → `PP_A2A_011`.
3. `header.api_key` and `header.secret_key` are present. Otherwise → `PP_A2A_003`.
4. The keys are valid. The device checks them online with PlusPay; a rejection
   gives `PP_A2A_003`, an unreachable server gives `PP_A2A_017`.

There is no pairing, IP allow-list or signature. Keys are masked in the device
logs.

<Callout type="warn">
  Keep `api_key` and `secret_key` out of source control and screenshots. Read
  them from environment variables or your configuration store. Sandbox keys work
  only with a sandbox device, production keys only with a production device.
</Callout>

## Timeouts

| Phase                                                   | Recommended timeout |
| ------------------------------------------------------- | ------------------- |
| TCP connect                                             | 10 s                |
| `ORDER_CREATE`, `*_RESULT`, `AVAILABLE_PAYMENT_METHODS` | 30 s                |
| Payments, cancellations, `EOD`, `PARAMETERS`            | **900 s**           |

The device has no server-side timeout on payments: the reply comes when the
cashier is done. If your connection drops in the meantime, the operation still
completes on the device — see [Recovery](/docs/lan/errors#recovery).

## USB serial

The same framing also works over a USB serial cable: 115200 baud, 8N1, DTR and
RTS on. FTDI, CP210x, PL2303 and CH34x adapters are supported. Authentication
and commands are identical.