Как подключить Payora к сайту на PHP
Если ваш сайт — это отдельная PHP-разработка, задача довольно простая: создайте платеж, отправьте клиента в Payora, а затем верните результат в свою систему заказов. Никакого WooCommerce. И без лабиринта плагинов.
В этом руководстве мы разберём, как подключить Payora к кастомному PHP-сайту, не превращая оформление заказа в научный эксперимент. Вы увидите, где именно PHP должен запускать оплату, где принимать возврат, и где ваше приложение должно решать, оплачен заказ, в ожидании он или завершился ошибкой. На практике такая интеграция Payora с PHP сайтом обычно требует лишь аккуратно выстроенного потока и ясного разделения ролей между браузером и сервером.
1. Подтвердите схему интеграции для сайта на PHP
Начните с одного решения: вы делаете простую ссылку на оплату, серверный запрос на создание платежа или полноценный платёжный поток с отслеживанием заказа? Это не одно и то же. Одностраничный сайт для пожертвований может обойтись ссылкой на оплату, а магазину с 20 товарами обычно нужно создавать заказ на сервере до того, как клиент покинет сайт.
Для кастомного PHP-сайта чаще всего лучше работает такая схема: сначала создайте заказ локально, затем создайте платёж Payora из PHP, перенаправьте клиента и после этого дождитесь возврата и серверного подтверждения. Так у вас будет запись в своей системе ещё до того, как деньги будут списаны. И вся логика корзины и счёта останется внутри вашего приложения, где ей и место.
Если оформление заказа совсем небольшое, вам может хватить обычного редиректа на платёжную страницу Payora. Если нужны позиции заказа, комментарии клиента или ID заказа, PHP-код должен отправить эти данные до перенаправления. Просто. Но не примитивно.
Практический пример помогает понять разницу. Digital-агентство, которое продаёт пакет обслуживания на 3 шага, может создать заказ в PHP, привязать email клиента и отправить его в Payora с номером счёта. Небольшой проект, где продаётся один лицензионный ключ, может обойтись только ссылкой на оплату и страницей возврата. Разница не в объёме кода, а в том, сколько состояния вам нужно сохранить.
2. Сопоставьте страницы, конечные точки и поток сессии
Прежде чем писать код, перечислите страницы. Вам нужны как минимум три: страница оформления заказа, страница возврата и серверная конечная точка для подтверждения оплаты. Если не спланировать это заранее, потом придётся гадать, какой именно запрос изменил заказ. А угадывать дорого.
Используйте обычную PHP-сессию для потока в браузере, но не полагайтесь только на неё. Состояние сессии может исчезнуть, если клиент переключит устройство, закроет вкладку или вернётся из Payora позже. Храните ID заказа ещё и в базе данных, чтобы ваш PHP-код мог найти транзакцию даже тогда, когда браузерная сессия уже исчезла.
Обычно поток выглядит так:
- Страница оформления заказа собирает товар, email и количество.
- PHP создаёт локальный заказ со статусом pending.
- PHP отправляет клиента в Payora.
- Payora возвращает браузер на ваш URL возврата.
- Ваш сервер проверяет статус оплаты, прежде чем отметить заказ как оплаченный.
Такой поток разделяет страницу возврата в браузере и серверную истину. И это правильно. Они должны быть разделены. Браузер показывает, что увидел клиент, а ваш сервер решает, что означает заказ.
Одна небольшая привычка сэкономит часы позже: сохраните платёжный reference Payora рядом с ID заказа сразу после создания платежа. Если вы подождёте до редиректа, ошибка сети или нетерпеливое обновление страницы могут оставить вас с заказом без reference Payora. Тогда в продакшене придётся играть в детектива.
3. Подготовьте минимальный PHP-слой для платёжных запросов
Не держите платёжный код в шаблонах. Достаточно небольшого PHP-класса или helper-файла. Один метод может собирать payload, другой отправлять HTTP-запрос, а третий разбирать ответ. Такое разделение важно, потому что платёжная логика меняется чаще, чем разметка страницы.
Например, ваш helper может принимать массив с amount, currency, order_id и return_url, а затем подставлять учётные данные Payora из переменных окружения. Страница оформления заказа не должна знать, где лежит API-токен. Она должна знать только, какую кнопку нажали.
Вот схема логики кода, не полноценная реализация:
- Прочитать заказ из базы данных.
- Собрать массив запроса Payora.
- Отправить запрос через cURL или похожий HTTP-клиент.
- Сохранить полученный payment reference Payora.
- Перенаправить клиента на URL оплаты Payora.
Делайте этот helper скучным. Скучный код легче тестировать. Скучный код реже ломается, когда вы меняете цену товара или добавляете следующем месяце вторую форму оформления заказа.
Если у вас в приложении уже есть абстракция для платежей, используйте её. Если нет — создайте один файл и назовите его понятно, например PayoraClient.php. В нём должны быть учётные данные, вызовы API и разбор ответов. Ничего больше. Ни HTML. Ни CSS. Ни сообщение с благодарностью.
4. Перенаправьте клиента в Payora из вашего кастомного чекаута
Когда локальный заказ создан, отправьте платёжный запрос Payora и перенаправьте клиента на платёжную страницу Payora. Передача должна происходить только после того, как сервер уже сохранил заказ, потому что пользователь может закрыть вкладку сразу же после начала редиректа.
Передавайте только те данные заказа, которые действительно нужны. Обычно это ID заказа, сумма, валюта и email клиента. Можно также отправлять метаданные, например название продукта или внутренний ID аккаунта, но не выгружайте все поля из базы данных только потому, что они доступны. Лишние данные потом создают путаницу, когда служба поддержки сравнивает записи.
Кастомный чекаут часто использует POST-форму с кнопкой «Оплатить сейчас». Эта форма отправляется на ваш PHP-эндпоинт, эндпоинт создаёт платёж Payora, а затем отвечает редиректом. Клиент никогда не видит ответ API. Он видит только Payora.
Одна важная оговорка: не доверяйте расчётам на стороне клиента. Если на странице товара указано $49, а браузер отправляет $39, сервер должен отклонить расхождение. Платёжный запрос нужно создавать на основе итоговой суммы на сервере, а не на значении, скрытом в форме. Это правило важно всегда.
Если хотите посмотреть на картину шире, в руководстве по платёжному шлюзу для криптоплатежей в ecommerce есть полезный контекст, без повторения PHP-потока здесь.
5. Получите и проверьте результат оплаты в своём приложении
URL возврата в браузере полезен, но это не окончательная истина. Он может показать, что страница оплаты была открыта, и может передать значение статуса, но ваше PHP-приложение всё равно должно считать этот результат предварительным, пока сервер не подтвердит его. Pending — это не paid.
Сделайте страницу возврата так, чтобы она обрабатывала три случая: success, pending и failure. Если Payora сообщает success, покажите страницу благодарности и сообщите пользователю, что заказ подтверждается. Если статус pending — так и скажите. Если произошла ошибка, предложите клиенту попробовать ещё раз, не теряя запись о заказе. Понятный текст снижает число обращений в поддержку.
Есть полезное правило: страница возврата никогда не должна сама создавать оплаченный заказ. Она должна только показывать текущее состояние и, возможно, предлагать ссылку обратно на страницу заказа. Обновление в базе данных происходит после проверки, а не после редиректа в браузере. Это защищает от случайного двойного обновления.
Сделайте endpoint возврата достаточно простым, чтобы его можно было понять с одного взгляда. Если он получает payment reference Payora, найдите его в системе. Если reference отсутствует, залогируйте запрос и остановитесь. Если заказ уже оплачен, покажите дружелюбное сообщение и ничего не меняйте. Именно так поток с идемпотентностью остаётся спокойным при повторных обновлениях страницы.
Для команд, которым нужен ещё и взгляд со стороны чекаута, статья о том, как принимать криптоплатежи, содержит полезные замечания по биллингу, особенно если вы продаёте услуги с регулярными счетами или ручным подтверждением.
6. Подтвердите транзакцию на сервере, прежде чем отмечать заказ как оплаченный
Это более безопасный шаг. Ваш PHP-приложение должно обращаться к Payora на стороне сервера и подтверждать статус транзакции до того, как заказ будет помечен как paid. Редиректы в браузере могут умолчать о важных деталях; серверная проверка не зависит от того, закрыл ли клиент вкладку, обновил ли её дважды или использовал второе устройство.
Используйте сохранённый ранее payment reference Payora и запросите текущее состояние транзакции. Сравните полученный статус с тем, который нужен для выполнения заказа. Если транзакция settled или confirmed, обновите заказ. Если она pending, оставьте заказ в ожидании. Если она failed или canceled, не трогайте заказ.
К слову, именно здесь многие кастомные PHP-сайты начинают халтурить. Они доверяют странице возврата, потому что так быстрее написать код. Быстрее — да. Безопаснее — нет. Пятисекундная проверка всегда лучше, чем потом длинная переписка с поддержкой.
Если Payora предоставляет подписанный callback или механизм server-to-server подтверждения, используйте его вместе с проверкой статуса. Так у вас будет два уровня контроля: один из пользовательского потока и один из серверного. Если вашей реализации нужна пошаговая проверка подписи, посмотрите как протестировать криптоплатеж — там есть дисциплина валидации, которая особенно окупается перед запуском.
Помечайте заказ как оплаченный только после того, как сервер согласится. Не после слов клиента. И не после слов браузера. Ваша база данных должна отражать тот платёжный статус, который подтверждает Payora, потому что именно на него потом будут опираться команды выполнения заказов и бухгалтерия.
7. Сохраните запись о платеже и обработайте повторные отправки
Храните в базе данных reference транзакции Payora, локальный ID заказа, сумму, валюту и финальный статус. По возможности делайте это одной записью. Позже, когда клиент напишет «я оплатил дважды», вам понадобится чистая запись, а не три незавершённых обновления.
Повторные отправки случаются по обычным причинам. Клиент нажимает кнопку дважды. Используется кнопка «назад». Браузер повторяет запрос. Ваш PHP-код должен определять, что у заказа уже есть reference Payora, и не создавать второй платёж для того же заказа, если только первый не завершился ошибкой или не истёк. Это и есть основа идемпотентности.
Хорошо работает простое правило: один локальный заказ — одна активная транзакция Payora. Если приходит второй запрос по тому же заказу, пока первый ещё в ожидании, покажите существующую ссылку на чекаут Payora вместо создания новой. Если заказ уже оплачен — ничего не делайте. Спокойно. Это молчание — не баг, а функция.
Делайте столбцы базы данных точными. Например, храните payora_reference, payment_status, paid_at и last_checked_at. Эти поля помогают поддержке, бухгалтерии и отладке. Если позже понадобится сверить платёж, эти четыре поля ответят на большинство вопросов без часового поиска по логам.
Если вы строите поток клиентских счетов, а не магазинный чекаут, статья о платёжном шлюзе для фрилансеров тоже может помочь с той же логикой учёта, особенно там, где номера счетов важнее корзины.
8. Протестируйте весь поток на staging-копии сайта
Перед запуском на боевом сайте скопируйте его на staging и проверьте всю цепочку: создание заказа, редирект Payora, страницу возврата, серверную проверку и обработку двойного клика. Если вы тестируете только редирект, вы проверили лишь треть проблемы.
Выполните как минимум такие проверки:
- Создайте новый заказ и убедитесь, что запрос на оплату Payora сгенерирован.
- Обновите страницу возврата 2 раза и проверьте, что заказ не меняется повторно.
- Отправьте форму чекаута дважды и убедитесь, что существует только 1 активная транзакция.
- Принудительно задайте pending или failed результат и убедитесь, что заказ остаётся неоплаченным.
- Проверьте, что сохранённый reference Payora совпадает с записью в базе данных.
Тестируйте на той же версии PHP и с тем же серверным окружением, которое планируете использовать в продакшене. Поток, работающий на локальном ноутбуке, может сломаться на боевом сервере из-за более строгой SSL-конфигурации или других настроек cURL. Это не редкость. Такое бывает.
И ещё одна практическая проверка: откройте заказ в инкогнито-окне, завершите оплату, а затем откройте тот же URL возврата во втором браузере. Ваше приложение не должно выполнять второе обновление оплаты. Если выполняет — исправьте это до запуска. Без исключений.
Для команд, которые продают пути оплаты USDC вместе с другими способами оплаты, заметки в как принимать платежи USDC помогут сравнить ожидания клиентов до того, как вы зафиксируете PHP-поток в продакшене.
И это последнее, что нужно проверить: один и тот же заказ должен пережить один редирект, одно обновление и одно серверное подтверждение, не выходя из синхронизации. Если так и есть, ваш кастомный PHP-чекаут готов к первому живому платежу. Такой Payora PHP пример оплаты удобнее всего держать на staging до тех пор, пока все статусы и повторные запросы не начнут вести себя предсказуемо.



Комментарии