import logging import os import requests from django.conf import settings from django.db import transaction from django.utils import timezone from yandex_money.models import Payment from finance.loggers import FinanceLogger from finance.models import InvoiceRebilling, Invoice from lms import celery_app finance_logger = FinanceLogger() @celery_app.task def periodic_billing(): finance_logger.info("start periodic billing task") # TODO заюзать Invoice.BILL_STATUSES invoices = InvoiceRebilling.objects.filter(method='Y', status='W') # TODO тут был exclude('F') то есть все неоплаченные... но это не верно! for invoice in invoices.filter(expected_date__lt=timezone.now()): # выбираем все необработанные из прошлого with transaction.atomic(): try: _yandex_repeat_card_payment(invoice) except Exception as exc: finance_logger.exception('YandexMoney repeatCardPayment Exception', invoice_id=invoice.id) invoice.comment = 'Ошибка при попытке повторного платежа, свяжитесь с клиентской службой' invoice.save() def _yandex_repeat_card_payment(invoice): user = invoice.bill.user yandex_pay = Payment.objects.create( order_amount=invoice.price, customer_number=user.id, user=user, cps_email=user.email, shop_id=settings.YANDEX_MONEY_REBILLING_SHOP_ID, scid=settings.YANDEX_MONEY_REBILLING_SCID ) invoice.yandex_pay = yandex_pay finance_logger.info('YandexMoney repeatCardPayment start', invoice_id=invoice.id) resp = requests.post( url=settings.YANDEX_MONEY_MWS_URL + 'repeatCardPayment', data={ 'clientOrderId': invoice.id, # уникальное возрастающее целое число 'invoiceId': invoice.key, 'amount': invoice.price, 'orderNumber': invoice.yandex_pay.order_number }, cert=( os.path.join(settings.SSL_ROOT, 'skillbox.cer'), os.path.join(settings.SSL_ROOT, 'skillbox.key') ), verify=os.path.join(settings.SSL_ROOT, 'yamoney_chain.cer') ) resp_text = resp.text finance_logger.info('YandexMoney repeatCardPayment response', invoice_id=invoice.id, response=resp_text, code=resp.status_code, ) try: _check_yandex_response_status(invoice, resp_text) except Exception as exc: finance_logger.exception("Can't parse yandex response", invoice_id=invoice.id, response=resp_text) def _check_yandex_response_status(invoice, resp_text): from xml.dom import minidom dom = minidom.parseString(resp_text) dom.normalize() resp_node = dom.getElementsByTagName("repeatCardPaymentResponse")[0] status = resp_node.getAttribute('status') if status != '0': error = resp_node.getAttribute('error') processed_dt = resp_node.getAttribute('processedDT') tech_message = resp_node.getAttribute('techMessage') invoice.status += Invoice.BILL_STATUSES[-1][0] invoice.comment += 'Yandex Kassa: ошибка № {}, сообщение {} от {}'.format(error, tech_message, processed_dt)