# Terminal

> Use a project link as an in-person crypto terminal on a phone or tablet, enter the amount, show a QR code, and track confirmation.

Open the link on a phone or tablet, key the amount on the numpad, hand the device to the customer. After payment confirms, the page resets to the numpad automatically — ready for the next sale.

Terminal works out of the box. No code, no embedded API keys, no server side. Brand, currency, and active networks are all inherited from the project's own settings.

## Where to get the terminal URL

Terminal is an integration method, not a switch. You pick the project's **Integration method** when you create the project, and it stays fixed after that — a project connected any other way has no terminal at all. Give a till its own project.

For a project connected as a terminal:

1. Select the project.
2. Open [**Terminal**](/terminal).
3. Copy the **Terminal URL** from the **Terminal access** card.

The URL looks like:

```http
https://paymos.io/terminal?key=pk_live_xxx&pid=prj_yyy
```

Share the link with cashiers or save it to the counter device's bookmarks. A device bookmarked on the older `/pos` address keeps working — that path redirects to `/terminal` and carries the query string over — but publish the `/terminal` form from here on.

### What's in the URL

| Parameter | Purpose |
|---|---|
| `key` | Project's public key (prefix `pk_live_` or `pk_test_`). Not secret — but possession grants the ability to create invoices against your project. Pulled from your project's active payment key. |
| `pid` | Project identifier (prefix `prj_`). Decides which tokens, networks, and branding load. |

The URL isn't device-bound — open it on any browser device. Each open is an independent session.

## How a sale runs

:::dash-numbered
- Cashier opens the terminal URL in a browser (phone or tablet).
- Picks the fiat currency (USD, EUR, RUB plus 43 more) and keys the amount on the numpad.
- Taps **Pay** — terminal creates an invoice and opens the standard payment page.
- Customer pays from their own device: scans the QR off the terminal screen or follows the link.
- Once confirmed on-chain, terminal auto-resets to the numpad.
:::

The cashier never touches a wallet. The customer never signs up with Paymos. Most of the wait is on-chain confirmation — seconds on a fast-finality chain, a few minutes for a large payment on a slower one.

## Customizing the look

Terminal inherits the same brand settings as the regular checkout page. Edit them in the **Branding** card on the [**Checkout form**](/checkout-form) page:

| Setting | What it changes |
|---|---|
| **Checkout style** | Base style template for the payment page (background pattern, theme) |
| **Accent** | Primary color: buttons, links, hover, active network indicator |
| **Background** | Page background |
| **Surface** | Card and panel surface |
| **Text** | Main body text |
| **Muted** | Secondary text (hints, captions) |
| **Corner radius** | Rounding on buttons and cards, 0-32px |

After saving, the preview beside the settings updates automatically. Terminal picks up the changes on next open.

### Logo

The project logo appears in the terminal header automatically. Open the project from [**Projects**](/projects) and upload the file on its own page — the picker takes PNG, JPEG, and WebP up to 2 MB. SVG is rejected.

### Currency list

Terminal exposes the fiat currencies enabled in the project under the **Currencies** tab on the project detail page. The default retail set is USD, EUR, RUB. Add or remove to fit your geography.

### Active networks and tokens

Terminal only shows the customer the networks and tokens enabled on the project's [**Currencies** tab](/projects). A typical retail mix:
- Tron (USDT) — CIS and Asia customers
- Polygon (USDC/USDT) — low customer fee
- BSC (USDT) — Binance-native users
- TON — Telegram-native audiences

Keep Ethereum mainnet enabled if you expect high-ticket sales.

## Sandbox vs production

The terminal URL key prefix decides the environment — `pk_test_` for sandbox, `pk_live_` for production. When running in sandbox, the terminal shows an amber **Sandbox** banner across the top.

For testing:
1. Generate a `pk_test_` key in [**Dashboard → Developer → API Keys**](/developers/api).
2. Build the sandbox terminal URL (same shape, test key).
3. Settle the invoice with [`POST /v1/sandbox/invoices/:invoice_id/simulate-payment`](/docs/testing.md) — sandbox transactions are simulated, so no wallet and no testnet coins are involved.

To go live, create a `pk_live_` key and update the URL on the counter devices.

## Terminal as a Low-Code SDK fallback

If you use the [Low-Code SDK](/docs/widget-sdk.md) without a fixed amount (`amount` omitted), pass the terminal URL as the SDK's `pos_url` option — the widget then opens the terminal instead of the standard checkout form. One widget covers two flows:
- **Fixed amount** — customer pays the set amount via the standard form.
- **Free amount** — customer enters the amount on the terminal numpad.

One script, two modes, no separate build. Without `pos_url` there is no fallback: a click with no resolvable amount raises a `paymos:error` event instead of opening the terminal.

## Multiple cashiers or devices

The URL is shared. Open it on as many devices as you need — they all run in parallel against the same project. Transactions feed into the project's shared history; the dashboard shows everything.

:::warning
**Per-cashier attribution is not built in.** If you need it, run a project per till or per location. Each project gets its own URL, its own history, its own dashboard summary.
:::

## Multiple locations

Run a project per location:
1. [**Dashboard → Projects → New project**](/projects/create), with **Terminal** as the integration method.
2. Configure brand and active networks.
3. Copy that location's URL from [**Terminal**](/terminal).

All projects sit under one merchant account — reporting rolls up to the shared dashboard.

## Security

The `key` in the URL is the **public** key. It doesn't grant access to withdrawals, project settings, or any restricted operation. It does grant the ability to **create invoices** against your project.

In practice:
- The terminal URL is safe to keep in browser bookmarks on a public counter device.
- If the URL leaks to an outsider, they can create invoices (but not pay them on your behalf, and not withdraw funds).
- If compromised, generate a new `pk_live_` key in [**Dashboard → Developer → API Keys**](/developers/api) and update the URL. Revoke the old key.

:::info
Secret keys (`sk_live_`) **never appear in the terminal**. They're only used for server-side API requests.
:::

## Troubleshooting

### Terminal won't open

Check:
1. URL has both parameters — `key` and `pid`.
2. The project is connected as a terminal — no other integration method resolves this URL.
3. The key isn't revoked in **Developer → API Keys**.

### Page says "Payment unavailable"

One screen covers every reason the link didn't resolve: a wrong or revoked `key`, a wrong `pid`, or a project that isn't connected as a terminal. Copy the URL again from [**Terminal**](/terminal) — and if that page has no URL to copy, the integration method is the reason, so the till needs a project of its own.

### QR doesn't appear after tapping "Pay"

Check that at least one token is enabled in the project's **Currencies**.

### Payment doesn't confirm

Confirmation depth depends on the network and on the payment amount — small amounts clear fast, large ones wait longer for finality. Chains with native fast finality (BSC, Polygon, Solana, Avalanche, Plasma) settle in seconds; on Tron, Ethereum, and the L2s a large ticket can take a couple of minutes. If the customer paid several minutes ago and the page hasn't moved, open the transaction in the network's explorer to check it landed.

### Terminal looks broken after a theme change

The old theme is still cached in the open tab. Close the tab and reopen the URL to pull the new one.
