Как видно из названия, это приложение для работы с платежной системой
http://onpay.ru/ для сайта, построенного на фреймворке джанго.
Пользователи других фреймворков или своих велосипедов на python (svarga,
pylons, turbogears, web.py, etc) могут написать своё приложение, специально
для этого основная функциональность собрана в файле `common.py`.
Фреймворко-зависимую часть (запросы, систему хранения, обработку форм,
оповещение менеджеров) естественно придётся переписать, взяв за основу
текущий код.
Как работает onpay?
Все просто, надо:
1. Сгенерировать тег `iframe` из множества параметров. В этом поможет
класс `IframeGenerator`.
2. Принять запрос от сервиса, который и скажет, кому и сколько денег положили
и собственно внести сумму в базу данных.
Настройки в личном кабинете OnPay для работы с django
В личном кабинете OnPay.ru (Настройки магазина) необходимо настроить параметры
API IN:
- Уведомлять по API - Да
- Проверять MD5 на ссылках - Да (не обязательно)
- URL API: http://вашдомен/onpay/api/ (можно переопределить через URLconf)
- Пароль для API IN: ksjgJskLJds - ваш секретный код, который будет нужен при
настройках платежного модуля OnPay в django
Установка django-onpay
Приложение требует модуль lxml. Начиная с версии 2.6 python содержит его
в стандартной библиотеке. Если вы пользуетесь более ранней версией
(например, той, что идёт в пакетах с debian lenny), необходимо установить
пакет python-lxml.
Для собственно установки пакета подойдет один из вариантов:
1. прописываем `onpay` в `INSTALLED_APPS`,
1. `./manage.py syncdb`
1. в `settings.py` добавляем переменную `ONPAY` с минимумом настроек (см. ниже),
1. добавляем в `urls.py`: `('^onpay/', include('onpay.urls')),`,
1. тестируем работу.
Настройка
Все параметры хранятся в словаре `ONPAY` в файле `settings.py`.
Обязательные параметры:
ONPAY = {
"onpay_login": "example", # Ваш логин на onpay
"private_code": "ksjgJskLJds", # Пароль, который вы ввели на сайте onpay
}
Необязательные параметры:
"url_success": "http://example.org/onpay/api/",
# default: то что задано в настройках на сайте onpay
"use_balance_table": True,
# записывать в таблицу баланса. Без нее если честно не пробовал
"pay_mode": "fix",
# "free" - обновление баланса, юзер может изменить цифру
# "fix" - фиксированный платеж, цифра в фрейме только для чтения
"f": None,
# скин, возможные значения - None, 1, 2, 3
# в зависимости от скина
# подробнее: http://onpay.ru/form/
"enable_email_notify": None,
# если включить опцию, при платежах будет отправлен email
# через функцию email_managers
"enable_footman_update_balance": None,
# это только для примера и включать ни в коем случае нельзя!
# при получении платежа накидывается баланс на счет пользователя
# из профиля другого приложения (не путать с таблицей Balance)
# по аналогии стоит написать свою функцию и подключить через сигнал,
# если вам требуется хранить счет пользователя в другом месте
"new_operation_status": 0,
# опция довольно бесполезная, оставил так как была в рхршных примерах
"debug": None,
# на данный момент отправляет через mail_admins запрос от onpay
Чтобы встроить платежную систему в свой дизайн надо переопределить шаблоны
из папки onpay. Надеюсь с этим справитесь без проблем.
Можно вместо include в urls.py прописать свои роуты к своим views,
если требуется какие-то изменения.
Можно поменять параметры после инициализации IframeGenerator:
После оплаты отправляется сигнал `onpay.signals.refilled_balance`,
если на него подписать свою функцию, можно добиться любой функциональности.
Примеры смотрите в файле `signals.py`.
Ну и, наконец, можно изменить исходные тексты и прислать hg патчи мне
- по возможности добавлю в репозиторий. Комментарии писались по большей части
на русском, так как сама платежная система русская.
common.py для работы с dom.minidom
# coding: UTF-8
import urllib
from hashlib import md5
#from lxml import etree
from xml.dom.minidom import getDOMImplementation
def set_f(self, f):
"Определение ширины и высоты в зависимости от текущего скина"
self.f = f
self.width, self.height = {
None: ( 300, 500),
1: (1020, 660),
2: ( 250, 540),
3: ( 960, 800),
}[f]
def answer(type, code, pay_for, order_amount, order_currency, text):
"функция выдает ответ для сервиса onpay в формате XML на чек запрос"
array_for_md5 = (type, pay_for, order_amount, order_currency, str(code),
get_constant('private_code'))
result_md5 = md5(";".join(array_for_md5)).hexdigest().upper()
dom = getDOMImplementation()
doc = dom.createDocument(None, 'result', None)
def answer_dict(POST, code, text):
"Shortcut for call answer with POST or form dict as parameter"
return answer(
POST.get("type"),
code,
POST.get("pay_for"),
POST.get("order_amount"),
POST.get("order_currency"),
text,
)
def answerpay(type, code, pay_for, order_amount, order_currency, text, onpay_id):
"функция выдает ответ для сервиса onpay в формате XML на pay запрос"
def answerpay_dict(request_dict, code, text):
"Shortcut for call answerpay with POST or form dict as parameter"
return answerpay(
request_dict.get('type'),
code,
request_dict.get('pay_for'),
request_dict.get('order_amount'),
request_dict.get('order_currency'),
unicode(text),
request_dict.get('onpay_id'),
)
To-Do
То, что хотелось бы сделать (но врядли у меня дойдут руки до этого,
"и так работает"):
1. Опция для английского языка фрейма
1. Более качественная поддержка fix платежей (я концентрировался на free)
1. Поддержка скинов для одной валюты
1. Добавить сигналы на все случаи жизни
1. Сделать `setup.py` и установку через `pip`
1. Автоматические тесты
1. Еще несколько фич, которые в данный момент не помню