Интеграция с помощью ИИ
Эту документацию удобно отдавать ИИ-ассистенту: ChatGPT, Claude, Cursor, GitHub Copilot и другим.
Документация для ИИ
| Файл | Что внутри |
|---|---|
| https://avantpay.io/developers/llms-full.txt | Вся документация одним файлом в формате Markdown: поля, примеры, ошибки, уведомления, чеклист. Лучший вариант для ассистента. |
| https://avantpay.io/developers/llms.txt | Оглавление по стандарту llms.txt со ссылками на страницы и разделы справочника. |
Страница + .md | Любая страница в формате Markdown. Например, https://avantpay.io/developers/api.md — справочник API. |
Файлы собираются из страниц этого сайта при каждом обновлении документации, поэтому всегда совпадают с ним.
Если ассистент не умеет открывать ссылки, скачайте https://avantpay.io/developers/llms-full.txt и приложите файл к сообщению.
Готовое задание
Скопируйте текст, допишите в первой строке свой язык и фреймворк и отправьте ассистенту.
Подключи приём платежей AvantPay к моему проекту. Проект: <язык, фреймворк, где хранятся заказы>.
Документация: https://avantpay.io/developers/llms-full.txt. Прочитай её целиком до того, как писать код. Используй только методы, поля и значения из этой документации. Если чего-то в документации нет, не придумывай — спроси меня.
Что нужно сделать:
1. Создание платежа: POST https://api.avantpay.io/v3/payments, HTTP Basic (ID магазина и секретный ключ из переменных окружения AVANTPAY_SHOP_ID и AVANTPAY_SECRET_KEY). Поля: amount (value — строка с двумя знаками после точки, currency — RUB), capture = true (обязательно), confirmation (type = redirect, return_url — адрес страницы этого заказа), description, metadata.email — email покупателя (обязательно; покупатель из Telegram — <telegram_id>@telegram.org), metadata.order_id — номер заказа. Не передавай receipt и другие поля, которых нет в разделе «Создать платёж» справочника.
2. Ключ идемпотентности (заголовок Idempotence-Key): новый UUID на каждую попытку оплаты. Сохрани его в заказе до запроса. При таймауте, ответе 500, 429 или 202 повтори запрос с тем же ключом и тем же телом: 1–2 минуты, потом покажи покупателю «Платёж создаётся» и продолжай в фоне с тем же ключом, но не дольше 24 часов. Сохрани id платежа из ответа в заказе.
3. Перенаправление покупателя на confirmation.confirmation_url — только если status = pending и ссылка есть. Если повтор с тем же ключом вернул status = canceled, платёж не создался до конца: создай новый платёж с новым ключом.
4. Обработчик уведомлений (POST на мой адрес): проверь подпись из заголовков Signature и Signature-Timestamp по строке «<Signature-Timestamp>.<сырое тело запроса>» и отклони уведомление старше 5 минут; на незнакомый event ответь 200 и ничего не делай; запроси платёж GET https://api.avantpay.io/v3/payments/{id} и решай по ответу API; на ответ 404 и на платёж, которого нет в моих заказах (например, счёт из личного кабинета), ответь 200 и ничего не делай; при status = succeeded сверь amount.value и amount.currency с суммой заказа и отметь заказ оплаченным атомарно (условный UPDATE … WHERE paid_payment_id IS NULL или блокировка строки), потом выполни заказ ровно один раз; ответь 200 не позже чем через 10 секунд; если не удалось обработать — ответь 500.
5. Страница возврата (return_url): AvantPay открывает её без параметров. Найди заказ по адресу страницы, возьми из заказа id платежа, запроси платёж GET https://api.avantpay.io/v3/payments/{id} и покажи покупателю результат по status. Если выполняешь заказ и здесь — той же атомарной функцией, что и обработчик уведомлений: возврат покупателя и уведомление приходят одновременно.
6. Сверка по расписанию: раз в несколько минут запрашивай GET https://api.avantpay.io/v3/payments?status=succeeded&captured_at.gte=<время прошлой сверки минус 10 минут> по всем страницам и обрабатывай каждый платёж тем же кодом, что и уведомление. Уведомление может не дойти.
7. Учти: одно уведомление может прийти несколько раз и не по порядку; незнакомые поля в ответах не должны ломать код; повторная оплата того же заказа — новый платёж с новым ключом идемпотентности; если сумма заказа изменилась после создания платежа, создай новый платёж с новым ключом, а платёж на старую сумму не засчитывай.
8. Запросы к API — только с сервера. Секретный ключ не должен попасть в браузер, мобильное приложение, логи или репозиторий.
В конце перечисли, что я должен настроить в личном кабинете AvantPay (адрес уведомлений — до первого платежа), и как проверить интеграцию по разделу «Проверка интеграции» документации.
Если нужны возвраты
Добавьте к заданию этот текст:
Добавь возврат денег покупателю через API AvantPay (раздел «Возвраты» и разделы «Объект возврата», «Создать возврат», «Получить возврат» справочника).
1. Возврат: POST https://api.avantpay.io/v3/refunds с полями payment_id (id оплаченного платежа), amount (value — строка с двумя знаками после точки, currency — RUB; можно вернуть часть суммы, но не меньше 1 ₽, если это не весь остаток), description и metadata (мои данные к возврату, например metadata.order_id: по ним найдёшь возврат в списке и в уведомлении, если ответ на создание не дошёл). Перед запросом проверь, что у платежа refundable = true. Не передавай receipt, sources, deal и refund_method_data. Таймаут запроса — 40 секунд.
2. Ключ идемпотентности (Idempotence-Key): один ключ на один возврат, например refund-<номер заказа>-<номер возврата>. Сохрани его в моей базе до запроса. При таймауте, ответе 500 или 429 повтори запрос с тем же ключом и тем же телом, но не дольше 24 часов: позже запрос с тем же ключом создаст новый возврат. Если повтор получил 400, 401 или 403, ключ не меняй: возврат мог создаться первым запросом; после исправления повтори с тем же ключом или найди возврат в GET /v3/refunds?payment_id=… по сумме и metadata. Ответ 400 с parameter Idempotence-Key на повтор значит, что возврат с этим ключом уже создан. Новый ключ — только для нового возврата: запрос с новым ключом может вернуть деньги второй раз.
3. На запрос, который создал возврат, приходит status = pending: это не значит, что деньги вернули. Повтор с тем же ключом может вернуть тот же возврат уже в статусе succeeded или canceled — обрабатывай любой статус из ответа. Сохрани id возврата. Итог узнавай запросом GET https://api.avantpay.io/v3/refunds/{id}: succeeded — деньги вернули покупателю, canceled — не вернули (причина в cancellation_details). Уведомления об отмене нет, поэтому возвраты в pending проверяй по расписанию. Возврат в pending дольше часа не считай отменённым: покажи мне, что нужно написать в поддержку AvantPay.
4. Уведомление refund.succeeded обрабатывай как остальные: проверь подпись, запроси возврат по object.id и решай по ответу API; на 404 и если заказа с таким payment_id нет (счёт из личного кабинета) ответь 200 и ничего не делай; повтор уведомления не должен ничего менять.
5. По одному платежу одновременно может выполняться только один возврат: следующий создавай, когда прежний стал succeeded или canceled. Ответ 403 — у ключа нет права «Возвраты» или IP-адрес сервера не в списке ключа: скажи мне написать в поддержку AvantPay. Текст description в ошибках не разбирай в коде: причину отказа по платежу определяй по самому платежу (status, refundable, refunded_amount), а description показывай мне.
Что проверить в коде от ассистента
Чаще всего ассистенты ошибаются так:
- не передают email покупателя в
metadata.email— платёж не создаётся, ошибка 400; - не передают
"capture": true; - передают
receipt— чеки AvantPay не отправляет, запрос получит ошибку 400; - выполняют заказ, когда покупатель вернулся на
return_url, без проверки статуса; - не сверяют
amountплатежа с суммой заказа: после смены корзины заказ выполняется по старому платежу на меньшую сумму; - проверяют «заказ не выполнен», а потом выполняют его без атомарной отметки: уведомление и возврат покупателя на
return_urlвыполняют заказ дважды; - выполняют заказ только по уведомлению, без сверки по расписанию;
- отвечают 500 на уведомление о платеже, которого нет в заказах, или на ответ 404 — уведомление повторяется сутки;
- ждут на странице
return_urlпараметр сidплатежа — его там нет; - создают новый ключ идемпотентности при каждом повторе запроса;
- передают сумму числом (
100) вместо строки ("100.00"); - считают подпись только по телу, без
Signature-Timestamp; - выполняют заказ повторно на повторное уведомление;
- считают возврат выполненным по ответу на его создание — на новый возврат там
pending; - считают ошибкой любой статус, кроме
pending, в ответе на повтор создания возврата — повтор может вернуть ужеsucceededилиcanceled; - повторяют запрос на возврат с новым ключом идемпотентности, в том числе после ошибки 401 или 403 на повторе, — деньги могут вернуться дважды.