Повторные платежи

remotes/origin/yandex_rebiling
Evgeniy Shabanov 8 years ago
parent c27f4fb103
commit e6d4988b9e
  1. 7
      finance/admin.py
  2. 2
      finance/models.py
  3. 4
      finance/signals.py
  4. 54
      finance/tasks.py
  5. 7
      finance/views.py

@ -3,5 +3,10 @@ from django.contrib import admin
from finance.models import Bill, Invoice
class InvoiceAdmin(admin.ModelAdmin):
list_display = ('__str__', 'rebilling_on', 'rebilling')
admin.site.register(Bill)
admin.site.register(Invoice)
admin.site.register(Invoice, InvoiceAdmin)

@ -54,6 +54,8 @@ class Invoice(models.Model):
bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт")
is_open = models.BooleanField(default=True, verbose_name="Открывает ли платёж курс")
date = models.DateTimeField(auto_now_add=True)
rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False)
rebilling = models.BooleanField(verbose_name='Повторный платеж', default=False, editable=False)
def __str__(self):
return '%s:%s %s' % (self.id, self.get_status_display(), self.bill.user)

@ -16,7 +16,7 @@ def invoice_signal(instance, **kwargs):
course = Course.objects.get(token=instance.bill.course_token)
if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P':
if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P' and not instance.rebilling:
msg = EmailMessage(
'Вам выставлен новый счёт',
'''Вам выставлен счёт, для оплаты перейдите по ссылке
@ -28,7 +28,7 @@ def invoice_signal(instance, **kwargs):
)
msg.send()
if instance.status == 'F':
if instance.status == 'F' and not instance.rebilling:
if instance.is_open:
try:
Progress.objects.get(

@ -0,0 +1,54 @@
import json
from datetime import datetime, timedelta
from django_celery_beat.models import CrontabSchedule, PeriodicTask
from yandex_money.models import Payment
from finance.models import Invoice
from lms import celery_app
def setup_periodic_billing(invoice_id):
# TODO: настроить периодичность и срок окончания
schedule, _ = CrontabSchedule.objects.get_or_create(
minute='*',
hour='*',
day_of_week='*',
day_of_month='*',
month_of_year='*'
)
PeriodicTask.objects.create(
crontab=schedule,
name='Periodic billing #{}'.format(invoice_id),
task='finance.tasks.periodic_billing',
args=json.dumps([invoice_id]),
expires=datetime.utcnow() + timedelta(minutes=5)
)
@celery_app.task
def periodic_billing(invoice_id):
try:
sample = Invoice.objects.get(id=invoice_id)
except Invoice.DoesNotExist:
raise ValueError('Платеж с id={} не найден'.format(invoice_id))
bill = sample.bill
invoice = Invoice.objects.create(
status='P',
price=sample.price,
method=sample.method,
rebilling=True,
bill=bill
)
if invoice.method == 'Y':
user = bill.user
yandex_pay = Payment.objects.create(
invoice_id=sample.yandex_pay.invoice_id,
order_amount=invoice.price,
customer_number=user.id,
user=user,
cps_email=user.email
)
invoice.yandex_pay = yandex_pay
invoice.save()
# TODO: запрос repeatCardPayment

@ -17,6 +17,7 @@ from django.conf import settings
from courses.api import CourseParamsApi
from finance.models import Bill, Invoice
from finance.serializers import BillSerializer, InvoiceSerializer
from finance.tasks import setup_periodic_billing
from lms.global_decorators import transaction_decorator
from lms.tools import get_real_name
from django.utils import timezone
@ -155,6 +156,7 @@ class YandexPay(APIView):
'customerNumber': pay.customer_number,
'orderNumber': pay.order_number,
'cps_email': pay.cps_email,
'rebillingOn': pay.invoice.rebilling_on,
'shopSuccessURL': settings.YANDEX_MONEY_SUCCESS_URL,
'shopFailURL': settings.YANDEX_MONEY_FAIL_URL,
})
@ -273,12 +275,17 @@ class YandexAvisoView(APIView):
pay.shop_amount = data['shopSumAmount']
pay.status = Payment.STATUS.SUCCESS
pay.invoice_id = data['invoiceId']
pay.save()
xml_res = """<paymentAvisoResponse performedDatetime="%s" code="0" invoiceId="%s" shopId="%s"/>
""" % (pay.performed_datetime, str(data['invoiceId']), str(pay.shop_id))
logger_yandex.info(xml_res)
invoice = pay.invoice
if invoice.rebilling_on:
setup_periodic_billing(invoice.id)
return HttpResponse(xml_res, content_type='application/xml')

Loading…
Cancel
Save