# Сделайте банку для чаевых на своём аккаунте Stripe

> Три вызова API дают хостируемую страницу «плати сколько хочешь» с Apple Pay и Google Pay — и ни одного сервера. Вот вся сборка: ограниченный ключ, права, как читать чаевые без вебхука, и честная арифметика комиссий, которую никто не печатает.

Canonical: https://live.tips/ru/blog/sdelayte-banku-dlya-chaevykh-na-svoyom-akkaunte-stripe/
Published: 2026-07-11
Language: ru
Tags: Stripe, open source, how-to, API, fees

---

Вам нужна банка для чаевых. Вам не хочется отдавать платформе 5 % вечера уличного
музыканта, и вы прекрасно умеете разговаривать с API. Значит, вопрос не в том, *в какой
банке для чаевых зарегистрироваться*, а в том, *сколько на самом деле надо построить*.

Меньше, чем кажется. В Stripe работающий ответ — три вызова API: ни сервера, ни бэкенда, ни
вебхук-эндпойнта. Остальная часть этого поста — как раз эта сборка, плюс две вещи, в которых
все ошибаются.

## Весь фокус — это Price «плати сколько хочешь»

В Stripe есть режим цены, где сумму вводит сам фанат. Он называется
[pay what you want](https://docs.stripe.com/payments/checkout/pay-what-you-want) — и это вся
функциональность. Вы создаёте Product, вешаете на него Price с
`custom_unit_amount[enabled]=true`, а сверху —
[Payment Link](https://docs.stripe.com/payment-links/create).

```sh
# 1. то, что вы "продаёте"
curl https://api.stripe.com/v1/products \
  -u "$RK:" \
  -d name="Tips — Mira" \
  -d "metadata[managed_by]"=my-tip-jar

# 2. цена, которую выбирает фанат
curl https://api.stripe.com/v1/prices \
  -u "$RK:" \
  -d product=prod_... \
  -d currency=eur \
  -d "custom_unit_amount[enabled]"=true \
  -d "custom_unit_amount[preset]"=500 \
  -d "custom_unit_amount[minimum]"=200

# 3. страница
curl https://api.stripe.com/v1/payment_links \
  -u "$RK:" \
  -d "line_items[0][price]"=price_... \
  -d "line_items[0][quantity]"=1 \
  -d submit_type=pay
```

Третий вызов возвращает `url`. Этот URL *и есть* ваша банка для чаевых. Это страница, которую
хостит Stripe: она PCI-совместима без вашего участия, локализована и показывает Apple Pay или
Google Pay каждому фанату, у кого они настроены на телефоне, —
[динамические способы оплаты](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods)
решают это за вас, исходя из устройства и страны. Вы не написали ни строчки фронтенда.

Закодируйте URL в QR-код любой библиотекой — это просто строка — распечатайте, приклейте к
футляру. Код никогда не протухнет и не указывает ни на какой ваш сервер, потому что сервера у
вас нет.

Два параметра, которые стоит знать:

- **`custom_unit_amount[preset]`** — сумма, с которой открывается страница. `500` означает, что
  фанат видит уже вписанные 5,00 € и может их изменить. Это число делает для вашего среднего
  чаевого больше, чем всё остальное на странице.
- **`custom_unit_amount[minimum]`** — пол. Поставьте его. Причина — в разделе о комиссиях ниже, и
  это не погрешность округления.

Можно также собирать имя и сообщение. Payment Links принимают до трёх `custom_fields` — так вы
получаете «а от кого это было» без постройки формы:

```sh
  -d "custom_fields[0][key]"=nickname \
  -d "custom_fields[0][type]"=text \
  -d "custom_fields[0][label][type]"=custom \
  -d "custom_fields[0][label][custom]"="Ваше имя или ник" \
  -d "custom_fields[0][optional]"=true
```

У Stripe есть [требования к приёму чаевых и пожертвований](https://support.stripe.com/questions/requirements-for-accepting-tips-or-donations) —
прочитайте их один раз. «Плати сколько хочешь» также не сочетается с другими line items, скидками
и регулярными платежами. Для банки с чаевыми ничто из этого не мешает.

Эту разницу стоит понимать правильно. Stripe формулирует так: чаевые дают за уже оказанный
товар или услугу, а пожертвование должно быть привязано к благотворительной цели. Вы
отыграли сет; чаевые за него и платят. Поэтому вызов выше отправляет `submit_type=pay`, а
не `donate` — `donate` разместил бы вашу ссылку на `donate.stripe.com` и напечатал бы на
кнопке *Пожертвовать*. Это другой бизнес, и такой, который Stripe проверяет заметно
строже.

## Ключ: считайте, что он утечёт, — и сделайте это скучным

Не кладите секретный ключ (`sk_live_…`) на устройство, которое стоит на сцене. Возьмите
[ограниченный ключ](https://docs.stripe.com/keys/restricted-api-keys) (`rk_live_…`): вы выбираете
право для каждого ресурса, а всё, что не выбрали, остаётся на **None**.

Для сборки выше полный список — пять строк:

| Ресурс | Право | Что это даёт |
| --- | --- | --- |
| Products | Write | создать Product |
| Prices | Write | создать Price «плати сколько хочешь» |
| Payment Links | Write | создать ссылку |
| Checkout Sessions | Read | видеть пришедшие чаевые |
| Events | Read | живая лента (следующий раздел) |

Всё остальное — Balance, Payouts, Refunds, Customers, PaymentIntents, весь Connect — остаётся на
**None**.

А теперь сделайте упражнение, ради которого всё это и затевалось. В час ночи ваш планшет уводят со
столика с мерчем. Что вор сделает с ключом в кейчейне? Прочитает историю чаевых и создаст ещё
несколько ссылок на чаевые в вашем аккаунте. Это весь радиус поражения. Он не увидит баланс, не
запустит выплату, не оформит возврат на свою карту, не прочитает список клиентов. Вы отзываете ключ
с телефона в такси по дороге домой — и устройство гаснет. Из ваших денег не сдвинулось ничего.

Эта асимметрия — запись в банку для чаевых и ноль доступа к деньгам — единственная причина, по которой
бессерверный дизайн со своим ключом вообще можно защищать. Она же — причина, почему «Login with Stripe»
здесь не ответ: OAuth требует сервера разработчика приложения, чтобы держать ваш токен, — а сервер это
ровно то, чего мы не строим.

(Странность, на которую вы наткнётесь: право *Prices* внутри называется `plan_write`, поэтому сообщение
об ошибке Stripe называет scope, которого под таким именем в дашборде нет. Речь про Prices.)

## Читать чаевые без вебхука

Здесь большинство руководств либо останавливается, либо хватается за вебхук — и здесь сцена по-настоящему
отличается от веб-приложения.

Вебхук — это входящий HTTP-запрос. Планшет за микрофонной стойкой не может его принять. Он сидит в гостевом
Wi-Fi заведения за NAT, у него нет публичного адреса и TLS-сертификата — и незачем им быть. Если пойти путём
вебхука, придётся поднять сервер, который ловит события, и сокет, который пропихивает их на устройство: бэкенд,
эксплуатационная нагрузка и место, где теперь живут имена ваших фанатов. Вы только что заново построили ту самую
платформу, которой хотели избежать.

Поэтому тяните, а не ждите, пока толкнут. Эндпойнт Stripe
[List all events](https://docs.stripe.com/api/events/list) публичный, задокументированный и возвращает события,
начиная с самых новых:

```sh
curl -G https://api.stripe.com/v1/events \
  -u "$RK:" \
  -d "types[]"=checkout.session.completed \
  -d "types[]"=checkout.session.async_payment_succeeded \
  -d ending_before=evt_ПОСЛЕДНЕЕ_ВИДЕННОЕ \
  -d limit=100
```

`ending_before` — это весь дизайн. Храните id самого свежего обработанного события; каждый опрос просит всё строго
более новое, а вы двигаете курсор. Никаких таймстемпов, никакого рассинхрона часов, никакой дедупликации по сумме.
На первом опросе сета попросите `limit=1` без курсора, чтобы зацепиться за то, что уже есть, — иначе на саундчеке
переиграете чаевые сегодняшнего утра.

Дальше фильтруйте то, что вернулось. Оба типа событий могут выстрелить на один платёж, поэтому дедуплицируйте по id
Checkout Session. Проверяйте `payment_status == "paid"` — завершённая сессия не обязательно оплаченная. И проверяйте,
что `payment_link` совпадает с *вашей* ссылкой, потому что `/v1/events` работает на уровне всего аккаунта и с радостью
подсунет вам трафик от всего остального, что этот аккаунт Stripe делает.

Будьте честны насчёт компромиссов, они настоящие:

- **Stripe рекомендует вебхуки.** Опрос — не благословенный путь; это задокументированный эндпойнт, который применяют
  осознанно. Напишите об этом в README и идите дальше.
- **События уходят на 30 дней назад.** [Слова самого Stripe](https://docs.stripe.com/api/events/list):
  *«List events, going back up to 30 days.»* Это живая лента, а не ваша бухгалтерская книга. Ваша книга — Checkout
  Sessions, а настоящая книга — дашборд Stripe.
- **Следите за квотой на чтение.** Все смотрят на лимит в секунду
  ([rate limits](https://docs.stripe.com/rate-limits): 100 запросов/с в live) и никто — на другой: Stripe выделяет
  примерно **500 запросов на чтение на одну транзакцию** за скользящие 30 дней, с полом в 10 000 чтений в месяц.
  Опрашивайте раз в 4 секунды — и трёхчасовой сет это ~2 700 чтений. Четыре длинных концерта за месяц, и вы на полу.
  Чаевые докупают запас по мере поступления, но тот, кто опрашивает раз в секунду, потому что «так бодрее», найдёт
  потолок. Четыре секунды — не ленивое число; это *то самое* число.

Вот честная форма дела: опрос стоит вам пары тысяч GET-запросов и покупает удаление целого бэкенда.

## Арифметика комиссий, сделанная как следует

Платформа, рекламирующая 0 %, не бесплатна — и это тоже. Собственная комиссия Stripe за обработку применяется к каждому
чаевому, и Stripe выставляет её вам напрямую. Сегодня, по
[евро-прайсу Stripe](https://stripe.com/ie/pricing), стандартная карта ЕЭЗ стоит **1,5 % + 0,25 €**. Премиальные карты
ЕЭЗ — 1,9 % + 0,25 €, британские — 2,5 % + 0,25 €, всё остальное — 3,25 % + 0,25 € плюс ещё 2 %, если нужна конвертация
валюты. (В США это 2,9 % + 0,30 $, что хуже ровно по причине ниже.)

Проблема не в проценте. Проблема в двадцати пяти центах.

| Чаевые | Stripe забирает | Артисту остаётся | Реальная доля |
| --- | --- | --- | --- |
| 2 € | 0,28 € | 1,72 € | **14,0 %** |
| 5 € | 0,33 € | 4,67 € | 6,5 % |
| 10 € | 0,40 € | 9,60 € | 4,0 % |
| 20 € | 0,55 € | 19,45 € | 2,8 % |
| 50 € | 1,00 € | 49,00 € | 2,0 % |

Фиксированная комиссия — это процент в маскировке, и на малых деньгах маскировка сползает. Те же 0,25 €, невидимые на
чаевых в 50 €, съедают восьмую часть чаевых в 2 €. Чаевые малы по своей природе — именно это и делает их чаевыми — так что
это не краевой случай, а медианный.

Именно поэтому вы ставите `custom_unit_amount[minimum]`. Где-то около 2 € транзакция перестаёт быть достойной обработки;
карточные чаевые в 0,50 € придут как 0,24 € и обойдутся Stripe в переводе дороже, чем стоят. Выбирайте пол осознанно, а не
обнаруживайте его при первой выплате.

И заметьте, что это делает со сравнением, с которого вы начали. Платформа, берущая 0 % поверх Stripe, берёт с вас 0 % поверх
**вот этого**. Их 0 % настоящие — и это 0 % от того, что оставил процессинг. Ничья карточная рельса не бесплатна: честная
формулировка — «никакой доли сверх той, что берёт процессинг», а кто утверждает больше, тот либо врёт, либо не использует
карты.

## Что у вас теперь есть — и чего нет

Три вызова API и QR-код — и настоящая банка для чаевых: хостируемая, PCI-совместимая, Apple Pay, Google Pay, чаевые падают на
ваш собственный баланс Stripe по вашему собственному графику выплат, и никакого сервера по дороге. Для многих это искренне
конец проекта, и вы вполне можете остановиться здесь и выпустить это.

Чего у вас нет — так это сцены. У вас есть страница оплаты. Между ними стоят скучные вещи: цикл опроса с курсором и бэкоффом;
экран, который видит публика, с целью и последним сообщением; место для ключа, которое не называется `localStorage`; блокировка,
чтобы чужой не тыкал в планшет между сетами; и слой из тысячи мелких решений о том, что делать, когда Wi-Fi заведения падает
посреди сета.

Именно это и есть [live.tips](https://github.com/mekedron/live.tips) — ровно эта архитектура, доведённая до конца, под лицензией
MIT. Ограниченный ключ с теми пятью правами, курсорный цикл по `/v1/events`, создание Product/Price/Payment Link — всё работает на
устройстве артиста, против его собственного аккаунта. В пути к Stripe нет сервера live.tips и нигде нет баланса live.tips — об этом
мы написали отдельно в [как live.tips обращается с деньгами](https://live.tips/ru/blog/kak-live-tips-obrashchaetsya-s-dengami/).

Читайте исходники, забирайте нужные куски или просто пользуйтесь. Смысл этого поста в том, что архитектура — не секрет и не
сложность: **Stripe захостит вашу банку для чаевых бесплатно, а ограниченный ключ плюс цикл опроса — это всё, что стоит между
артистом и его собственными деньгами.** Нам важнее, чтобы вы это знали, чем чтобы вы где-то регистрировались.
