# Endpoint (API v2): Список платежей Stripe за период

## Зачем это нужно

EasyPay отправляет события по вашим платежам вебхуком — но если вебхук не дошёл (упал ваш эндпоинт, потерялась сеть, ретраи закончились), состояние платежа надо чем-то восстановить. Этот метод возвращает **ваши платежи Stripe за период** — с суммой, статусом, комиссией, идентификатором платежа (`payment_intent_id`) и вашим `client_reference_id`. Его же удобно вызывать по расписанию для регулярной сверки с внутренней системой.

Метод доступен и через **прямой HTTP API** (с вашим API-ключом), и через **MCP-агента** (тул `list_partner_stripe_transactions`) — это одна и та же ручка.

Если вам нужен не перечень, а всё по одному конкретному платежу (включая связанные возвраты и споры) — смотрите [«Endpoint (API v2): Платёж Stripe по payment_intent_id»](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/endpoint-api-v2-platyozh-stripe-po-payment_intent_id-YClkCUGdKc).

## Как подключиться


1. Возьмите API-ключ в мини-апп EasyPay («Show key» на первом шаге онбординга) — или запросите у вашего менеджера. Подробнее: [«Где взять API-ключ»](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/gde-vzyat-api-klyuch-dlya-integracii-s-claude-code-cursor-N8e3jiAxdz).
2. Нужно разрешение `balance_view` — то же, по которому вы смотрите баланс. Оно выдаётся на онбординге, отдельно запрашивать обычно не требуется.
3. API-ключ — строка в формате UUID, например: `18fcf8a0-cde3-4a27-ab7c-2f3bca09b9a2`.

## Endpoint

```
POST https://api.appsign.me/list-partner-stripe-transactions
Content-Type: application/json
```

Ключ передаётся заголовком `X-Partner-Api-Key` **или** полем `api_key` в теле — на выбор.

## Формат запроса

```json
{
  "api_key": "ваш-api-ключ",
  "created_gte": "2026-08-01",
  "created_lte": "2026-08-19",
  "environment": "live",
  "limit": 50,
  "client_reference_id": "order-10482"
}
```

**Параметры:**

| Параметр | Обязательный | Описание |
|----------|--------------|----------|
| `api_key` | Да, если нет заголовка | API-ключ партнёра (UUID). Либо заголовок `X-Partner-Api-Key`. |
| `created_gte` | Нет          | Начало периода (включительно). ISO 8601: дата `"2026-08-01"` или дата-время. |
| `created_lte` | Нет          | Конец периода (включительно). Тот же формат. |
| `environment` | Нет          | `"live"` или `"test"`. Если параметр не передан — вернутся оба окружения. |
| `limit`  | Нет          | Сколько записей вернуть. По умолчанию `20`, максимум `100`. |
| `client_reference_id` | Нет          | Ваш номер заказа — точное совпадение. До 200 символов. Вернутся все движения по этому заказу. |

**Как понимаются даты.** Обе границы включительные, время — UTC. Если передана только дата без времени, она разворачивается на границы суток: `created_gte` → `00:00:00.000Z`, `created_lte` → `23:59:59.999Z`. То есть `{"created_gte": "2026-08-01", "created_lte": "2026-08-19"}` — это весь период с 1 по 19 августа включительно.

**Проверки строгие.** Несуществующая календарная дата (`"2026-02-31"`), нераспознанный формат или `environment` со значением, отличным от `test` / `live`, вернут `INVALID_INPUT` — запрос не будет молча выполнен «как-нибудь». Если `created_gte` окажется позже `created_lte`, ответ будет успешным с пустым списком.

**Пагинации нет.** Метод отдаёт максимум 100 последних записей за период, отсортированных по дате по убыванию. Чтобы выгрузить больше — разбивайте период на части (по дням или неделям) и вызывайте метод для каждой.

## Поиск по вашему номеру заказа

Если вы передавали свой идентификатор заказа при создании оплаты (добавляли `?client_reference_id=...` к платёжной ссылке), искать платёж можно прямо по нему — не выгружая период целиком:

```json
{
  "api_key": "ваш-api-ключ",
  "client_reference_id": "order-10482"
}
```

Три вещи, которые важно понимать про этот поиск:

* **Ответ — список, а не один платёж.** По одному заказу обычно несколько движений: сама оплата, а потом, например, возврат. Плюс, если клиент оплачивал с повторной попытки, номер заказа мог быть переиспользован. Рассчитывайте на 0, 1 или несколько записей.
* **Совпадение точное.** Поиска по части строки или по маске нет: `order-10482` не найдётся по запросу `order-104`. Регистр тоже имеет значение.
* **Не у всех платежей он есть.** Номер заказа приходит из чекаут-сессии. У оплат, где её не было — банковские инвойсы, автоматические продления подписок — его нет в принципе, и по нему они не найдутся никогда. Если поиск по заказу вернул пусто, проверьте платёж выборкой за период, прежде чем считать его потерянным.

Пустой список — это `{"success": true, "transactions": [], "count": 0}`, а не ошибка. Ошибка (`INVALID_INPUT`) придёт, только если сам параметр негодный — пустая строка, не строка или длиннее 200 символов. Так сделано намеренно: молча проигнорированный фильтр вернул бы всю вашу недавнюю историю, и это читалось бы как «заказа у них нет».

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

### Успешный ответ

```json
{
  "success": true,
  "transactions": [
    {
      "id": "stripe:txn_3TcXXXXXXXXXXXXX",
      "amount": 99.00,
      "net_amount": 95.13,
      "fee": 3.87,
      "currency": "USD",
      "status": "completed",
      "transaction_date": "2026-08-18T14:22:05.000Z",
      "description": "Premium Plan",
      "environment": "live",
      "type": "stripe_payment_in",
      "is_subscription": false,
      "client_reference_id": "order-10482",
      "payment_intent_id": "pi_3TcXXXXXXXXXXXXX"
    }
  ],
  "count": 1,
  "environment_filter": "live"
}
```

**Поля верхнего уровня:**

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | `true` при успехе. |
| `transactions` | array | Список платежей, отсортирован по `transaction_date` по убыванию. |
| `count` | number | Количество элементов в `transactions`. |
| `environment_filter` | string | Какие окружения попали в ответ: `live`, `test` или `all`. |

**Структура каждого элемента в** `**transactions**`**:**

| Поле | Тип | Описание |
|------|-----|----------|
| `id` | string | Идентификатор денежного движения (`stripe:txn_…`). Стабилен, удобен как ключ дедупликации на вашей стороне. |
| `amount` | number | Сумма в основных единицах валюты (`99.00` = $99.00), **со знаком**: поступление — плюс, возврат или списание — минус. Делить на 100 не нужно. |
| `net_amount` | number \| null | Сумма за вычетом комиссии Stripe, в основных единицах. `null`, если ещё не рассчитана. |
| `fee` | number \| null | Комиссия Stripe в основных единицах. `null`, если ещё не известна. |
| `currency` | string | Валюта по ISO 4217 в верхнем регистре — `USD`, `EUR`, `GBP`. |
| `status` | string | `completed`, `pending`, `failed`, `refunded`, `disputed` или `dispute_won`. |
| `transaction_date` | string | Дата и время движения, ISO 8601 (UTC). |
| `description` | string \| null | Описание платежа или `null`. |
| `environment` | string | `live` или `test`. |
| `type` | string \| null | Тип движения, например `stripe_payment_in` (оплата), `stripe_refund` (возврат). `null`, если не классифицировано. |
| `is_subscription` | boolean | `true`, если платёж относится к подписке. |
| `client_reference_id` | string \| null | Ваш идентификатор заказа, если вы передавали его при создании чекаута. **Главное поле для сверки со своей системой.** |
| `payment_intent_id` | string \| null | Идентификатор платежа Stripe (`pi_…`). По нему можно запросить полный снэпшот платежа. `null` у движений, не связанных с конкретным платежом. |

### Ошибки

Все ошибки возвращаются с **HTTP 200** и полем `success: false` — чтобы боты, интеграции и MCP-агенты не путали клиентскую ошибку с сетевым сбоем.

```json
{
  "success": false,
  "error_code": "INVALID_INPUT",
  "error_message": "environment must be \"test\" or \"live\" (got \"prod\")",
  "details": { "field": "environment" }
}
```

| `error_code` | Когда срабатывает |
|------------|-------------------|
| `INVALID_API_KEY` | API-ключ невалиден, не в формате UUID, либо партнёр/сотрудник отключён |
| `PERMISSION_DENIED` | У партнёра нет разрешения `balance_view` |
| `INVALID_INPUT` | Некорректный `environment`, неразбираемая дата, несуществующая календарная дата или невалидный JSON в теле. Поле `details.field` укажет, что именно |
| `INTERNAL_ERROR` | Сбой на нашей стороне — повторите запрос позже |

## Что важно знать

* Метод отдаёт **только ваши** платежи — фильтр по партнёру зашит в саму ручку, чужие данные получить нельзя ни при каких параметрах.
* Запрос **только читает** и ничего не меняет: его можно безопасно повторять. Поле `idempotency_key` принимается для единообразия, но игнорируется.
* Тестовые и боевые платежи живут в одном ответе, если не передан `environment`. Для сверки бухгалтерии передавайте `"environment": "live"` явно.
* Возвраты и споры приходят **отдельными строками** с отрицательной суммой, а не изменением исходной. Чтобы увидеть исходный платёж и все связанные с ним движения вместе — используйте [запрос платежа по `payment_intent_id`](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/endpoint-api-v2-platyozh-stripe-po-payment_intent_id-YClkCUGdKc).
* Состав данных в вебхуке описан отдельно: [«Webhook EasyPay: структура данных платежей Stripe»](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/webhook-easypay-struktura-dannyh-platezhej-stripe-2aK80hyqzo).

## Пример на Python

```python
import urllib.request
import json

url = "https://api.appsign.me/list-partner-stripe-transactions"
payload = {
    "created_gte": "2026-08-01",
    "created_lte": "2026-08-19",
    "environment": "live",
    "limit": 100,
}

req = urllib.request.Request(
    url,
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Content-Type": "application/json",
        "X-Partner-Api-Key": "ваш-api-ключ",
    },
    method="POST",
)

with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read().decode("utf-8"))

if result.get("success"):
    print(f"Платежей за период: {result['count']}")
    for t in result["transactions"]:
        ref = t["client_reference_id"] or "—"
        print(f"  {t['transaction_date']}  {t['amount']} {t['currency']}  {t['status']}  заказ: {ref}")
else:
    print(f"Ошибка: {result.get('error_code')} — {result.get('error_message')}")
```

## Пример на cURL

```bash
curl -X POST https://api.appsign.me/list-partner-stripe-transactions \
  -H "Content-Type: application/json" \
  -H "X-Partner-Api-Key: ваш-api-ключ" \
  -d '{"created_gte": "2026-08-01", "created_lte": "2026-08-19", "environment": "live", "limit": 100}'
```

## Через AI-агента

Если у вас подключён MCP-сервер EasyPay, отдельный код не нужен — попросите агента: «покажи мои платежи через Stripe с 1 по 19 августа». Агент вызовет тот же метод. Настройка — [«MCP-сервер EasyPay: настройка платежей в чате с AI»](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/mcp-server-easypay-nastrojka-platezhej-v-chate-s-ai-cqtpnWTk2i).