remotes/origin/yandex
Bachurin Sergey 9 years ago
parent 4388a2cffe
commit 226d5b07da
  1. 21
      project/customer/callbacks.py
  2. 3
      project/customer/views/license.py
  3. 2
      project/settings.py
  4. 2
      project/templates/customer/profile/yandex.html
  5. 0
      project/yandex_money/__init__.py
  6. 40
      project/yandex_money/admin.py
  7. 172
      project/yandex_money/forms.py
  8. 141
      project/yandex_money/models.py
  9. 6
      project/yandex_money/signals.py
  10. 102
      project/yandex_money/south_migrations/0001_initial.py
  11. 81
      project/yandex_money/south_migrations/0002_auto__chg_field_payment_shop_amount.py
  12. 77
      project/yandex_money/south_migrations/0003_auto__del_field_payment_custome_number__add_field_payment_customer_num.py
  13. 118
      project/yandex_money/south_migrations/0004_auto__del_field_payment_payer_code__add_field_payment_article_id__add_.py
  14. 0
      project/yandex_money/south_migrations/__init__.py
  15. 11
      project/yandex_money/urls.py
  16. 1
      project/yandex_money/utils.py
  17. 153
      project/yandex_money/views.py

@ -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

@ -27,7 +27,8 @@ def yandex_pay(request, payment_id):
if payment.user != request.user: if payment.user != request.user:
raise raise
form = YaForm(instance=payment) 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 @login_required

@ -353,7 +353,7 @@ YANDEX_MONEY_SHOP_ID = 92585
YANDEX_MONEY_SHOP_PASSWORD = 'sQuMtorHE02U' YANDEX_MONEY_SHOP_PASSWORD = 'sQuMtorHE02U'
YANDEX_MONEY_FAIL_URL = 'https://dokumentor.ru/my/payment/fail/' YANDEX_MONEY_FAIL_URL = 'https://dokumentor.ru/my/payment/fail/'
YANDEX_MONEY_SUCCESS_URL = 'https://dokumentor.ru/my/payment/success/' 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 YANDEX_MONEY_MAIL_ADMINS_ON_PAYMENT_ERROR = True

@ -12,7 +12,7 @@
<div class='content-white'> <div class='content-white'>
<div> <div>
<form class="" action="https://demomoney.yandex.ru/eshop.xml" method="post"> <form class="" action="{{ ya_url }}" method="post">
{{ form.as_ul }} {{ form.as_ul }}
<p>Сумма: <p>Сумма:
{{ form.sum.value }}</p> {{ form.sum.value }}</p>

@ -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)

@ -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 <no use>
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 <no use>
orderSumAmount order_amount
orderSumCurrencyPaycash order_currency
orderSumBankPaycash <no use>
shopSumAmount shop_amount
shopSumCurrencyPaycash shop_currency
shopSumBankPaycash <no use>
paymentPayerCode payer_code
paymentDatetime <no use>
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)

@ -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)

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from django.dispatch import Signal
payment_process = Signal()
payment_completed = Signal()

@ -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']

@ -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']

@ -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']

@ -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']

@ -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'),
)

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

@ -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()
Loading…
Cancel
Save