You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.3 KiB
81 lines
3.3 KiB
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('Yandex Money repeatCardPayment Exception', invoice_id=invoice.id)
|
|
invoice.comment += 'Yandex Money: Ошибка при попытке повторного платежа, свяжитесь с клиентской службой'
|
|
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 Money: ошибка № {}, сообщение {} от {}'.format(error, tech_message, processed_dt)
|
|
|