Вам потрібна банка для чайових. Вам не хочеться віддавати платформі 5 % вечора вуличного музиканта, і ви цілком спроможні поговорити з API. Тож питання не в тому, у якій банці зареєструватися, а в тому, скільки насправді треба збудувати.
Менше, ніж здається. У Stripe робоча відповідь — три виклики API: жодного сервера, жодного бекенда, жодного вебхук-ендпойнта. Решта цього допису — саме ця збірка, плюс дві речі, які всі роблять неправильно.
Уся хитрість — це Price «плати скільки хочеш»
У Stripe є режим ціни, де суму вводить сам фан. Він називається
pay what you want — і це вся
функціональність. Ви створюєте Product, чіпляєте до нього Price з
custom_unit_amount[enabled]=true, а зверху вішаєте
Payment Link.
# 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 кожному фану, у чийому телефоні вони налаштовані —
динамічні методи оплати
вирішують це за вас, залежно від пристрою й країни. Ви не написали жодного фронтенду.
Закодуйте URL у QR-код будь-якою бібліотекою — це просто рядок — надрукуйте, приклейте до футляра. Код ніколи не протухає й не вказує на жоден ваш сервер, бо сервера у вас немає.
Два параметри, які варто знати:
custom_unit_amount[preset]— сума, з якою сторінка відкривається.500означає, що фан бачить уже вписані 5,00 € і може їх змінити. Це число робить для вашого середнього чайового більше, ніж будь-що інше на сторінці.custom_unit_amount[minimum]— підлога. Поставте її. Причина — у розділі про комісії нижче, і це не похибка округлення.
Можна також збирати ім'я та повідомлення. Payment Links приймають до трьох custom_fields — так
ви отримуєте «а від кого це було» без побудови форми:
-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 є вимоги до прийому чайових і пожертв — прочитайте їх один раз. «Плати скільки хочеш» також не поєднується з іншими line items, знижками чи регулярними платежами. Для банки з чайовими нічого з цього не заважає.
Цю різницю варто розуміти правильно. Stripe формулює так: чайові дають за вже надані товар
чи послугу, а пожертва має бути прив'язана до благодійної мети. Ви відіграли сет; чайові за
нього й платять. Тому виклик вище надсилає submit_type=pay, а не donate — donate
розмістив би ваше посилання на donate.stripe.com і надрукував би на кнопці
Пожертвувати. Це інший бізнес, і такий, який Stripe перевіряє помітно суворіше.
Ключ: припустіть, що він витече, — і зробіть це нудним
Не кладіть секретний ключ (sk_live_…) на пристрій, який стоїть на сцені. Візьміть
обмежений ключ (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-сертифіката — і не має жодних підстав це все мати. Якщо піти шляхом вебхука, доведеться підняти сервер, який ловитиме події, і сокет, який штовхатиме їх на пристрій: бекенд, експлуатаційний тягар і місце, де тепер живуть імена ваших фанів. Ви щойно відбудували ту саму платформу, якої хотіли уникнути.
Тож тягніть, замість чекати, поки штовхнуть. Ендпойнт List all events у Stripe публічний, задокументований і повертає події від найновіших:
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: «List events, going back up to 30 days.» Це стрічка наживо, а не ваша бухгалтерська книга. Ваша книга — це Checkout Sessions, а справжня — дашборд Stripe.
- Стежте за квотою читань. Усі дивляться на ліміт на секунду (rate limits: 100 запитів/с у live) і ніхто — на інший: Stripe виділяє приблизно 500 запитів на читання на одну транзакцію за ковзні 30 днів, з підлогою 10 000 читань на місяць. Опитуйте раз на 4 секунди — і тригодинний сет це ~2 700 читань. Чотири довгі концерти на місяць, і ви на підлозі. Чайові докуповують запас у міру надходження, але той, хто опитує щосекунди, бо «так жвавіше», знайде стелю. Чотири секунди — не лінива цифра; це та цифра.
Ось чесна форма справи: опитування коштує вам кількох тисяч GET-запитів і купує видалення цілого бекенда.
Арифметика комісій, зроблена як слід
Платформа, що рекламує 0 %, не є безкоштовною — і це теж. Власна комісія Stripe застосовується до кожного чайового, і Stripe виставляє її вам напряму. Сьогодні, за цінами Stripe в євро, стандартна картка ЄЕЗ коштує 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 — точнісінько ця архітектура, доведена до
кінця, під ліцензією MIT. Обмежений ключ із тими п'ятьма дозволами, курсорний цикл на /v1/events,
створення Product/Price/Payment Link — усе працює на пристрої артиста, проти його власного акаунта. У
шляху Stripe немає сервера live.tips і ніде немає балансу live.tips — про це ми написали окремо в
як live.tips поводиться з грошима.
Читайте код, беріть звідти те, що потрібно, або просто користуйтеся. Суть цього допису в тому, що архітектура — не таємниця й не складність: Stripe захостить вашу банку для чайових безкоштовно, а обмежений ключ плюс цикл опитування — це все, що стоїть між артистом і його власними грошима. Нам більше хочеться, щоб ви це знали, ніж щоб ви десь реєструвалися.