Принимаем платежи онлайн. Продолжение.
Автор: | Иван Коржавин |
email: | korjavin@yandex.ru |
Решим вторую главную задачу приема платежей - получение результатов авторизации клиентской оплаты от платежной системы.
Существует несколько основных способов, которыми платежная система оповещает нас о статусе платежа
- Отправка данных о платеже на e-mail;
- Перенаправление браузера клиента на специальную страницу нашего сайта с заполненными и подписанными параметрами;
- Передача параметров платежа на специальную страницу нашего сайта самостоятельно, со своих серверов;
- Вариант когда платежная система не передает нам результатов, мы сами должны опрашивать специальный интерфейс, с кодом платежа, получая в ответ статyс обработки.
Напомню, что в нашем примере, мы используем платежную систему Moneybookers, которая позволяет использовать варианты 1,2 и 3. Поговорим о плюсах и минусах этих вариантов.
Передача данных платежа по e-mail
Очевидно, самый простой способ. Не требует никакого специально кода, единственное что мы должны указать e-mail, на который хотим получать уведомления. Сделать это можно через запрос регистрации платежа, вместе с передачей остальных параметров. Однако, этот способ имеет несколько больших минусов:
- Негарантированная скорость доставки данных;
- Плохо подходит для автоматизированной обработки, гораздо удобнее обрабатывать запросы напрямую, чем добавлять в систему ненужные точки отказа в виде smtp серверов.
На мой взгляд, минусы перевешивают.
Перенаправление клиентского браузера
В этом способе, после проведения авторизации платежная система, сформирует нужный url, состоящий из адреса нашей страницы возврата, параметров платежа, и перенаправит клиентский браузер на этот url.
Для того, что бы злоумышленник не смог подменить данные о платеже, а они передаются в открытом виде, платежная система добавит специальную подпись. В случае moneybookers, вы должны заранее придумать секретное слово, указать его в личном кабинете, и тогда подпись сформируется как md5 хэш от конкатенации кода вашего магазина в система moneybookers, кода транзакции, и md5 хеша от секретного слова. Так как злоумышленник не может знать секретного слова, оно нигде не передается по открытым каналам, то и подделать эту подпись он не может.
Этот способ подходит для автоматической обработки заказов, так как мы можем провести любую обработку на нашей странице возврата. После проверки данных и подписи, мы можем разослать нужные нам e-mail, пополнить баланс лицевого счета клиента и/или изменить статус его заказа автоматически.
К минусам данного способа отнесем:
- Зависимость от клиентского браузера, если у клиента будут проблемы со связью, или програмным обеспечением, мы можем не узнать о фактически совершенном платеже.
- Некрасивые url - вместо простого url вроде supershop.my/success, в клиентском браузере будет длинная конструкция с http get запросом с параметрами, например ?par1=val1&par2=val2&transaction_id=A205220&msid=730743ed4ef7ec631155f5e15d2f4fa0
- Если мы передаем дополнительные поля, не предназначенные для публичного доступа, следует помнить что http get запросы, видны в лог-файлах прокси серверов, истории браузера и множестве других мест. Так же, в случае публичного wifi или незащищенной сети они могут быть прослушаны другими лицами. Во избежании этого следует использовать https протокол, а значит выделенный отдельный ип адрес для сервера. Для крупных магазинов это не проблема, но если магазин мелкий, то вероятно и сертификат ssl и фиксированный выделенный ип адрес будут лишними расходами.
- Может возникнуть ситуация, когда пользовательский браузер вызовет страницу возрата несколько раз. Например просто нажав кнопку "обновить", если ему покажется что загрузка идет медленно. Следует обязательно иметь это ввиду, и не допускать возникновения race condition. Сразу занести эту транзакию в список "обрабатываемых" и отвергать последующие попытки. Ошибкой будет, попытаться сначала выполнять длительные процедуры навроде отправки e-mail или обновления статуса заказов, до блокировки транзакции - ведь в таком случае возможно что вторичный запрос придет быстрее вашей блокировки и вы проведете оплату дважды.
Способ не плох, но есть вариант лучше.
Передача данных платежной системой напрямую
В этом случае, клиентский браузер перенаправляется на "чистый" url без параметров success_url или cancel_url которые мы указали в настройках, в зависимости от результата.
И параллельно платежная система сама вызовет указанный нами result_url и передаст на него параметры платежа.
Способ сочетает в себе все плюсы предыдущего - подходит для автоматической обработки, и избавляет нас от многих минусов. Нет зависимости от поведения клиента, параметры платежа не передаются в "сторону" клиента. И имеет дополнительные плюсы - для безопасности мы можем дополнительно указать ип сети с которых мы будем принимать информацию на страницу результатов. Прописав ипы нашей платежной системы, мы практически не оставим злоумышленникам шанса.
Также к плюсам можно отнести то, что платежная система контролирует код возврата нашей странице, и в случае какой либо неудачи, повторит запрос
Выберем этот способ, и схематично реализуем обработчик на php.
Но для полноты, рассмотрим плюсы и минусы последнего способа
Периодический опрос специального интерфейса платежной системы
Основной минус этого способа, в том, что он меняет концепцию обработки платежа от событийной (клиент ввел данные - мы обработали) к растянутой во времени - не зависимо от ввода клиента, мы вынуждены параллельно по таймеру запрашивать результаты, а так как ввод данных банковской карты, может занять продолжительное время, мы должны будем серьезно усложнить наш обработчик платежей. Добавить расписание, логику опросов.
Иногда, в случаях некоторых банковских процессингов этот способ приходится использовать по причине отсутствия остальных, но с платежной системой moneybookers это бессмысленно. У нас уже есть вариант лучше.
Реализация
Обратите внимание, что в приведенном примере проверяется только статус и подпись.
Это сделано для упрощения, мы не предусмотрели в примере хранение сформированного заказа, но в реальной жизни
полезно также проверять сумму и валюту заказа.
Так как эта страница всегда вызывается между двумя серверами, выводить в ней ошибки бессмысленно, записывайте их в лог, или отправляйте по почте ответственному лицу