Unitpay
Gem для подключения к платежному шлюзу unitpay.
- Установка
- Подключение
- Получение ссылки для оплаты
- Использование в Rails
- Подключение виджета для карт оплаты
Добавьте эти строки в Gemfile вашего приложения:
gem 'unitpay'
И выполните:
$ bundle
Или установите напрямую:
$ gem install unitpay
## Подключение
Чтобы получить доступ к сервисному классу, достаточно проинициализировать его с public
и secret
ключами.
Unitpay::Service.new('unitpay_public_key', 'unitpay_secret_key')
По умолчанию курс валюты выставлен в RUB
, а использование сигнатуры в true
.
Переопределить их можно и при инициализации.
use_sign, currency = false, 'RUB'
Unitpay::Service.new('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('unitpay_public_key', 'unitpay_secret_key')
service.payment_url(sum, account, desc)
# => 'https://unitpay.ru/pay/public_key?sum=100&account=1&desc=description...'
Добавьте роуты для получения запросов от unitpay (config/routes.rb
)
scope :unitpay do
get :success, to: 'unitpay#success'
get :fail, to: 'unitpay#fail'
get :notify, to: 'unitpay#notify'
end
Создайте app/controllers/unitpay_controller.rb
со следующим кодом:
class UnitpayController < ApplicationController
include Unitpay::Controller
skip_before_filter :verify_authenticity_token
def success
# вызывается при отправке шлюзом пользователя на Success URL.
#
# ВНИМАНИЕ: является незащищенным действием!
# Для выполнения действий после успешной оплаты используйте pay
end
def fail
# вызывается при отправке шлюзом пользователя на Fail URL.
# (во время принятия платежа возникла ошибка)
end
private
def pay
# вызывается при оповещении магазина об
# успешной оплате пользователем заказа и после проверки сигнатуры.
#
# ВНИМАНИЕ: правильный ответ будет сгенерирован автоматически (не нужно использовать render\redirect_to)!
# order = Order.find(params[:params][:account])
# order.payed!
end
def error
# вызывается при оповещении магазина об ошибке при оплате заказа.
# При отсутствии логики обработки ошибок на стороне приложения оставить метод пустым.
#
# ВНИМАНИЕ: правильный ответ будет сгенерирован автоматически (не нужно использовать render\redirect_to)!
# puts params[errorMessage]
# => Текст ошибки, присланный unitpay
end
def service
# ВНИМАНИЕ: обязательный метод! Используется при проверке сигнатуры.
Unitpay::Service.new('unitpay_public_key', 'unitpay_secret_key')
end
end
Описание параметров, передаваемых при запросе.
Исключения при обработке запросов
Важно понимать, что до вызова метода pay
происходит проверка только сигнатуры.
Прочие проверки на соответствие платежа правилам логики приложения остаются на вашей совести (например, эквивалентность суммы оплаты и суммы заказа).
Для удобства обработки таких ситуаций существует зарезервированное исключение Unitpay::Controller::RuntimeException
. В этом случае в ответе будет передан текст вашей ошибки.
Пример:
def pay
order = Order.find(params[:params][:account])
if order.total_cost == params[:params][:sum]
order.payed!
else
raise Unitpay::Controller::RuntimeException.new('Неверная сумма оплаты')
end
end
## Подключение виджета для карт оплаты
Рассмотрим один из способов реализации случая, когда необходимо показать виджет оплаты после заполнения пользователем формы заказа.
- Подключите на странице внешний скрипт:
<script src="https://widget.unitpay.ru/unitpay.js"></script>
- Добавьте обработчик формы заказа:
unitpay.js.coffe
class Unitpay
bindEvents: ->
@handleAfterSubmitForm()
handleAfterSubmitForm: ->
$('#id-your-form').submit (e) ->
e.preventDefault()
tryUnitpay() # при сабмите формы пытаемся получить параметры для виджета
tryUnitpay = ->
$.ajax({
type: 'POST',
dataType: 'json'
url: '/orders' # любой другой путь сохранения\создания вашего платежа (заказа). Не забудьте добавить его в routes.rb
data: $('#id-your-form').serialize(),
success: (data) ->
payment = new UnitPay()
payment.createWidget(data)
payment.success ->
console.log('Unitpay: успешный платеж')
payment.error ->
# ошибка платежного шлюза (например, пользователь не завершил оплату)
console.log('Unitpay: ошибка платежа')
error: ->
# ошибка при сохранении заказа (например, ошибки валидации)
console.log('Ошибка сохранения\создания платежа (заказа)')
})
$ ->
unitpay = new Unitpay
unitpay.bindEvents()
- Измените контроллер так, чтобы он отдавал необходимый
json
ответ:
orders_controller.rb
class OrdersController < ApplicationController
def create
order = Order.new(permitted_params)
if order.save
render json: unitpay_service.params_for_widget(order.total_cost, order.id, order.description)
else
render json: order.errors, status: :unprocessable_entity
end
end
private
def unitpay_service
# Внимание: не храните ключи в открытом виде в репозитории.
# используйте конфигурационные файлы (https://github.com/binarylogic/settingslogic)
Unitpay::Service.new('public_key', 'secret_key')
end
def permitted_params
# используйте strong params
end
end
Contributing
- 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