def check_and_finish_payment(payment_id):
    """
    Контрольная проверка счета (запрос к серверу soap) и завершение транзакции
    """
    logger = logging.getLogger('payment')
    logger.debug('finish payment task: call for payment: {0}'\
                 .format(str(payment_id)))

    payment = get_object_or_None(QiwiPayment, id=payment_id)
    if payment is None:
        logger.error('finish payment task: payment not found! {0}'\
                     .format(str(payment_id)))
        return

    client = QiwiSoapClient(**settings.QIWI)
    result = client.checkBill(int(payment.id))
    if 'error' in result:
        payment.finish(QiwiPaymentStatus.REJECTED_UNKNOWN_ERROR,
                       successful=False,
                       description=result.get('error'))
    else:
        # проверка что счет оплачен
        try:
            status = int(result.get('status'))
        except (TypeError, ValueError):
            # формат статуса не совпадает с ожидаемым, прервать транзакцию
            logger.error('finish payment task: payment {0} has unknown qiwi status {1}'\
                     .format(str(payment_id, result.get('status'))))
            payment.finish(QiwiPaymentStatus.REJECTED_UNKNOWN_ERROR,
                           successful=False,
                           description="has unknown qiwi status {1}"\
                                        .format(result.get('status')))
            return

        if status == QiwiPaymentStatus.HAS_PAID:
            # суммы должны совпадать
            if payment.charge_amount == result.get('amount'):
                payment.finish(
                    status,
                    description='Correct finished. Created on qiwi: {0}, lifetime: {1}'\
                                .format(result.get('date_str'),
                                        result.get('lifetime_str')))
            else:
                logger.error('finish payment task: payment: {0} not found! Amount not equal! qiwi amount: {1}'\
                             .format(str(payment_id),
                                     result.get('amount')))
                payment.finish(
                    status,
                    successful=False,
                    description='Error! Amount changed! {0} != {1}'\
                                .format(payment.charge_amount, result.get('amount')))
        else:
            # такого статуса не должно случаться, только если у qiwi будут проблемы
            logger.error('finish payment task: payment: {0} has status {1} after successful paymen'\
                         .format(payment.id, status))
            payment.log_status(
                status,
                description="qiwi: {0}"\
                    .format(QiwiPaymentStatus.status_msg_by_code(status)))
def check_order_create(payment_id):
    logger = logging.getLogger('payment')
    logger.debug('check payment create task: call for payment: {0}'\
                 .format(str(payment_id)))

    payment = get_object_or_None(QiwiPayment, id=payment_id)
    if payment is None:
        logger.error('check payment create task: payment not found! {0}'\
                     .format(str(payment_id)))
        return

    client = QiwiSoapClient(**settings.QIWI)
    result = client.checkBill(int(payment.id))
    if 'error' in result:
        payment.finish(
            successful=False,
            QiwiPaymentStatus.REJECTED_UNKNOWN_ERROR,
            description=result.get('error'))
    else:
        try:
            status = int(result.get('status'))
        except (TypeError, ValueError):
            # формат статуса не совпадает с ожидаемым, прервать транзакцию
            logger.error('check payment create task: payment {0} has unknown qiwi status {1}'\
                     .format(str(payment_id, result.get('status'))))
            return
        payment.qiwi_status = status
        payment.save()
        logger.debug('check payment create task: payment {0} set qiwi status {1}'\
                     .format(str(payment_id, status)))
        # может быть ошибка счета сразу после создания, в этом случае транзакция завершится
        if QiwiPaymentStatus.is_error(status):
            logger.error('check payment create task: payment {0} has error qiwi status {1}'\
                     .format(str(payment_id, status)))
            payment.finish(
                status,
                successful=False,
                description="qiwi: {0}"\
                    .format(QiwiPaymentStatus.status_msg_by_code(status)))
 def finish(self, status, successful=True, description=None):
     if successful:
         self.successful = datetime_now()
         self.failed = None
     else:
         self.failed = datetime_now()
         self.successful = None
     if description:
         self.status_description = smart_unicode(description)[:255]
     else:
         self.status_description =\
         smart_unicode(QiwiPaymentStatus.status_msg_by_code(status))[:255]
     self.qiwi_status = status
     self.save()
    def checkBill(self, payment_id):
        """
        Запрос на получение информации о выставленном счете.
        В случае успешной обработки запроса в параметре status указывается положительное число - статус платежа,
        в случае ошибки - отрицательное число с кодом ошибки.
        Возвращает dict с обязательным 'status', с возможным описанием ошибки 'error'
        payment_id - уникальный идентификатор счета
        """
        if not isinstance(payment_id, int) or payment_id < 1:
            raise ValueError(self.__message_format('Payment id incorrect!'))

        res = self.soappy_connection.checkBill(
            login=self.__configuration.get('login'),
            password=self.__configuration.get('password'),
            txn=str(payment_id))

        payment_data = {}
        try:
            payment_data.update(status=int(res.status))
        except (TypeError, ValueError):
            return {'error': 'Answer of createBill has incorrect format of status!',
                    'status': QiwiPaymentStatus.REJECTED_UNKNOWN_ERROR}

        if payment_data.get('status') < 0:
            return {'error': QiwiPaymentStatus.status_msg_by_code(
                                abs(payment_data.get('status'))),
                    'status': abs(payment_data.get('status'))}

        try:
            payment_data.update(
                user = res.user,
                date = datetime.strptime(res.date, self.__datetime_format).replace(tzinfo=utc),
                date_str = res.date,
                lifetime = datetime.strptime(res.lifetime, self.__datetime_format).replace(tzinfo=utc),
                lifetime_str = res.lifetime,
                amount = Decimal(res.amount)
            )
        except (TypeError, ValueError):
            return {'error': 'Answer of createBill has incorrect data format!',
                    'status': QiwiPaymentStatus.REJECTED_UNKNOWN_ERROR}
        return payment_data