django-rbkmoney 0.1
Приложение для интеграции системы приема платежей RBKMoney в проекты на основе Django.
License: MIT license

===============
django-rbkmoney
===============

**django-rbkmoney** - это приложение для интеграции системы приема платежей
RBKMoney с проектами на основе Django.

До использования следует ознакомиться с официальной документацией RBKMoney
(`Подключение интернет магазинов <http://www.rbkmoney.ru/podklyuchenie-internet-magazinov>`_;
файл с описанием API на сайте найти достаточно проблематично, скорее всего
придется запрашивать у поддержки, одна из версий
`тут <https://docs.google.com/leaf?id=0B9UL0sMPo7JJOGNiYmJkZWItY2JkZi00ZjhlLWE3NDItOWRjZWRkMTFmZTk1&hl=ru>`_)
Приложение реализует протокол взаимодействия с системой RBKMoney.

Установка
=========

Сначала необходимо установить сам пакет::

    $ pip install django-rbkmoney

затем следует добавить 'rbkmoney' в INSTALLED_APPS и выполнить::

    $ python manage.py syncdb

Для работы требуется django >= 1.3.x.

Настройка
=========

В ``settings.py`` необходимо указать следующие параметры:

* RBKMONEY_SHOP_ID - номер магазина в системе RBKMoney
* RBKMONEY_SECRET_KEY - секретный ключ (указывается в личном кабинете
  самостоятельно)

Необязательные параметры:

* RBKMONEY_HASH_CHECK - проверка контрольной подписи формы заявки на перевод,
  в качестве значения можно указать названия возможных алгоритмов,
  ``MD5`` или ``SHA512`` (при любом другом <истинном> значении будет выбран
  алгоритм ``MD5``, при <ложном> - проверка будет отключена; отключение проверки
  крайне не рекомендуется).

* RBKMONEY_ACTION - URL страницы, на которую будет отправлена форма заявки
  на перевод (по умолчанию: ``https://rbkmoney.ru/acceptpurchase.aspx``).

* RBKMONEY_URI_PROTOCOL - протокол, используемый при генерации абсолютных
  ссылок succesURL и failURL (возможные значения: ``http``, ``https``;
  по умолчанию: ``http``).

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

Форма заявки на перевод
-----------------------

django-rbkmoney содержит класс формы ``RequestRBKMoneyForm`` (наследник
``django.forms.Form``), позволяющий упростить процесс генерации html кода
формы заявки на перевод, разработчики могут использовать его в качестве
родительского при наследовании, например, для добавления некоторых
дополнительных параметров.

Пример кода представления::

    from decimal import Decimal
    from django.shortcuts import render
    from rbkmoney.forms import RequestRBKMoneyForm

    @login_required
    def payment_rbkmoney(request, order_id)
        form = RequestRBKMoneyForm(initial={
            'orderId': 200005,
            'serviceName': u'Два колеса, руль, педали и мешок свободы.',
            'recipientAmount': Decimal('20000.00'),
            'recipientCurrency': u'RUR',
            'user_email': u'client@some.mail',
            'userFields': ['some', 'values', 'list',],
            # 'successUrl': 'http://site.name/payment/success/',
            # 'failUrl': 'http://site.name/payment/fail/',
        })

        return render(request, 'payment.html', {'form': form})

Обязательными параметрами в initial являются ``recipientAmount``
и ``recipientCurrency``. Детальную справку по параметрам можно посмотреть
в документации по API RBKMoney. Пользовательские поля в ``initial``
можно передать с помощью параметра ``userFields``, значением должен быть
список или кортеж строк, поля формы будут сгенерированы автоматически,
начиная с индекса 0.

Соответствующий шаблон::

    {% extends 'base.html' %}

    {% block content %}
        <form action="{{ form.action }}" method="post">
            {{ form }}
            <input type="submit" value="Оплатить">
        <form>
    {% endblock %}

Форма выведется в виде набора скрытых input-тегов.

У формы есть атрибут ``action``, содержащий URL страницы, на которую будет
отправлена форма (см. параметр ``RBKMONEY_ACTION``).

Обратите внимание, ``{% csrf_token %}`` в форме не нужен (и более того,
добавлять его к форме небезопасно), т.к. форма ведет на внешний
сайт - сайт RBKMoney.

django-rbkmoney не включает в себя модели "Заказ" (``Order``),
т.к. эта модель будет отличаться от сайта к сайту. Обработку смены статусов
заказов следует осуществлять в обработчиках сигналов.

Получение результатов платежей
------------------------------

django-rbkmoney реализует механизм приема сообщений о статусах переводов со
стороны RBKMoney, сообщения должны отправляться на страницу представления
``rbkmoney_result`` (url: ``/адрес-приложения-rbkmoney/result/``), абсолютный
адрес которого необходимо указывать в личном кабинете пользователя системы.

В целях безопасности лучше всегда использовать проверку контрольной подписи и
отключать отправку секретного ключа.

Общий принцип работы примерно следующий:

1. После оплаты RBKMoney отправляет запрос на адрес, соответствующий
   представлению ``rbkmoney_result``.

2. Внутри ``rbkmoney_result`` происходит проверка содержащейся в
   запросе контрольной подписи с помощью секретного ключа и выбранного
   алгоритма (если она не отключена в параметрах).

3. Если запрос корректный, то ``rbkmoney_result`` шлет сигнал
   ``rbkmoney.signals.result_received``, предусмотренный для
   совершения дополнительных манипуляций на сайте.
   Для этого необходимо добавить соответствующий обработчик сигнала.

4. Если все в порядке, то ``rbkmoney_result`` возвращает RBKMoney
   строку ``OK`` со статусом запроса ``200``. Этот ответ необходим для того,
   чтобы система получила подтверждение того, что все необходимые действия
   произведены.

5. Если RBKMoney получает положительный ответ, то пользователь перенаправляется
   на ``successUrl`` (по умолчанию это адрес представления ``rbkmoney_success``).
   На этой страничке обычно выводится сообщение об успешном прохождении
   платежа/оплаты. Если ответ отрицательный, то пользователь перенаправляется
   на ``failURL`` (по умолчанию это адрес представления ``rbkmoney_fail``),
   где ему будет отображено сообщение о произошедшей ошибке.

В целом ``rbkmoney_result`` должно получить сообщение дважды, со значениями
``paymentStatus`` равными:

* ``3`` - операция принята на обработку и
* ``5`` - операция исполнена, соответственно.

При этом в обработчике сигнала следует учитывать, что перевод прошел успешно
лишь при получении ``paymentStatus`` равного ``5``.

Сигналы
-------

Обработку смены статусов заказов следует осуществлять в обработчике сигнала
``robokassa.signals.result_received``. Данный сигнал отсылается лишь
при получении корректного уведомления от RBKMoney. Получение этого сигнала
означает что оплата либо создана, либо прошла успешно (в зависимости от
значения ``paymentStatus``).

В качестве ``sender`` передается экземпляр модели ``RBKMoneyPayment``
со всеми данными оплаты, так же в качестве дополнительного параметра
передается значение ``user_fields``, отправленное еще в запросе
на перевод (список кортежей (имя, значение)).

Пример::

    from rbkmoney.signals import result_received
    from orders.models import Order

    def on_payment_received(sender, **kwargs):
        if sender.paymentStatus != 5: return
        order = Order.objects.get(id=sender.orderId)
        order.change_status('paid')
        order.save()

    result_received.connect(on_payment_received)

urls.py
-------

Для настройки адресов представлений ``rbkmoney_result``, ``rbkmoney_success``
и ``rbkmoney_fail`` можно подключить модуль ``rbkmoney.urls``::

    urlpatterns = patterns('',
        # ...
        url(r'^rbkmoney/', include('rbkmoney.urls')),
        # ...
    )

Адрес представления ``rbkmoney_result``, указываемый в личном кабинете,
в этом случае будет иметь вид: ``http://yoursite.ru/rbkmoney/result/``.

Шаблоны
-------

* ``rbkmoney/success.html`` - показывается в случае успешной оплаты.
* ``robokassa/fail.html`` - показывается в случае неуспешной оплаты.

Разработка
==========

Разработка ведется на bitbucket:

https://bitbucket.org/sakkada/django-rbkmoney/

Пожелания, идеи, баг-репорты и тд. пишите в трекер:

https://bitbucket.org/sakkada/django-rbkmoney/issues

Лицензия - MIT.

Тестирование
------------

Для запуска тестов установите выполните команду::

    $ python manage.py test rbkmoney

Пример интеграции
-----------------

В архиве пакета, а так же в репозитарии находится директория ``sample``,
в которой находится код ``django`` проекта с примером интеграции
``django-rbkmoney``.История изменений
=================

0.1.0 (2013-05-09)
------------------
Первая версия