Gem для подключения к платежному шлюзу unitpay.money и unitpay.ru.
Документация к шлюзу help.unitpay.money и help.unitpay.ru
- Установка
- Подключение
- Получение ссылки для оплаты
- Использование в Rails
- Подключение виджета для карт оплаты
Добавьте эти строки в Gemfile вашего приложения:
gem'unitpay'И выполните:
$ bundle
Или установите напрямую:
$ gem install unitpay
## Подключение
Чтобы получить доступ к сервисному классу, достаточно проинициализировать его с вашим рабочим доменом (unitpay.money или unitpay.ru) и public и secret ключами.
Unitpay::Service.new('domain','unitpay_public_key','unitpay_secret_key')По умолчанию курс валюты выставлен в RUB, а использование сигнатуры в true.
Переопределить их можно и при инициализации.
use_sign,currency=false,'RUB'Unitpay::Service.new('domain','unitpay_public_key','unitpay_secret_key',use_sign,currency)Чтобы включить проверку сигнатуры со стороны unitpay, необходимо нажать на "замочек" в настройках вашего партнера.
- Включение проверки сигнатуры.
Secret keyдля инициализацииUnitpay::Service.- Необходимо изменить
example.comна адрес вашего приложения. - Необходимо изменить
example.comна адрес вашего приложения.
## Получение ссылки для оплаты
Чтобы получить ссылку для оплаты, необходимо использовать метод payment_url, в который нужно передать следующие параметры:
| Название | Описание |
|---|---|
sum | Цена, которую необходимо оплатить пользователю |
account | Внутренний идентификатор платежа (или заказа), однозначно определяющий его в магазине. |
desc | Описание платежа, отображающееся пользователю на стороне шлюза. |
sum,account,desc=100,1,'description'service=Unitpay::Service.new('domain','unitpay_public_key','unitpay_secret_key')service.payment_url(sum,account,desc)# => domain - 'unitpay.money' or 'unitpay.ru'# => 'https://domain/pay/public_key?sum=100&account=1&desc=description...'Добавьте роуты для получения запросов от unitpay (config/routes.rb)
scope:unitpaydoget:success,to: 'unitpay#success'get:fail,to: 'unitpay#fail'get:notify,to: 'unitpay#notify'endСоздайте app/controllers/unitpay_controller.rb со следующим кодом:
classUnitpayController < ApplicationControllerincludeUnitpay::Controllerskip_before_filter:verify_authenticity_tokendefsuccess# вызывается при отправке шлюзом пользователя на Success URL.## ВНИМАНИЕ: является незащищенным действием!# Для выполнения действий после успешной оплаты используйте payenddeffail# вызывается при отправке шлюзом пользователя на Fail URL.# (во время принятия платежа возникла ошибка)endprivatedefpay# вызывается при оповещении магазина об# успешной оплате пользователем заказа и после проверки сигнатуры.## ВНИМАНИЕ: правильный ответ будет сгенерирован автоматически (не нужно использовать render\redirect_to)!# order = Order.find(params[:params][:account])# order.payed!enddeferror# вызывается при оповещении магазина об ошибке при оплате заказа.# При отсутствии логики обработки ошибок на стороне приложения оставить метод пустым.## ВНИМАНИЕ: правильный ответ будет сгенерирован автоматически (не нужно использовать render\redirect_to)!# puts params[errorMessage]# => Текст ошибки, присланный unitpayenddefservice# ВНИМАНИЕ: обязательный метод! Используется при проверке сигнатуры.Unitpay::Service.new('domain','unitpay_public_key','unitpay_secret_key')endendОписание параметров, передаваемых при запросе: help.unitpay.money и help.unitpay.ru
Важно понимать, что до вызова метода pay происходит проверка только сигнатуры.
Прочие проверки на соответствие платежа правилам логики приложения остаются на вашей совести (например, эквивалентность суммы оплаты и суммы заказа).
Для удобства обработки таких ситуаций существует зарезервированное исключение Unitpay::Controller::RuntimeException. В этом случае в ответе будет передан текст вашей ошибки.
Пример:
defpayorder=Order.find(params[:params][:account])iforder.total_cost == params[:params][:sum]order.payed!elseraiseUnitpay::Controller::RuntimeException.new('Неверная сумма оплаты')endend## Подключение виджета для карт оплаты
Рассмотрим один из способов реализации случая, когда необходимо показать виджет оплаты после заполнения пользователем формы заказа.
- Подключите на странице внешний скрипт:
<scriptsrc="https://widget.unitpay.ru/unitpay.js"></script>- Добавьте обработчик формы заказа:
unitpay.js.coffe
classUnitpaybindEvents:->@handleAfterSubmitForm()
handleAfterSubmitForm:->$('#id-your-form').submit (e) ->e.preventDefault()
tryUnitpay() # при сабмите формы пытаемся получить параметры для виджетаtryUnitpay=->$.ajax({
type:'POST',
dataType:'json'url:'/orders'# любой другой путь сохранения\создания вашего платежа (заказа). Не забудьте добавить его в routes.rbdata:$('#id-your-form').serialize(),
success: (data) ->payment=newUnitPay()
payment.createWidget(data)
payment.success->console.log('Unitpay: успешный платеж')
payment.error-># ошибка платежного шлюза (например, пользователь не завершил оплату)console.log('Unitpay: ошибка платежа')
error:-># ошибка при сохранении заказа (например, ошибки валидации)console.log('Ошибка сохранения\создания платежа (заказа)')
})
$->unitpay=newUnitpayunitpay.bindEvents()
- Измените контроллер так, чтобы он отдавал необходимый
jsonответ:
orders_controller.rb
classOrdersController < ApplicationControllerdefcreateorder=Order.new(permitted_params)iforder.saverenderjson: unitpay_service.params_for_widget(order.total_cost,order.id,order.description)elserenderjson: order.errors,status: :unprocessable_entityendendprivatedefunitpay_service# Внимание: не храните ключи в открытом виде в репозитории.# используйте конфигурационные файлы (https://github.com/binarylogic/settingslogic) Unitpay::Service.new('domain','public_key','secret_key')enddefpermitted_params# используйте strong paramsendend- Fork it ( https://github.com/ssnikolay/unitpay/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
