Архітектура платіжної інтеграції: картки, гаманці, рахунки та статус замовлень
Створення уніфікованої архітектури платіжної інтеграції, яка обробляє картки, цифрові гаманці, рахунки та відстеження статусу замовлень. Технічні інсайти та реальні компроміси.

Інтеграція платежів рідко буває такою простою, як підключення одного SDK. У наших проєктах у DigiForge ми бачили, як обсяги роботи зростали через те, що команди недооцінювали складність роботи з кількома способами оплати — картками, цифровими гаманцями, рахунками-фактурами — і прив'язки їх до життєвого циклу замовлення. Кожен тип платежу має свої особливості, і поєднання їх без цілісної архітектури призводить до крихкого коду та складного звіряння. У цій статті ми розглядаємо, як виглядає уніфікований шар інтеграції платежів, спираючись як на усталені патерни, так і на новітні розробки, як-от картки, забезпечені стейблкоїнами.
Картки: Токенізація, мережеві токени та поява карток, забезпечених стейблкоїнами
Карткові платежі залишаються основою електронної комерції та багатьох SaaS-бізнесів. Золоте правило — ніколи не обробляти сирі номери карток. Токенізація через PCI-сумісний шлюз (Stripe, Braintree, Adyen) є обов'язковою. Але є тонший рівень: мережеві токени. Це пристроє-специфічні одноразові токени, випущені самими картковими мережами, які забезпечують вищі показники авторизації та знижують рівень шахрайства. Зазвичай ми рекомендуємо клієнтам впроваджувати мережеву токенізацію на ранніх етапах, особливо якщо вони обробляють регулярні платежі, оскільки термін дії токенів довший, а оновлення виконуються мережею.
Новою хвилею є картки, забезпечені стейблкоїнами. Станом на кінець 2025 року обсяг криптокарток досяг $18 мільярдів річного обсягу, зростаючи на 106% щорічно з 2023 року (пресреліз Wirex/Crossmint). Архітектура тут інша: замість списання з банківського рахунку або кредитної лінії, картка використовує гаманець зі стейблкоїнами. Для розробників це означає інтеграцію з постачальником гаманців (наприклад, смарт-гаманець Crossmint) та емітентом карток (наприклад, Wirex). Складність полягає в комплаєнсі — у пресрелізі зазначається, що фінтех-компаніям раніше доводилося збирати окремі компоненти гаманця, емітента та комплаєнсу. У DigiForge ми працювали над подібними багатовендорними інтеграціями і виявили, що абстракційний шар з уніфікованою моделлю транзакцій є критично важливим. Інакше налагодження невдалого платежу перетворюється на гонитву за трьома панелями постачальників.
Цифрові гаманці: UPI, Google Pay та інтеграція через хостинг або API
Цифрові гаманці не є монолітними. Google Pay (тепер частина ширшої екосистеми Google Payments) працює інакше, ніж індійські UPI-гаманці на кшталт Paytm, а обидва відрізняються від гаманців конкретних додатків. Архітектурне рішення полягає у виборі між хостинговою оплатою (простіше, менше контролю) та інтеграцією через API (складніше, багатший UX).
Для гаманців, таких як Google Pay, Apple Pay та PayPal, поширеним патерном є кнопка гаманця, яка викликає шторку або перенаправлення. Інтеграція зазвичай виконується через уніфікований платіжний інтерфейс платіжного шлюзу — наприклад, Stripe Payment Element автоматично відображає всі гаманці. Це підходить для багатьох випадків, але ми стикалися з обмеженнями, коли потрібне власне стилювання або збір додаткових даних до оплати. Глибша інтеграція через власний SDK гаманця дає більше контролю, але зобов'язує підтримувати окремі кодові шляхи.
UPI-гаманці, такі як Paytm, працюють інакше. UPI (Unified Payments Interface) — це система миттєвих платежів, що дозволяє прямі перекази між банками. При інтеграції Paytm як платіжного методу типовий потік виглядає так: користувач обирає Paytm, бекенд генерує платіжний запит, користувач авторизує в додатку Paytm, а Paytm надсилає зворотний виклик. Проблема тут — ідемпотентність: UPI-платежі можуть успішно виконатися на стороні банку, але повідомити про помилку мерчанту через мережеві тайм-аути. Ми завжди будуємо завдання звірки, яке порівнює статус нашого замовлення зі статусом транзакції Paytm кожні кілька хвилин.
Один патерн, який ми визнали надійним: розглядайте кожен платіж через гаманець як двофазний коміт. Перша фаза створює очікуване замовлення, друга фаза підтверджує через вебхук. Ніколи не позначайте замовлення як виконане лише на основі зворотного перенаправлення.
Рахунки-фактури: платіжні запити та звірка
Інвойсні платежі — коли бізнес виставляє рахунок, а клієнт оплачує пізніше — створюють інший набір проблем. Сторінка платежів IRS (irs.gov/payments) є прикладом великої системи виставлення рахунків: ви перевіряєте свій баланс (через повідомлення або онлайн-акаунт), а потім оплачуєте за допомогою банківського рахунку (Direct Pay) або плану платежів. Архітектура має обробляти як життєвий цикл рахунку (виставлений, надісланий, прострочений, оплачений), так і життєвий цикл платежу (ініційований, в обробці, завершений, невдалий).
Для B2B SaaS або користувацьких веб-додатків ми часто будуємо модуль виставлення рахунків, який генерує PDF-файли та розміщує платіжний портал. Портал має приймати кілька методів: картка, гаманець або банківський переказ. Хитрість полягає в тому, щоб пов'язати ID рахунку з ID транзакції платежу в шлюзі, а потім використовувати вебхуки для оновлення статусу рахунку. Поширена помилка — покладатися на вбудовану функцію виставлення рахунків платіжного шлюзу, але втратити контроль над звіркою. Ми віддаємо перевагу зберігати власні записи рахунків і використовувати шлюз лише як платіжний процесор.
// Example webhook handler for invoice payment confirmation
app.post('/webhooks/stripe', async (req, res) => {
const event = req.body;
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
const invoiceId = session.metadata.invoice_id;
await db.invoices.update({ id: invoiceId }, { status: 'paid' });
}
res.json({ received: true });
});
Наведений вище код є спрощеним, але ілюструє основну ідею: зіставте подію шлюзу з вашою власною моделлю домену. Поле metadata — це ваш рятівний круг. Без нього вам довелося б робити запити до Stripe для зіставлення сесій, що додає затримки та складності.
Статус замовлення: відображення платіжних подій на життєвий цикл
Замовлення може проходити через багато статусів: pending_payment, payment_received, processing, fulfilled, cancelled. Подія оплати має бути лише одним із багатьох тригерів. Ключовим архітектурним рішенням є використання скінченного автомата або простішого поля статусу. Ми наполегливо рекомендуємо скінченні автомати для будь-яких систем із більш ніж чотирма статусами або зі складними переходами (наприклад, замовлення може перейти з 'payment_received' на 'processing', потім на 'shipped', а також з 'pending_payment' на 'cancelled'). Добре підходить гем StateMachines для Rails або власний скінченний автомат на Node.js.
Вебхуки від платіжних шлюзів мають надходити безпосередньо до скінченного автомата. Наприклад, подія payment_intent.succeeded повинна перевести замовлення з 'pending_payment' на 'payment_received'. Але слід захиститися від стану гонки: якщо вебхук надходить двічі (більшість шлюзів гарантують доставку щонайменше один раз), ваш скінченний автомат має бути ідемпотентним — тобто перехід з того самого поточного стану до того самого наступного стану має бути безопераційним. Ми зберігаємо event_id для кожного вебхука, щоб виключити дублікати.
Ідемпотентність не є опціональною. Якщо ваш обробник платіжних вебхуків не ідемпотентний, ви зрештою подвійно списаєте кошти з клієнта або створите замовлення-привиди. Тестувати це при звичайному навантаженні важко; ми імітуємо затримані та дубльовані вебхуки в нашому конвеєрі CI.
Статус замовлення також потрібно показувати клієнтам. Проста сторінка статусу (наприклад, прогрес-бар) працює, але лише якщо базові переходи точні. Ми бачили системи, де фронтенд опитує API, яке кешує статус замовлення — але кеш може бути застарілим, якщо вебхук ще не оброблено. Рішення — використовувати канал реального часу (WebSocket або Server-Sent Events), який надсилає зміни статусу, щоб інтерфейс оновлювався негайно після обробки вебхука. Для простіших проєктів прийнятним є короткочасний кеш із TTL 30 секунд.
Позиція DigiForge: Створюйте шар інтеграції платежів, а не безлад
Після інтеграції десятків платіжних методів у різних проєктах наша рекомендація — абстрагувати обробку платежів за допомогою тонкого сервісного шару. Цей шар має нормалізувати події кожного платіжного провайдера у спільний формат подій, обробляти повторні спроби та вести журнал транзакцій. Система замовлень ніколи не спілкується безпосередньо з Stripe, Paytm чи будь-яким емітентом — вона спілкується з вашим платіжним сервісом. Це значно спрощує додавання нових платіжних методів (наприклад, картки на основі стейблкоїнів) без зміни логіки замовлень.
Також ми рекомендуємо розглядати рахунки-фактури як окремий домен, а не просто статус замовлення. Рахунок-фактура має власний життєвий цикл (чернетка, надіслано, прострочено, оплачено) і може бути пов'язаний з кількома замовленнями (наприклад, щомісячна підписка). Аналогічно, статус замовлення має керуватися скінченним автоматом, який обробляє всі можливі переходи, включаючи часткові оплати, повернення коштів та чарджбеки.
Якщо ви створюєте платіжну інтеграцію з нуля, почніть зі складання карти всіх платіжних методів, які плануєте підтримувати, та визначення спільних подій, які вони генерують. Потім спроєктуйте скінченний автомат і обробник вебхуків. Якщо це зроблено правильно, решта — лише технічна реалізація. Якщо вам потрібна друга думка щодо вашої архітектури, команда DigiForge бачила достатньо крайових випадків, щоб заощадити вам кілька безсонних ночей.
Джерела
- Wirex and Crossmint Announce Card Integration to Connect Stablecoin Wallets and Real-World Spending
- Wirex and Crossmint Announce Card Integration to Connect Stablecoin Wallets and Real-World Spending
- payments.google.com
- Payments | Internal Revenue Service
- Paytm: Secure & Fast UPI Payments, Recharge Mobile & Pay Bills


