1. sakkada
  2. django-rbkmoney

Overview

django-rbkmoney

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

До использования следует ознакомиться с официальной документацией RBKMoney (Подключение интернет магазинов; файл с описанием API на сайте найти достаточно проблематично, скорее всего придется запрашивать у поддержки, одна из версий тут) Приложение реализует протокол взаимодействия с системой 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.