# Запросы и ответы

> Адрес PS Wallet Pay API, авторизация по токену, HTTP-методы, формат параметров и ответов, лимит запросов.

Все методы PS Wallet Pay API вызываются по одному адресу, авторизуются токеном приложения в заголовке и отвечают JSON-объектом с полем `ok`.

## Адрес API

```
https://pay.pswallet.org/api/{method}
```

Вместо `{method}` подставьте имя метода, например `https://pay.pswallet.org/api/createInvoice`.

- Только HTTPS, кодировка UTF-8.
- Регистр в имени метода не важен: `getMe` и `getme` — один и тот же метод.

## Авторизация

Передавайте токен приложения в заголовке `PSWallet-Pay-API-Token`:

```
PSWallet-Pay-API-Token: 1234:AbCdEf...
```

Токен выглядит как `<ID приложения>:<секрет>`. Его можно посмотреть и перевыпустить в кабинете приложения в разделе «API-токен» — подробнее в разделе [Безопасность](https://help.pswallet.org/ru/pay-api/security).

Запрос без токена, с неверным или перевыпущенным токеном, а также к удалённому приложению получит ошибку `401 UNAUTHORIZED`.

## HTTP-методы и параметры

- Поддерживаются `GET` и `POST`.
- Параметры передаются в строке запроса или в теле `POST` в формате `application/json` либо `application/x-www-form-urlencoded`.
- Методы, которые создают или удаляют данные, принимают только `POST`. На `GET` они отвечают ошибкой `405 POST_REQUIRED`.

Методы только для `POST`:

- `createInvoice`
- `deleteInvoice`
- `transfer`
- `createCheck`
- `deleteCheck`

> [!TIP]
> Проще всего всегда вызывать методы через `POST` с JSON-телом: так работают все методы, а суммы и списки передаются без экранирования.

## Формат ответа

Ответ — всегда JSON-объект с полем `ok`.

Успешный ответ — `ok: true`, результат лежит в поле `result`:

```json
{
  "ok": true,
  "result": {
    "app_id": 1234,
    "name": "My Shop",
    "payment_processing_bot_username": "pswallet"
  }
}
```

Ошибка — `ok: false`, описание лежит в поле `error`:

```json
{
  "ok": false,
  "error": { "code": 400, "name": "PARAM_AMOUNT_INVALID" }
}
```

`code` совпадает с HTTP-статусом ответа, `name` — машинное имя ошибки. Все коды перечислены в разделе [Ошибки](https://help.pswallet.org/ru/pay-api/errors).

## Пример запроса

Создадим счёт на 12.5 USDT. Функции `payApi` в примерах на Node.js и Python можно использовать для вызова любого метода.

```bash title="cURL"
curl https://pay.pswallet.org/api/createInvoice \
  -H "PSWallet-Pay-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"asset": "USDT", "amount": "12.5", "description": "Подписка на месяц"}'
```

```js title="Node.js"
// Node.js 18+ (встроенный fetch)
const TOKEN = process.env.PSWALLET_PAY_TOKEN;

async function payApi(method, params = {}) {
  const response = await fetch(`https://pay.pswallet.org/api/${method}`, {
    method: "POST",
    headers: {
      "PSWallet-Pay-API-Token": TOKEN,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(params),
  });
  const data = await response.json();
  if (!data.ok) {
    throw new Error(`PS Wallet Pay: ${data.error.code} ${data.error.name}`);
  }
  return data.result;
}

const invoice = await payApi("createInvoice", {
  asset: "USDT",
  amount: "12.5",
  description: "Подписка на месяц",
});
console.log(invoice.bot_invoice_url);
```

```python title="Python"
import os
import requests

TOKEN = os.environ["PSWALLET_PAY_TOKEN"]

def pay_api(method: str, params: dict | None = None):
    response = requests.post(
        f"https://pay.pswallet.org/api/{method}",
        headers={"PSWallet-Pay-API-Token": TOKEN},
        json=params or dict(),
        timeout=15,
    )
    data = response.json()
    if not data["ok"]:
        error = data["error"]
        raise RuntimeError(f"PS Wallet Pay: {error['code']} {error['name']}")
    return data["result"]

invoice = pay_api("createInvoice", {
    "asset": "USDT",
    "amount": "12.5",
    "description": "Подписка на месяц",
})
print(invoice["bot_invoice_url"])
```

## Лимит запросов

На одно приложение — не больше 30 запросов в секунду. Сверх лимита API отвечает ошибкой `429 TOO_MANY_REQUESTS`: подождите немного и повторите запрос.

Если нужно часто узнавать об оплате счетов, не опрашивайте `getInvoices` в цикле — подключите [вебхуки](https://help.pswallet.org/ru/pay-api/webhooks).

## Что проверяется до вызова метода

Перед выполнением метода API по очереди проверяет запрос и при первой же проблеме возвращает ошибку:

| Проверка | Ошибка |
|---|---|
| Метод существует | `405 METHOD_NOT_FOUND` |
| Создающий или удаляющий метод вызван через `POST` | `405 POST_REQUIRED` |
| Токен передан и действителен | `401 UNAUTHORIZED` |
| PS Wallet Pay сейчас работает | `503 TEMPORARILY_UNAVAILABLE` |
| Не превышен лимит запросов | `429 TOO_MANY_REQUESTS` |
| Адрес запроса есть в белом списке IP (если список задан) | `403 IP_NOT_ALLOWED` |
| Приложение не заморожено | `403 APP_FROZEN` |

После этого проверяются параметры самого метода — см. разделы с описанием методов.

## Повторные запросы

Методы чтения (`getMe`, `getInvoices`, `getBalance` и другие) можно безопасно повторять.

- `transfer` защищён от двойной отправки параметром `spend_id`. Если запрос оборвался и вы не знаете, прошёл ли перевод, проверьте его через `getTransfers` с тем же `spend_id` — подробнее в разделе [Переводы](https://help.pswallet.org/ru/pay-api/transfers).
- У `createInvoice` и `createCheck` нет ключа повтора: повторный запрос создаст ещё один счёт или чек. Лишний неоплаченный счёт можно удалить через `deleteInvoice`, неактивированный чек — через `deleteCheck`.

---
Источник: https://help.pswallet.org/ru/pay-api/requests
