# Endpoint: Корзина Stripe — одна платёжная ссылка на несколько продуктов

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

Корзина — это **одна платёжная ссылка Stripe на несколько ваших продуктов**, у каждого своя цена и количество. Клиент открывает одну ссылку и видит все позиции сразу.

Используйте, когда клиент покупает комбинацию, а не один продукт:

* тариф собирается из частей — «базовый план + 2 места + 100 аккаунтов»;
* заказ из нескольких товаров, которые нужно оплатить одним платежом;
* AI-агент партнёра должен собрать такую ссылку по запросу клиента прямо в чате (через MCP — инструмент `create_partner_stripe_cart_payment_link`).

**Два режима — выбираются автоматически по продуктам:**

| Продукты в корзине | Что получит клиент |
|--------------------|--------------------|
| все **разовые**    | одну оплату всей корзины |
| все **подписочные** с одинаковым периодом (например, все помесячные) | **одну подписку** из нескольких позиций: каждый период списывается сумма всех позиций × количества |

Смешивать разовые и подписочные продукты в одной ссылке нельзя, как и подписки с разным периодом (месяц + год), разные валюты или тестовые продукты вместе с боевыми — запрос вернёт `INVALID_INPUT`. Пробного периода у корзины нет: если нужен trial, выпускайте ссылку на один продукт.

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


1. Возьмите API-ключ партнёра (мини-апп или ваш менеджер EasyPay). Нужно разрешение `product_create` — то же, что для создания продукта и платёжной ссылки.
2. Все продукты корзины должны быть **уже одобрены** командой заботы. Их `stripe_product_id` (`prod_…`) видны в мини-апп в карточках продуктов и в MCP-инструменте `list_partner_live_stripe_payment_links`.

## Endpoint

```
POST https://api.appsign.me/create-partner-stripe-cart-payment-link
X-Partner-Api-Key: ваш-api-ключ
Content-Type: application/json
```

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

```json
{
  "items": [
    { "stripe_product_id": "prod_PLAN",     "unit_amount": 4900, "quantity": 1 },
    { "stripe_product_id": "prod_SEATS",    "unit_amount": 4900, "quantity": 2 },
    { "stripe_product_id": "prod_ACCOUNTS", "unit_amount": 1000, "quantity": 100 }
  ],
  "allow_promotion_codes": false,
  "success_url": "https://example.com/thanks",
  "client_token": "order-2417"
}
```

| Параметр | Обязательный | Описание |
|----------|--------------|----------|
| `items`  | Да           | 1\..20 позиций. Каждый продукт — не больше одной позиции: количество складывайте в `quantity`. |
| `items[].stripe_product_id` | Да           | Одобренный продукт вашего аккаунта (`prod_…`). |
| `items[].unit_amount` | Да           | Цена **одной единицы** в минимальных единицах валюты (центах): `4900` = $49.00. Для подписки — цена единицы за период. Минимум 50. |
| `items[].quantity` | Да           | Количество, целое 1..999. |
| `currency` | Нет          | Проверка валюты (USD/EUR/GBP/BRL). Валюта всегда берётся из продуктов; если передали — должна совпасть. |
| `payment_method_types` | Нет          | Способы оплаты на чекауте. Не передавайте — Stripe покажет стандартный набор для валюты. |
| `allow_promotion_codes` | Нет          | Показать поле промокода на чекауте. По умолчанию `false`. |
| `success_url` | Нет          | HTTPS-адрес, куда вернуть клиента после оплаты (до 2048 символов). |
| `client_token` | Нет          | Ваш идентификатор запроса (номер заказа, uuid). Подробнее — в разделе «Повторы». |

**Что берётся из продуктов** (передать нельзя): валюта, окружение (test/live), тип корзины и период подписки.

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

HTTP-статус всегда 200 — смотрите поле `success`.

```json
{
  "success": true,
  "payment_link_id": "plink_…",
  "short_url": "https://short.appsign.me/AbCdEf1234",
  "short_url_id": "…",
  "currency": "USD",
  "mode": "subscription",
  "interval": "month",
  "interval_count": 1,
  "line_item_count": 3,
  "items": [
    { "stripe_product_id": "prod_PLAN", "stripe_price_id": "price_…", "quantity": 1 },
    { "stripe_product_id": "prod_SEATS", "stripe_price_id": "price_…", "quantity": 2 },
    { "stripe_product_id": "prod_ACCOUNTS", "stripe_price_id": "price_…", "quantity": 100 }
  ],
  "duplicate": false
}
```

Клиенту отдавайте `short_url`. У разовой корзины `mode` = `one_time`, а `interval` и `interval_count` = `null`.

## Повторы

* Та же корзина (те же продукты, цены, количества и опции) без `client_token` вернёт **ту же ссылку** с `duplicate: true` — случайный повтор не создаёт вторую ссылку.
* Нужна **отдельная** ссылка того же состава (например, второму клиенту) — передайте новый `client_token`.
* Тот же `client_token` с другой корзиной вернёт `IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD`.
* Состав выданной ссылки не редактируется: изменилось количество — создайте новую корзину.

## Ошибки

| `error_code` | Что значит |
|------------|------------|
| `INVALID_INPUT` | Неверные поля, смесь разовых и подписочных продуктов, разный период подписок, разные валюты или окружения. Причина — в `error_message`. |
| `PRODUCT_NOT_FOUND` | Продукта нет в вашем аккаунте. |
| `PRODUCT_NOT_APPROVED` | Продукт ещё на модерации. |
| `CROSS_TENANT_ATTEMPT` | Продукт принадлежит другому аккаунту — проверьте ID. |
| `SHORT_URL_UNAVAILABLE` | Ссылка создана, но короткий адрес не выпустился — напишите в команду заботы, указав `client_token`. |
| `INTEGRATION_UPSTREAM_ERROR` / `INTEGRATION_TIMEOUT` | Сбой на стороне Stripe — повторите с новым `client_token`. |


---

# Stripe cart: one payment link for several products (EN)

A cart is **one Stripe payment link for several of your products**, each with its own price and quantity. Use it when a customer buys a combination — "base plan + 2 seats + 100 accounts" — instead of sending several links. Via MCP the tool is `create_partner_stripe_cart_payment_link`.

**The mode is derived from the products:**

| Products in the cart | What the customer gets |
|----------------------|------------------------|
| all **one-time**     | a single payment for the whole cart |
| all **subscriptions** with the same billing period (e.g. all monthly) | **one subscription** with several items, charged the sum of items × quantities every period |

Mixing one-time and subscription products, subscriptions with different periods, different currencies, or test with live products returns `INVALID_INPUT`. Free trials are not available in a cart.

**Endpoint:** `POST https://api.appsign.me/create-partner-stripe-cart-payment-link`, header `X-Partner-Api-Key`, permission `product_create`. All products must be approved.

**Request:** `items` (1..20 of `{stripe_product_id, unit_amount, quantity}` — `unit_amount` is the price of ONE unit in cents, per period for subscriptions; `quantity` 1..999; one entry per product), optional `currency` (check only — always inherited), `payment_method_types`, `allow_promotion_codes`, `success_url`, `client_token`.

**Response** (HTTP 200, check `success`): `short_url` (share it with the customer), `payment_link_id`, `currency`, `mode` (`one_time` / `subscription`), `interval`, `interval_count` (null for one-time), `line_item_count`, `items[]` with `stripe_price_id`, `duplicate`.

**Repeats:** an identical cart returns the same link with `duplicate: true`; pass a new `client_token` to get a separate link with the same composition. An issued link can't be edited — create a new cart when quantities change.

**Errors:** `INVALID_INPUT`, `PRODUCT_NOT_FOUND`, `PRODUCT_NOT_APPROVED`, `CROSS_TENANT_ATTEMPT`, `SHORT_URL_UNAVAILABLE` (link created, short URL missing — contact support with your `client_token`), `INTEGRATION_UPSTREAM_ERROR` / `INTEGRATION_TIMEOUT` (Stripe failure — retry with a new `client_token`).