From 226d5b07dadc683f9d40297ff860bd01acafe0b1 Mon Sep 17 00:00:00 2001 From: Bachurin Sergey Date: Fri, 30 Dec 2016 14:03:56 +0300 Subject: [PATCH] yandex --- project/customer/callbacks.py | 21 --- project/customer/views/license.py | 3 +- project/settings.py | 2 +- .../templates/customer/profile/yandex.html | 2 +- project/yandex_money/__init__.py | 0 project/yandex_money/admin.py | 40 ++++ project/yandex_money/forms.py | 172 ++++++++++++++++++ project/yandex_money/models.py | 141 ++++++++++++++ project/yandex_money/signals.py | 6 + .../south_migrations/0001_initial.py | 102 +++++++++++ ...002_auto__chg_field_payment_shop_amount.py | 81 +++++++++ ..._number__add_field_payment_customer_num.py | 77 ++++++++ ...ode__add_field_payment_article_id__add_.py | 118 ++++++++++++ .../yandex_money/south_migrations/__init__.py | 0 project/yandex_money/urls.py | 11 ++ project/yandex_money/utils.py | 1 + project/yandex_money/views.py | 153 ++++++++++++++++ 17 files changed, 906 insertions(+), 24 deletions(-) delete mode 100644 project/customer/callbacks.py create mode 100644 project/yandex_money/__init__.py create mode 100644 project/yandex_money/admin.py create mode 100644 project/yandex_money/forms.py create mode 100644 project/yandex_money/models.py create mode 100644 project/yandex_money/signals.py create mode 100644 project/yandex_money/south_migrations/0001_initial.py create mode 100644 project/yandex_money/south_migrations/0002_auto__chg_field_payment_shop_amount.py create mode 100644 project/yandex_money/south_migrations/0003_auto__del_field_payment_custome_number__add_field_payment_customer_num.py create mode 100644 project/yandex_money/south_migrations/0004_auto__del_field_payment_payer_code__add_field_payment_article_id__add_.py create mode 100644 project/yandex_money/south_migrations/__init__.py create mode 100644 project/yandex_money/urls.py create mode 100644 project/yandex_money/utils.py create mode 100644 project/yandex_money/views.py diff --git a/project/customer/callbacks.py b/project/customer/callbacks.py deleted file mode 100644 index a237378..0000000 --- a/project/customer/callbacks.py +++ /dev/null @@ -1,21 +0,0 @@ -# encoding:utf-8 -from datetime import date - -from django.dispatch import receiver - -from yandex_money.signals import payment_completed - -from customer.models import License - - -@receiver(payment_completed) -def pay_license(sender, **kwargs): - try: - print '!!!!!!!!!!!!!' - license = License.objects.get(id=sender.order_number) - license.paid_date = date.today() - license.status = 1 - license.save() - except: - print 8789879787897, '@@@@@@@@@@@@@@@@' - pass diff --git a/project/customer/views/license.py b/project/customer/views/license.py index 6fa5981..08c0df7 100644 --- a/project/customer/views/license.py +++ b/project/customer/views/license.py @@ -27,7 +27,8 @@ def yandex_pay(request, payment_id): if payment.user != request.user: raise form = YaForm(instance=payment) - return render(request, template_name, {'form': form}) + return render(request, template_name, {'form': form, + 'ya_url': settings.YANDEX_MONEY_PAYMENT_URL}) @login_required diff --git a/project/settings.py b/project/settings.py index 2a227c4..131dfc8 100644 --- a/project/settings.py +++ b/project/settings.py @@ -353,7 +353,7 @@ YANDEX_MONEY_SHOP_ID = 92585 YANDEX_MONEY_SHOP_PASSWORD = 'sQuMtorHE02U' YANDEX_MONEY_FAIL_URL = 'https://dokumentor.ru/my/payment/fail/' YANDEX_MONEY_SUCCESS_URL = 'https://dokumentor.ru/my/payment/success/' -YANDEX_MONEY_PAYMENT_URL = 'https://demomoney.yandex.ru/eshop.xml' +YANDEX_MONEY_PAYMENT_URL = 'https://money.yandex.ru/eshop.xml' # информировать о случаях, когда модуль вернул Яндекс.Кассе ошибку YANDEX_MONEY_MAIL_ADMINS_ON_PAYMENT_ERROR = True diff --git a/project/templates/customer/profile/yandex.html b/project/templates/customer/profile/yandex.html index dbb6378..ae8c1df 100644 --- a/project/templates/customer/profile/yandex.html +++ b/project/templates/customer/profile/yandex.html @@ -12,7 +12,7 @@
-
+ {{ form.as_ul }}

Сумма: {{ form.sum.value }}

diff --git a/project/yandex_money/__init__.py b/project/yandex_money/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/project/yandex_money/admin.py b/project/yandex_money/admin.py new file mode 100644 index 0000000..14902a9 --- /dev/null +++ b/project/yandex_money/admin.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +from django.contrib import admin +from .models import Payment + + +class PaymentAdmin(admin.ModelAdmin): + list_display_links = ('customer_number',) + list_display = ( + 'customer_number', + 'payment_type', + 'order_number', + 'order_amount', + 'shop_amount', + 'shop_currency', + 'invoice_id', + 'status', + 'pub_date', + 'user', + 'cps_phone', + ) + list_filter = ( + 'pub_date', + 'status', + ) + search_fields = ( + 'customer_number', + 'cps_email', + 'cps_phone', + 'scid', + 'shop_id', + 'invoice_id', + 'order_number', + ) + + def has_add_permission(self, obj): + return False + + +admin.site.register(Payment, PaymentAdmin) \ No newline at end of file diff --git a/project/yandex_money/forms.py b/project/yandex_money/forms.py new file mode 100644 index 0000000..9346f03 --- /dev/null +++ b/project/yandex_money/forms.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- + +from hashlib import md5 +from django import forms +from django.conf import settings +from .models import Payment + + +class BasePaymentForm(forms.Form): + """ + shopArticleId + scid scid + sum amount + customerNumber user + orderNumber id + shopSuccessURL success_url + shopFailURL fail_url + cps_provider payment_type + cps_email cps_email + cps_phone cps_phone + paymentType payment_type + shopId shop_id + invoiceId invoice_id + orderCreatedDatetime + orderSumAmount order_amount + orderSumCurrencyPaycash order_currency + orderSumBankPaycash + shopSumAmount shop_amount + shopSumCurrencyPaycash shop_currency + shopSumBankPaycash + paymentPayerCode payer_code + paymentDatetime + cms_name django + """ + + class ERROR_MESSAGE_CODES: + BAD_SCID = 0 + BAD_SHOP_ID = 1 + + error_messages = { + ERROR_MESSAGE_CODES.BAD_SCID: u'scid не совпадает с YANDEX_MONEY_SCID', + ERROR_MESSAGE_CODES.BAD_SHOP_ID: u'scid не совпадает с YANDEX_MONEY_SHOP_ID' + } + + class ACTION: + CHECK = 'checkOrder' + CPAYMENT = 'paymentAviso' + + CHOICES = ( + (CHECK, u'Проверка заказа'), + (CPAYMENT, u'Уведомления о переводе'), + ) + + shopId = forms.IntegerField(initial=settings.YANDEX_MONEY_SHOP_ID) + scid = forms.IntegerField(initial=settings.YANDEX_MONEY_SCID) + orderNumber = forms.CharField(min_length=1, max_length=64) + customerNumber = forms.CharField(min_length=1, max_length=64) + paymentType = forms.CharField(label=u'Способ оплаты', + widget=forms.Select(choices=Payment.PAYMENT_TYPE.CHOICES), + min_length=2, max_length=2, + initial=Payment.PAYMENT_TYPE.PC) + orderSumBankPaycash = forms.IntegerField() + + md5 = forms.CharField(min_length=32, max_length=32) + action = forms.CharField(max_length=16) + + def __init__(self, *args, **kwargs): + super(BasePaymentForm, self).__init__(*args, **kwargs) + if hasattr(settings, 'YANDEX_ALLOWED_PAYMENT_TYPES'): + allowed_payment_types = settings.YANDEX_ALLOWED_PAYMENT_TYPES + self.fields['paymentType'].widget.choices = filter( + lambda x: x[0] in allowed_payment_types, + self.fields['paymentType'].widget.choices) + + @classmethod + def make_md5(cls, cd): + """ + action;orderSumAmount;orderSumCurrencyPaycash;orderSumBankPaycash;shopId;invoiceId;customerNumber;shopPassword + """ + return md5(';'.join(map(str, ( + cd['action'], + cd['orderSumAmount'], + cd['orderSumCurrencyPaycash'], + cd['orderSumBankPaycash'], + cd['shopId'], + cd['invoiceId'], + cd['customerNumber'], + settings.YANDEX_MONEY_SHOP_PASSWORD, + )))).hexdigest().upper() + + @classmethod + def check_md5(cls, cd): + return cls.make_md5(cd) == cd['md5'] + + def clean_scid(self): + scid = self.cleaned_data['scid'] + if ( + scid != settings.YANDEX_MONEY_SCID and + not scid in Payment.get_used_scids() + ): + raise forms.ValidationError(self.error_messages[self.ERROR_MESSAGE_CODES.BAD_SCID]) + return scid + + def clean_shopId(self): + shop_id = self.cleaned_data['shopId'] + if ( + shop_id != settings.YANDEX_MONEY_SHOP_ID and + not shop_id in Payment.get_used_shop_ids() + ): + raise forms.ValidationError(self.error_messages[self.ERROR_MESSAGE_CODES.BAD_SHOP_ID]) + return shop_id + + +class PaymentForm(BasePaymentForm): + sum = forms.FloatField(label='Сумма заказа') + + cps_email = forms.EmailField(label='Email', required=False) + cps_phone = forms.CharField(label='Телефон', + max_length=15, required=False) + + shopFailURL = forms.URLField(initial=settings.YANDEX_MONEY_FAIL_URL) + shopSuccessURL = forms.URLField(initial=settings.YANDEX_MONEY_SUCCESS_URL) + + def __init__(self, *args, **kwargs): + instance = kwargs.pop('instance') + super(PaymentForm, self).__init__(*args, **kwargs) + + self.fields.pop('md5') + self.fields.pop('action') + self.fields.pop('orderSumBankPaycash') + + if not getattr(settings, 'YANDEX_MONEY_DEBUG', False): + for name in self.fields: + if name not in self.get_display_field_names(): + self.fields[name].widget = forms.HiddenInput() + + if instance: + self.fields['sum'].initial = instance.order_amount + self.fields['paymentType'].initial = instance.payment_type + self.fields['customerNumber'].initial = instance.customer_number + self.fields['orderNumber'].initial = instance.order_number + if instance.fail_url: + self.fields['shopFailURL'].initial = instance.fail_url + if instance.success_url: + self.fields['shopSuccessURL'].initial = instance.success_url + if instance.cps_email: + self.fields['cps_email'].initial = instance.cps_email + if instance.cps_phone: + self.fields['cps_phone'].initial = instance.cps_phone + + def get_display_field_names(self): + return ['paymentType', 'cps_email', 'cps_phone'] + + +class CheckForm(BasePaymentForm): + invoiceId = forms.IntegerField() + orderSumAmount = forms.DecimalField(min_value=0, decimal_places=2) + orderSumCurrencyPaycash = forms.IntegerField() + shopSumAmount = forms.DecimalField(min_value=0, decimal_places=2) + shopSumCurrencyPaycash = forms.IntegerField() + paymentPayerCode = forms.IntegerField(min_value=1) + + +class NoticeForm(BasePaymentForm): + invoiceId = forms.IntegerField(min_value=1) + orderSumAmount = forms.DecimalField(min_value=0, decimal_places=2) + orderSumCurrencyPaycash = forms.IntegerField() + shopSumAmount = forms.DecimalField(min_value=0, decimal_places=2) + shopSumCurrencyPaycash = forms.IntegerField() + paymentPayerCode = forms.IntegerField(min_value=1) + cps_email = forms.EmailField(required=False) + cps_phone = forms.CharField(max_length=15, required=False) diff --git a/project/yandex_money/models.py b/project/yandex_money/models.py new file mode 100644 index 0000000..4c24893 --- /dev/null +++ b/project/yandex_money/models.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- + +from uuid import uuid4 + +from django.conf import settings +from django.db import models + +from .signals import payment_process +from .signals import payment_completed + + +class Payment(models.Model): + class STATUS: + PROCESSED = 'processed' + SUCCESS = 'success' + FAIL = 'fail' + + CHOICES = ( + (PROCESSED, 'Processed'), + (SUCCESS, 'Success'), + (FAIL, 'Fail'), + ) + + class PAYMENT_TYPE: + PC = 'PC' + AC = 'AC' + GP = 'GP' + MC = 'MC' + WM = 'WM' + SB = 'SB' + AB = 'AB' + MA = 'MA' + PB = 'PB' + QW = 'QW' + QP = 'QP' + + CHOICES = ( + (PC, u'Кошелек Яндекс.Деньги'), + (AC, u'Банковская карта'), + (GP, u'Наличными через кассы и терминалы'), + (MC, u'Счет мобильного телефона'), + (WM, u'Кошелек WebMoney'), + (SB, u'Сбербанк: оплата по SMS или Сбербанк Онлайн'), + (AB, u'Альфа-Клик'), + (MA, u'MasterPass'), + (PB, u'Интернет-банк Промсвязьбанка'), + (QW, u'QIWI Wallet'), + (QP, u'Доверительный платеж (Куппи.ру)'), + ) + + class CURRENCY: + RUB = 643 + TEST = 10643 + + CHOICES = ( + (RUB, u'Рубли'), + (TEST, u'Тестовая валюта'), + ) + + user = models.ForeignKey( + settings.AUTH_USER_MODEL, blank=True, null=True, + verbose_name=u'Пользователь') + pub_date = models.DateTimeField(u'Время создания', auto_now_add=True) + + # Required request fields + shop_id = models.PositiveIntegerField( + u'ID магазина', default=settings.YANDEX_MONEY_SHOP_ID) + scid = models.PositiveIntegerField( + u'Номер витрины', default=settings.YANDEX_MONEY_SCID) + customer_number = models.CharField( + u'Идентификатор плательщика', max_length=64, + default=lambda: str(uuid4()).replace('-', '')) + order_amount = models.DecimalField( + u'Сумма заказа', max_digits=15, decimal_places=2) + + # Non-required fields + article_id = models.PositiveIntegerField( + u'Идентификатор товара', blank=True, null=True) + payment_type = models.CharField( + u'Способ платежа', max_length=2, default=PAYMENT_TYPE.PC, + choices=PAYMENT_TYPE.CHOICES) + order_number = models.CharField( + u'Номер заказа', max_length=64, + default=lambda: str(uuid4()).replace('-', '')) + cps_email = models.EmailField( + u'Email плательщика', max_length=100, blank=True, null=True) + cps_phone = models.CharField( + u'Телефон плательщика', max_length=15, blank=True, null=True) + success_url = models.URLField( + u'URL успешной оплаты', default=settings.YANDEX_MONEY_SUCCESS_URL) + fail_url = models.URLField( + u'URL неуспешной оплаты', default=settings.YANDEX_MONEY_FAIL_URL) + + # Transaction info + status = models.CharField( + u'Статус', max_length=16, choices=STATUS.CHOICES, + default=STATUS.PROCESSED) + invoice_id = models.PositiveIntegerField( + u'Номер транзакции оператора', blank=True, null=True) + shop_amount = models.DecimalField( + u'Сумма полученная на р/с', max_digits=15, decimal_places=2, blank=True, + null=True, help_text=u'За вычетом процента оператора') + order_currency = models.PositiveIntegerField( + u'Валюта', default=CURRENCY.RUB, choices=CURRENCY.CHOICES) + shop_currency = models.PositiveIntegerField( + u'Валюта полученная на р/с', blank=True, null=True, + default=CURRENCY.RUB, choices=CURRENCY.CHOICES) + performed_datetime = models.DateTimeField( + u'Время выполнение запроса', blank=True, null=True) + + @property + def is_payed(self): + return self.status == self.STATUS.SUCCESS + + def send_signals(self): + status = self.status + if status == self.STATUS.PROCESSED: + payment_process.send(sender=self) + if status == self.STATUS.SUCCESS: + payment_completed.send(sender=self) + + @classmethod + def get_used_shop_ids(cls): + return cls.objects.values_list('shop_id', flat=True).distinct() + + @classmethod + def get_used_scids(cls): + return cls.objects.values_list('scid', flat=True).distinct() + + class Meta: + ordering = ('-pub_date',) + unique_together = ( + ('shop_id', 'order_number'), + ) + verbose_name = u'платёж' + verbose_name_plural = u'платежи' + app_label = 'yandex_money' + + def __unicode__(self): + return u'[Payment id={}, order_number={}, payment_type={}, status={}]'.format( + self.id, self.order_number, self.payment_type, self.status) diff --git a/project/yandex_money/signals.py b/project/yandex_money/signals.py new file mode 100644 index 0000000..06cec6e --- /dev/null +++ b/project/yandex_money/signals.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from django.dispatch import Signal + +payment_process = Signal() +payment_completed = Signal() \ No newline at end of file diff --git a/project/yandex_money/south_migrations/0001_initial.py b/project/yandex_money/south_migrations/0001_initial.py new file mode 100644 index 0000000..df95c58 --- /dev/null +++ b/project/yandex_money/south_migrations/0001_initial.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Payment' + db.create_table(u'yandex_money_payment', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)), + ('custome_number', self.gf('django.db.models.fields.CharField')(default='89734j7t5w9438h7tow843htco3', unique=True, max_length=64)), + ('status', self.gf('django.db.models.fields.CharField')(default='processed', max_length=16)), + ('scid', self.gf('django.db.models.fields.PositiveIntegerField')(default=12345)), + ('shop_id', self.gf('django.db.models.fields.PositiveIntegerField')(default=12345)), + ('payment_type', self.gf('django.db.models.fields.CharField')(default='ac', max_length=2)), + ('invoice_id', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)), + ('order_amount', self.gf('django.db.models.fields.FloatField')()), + ('shop_amount', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2, blank=True)), + ('order_currency', self.gf('django.db.models.fields.PositiveIntegerField')(default=643)), + ('shop_currency', self.gf('django.db.models.fields.PositiveIntegerField')(default=643, null=True, blank=True)), + ('payer_code', self.gf('django.db.models.fields.CharField')(max_length=33, null=True, blank=True)), + ('success_url', self.gf('django.db.models.fields.URLField')(default='http://example.com/success-payment/', max_length=200)), + ('fail_url', self.gf('django.db.models.fields.URLField')(default='http://example.com/fail-payment/', max_length=200)), + ('cps_email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True)), + ('cps_phone', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)), + ('pub_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('performed_datetime', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + )) + db.send_create_signal(u'yandex_money', ['Payment']) + + + def backwards(self, orm): + # Deleting model 'Payment' + db.delete_table(u'yandex_money_payment') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'yandex_money.payment': { + 'Meta': {'ordering': "('pub_date',)", 'object_name': 'Payment'}, + 'cps_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'cps_phone': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'custome_number': ('django.db.models.fields.CharField', [], {'default': "'89734j7t5w9438h7tow843htco3'", 'unique': 'True', 'max_length': '64'}), + 'fail_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/fail-payment/'", 'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invoice_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'order_amount': ('django.db.models.fields.FloatField', [], {}), + 'order_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643'}), + 'payer_code': ('django.db.models.fields.CharField', [], {'max_length': '33', 'null': 'True', 'blank': 'True'}), + 'payment_type': ('django.db.models.fields.CharField', [], {'default': "'ac'", 'max_length': '2'}), + 'performed_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'scid': ('django.db.models.fields.PositiveIntegerField', [], {'default': '12345'}), + 'shop_amount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), + 'shop_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643', 'null': 'True', 'blank': 'True'}), + 'shop_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '12345'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'processed'", 'max_length': '16'}), + 'success_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/success-payment/'", 'max_length': '200'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['yandex_money'] \ No newline at end of file diff --git a/project/yandex_money/south_migrations/0002_auto__chg_field_payment_shop_amount.py b/project/yandex_money/south_migrations/0002_auto__chg_field_payment_shop_amount.py new file mode 100644 index 0000000..d2bd39e --- /dev/null +++ b/project/yandex_money/south_migrations/0002_auto__chg_field_payment_shop_amount.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'Payment.shop_amount' + db.alter_column(u'yandex_money_payment', 'shop_amount', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=15, decimal_places=2)) + + def backwards(self, orm): + + # Changing field 'Payment.shop_amount' + db.alter_column(u'yandex_money_payment', 'shop_amount', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=2)) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'yandex_money.payment': { + 'Meta': {'ordering': "('pub_date',)", 'object_name': 'Payment'}, + 'cps_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'cps_phone': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'custome_number': ('django.db.models.fields.CharField', [], {'default': "'89734j7t5w9438h7tow843htco3'", 'unique': 'True', 'max_length': '64'}), + 'fail_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/fail-payment/'", 'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invoice_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'order_amount': ('django.db.models.fields.FloatField', [], {}), + 'order_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643'}), + 'payer_code': ('django.db.models.fields.CharField', [], {'max_length': '33', 'null': 'True', 'blank': 'True'}), + 'payment_type': ('django.db.models.fields.CharField', [], {'default': "'ac'", 'max_length': '2'}), + 'performed_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'scid': ('django.db.models.fields.PositiveIntegerField', [], {'default': '12345'}), + 'shop_amount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '15', 'decimal_places': '2', 'blank': 'True'}), + 'shop_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643', 'null': 'True', 'blank': 'True'}), + 'shop_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '12345'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'processed'", 'max_length': '16'}), + 'success_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/success-payment/'", 'max_length': '200'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['yandex_money'] \ No newline at end of file diff --git a/project/yandex_money/south_migrations/0003_auto__del_field_payment_custome_number__add_field_payment_customer_num.py b/project/yandex_money/south_migrations/0003_auto__del_field_payment_custome_number__add_field_payment_customer_num.py new file mode 100644 index 0000000..fef7d8c --- /dev/null +++ b/project/yandex_money/south_migrations/0003_auto__del_field_payment_custome_number__add_field_payment_customer_num.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.rename_column(u'yandex_money_payment', 'custome_number', 'customer_number') + + def backwards(self, orm): + db.rename_column(u'yandex_money_payment', 'customer_number', 'custome_number') + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'yandex_money.payment': { + 'Meta': {'ordering': "('pub_date',)", 'object_name': 'Payment'}, + 'cps_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'cps_phone': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'customer_number': ('django.db.models.fields.CharField', [], {'default': "'3c2137145c764a33b35ec4eab3eae52b'", 'unique': 'True', 'max_length': '64'}), + 'fail_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/fail-payment/'", 'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invoice_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'order_amount': ('django.db.models.fields.FloatField', [], {}), + 'order_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643'}), + 'payer_code': ('django.db.models.fields.CharField', [], {'max_length': '33', 'null': 'True', 'blank': 'True'}), + 'payment_type': ('django.db.models.fields.CharField', [], {'default': "'pc'", 'max_length': '2'}), + 'performed_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'scid': ('django.db.models.fields.PositiveIntegerField', [], {'default': '123'}), + 'shop_amount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '15', 'decimal_places': '2', 'blank': 'True'}), + 'shop_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643', 'null': 'True', 'blank': 'True'}), + 'shop_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '456'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'processed'", 'max_length': '16'}), + 'success_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/success-payment/'", 'max_length': '200'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['yandex_money'] \ No newline at end of file diff --git a/project/yandex_money/south_migrations/0004_auto__del_field_payment_payer_code__add_field_payment_article_id__add_.py b/project/yandex_money/south_migrations/0004_auto__del_field_payment_payer_code__add_field_payment_article_id__add_.py new file mode 100644 index 0000000..86b4817 --- /dev/null +++ b/project/yandex_money/south_migrations/0004_auto__del_field_payment_payer_code__add_field_payment_article_id__add_.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Removing unique constraint on 'Payment', fields ['customer_number'] + db.delete_unique(u'yandex_money_payment', ['customer_number']) + + # Deleting field 'Payment.payer_code' + db.delete_column(u'yandex_money_payment', 'payer_code') + + # Adding field 'Payment.article_id' + db.add_column(u'yandex_money_payment', 'article_id', + self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True), + keep_default=False) + + # Adding field 'Payment.order_number' + db.add_column(u'yandex_money_payment', 'order_number', + self.gf('django.db.models.fields.CharField')(max_length=64, unique=True, null=True, blank=True), + keep_default=False) + + + # Changing field 'Payment.order_amount' + db.alter_column(u'yandex_money_payment', 'order_amount', self.gf('django.db.models.fields.DecimalField')(max_digits=15, decimal_places=2)) + + # Changing field 'Payment.cps_email' + db.alter_column(u'yandex_money_payment', 'cps_email', self.gf('django.db.models.fields.EmailField')(max_length=100, null=True)) + + def backwards(self, orm): + # Adding field 'Payment.payer_code' + db.add_column(u'yandex_money_payment', 'payer_code', + self.gf('django.db.models.fields.CharField')(max_length=33, null=True, blank=True), + keep_default=False) + + # Deleting field 'Payment.article_id' + db.delete_column(u'yandex_money_payment', 'article_id') + + # Deleting field 'Payment.order_number' + db.delete_column(u'yandex_money_payment', 'order_number') + + + # Changing field 'Payment.order_amount' + db.alter_column(u'yandex_money_payment', 'order_amount', self.gf('django.db.models.fields.FloatField')()) + + # Changing field 'Payment.cps_email' + db.alter_column(u'yandex_money_payment', 'cps_email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True)) + # Adding unique constraint on 'Payment', fields ['customer_number'] + db.create_unique(u'yandex_money_payment', ['customer_number']) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'yandex_money.payment': { + 'Meta': {'ordering': "('pub_date',)", 'object_name': 'Payment'}, + 'article_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'cps_email': ('django.db.models.fields.EmailField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'cps_phone': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'customer_number': ('django.db.models.fields.CharField', [], {'default': "'e52ba3530c864d96a76987e2b09263a7'", 'max_length': '64'}), + 'fail_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/fail-payment/'", 'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invoice_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'order_amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '15', 'decimal_places': '2'}), + 'order_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643'}), + 'order_number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'payment_type': ('django.db.models.fields.CharField', [], {'default': "'pc'", 'max_length': '2'}), + 'performed_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'scid': ('django.db.models.fields.PositiveIntegerField', [], {'default': '123'}), + 'shop_amount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '15', 'decimal_places': '2', 'blank': 'True'}), + 'shop_currency': ('django.db.models.fields.PositiveIntegerField', [], {'default': '643', 'null': 'True', 'blank': 'True'}), + 'shop_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '456'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'processed'", 'max_length': '16'}), + 'success_url': ('django.db.models.fields.URLField', [], {'default': "'http://example.com/success-payment/'", 'max_length': '200'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['yandex_money'] \ No newline at end of file diff --git a/project/yandex_money/south_migrations/__init__.py b/project/yandex_money/south_migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/project/yandex_money/urls.py b/project/yandex_money/urls.py new file mode 100644 index 0000000..20d2846 --- /dev/null +++ b/project/yandex_money/urls.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +from django.conf.urls import patterns, url +from .views import NoticeFormView +from .views import CheckOrderFormView + + +urlpatterns = patterns('', + url(r'^check/$', CheckOrderFormView.as_view(), name='yandex_money_check'), + url(r'^aviso/$', NoticeFormView.as_view(), name='yandex_money_notice'), +) diff --git a/project/yandex_money/utils.py b/project/yandex_money/utils.py new file mode 100644 index 0000000..7c68785 --- /dev/null +++ b/project/yandex_money/utils.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- \ No newline at end of file diff --git a/project/yandex_money/views.py b/project/yandex_money/views.py new file mode 100644 index 0000000..2c4b6e6 --- /dev/null +++ b/project/yandex_money/views.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- + +import logging +from datetime import datetime + +from django.http import HttpResponse +from django.utils.decorators import method_decorator +from django.views.decorators.csrf import csrf_exempt +from django.views.generic import View +from django.conf import settings +from django.core.mail import mail_admins +from lxml import etree +from lxml.builder import E + +from .forms import CheckForm +from .forms import NoticeForm +from .models import Payment +from customer.models import License + + +logger = logging.getLogger('yandex_money') + + +class YandexValidationError(Exception): + params = None + + def __init__(self, params=None): + super(YandexValidationError, self).__init__() + self.params = params if params is not None else {} + + +class BaseView(View): + form_class = None + + @method_decorator(csrf_exempt) + def dispatch(self, *args, **kwargs): + return super(BaseView, self).dispatch(*args, **kwargs) + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) + if form.is_valid(): + cd = form.cleaned_data + if form.check_md5(cd): + payment = self.get_payment(cd) + if payment: + try: + self.validate(cd, payment) + except YandexValidationError as exc: + params = exc.params + else: + params = self.get_response_params(payment, cd) + self.mark_payment(payment, cd) + payment.send_signals() + else: + params = {'code': '1000'} + else: + params = {'code': '1'} + else: + params = {'code': '200'} + + self.logging(request, params) + content = self.get_xml(params) + + if ( + getattr(settings, 'YANDEX_MONEY_MAIL_ADMINS_ON_PAYMENT_ERROR', True) and + params.get('code') != '0' + ): + mail_admins('yandexmoney_django error', u'post data: {post_data}\n\nresponse:{response}'.format( + post_data=request.POST, + response=content, + )) + + return HttpResponse(content, content_type='application/xml') + + def validate(self, data, payment): + pass + + def get_payment(self, cd): + try: + payment = Payment.objects.get( + order_number=cd['orderNumber'], shop_id=cd['shopId']) + except Payment.DoesNotExist: + payment = None + return payment + + def get_response_params(self, payment, cd): + if payment: + now = datetime.now() + + payment.performed_datetime = now + payment.save() + + return {'code': '0', + 'shopId': str(cd['shopId']), + 'invoiceId': str(cd['invoiceId']), + 'performedDatetime': now.isoformat()} + return {'code': '100'} + + def mark_payment(self, payment, cd): + pass + + def get_xml(self, params): + element = self.get_xml_element(**params) + return etree.tostring(element, + pretty_print=True, + xml_declaration=True, + encoding='UTF-8') + + def get_xml_element(self, **params): + raise NotImplementedError() + + def logging(self, request, params): + message = 'Action %s has code %s for customerNumber "%s"' % ( + request.POST.get('action', ''), params['code'], + request.POST.get('customerNumber', '')) + logger.info(message) + + +class CheckOrderFormView(BaseView): + form_class = CheckForm + + def validate(self, data, payment): + if payment.order_amount != data['orderSumAmount']: + params = { + 'code': '100', + 'message': u'Неверно указана сумма платежа', + } + raise YandexValidationError(params=params) + + def get_xml_element(self, **params): + return E.checkOrderResponse(**params) + + +class NoticeFormView(BaseView): + form_class = NoticeForm + + def get_xml_element(self, **params): + return E.paymentAvisoResponse(**params) + + def mark_payment(self, payment, cd): + payment.cps_email = cd.get('cps_email', '') + payment.cps_phone = cd.get('cps_phone', '') + payment.order_currency = cd.get('orderSumCurrencyPaycash') + payment.shop_amount = cd.get('shopSumAmount') + payment.shop_currency = cd.get('shopSumCurrencyPaycash') + payment.payer_code = cd.get('paymentPayerCode') + payment.payment_type = cd.get('paymentType') + payment.status = payment.STATUS.SUCCESS + payment.save() + license = License.objects.get(id=payment.order_number) + license.paid_date = date.today() + license.status = 1 + license.save()