add robokassa paymant

prod
Dmitriy Shesterkin 9 years ago
parent f09b5408ae
commit 1a2d3b7164
  1. 20
      src/customer/admin.py
  2. 46
      src/customer/models.py
  3. 9
      src/customer/views/license.py
  4. 14
      src/dokumentor/settings/common.py
  5. 10
      src/dokumentor/settings/local.py
  6. 11
      src/dokumentor/settings/production.py
  7. 10
      src/dokumentor/settings/stage.py
  8. 5
      src/robokassa/views.py
  9. 9
      static/css/style.css
  10. 37
      templates/customer/profile/license_list.html
  11. 31
      templates/customer/profile/paid_list.html
  12. 29
      templates/customer/profile/yandex.html
  13. 15
      templates/robokassa/error.html
  14. 12
      templates/robokassa/fail.html
  15. 8
      templates/robokassa/form.html
  16. 13
      templates/robokassa/success.html

@ -104,7 +104,25 @@ class ClientAdmin(admin.ModelAdmin):
@admin.register(models.Payment) @admin.register(models.Payment)
class PaymentAdmin(admin.ModelAdmin): class PaymentAdmin(admin.ModelAdmin):
pass list_display = (
'admin_pk',
'admin_user',
'order_amount',
'order_number',
'status'
)
def admin_pk(self, obj):
return obj.pk
admin_pk.short_description = 'Ключ'
admin_pk.admin_order_field = 'pk'
def admin_user(self, obj):
return obj.user.email
admin_user.short_description = 'Email'
admin_user.admin_order_field = 'user__email'
admin.site.register(models.UserProfile, UserProfileAdmin) admin.site.register(models.UserProfile, UserProfileAdmin)

@ -6,6 +6,7 @@ import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from PIL import Image from PIL import Image
from django.dispatch import receiver
from pytils import numeral from pytils import numeral
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -19,7 +20,7 @@ from django.conf import settings
from customer import consts, managers, utils from customer import consts, managers, utils
from myauth.models import DokUser from myauth.models import DokUser
from commons.utils import only_numerics from commons.utils import only_numerics
from robokassa.signals import result_received from robokassa.signals import result_received, success_page_visited
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -751,12 +752,47 @@ class Payment(models.Model):
verbose_name_plural = 'Платежи' verbose_name_plural = 'Платежи'
def __str__(self): def __str__(self):
return f'{self.user}-{self.order_number}' return f'{self.user}-{self.order_number}-{self.get_status_display()}'
def payment_received(sender, **kwargs): @receiver(result_received)
print(kwargs) def order_completed(sender, **kwargs):
try:
payment = Payment.objects.get(
pk=kwargs['InvId'],
order_amount=kwargs['OutSum']
)
payment.status = Payment.SUCCESS
payment.save()
lic = License.objects.get(pk=payment.order_number)
lic.status = consts.STATUS_PAID
lic.paid_date = datetime.now().date()
lic.save()
except Payment.DoesNotExist:
log.info(f"payment with id={kwargs['InvId']} not found")
except License.DoesNotExist:
log.info(f"payment with id={kwargs['InvId']} not found")
result_received.connect(payment_received)
@receiver(success_page_visited)
def success_page_visited_completed(sender, **kwargs):
if settings.DEBUG:
try:
payment = Payment.objects.get(
pk=kwargs['InvId'],
order_amount=kwargs['OutSum']
)
payment.status = Payment.SUCCESS
payment.save()
lic = License.objects.get(pk=payment.order_number)
lic.status = consts.STATUS_PAID
lic.paid_date = datetime.now().date()
lic.save()
except Payment.DoesNotExist:
log.info(f"payment with id={kwargs['InvId']} not found")
except License.DoesNotExist:
log.info(f"payment with id={kwargs['InvId']} not found")

@ -46,8 +46,7 @@ def order_license(request):
payment = Payment.objects.create( payment = Payment.objects.create(
order_amount=form.cleaned_data['term'].price, order_amount=form.cleaned_data['term'].price,
order_number=new_license.id, order_number=new_license.id,
user=request.user user=request.user)
)
return redirect(reverse('payment_robokassa', kwargs={'payment_id': payment.id})) return redirect(reverse('payment_robokassa', kwargs={'payment_id': payment.id}))
return redirect(reverse('customer-orders')) return redirect(reverse('customer-orders'))
@ -179,12 +178,6 @@ def orders_list(request):
def pay_with_robokassa(request, payment_id): def pay_with_robokassa(request, payment_id):
payment = get_object_or_404(Payment, pk=payment_id) payment = get_object_or_404(Payment, pk=payment_id)
# https://auth.robokassa.ru/Merchant/Index.aspx?isTest=1&MerchantLogin=Dokumentor&InvId=231849535&OutSum=100.00&SignatureValue=5c330dbb455ab540fb5fb4ee6b476f3a&Culture=ru
# http://127.0.0.1:8000/robokassa/success/?inv_id=3&InvId=3&out_summ=200.00&OutSum=200.00&crc=2c5050aaff3788c19cbd50ac6974f650&SignatureValue=2c5050aaff3788c19cbd50ac6974f650&Culture=ru&IsTest=1
# http://127.0.0.1:8000/robokassa/success/?inv_id=5&InvId=5&out_summ=3000.00&OutSum=3000.00&crc=3e9ae74938ad9397053bf184732e8bfa&SignatureValue=3e9ae74938ad9397053bf184732e8bfa&Culture=ru&IsTest=1
# 29CE5970A619428DE1E800A49E68E13B
# 3e9ae74938ad9397053bf184732e8bfa
form = RobokassaForm(initial={ form = RobokassaForm(initial={
'OutSum': payment.order_amount, 'OutSum': payment.order_amount,
'InvId': payment.id, 'InvId': payment.id,

@ -320,20 +320,6 @@ OWNER = {
'SIGN_GB': os.path.join(ROOT_DIR, 'extra', 'gb_sign.png') 'SIGN_GB': os.path.join(ROOT_DIR, 'extra', 'gb_sign.png')
} }
# ROBOKASSA_PASSWORD1 = 'O9ohc2uT8T9s1fKwXbuq'
# ROBOKASSA_PASSWORD2 = 'D552KBeAJhhVOfKEqT62'
# Robokassa
ROBOKASSA_LOGIN = 'Dokumentor'
# Test
ROBOKASSA_PASSWORD1 = 'ZtcV4jzgJ5qI2Cx7Rc4a'
ROBOKASSA_PASSWORD2 = 'iuJI7adaUGGE96QKz17a'
ROBOKASSA_USE_POST = False
ROBOKASSA_STRICT_CHECK = True
ROBOKASSA_TEST_MODE = True
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': True, 'disable_existing_loggers': True,

@ -27,3 +27,13 @@ DATABASES = {
EMAIL_BACKEND = 'eml_email_backend.EmailBackend' EMAIL_BACKEND = 'eml_email_backend.EmailBackend'
EMAIL_FILE_PATH = os.path.join(ROOT_DIR, 'tmp_emails') EMAIL_FILE_PATH = os.path.join(ROOT_DIR, 'tmp_emails')
# Robokassa
ROBOKASSA_LOGIN = 'Dokumentor'
# Test
ROBOKASSA_PASSWORD1 = 'ZtcV4jzgJ5qI2Cx7Rc4a'
ROBOKASSA_PASSWORD2 = 'iuJI7adaUGGE96QKz17a'
ROBOKASSA_USE_POST = True
ROBOKASSA_STRICT_CHECK = False
ROBOKASSA_TEST_MODE = True

@ -35,3 +35,14 @@ EMAIL_HOST_PASSWORD = e.get('DJANGO_EMAIL_PASSWORD')
EMAIL_USE_TLS = e.get('DJANGO_EMAIL_USE_TLS') EMAIL_USE_TLS = e.get('DJANGO_EMAIL_USE_TLS')
EMAIL_USE_SSL = e.get('DJANGO_EMAIL_USE_SSL') EMAIL_USE_SSL = e.get('DJANGO_EMAIL_USE_SSL')
EMAIL_SUBJECT_PREFIX = 'dokumentor ' EMAIL_SUBJECT_PREFIX = 'dokumentor '
# Robokassa
ROBOKASSA_LOGIN = 'Dokumentor'
ROBOKASSA_PASSWORD1 = 'O9ohc2uT8T9s1fKwXbuq'
ROBOKASSA_PASSWORD2 = 'D552KBeAJhhVOfKEqT62'
ROBOKASSA_USE_POST = True
ROBOKASSA_STRICT_CHECK = True
ROBOKASSA_TEST_MODE = False

@ -59,3 +59,13 @@ CALLBACK_SETTINGS = {
'MANAGERS_EMAILS': ('mitri4@bk.ru', 'alexander.time@gmail.com', 'dmitriy.shesterkin@gmail.com'), 'MANAGERS_EMAILS': ('mitri4@bk.ru', 'alexander.time@gmail.com', 'dmitriy.shesterkin@gmail.com'),
'NEW_REQ_AVAIL_EMAIL_SUBJ': u'Вопрос техподдержке', 'NEW_REQ_AVAIL_EMAIL_SUBJ': u'Вопрос техподдержке',
} }
# Robokassa
ROBOKASSA_LOGIN = 'Dokumentor'
# Test
ROBOKASSA_PASSWORD1 = 'ZtcV4jzgJ5qI2Cx7Rc4a'
ROBOKASSA_PASSWORD2 = 'iuJI7adaUGGE96QKz17a'
ROBOKASSA_USE_POST = True
ROBOKASSA_STRICT_CHECK = True
ROBOKASSA_TEST_MODE = True

@ -19,12 +19,11 @@ def receive_result(request, **credentials):
""" """
data = request.POST if USE_POST else request.GET data = request.POST if USE_POST else request.GET
form = ResultURLForm(data, **credentials) form = ResultURLForm(data, **credentials)
print(form.is_valid())
if form.is_valid(): if form.is_valid():
inv_id = form.cleaned_data['InvId'] inv_id = form.cleaned_data['InvId']
out_sum = form.cleaned_data['OutSum'] out_sum = form.cleaned_data['OutSum']
print('----------------------------------------------------')
print(form.cleaned_data['InvId'], form.cleaned_data['OutSum'])
# сохраняем данные об успешном уведомлении в базе, чтобы # сохраняем данные об успешном уведомлении в базе, чтобы
# можно было выполнить дополнительную проверку на странице успешного # можно было выполнить дополнительную проверку на странице успешного
# заказа # заказа

@ -1134,3 +1134,12 @@ input[type=number] {
border-left: 13px solid #DEDEDE; border-left: 13px solid #DEDEDE;
margin-left: -15px; margin-left: -15px;
} }
.payform {
text-align: center;
}
.payform__btn {
font-weight: normal;
cursor: pointer;
}

@ -1,37 +0,0 @@
{% extends "base.html" %}
{% load pytils_numeral static %}
{% block title %}Мои счета{% endblock %}
{% block content %}
<h1>Мои заказы</h1>
<div class="btn yellow-btn docs-btn"><a href="{% url 'customer_order_license' %}">Купить лицензию</a></div>
<div class="btn yellow-btn docs-btn"><a href="{% url 'customer_paid_list' %}">Оплаченные лицензии</a></div>
<table id="history" class="list">
<tr>
<th>Номер</th>
<th>Дата счёта</th>
<th>Срок лицензии</th>
<th>Сумма</th>
<th>Вид платежа</th>
<th>Статус</th>
<th>Действия</th>
<th>Отменить заявку</th>
</tr>
{% for license in licenses %}
<tr class='license_{{ license.id }}'>
<td>{% if license.pay_sum > 0 %}{{ license.id }}{% else %}--{% endif %}</td>
<td>{{ license.order_date }}</td>
<td>{{ license.get_term }}</td>
<td>{% if license.pay_sum > 0 %}{{ license.pay_sum|get_plural:"рубль,рубля,рублей" }}{% else %}Бесплатно{% endif %}</td>
<td>{{ license.get_payform_display }}</td>
<td>{{ license.get_status_display }}</td>
<td>{{ license.get_action_link|safe }}</td>
<td>{% if license.status == 0 %}<a href='#' class='delete_license' data-id='{{ license.pk }}'>Удалить</a>{% endif %}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% block js %}
<script src="{% static 'js/license.js' %}"></script>
{% endblock %}

@ -1,31 +0,0 @@
{% extends "base.html" %}
{% load pytils_numeral %}
{% block title %}История расчётов{% endblock %}
{% block content %}
<h1>История оплат</h1>
<div class="btn yellow-btn docs-btn"><a href="{% url 'customer_order_license' %}">Купить лицензию</a></div>
<div class="btn yellow-btn docs-btn"><a href="{% url 'customer_license_list' %}">Все счета</a></div>
<table id="history" class="list">
<tr>
<th>Дата оплаты</th>
<th>По счёту</th>
<th>Сумма</th>
<th>Срок лицензии</th>
<th>Период действия лицензии</th>
<th>Статус лицензии</th>
<th>Закрывающие документы</th>
</tr>
{% for license in licenses %}
<tr>
<td>{{ license.paid_date|default:'-' }}</td>
<td>{% if license.pay_sum %}{{ license.id }}{% else %}-{% endif %}</td>
<td>{% if license.pay_sum %}{{ license.pay_sum }}{% else %}-{% endif %}</td>
<td>{{ license.get_term }}</td>
<td>{% if license.date_from %}{{ license.date_from }} - {{ license.date_to }}{% else %}-{% endif %}</td>
<td>{{ license.get_status_display }}<p>{{ license.get_paid_status|default:'' }}</p></td>
<td>Разные документы</td>
</tr>
{% endfor %}
</table>
{% endblock %}

@ -1,29 +0,0 @@
{% extends "base.html" %}
{% load pytils_numeral %}
{% block title %}Подтвердить платёж{% endblock %}
{% block content %}
<h2>Купить лицензию</h2>
{% if form.non_field_errors %}
<p class="error">{{ form.non_field_errors }}</p>
{% endif %}
<div class='content-white'>
<div>
<form class="" action="{{ ya_url }}" method="post">
{{ form.as_ul }}
<p>Сумма:
{{ form.sum.value }}</p>
<div class="">
<input type="submit" name="submit" value="Перейти" />
</div>
</form>
</div>
</div>
{% endblock %}
{% block js %}
{% endblock %}

@ -1,6 +1,11 @@
{% extends 'base.html' %} {% extends "base.html" %}
{% block content %}
Ошибка при оплате {% block title %}Ошибка при оплате{% endblock %}
{{ form.as_p }}
{% endblock content %} {% block right-column %}{% endblock %}
{% block content %}
<div id="content">
<h2>Опс!</h2>
<p>Ошибка при оплате!</p>
</div>
{% endblock %}

@ -1,4 +1,10 @@
{% extends 'base.html' %} {% extends "base.html" %}
{% block title %}Неудачная оплата{% endblock %}
{% block content %} {% block content %}
Неудачная оплата <div id="content">
{% endblock content %} <h2>Опс!</h2>
<p>Неудачная оплата!</p>
</div>
{% endblock %}

@ -1,7 +1,11 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Оплата лицензии{% endblock %}
{% block content %} {% block content %}
<form action="{{ form.target }}" method="GET"> <h1>Оплатить лицензию</h1>
<form class="payform" action="{{ form.target }}" method="POST">
<p>{{ form.as_p }}</p> <p>{{ form.as_p }}</p>
<p><input type="submit" value="Оплатить"></p> <p><input type="submit" class="btn yellow-btn docs-btn payform__btn"value="Оплатить"></p>
</form> </form>
{% endblock %} {% endblock %}

@ -1,4 +1,11 @@
{% extends 'base.html' %} {% extends "base.html" %}
{% block title %}Завершение заказа{% endblock %}
{% block right-column %}{% endblock %}
{% block content %} {% block content %}
Оплата успешна <div id="content">
{% endblock content %} <h2>Спасибо!</h2>
<p>Ваш заказ принят!</p>
</div>
{% endblock %}

Loading…
Cancel
Save