Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ssnickolay/unitpay

Gem для подключения к платежной системе unitpay.ru
https://github.com/ssnickolay/unitpay

payment ruby

Last synced: 2 days ago
JSON representation

Gem для подключения к платежной системе unitpay.ru

Awesome Lists containing this project

README

        

[![Gem Version](https://badge.fury.io/rb/unitpay.svg)](https://badge.fury.io/rb/unitpay)
[![Build Status](https://travis-ci.org/ssnikolay/unitpay.svg?branch=master)](https://travis-ci.org/ssnikolay/unitpay)
[![Code Climate](https://codeclimate.com/github/ssnikolay/unitpay.svg)](https://codeclimate.com/github/ssnikolay/unitpay)
[![Test Coverage](https://codeclimate.com/github/ssnikolay/unitpay/badges/coverage.svg)](https://codeclimate.com/github/ssnikolay/unitpay/coverage)

# Unitpay

Gem для подключения к платежному шлюзу [unitpay](http://unitpay.ru).

[Документация к шлюзу](http://help.unitpay.ru/)

- [Установка](#installation)
- [Подключение](#setup)
- [Получение ссылки для оплаты](#payment_url)
- [Использование в Rails](#rails)
- [Подключение виджета для карт оплаты](#widget)

## Установка

Добавьте эти строки в Gemfile вашего приложения:

```ruby
gem 'unitpay'
```

И выполните:

$ bundle

Или установите напрямую:

$ gem install unitpay

## Подключение
Чтобы получить доступ к сервисному классу, достаточно проинициализировать его с `public` и `secret` ключами.

```ruby
Unitpay::Service.new('unitpay_public_key', 'unitpay_secret_key')
```

По умолчанию курс валюты выставлен в `RUB`, а использование сигнатуры в `true`.
Переопределить их можно и при инициализации.
```ruby
use_sign, currency = false, 'RUB'
Unitpay::Service.new('unitpay_public_key', 'unitpay_secret_key', use_sign, currency)
```
Чтобы включить проверку сигнатуры со стороны `unitpay`, необходимо нажать на "замочек" в настройках вашего партнера.

![Settings](https://raw.github.com/ssnikolay/unitpay/master/unitpay.jpg)

1. Включение проверки сигнатуры.
2. `Secret key` для инициализации `Unitpay::Service`.
3. Необходимо изменить `example.com` на адрес вашего приложения.
4. Необходимо изменить `example.com` на адрес вашего приложения.

## Получение ссылки для оплаты

Чтобы получить ссылку для оплаты, необходимо использовать метод `payment_url`, в который нужно передать следующие параметры:

Название | Описание
--------------------|:-----------------------------------------
`sum` | Цена, которую необходимо оплатить пользователю
`account` | Внутренний идентификатор платежа (или заказа), однозначно определяющий его в магазине.
`desc` | Описание платежа, отображающееся пользователю на стороне шлюза.

```ruby
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...'
```

## Использование в Rails

Добавьте роуты для получения запросов от **unitpay** (`config/routes.rb`)

```ruby
scope :unitpay do
get :success, to: 'unitpay#success'
get :fail, to: 'unitpay#fail'
get :notify, to: 'unitpay#notify'
end
```

Создайте `app/controllers/unitpay_controller.rb` со следующим кодом:

```ruby
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
```

[Описание параметров, передаваемых при запросе.
](http://help.unitpay.ru/article/35-confirmation-payment)

### Исключения при обработке запросов

Важно понимать, что до вызова метода `pay` происходит проверка только сигнатуры.
Прочие проверки на соответствие платежа правилам логики приложения остаются на вашей совести (например, эквивалентность суммы оплаты и суммы заказа).
Для удобства обработки таких ситуаций существует зарезервированное исключение `Unitpay::Controller::RuntimeException`. В этом случае в ответе будет передан текст вашей ошибки.

Пример:

```ruby
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
```

## Подключение виджета для карт оплаты

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

- Подключите на странице внешний скрипт:

```html

```

- Добавьте обработчик формы заказа:

**unitpay.js.coffe**
```coffee
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**
```ruby
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

1. Fork it ( https://github.com/ssnikolay/unitpay/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request