# Confirm Payment

> Confirm the token and network on a fiat- or crypto-priced invoice from your own checkout, then show the deposit address and payment details the call returns.

`POST /v1/invoices/:invoice_id/confirm-payment`

:::endpoint
POST /v1/invoices/:invoice_id/confirm-payment
:::

**API key:** `Payment`

Confirm the stablecoin and network for an invoice still in `awaiting_client`. Whichever way the invoice was priced, the call assigns the deposit address and moves it to `awaiting_payment`. On a fiat-priced invoice the exchange rate is locked at the same moment. On a crypto-priced one there is no rate to lock — the token you confirm has to be the one the invoice was created with, and the network too when creation fixed one.

Use this when you render your own checkout and collect the token choice on your server. Every checkout Paymos runs — the hosted page behind `payment_url`, the iframe embed, the [Low-Code SDK](/docs/widget-sdk.md), and the Paymos bot a Telegram-bot project's `payment_url` opens instead — confirms the selection on its own, so none of them need this call. Nothing in the endpoint depends on the project's channel: confirm server-side on a Telegram-bot project too, and the payer's link opens straight at the deposit address, with no selection step.

What you get here is an endpoint, not a white-label product. It lets you build the payment page yourself, on your own domain, and it changes nothing about the pages we host: those carry the "Secured by Paymos" footer in every theme and embed mode, and a checkout on your own CNAME is not something Paymos offers.

## Request body

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `currency` | string | Yes | The stablecoin the customer chose to pay with (e.g. `USDT`, `USDC`). Must be enabled on the invoice's project |
| `network` | string | Yes | The network the customer chose to pay on (e.g. `TRC20`, `BASE`) — must be a network where that token is enabled. A network the project has switched off on its Currencies tab is refused with `400 field_invalid_enum` on `network` |

```json
{
  "currency": "USDT",
  "network": "TRC20"
}
```

## Response (200 OK)

Returns the full invoice with its `payment` section now populated — the chosen `currency` / `network`, the assigned deposit `address`, the locked `exchange_rate` on a fiat-priced invoice, and the `expected` crypto amount. Because this call is authenticated with your merchant key, the response also carries the merchant-only `fee` and `net` fields. The body has the same shape as [Retrieve an invoice](/docs/invoices/get.md).

## Errors

See [Error Codes](/docs/errors/codes.md) for the full catalogue. The `type` URI in every error response deep-links to the matching row. Confirming an invoice that isn't yours returns `404`, and so does an invoice in an archived or suspended project: your key confirms payments only in active projects. An `expired` or `cancelled` invoice returns `410`; every other status past `awaiting_client` returns `409` — including the terminal `paid`, `paid_over`, and `underpaid`.
