Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Интеграция Деньги Online в ActiveMerchant

Anna | 20.06.2014 | нет комментариев

В приложении, которое я разрабатываю на Ruby on Rails, мне необходимо было подключить платежную систему. Клиент заключил договор с Деньги Online, и первым делом я, безусловно, проверил список поддерживаемых систем в ActiveMerchant от Shopify — там этого обслуживания не оказалось, также еще поискал готовые решения, которые сумели бы упростить интеграцию, но ничего пригодного под RoR не нашлось. В выводе было решено форкнуть ActiveMerchant и разработать под него интеграцию для этого обслуживания, а в последствии применять наработки в плане.

В этой статье хочу рассказать о процессе подключения платежной системы, в вере что кому-нибудь это сгодится, потому что мне не хватало сходственной информации. А также допустимо кому-нибудь сгодится информация, реально по этой платежной системе.

До этого у меня теснее было знакомство с ActiveMerchant: в одном из планов интегрировал Robokassa —, тогда во много помогла эта статья, и ни с какими загвоздками я не столкнулся, но в код реализации модуля пришлось заглянуть лишь несколько раз, что бы проверить либо осознать работу каких-то определенных способов — на этом все ограничилось. А при интеграции своего модуля мне пришлось исследовать довольно огромную часть ActiveMerchant.

Конструкция ActiveMerchant

Для помощи в интеграции сходственных сервисов, в плане существует 3 базовых класса:

  • Helper — на основе него происходит построение формы при помощи способа payment_service_for, данный способ сам генерирует форму, со всеми нужными параметрами, разработчику остается лишь верно сделать Helper, для определенной платежной системы
  • Notification — в данном классе содержатся способы для проверки валидности информации пришедшей от сервера платежной системы, скажем при подтверждении заключения операции
  • Return — применяется для обработки колбеков, но нередко комфортнее трудиться со встроенными в рельсы хелперами, скажем для обработки пришедших параметров, чем с этим классом. И в реализациях этого класса в разных системах обыкновенно нет каких-то специфичных функций.

Всякая реализация платежной системы содержит несколько классов унаследованных от базовых, в некоторых модулях имеются добавочные классы, реализующие добавочные вероятности протокола. Так же для всякой платежной системы в ActiveMerchant есть модуль, в котором происходит загрузка классов из файлов, и в которых содержатся способы для создания определенного класса, включенного в данный модуль.

Интеграция Деньги Online в ActiveMerchant

Решение этой задачи началось с постижения протокола Деньги Online, и там все оказалось не так прозрачно как в случае с Robokassa: фоновая проверка правильности информации, доказательство и колбеки, по сути все легко, но в большей степени меня смущали параметры передаваемые при запросах и куча разных оговорок.

image
Всеобщая схема запросов

Лаконично: в всеобщем случае по положительному сценарию все происходит так: сайт отправляет системе форму со всеми нужными параметрами, при этом пользователь переходит на сайт платежной системы, дальше платежная система в фоне запрашивает доказательство правильности данных у нашего сайта. Если данные правильны, то пользователь будет перенаправлен туда, где увидит нужные инструкции для совержения платежа. Позже нажатия кнопки «Оплатить», платежная система перед принятием платежа, вновь проверит правильность данных, потом платеж будет принят и система отправит на сайт запрос о подтверждении оплаты, и в случае правильного результата, пользователь будет перенаправлен на колбек.

Основные особенности протокола, которые меня смутили:

  • При выставлении счета отправляются одни параметры, при проверках эти параметры возвращаются теснее под другими именами
  • Первоначально в протоколе предполагается, что проверка осуществляется только по идентификатору пользователя, сделавшего заказ, а нередко значительно комфортнее проверять данные по внутреннему идентификатору платежа
  • Не смотря на то, что дозволено передать системе внутренний идентификатор платежа, при проверке и в некоторых случаях при подтверждении он не будет возвращаться, и является необязательным параметром
  • В колбеки вообще не передаются какие-либо параметры
  • При выставлении счета есть много дополнительных вероятностей обеспечения комфорта для пользователей, но все эти вероятности в протоколе реализованы по различному

Из-за этих особенностей мне пришлось несколько раз написать в их поддержку (правда вначале я связался с ними через модуль голосовой связи на сайте, но девица выслушав мою загвоздку, перенаправила меня на автоответчик), и в течение этого же дня получал адекватные результаты.

Из плюсов подметил, что если сделать запрос верно по описанному протоколу, то в результат получишь ожидаемый итог, правда в некоторых случаях проверка данных не осуществляется, но видимо из-за особенностей шлюзов.

Также мне понравилась вероятность в фоновом режиме выписать счет в некоторых случаях. И я решил сделать максимально полную поддержку протокола выставления счета, но у меня не было вероятности протестить безусловно все, так что допустимо могут отслеживаться какие-то задачи.

Еще удалось выявить одну недокументированную вероятность: в результат на фоновый запрос создания счета для оплаты через QIWI, приходит совместно с описанными параметрами, параметр iframeSRC с непонятным оглавлением, недолго думая, декодировал данные из этого параметр при помощи base64 и получил ссылку, которая ведет на форму оплаты через QIWI, и видимо предполагается, что ссылку следует применять для создания iframe.

Если посмотреть на разные реализации интеграций платежных систем в ActiveMerchant, то дозволено увидеть как один и тот же код может перетекать во уйма модулей, в каких-то файлах кодом может стать объединение кода из нескольких модулей и так дальше, но нигде нет каких-то трудных сценариев. Мне пришлось написать много своего, в частности для реализации фоновых запросов, следственно опасаюсь что пул реквест не одобрят, правда по сути все вероятности и идеи, что несут в себе базовые классы в своей реализации я сберег, легко немножко добавил новых.

Что получилось в выводе дозволено посмотреть тут. Исключительное что у меня выходит из рамок всеобщей доктрины для хелпера, так это валидация данных, но в всеобщем случае она абсолютно не необходима, ей стоит пользоваться только при фоновых запросах, что бы избежать допустимых ошибок еще перед запросом (не смотря на это в моем случае при реализации системы оплаты на сайте, мне пришлось чумазо-хаково обойти это), и так же механически выставляются некоторые параметры запросов в специальных случаях, что бы разработчику не пришлось длинно разбираться с протоколом. Еще у моего хелпера есть вероятность отправить фоновый запрос, если это делается для валидных mode_type, то результат механически спарсится и с этим результатом дозволено будет комфортно трудиться.

Не могу сказать что код получился отличным, потому что с руби я знаком от силы месяца три, следственно буду рад всякий помощи либо советам, также сам готов подмогнуть тем, кто захочет интегрировать какую-либо платежную систему в ActiveMerchant.

Пример создания системы оплаты на сайте

Первым делом нужно включить ActiveMerchant в план, для этого добавляем его в Gemfile

gem 'activemerchant', :git => "https://github.com/ovcharik/active_merchant.git", :branch => "dengionline"

Пока дозволено добавлять так, но я отправил пул реквест в формальный репозиторий, и допустимо он скоро будет одобрен.

Дальше создаем нужные роутеры

scope 'top_up' do
  post 'create' => 'top_up#create', :as => 'top_up_create'

  post 'notify' => 'top_up#notify', :as => 'top_up_notify'
  post 'check' => 'top_up#check', :as => 'top_up_check'

  match 'success' => 'top_up#success', :as => 'top_up_success'
  match 'fail' => 'top_up#fail', :as => 'top_up_fail'
end
  • create применяется для создания объекта платежа и выписки счета, в тезисе он не непременен либо его логику дозволено поместить в ином месте, но мне было комфортнее сделать именно так.
  • success и fail — это колбеки, на которые пользователь будет перенаправлен позже заключения транзакции, кстати именно в эти колбеки от системы не возвращаются какие-либо параметры.
  • notify и check необходимы для подтверждения оплаты и проверки корректности данных системой оплаты на сайте соответсвенно, по этим адресам система оплаты будет делать push-запросы, с определенными параметрами.

Последние 4 адреса, указываются платежной системе при регистрации в ней: в процессе нужно будет заполнить анкету, в которой есть пункты по этим адресам. Сам сайт не предоставляет вероятности метаморфозы адресов, а делается это только через добавочные запросы в поддержку, следственно мне пришлось многое тестировать прямо в продакшене (не смотря на то, что план запущен он пока еще в стадии разработки и для пользователей это никак не сказалось).

В плане тот, что я делаю, происходит такой сценарий при оплате служб: пользователь нажав кнопку «Оплатить» посылает ajax-запрос на /top_up/create, там проверяется правильность данных, потом отправляется фоновый запрос в платежную систему, удачный результат выводится пользователю, ошибки обрабатываются отдельно. В моем случае, в качестве удачного результата, приходит форма со спрятанными полями и сразу позже нее скрипт тот, что исполнят отправку этой формы, то есть если вывести данный результат где-то на странице, то пользователь будет неявно перенаправлен на страницу шлюза, где он может закончить оплату.

Во время фонового запроса происходит следующее: я делаю фоновый запрос, система проверяет все данные и если они правильны то она обращается к способу /top_up/check, где должна получить позитивный результат, позже проверки система возвращает нужные данные.

На сайте шлюза пользователь видит форму, где ему нужно указать реквизиты, и позже нажатия кнопки «Оплатить», шлюз проверяет данные в системе Деньги Online, которая в свою очередь проверяет данные в плане (вновь по адресу /top_up/check), получает результат и передает его платежному шлюзу. Он подтверждает платеж и уведомляет об этом платежную систему, а она теснее отправляет на сайт уведомление (/top_up/notify), и в это же время пользователя возвращают на колбек.

Допустимо проще осознать данный процесс легко увидев логи

Started POST "/ru/top_up/create" for user_ip at 2013-10-05 14:45:00  0400
Processing by TopUpController#create as */*
  Parameters: {"amount"=>"1.0", "authenticity_token"=>"token", "currency"=>"RUB", "order"=>"78", "lang"=>"ru"}

    Started POST "/top_up/check" for deingionline_ip at 2013-10-05 13:45:00  0400
    Processing by TopUpController#check as */*
      Parameters: {"amount"=>"0", "userid"=>"example@mail.com", "userid_extra"=>"58", "paymentid"=>"0", "key"=>"key1"}
      Rendered text template (0.0ms)
    Completed 200 OK in 16ms (Views: 1.1ms | ActiveRecord: 2.5ms)

Completed 200 OK in 557ms (Views: 0.5ms | ActiveRecord: 11.1ms)

Started POST "/top_up/check" for deingionline_ip at 2013-10-05 14:46:20  0400
Processing by TopUpController#check as */*
  Parameters: {"amount"=>"0", "userid"=>"example@mail.com", "userid_extra"=>"58", "paymentid"=>"0", "key"=>"key1"}
  Rendered text template (0.0ms)
Completed 200 OK in 19ms (Views: 1.0ms | ActiveRecord: 1.9ms)

Started POST "/top_up/notify" for deingionline_ip at 2013-10-05 14:46:20  0400
Processing by TopUpController#notify as */*
  Parameters: {"amount"=>"1.00", "userid"=>"example@mail.com", "userid_extra"=>"58", "paymentid"=>"123456789", "paymode"=>"mode_type", "orderid"=>"58", "key"=>"key2"}
  Rendered text template (0.0ms)
Completed 200 OK in 127ms (Views: 0.9ms | ActiveRecord: 15.2ms)

Started GET "/top_up/success" for user_ip at 2013-10-05 14:46:30  0400
Processing by TopUpController#success as HTML
  Rendered ...
Completed 200 OK in 21ms (Views: 16.6ms | ActiveRecord: 0.7ms)

В логах дозволено увидеть какие параметры передаются во всех случаях, и что при обращении к /top_up/check платежная система не передает orderid (внутренний идентификатор платежа в плане, paymentid — идентификатор в платежной системе), следственно для идентификации платrk! if @payment.wait? @payment.do_payment_id = @notification.payment_id @payment.paid! saved = @payment.save Notifier.payment_paid(@payment).deliver if saved end if @payment.paid? and saved render :text => @notification.generate_response(“YES”) else render :text => @notification.generate_response(“NO”) end else render :text => @notification.generate_response(“NO”) end end # в колбеках легко рендерятся страницы def success end def fail end private def create_notification @notification = Dengionline.notification(request.raw_post, { :secret => CONFIG["dengionline"]["secret"] }) end def find_payment # ищу так, потому что комфортнее обработать nil, чем исключение @payment = Payment.where(:id => @notification.nick_extra).first end end

У меня все данные посылаются в фоне за-за особенностей результатов, но дозволено и применять метод описанный тут.

Еще приведу пример применения класса для приобретения удаленной информации о платеже, думаю ни у кого задач с использованием этого не возникнет.

Пример

$ rails c

irb(main):001:0> Dengionline = ActiveMerchant::Billing::Integrations::Dengionline
=> ActiveMerchant::Billing::Integrations::Dengionline

irb(main):002:0> status = Dengionline.status 69, 1234, :secret => "secret"
=> #<ActiveMerchant::Billing::Integrations::Dengionline::Status:0xb805bb4>

irb(main):003:0> status.to_hash 
=> {
  "id"=>123456789,
  "amount_rub"=>"1.00",
  "status"=>9,
  "status_description"=>"Success",
  "order"=>"69",
  "nick"=>"example@mail.com",
  "date_payment"=>"2013-10-05T13:00:00 04:00",
  "paymode"=>"mode_type",
  "currency_project"=>"RUB",
  "amount_project"=>"1.00",
  "currency_paymode"=>"RUB"
}

В данном примере в качестве основного параметра передается внутренний идентификатор платежа, если вы его не применяли при выписке счета, то дозволено передавать идентификатор платежа платежной системы, для этого последним параметром укажите :payment => payment_id.

Источник: programmingmaster.ru

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB