Ejemplo n.º 1
0
    def report(self, receipt_uuid):
        """
        The receipt may not yet be processed by the time of the request,
        the calling code should try this method again later.

        :param receipt_uuid: Receipt identifier previously returned by atol
        """
        try:
            response_data = self.request(
                'get', 'report/{uuid}'.format(uuid=receipt_uuid))
        # check for recoverable errors
        except exceptions.AtolClientRequestException as exc:
            logger.info('report request for receipt %s failed with code %s',
                        receipt_uuid, exc.error_data['code'])
            if exc.error_data['code'] in (self.ErrorCode.STATE_CHECK_NOT_FOUND,
                                          self.ErrorCode.BAD_REQUEST):
                raise exceptions.AtolRecoverableError()
            if exc.error_data['code'] == self.ErrorCode.PROCESSING_FAILED:
                logger.info(
                    'report request for receipt %s was not processed: %s; '
                    'Must repeat the request with a new unique value <external_id>',
                    receipt_uuid, exc.response_data.get('text'))
                raise exceptions.AtolReceiptNotProcessed(
                    exc.response_data.get('text'))
            # the rest of the errors are not recoverable
            raise exceptions.AtolUnrecoverableError()
        except Exception as exc:
            logger.info('report request for receipt %s failed due to %s',
                        receipt_uuid, exc)
            raise exceptions.AtolRecoverableError()

        return ReceiptReport(uuid=receipt_uuid, data=response_data)
Ejemplo n.º 2
0
    def _register_new_receipt(self, method_name, request_data):
        try:
            response_data = self.request('post',
                                         method_name,
                                         json=request_data)
        except exceptions.AtolClientRequestException as exc:
            logger.info('%s request with json %s failed with code %s',
                        method_name, request_data, exc.error_data['code'])
            if exc.error_data['code'] in (self.ErrorCode.VALIDATION_ERROR,
                                          self.ErrorCode.BAD_REQUEST):
                raise exceptions.AtolRecoverableError()
            if exc.error_data['code'] == self.ErrorCode.ALREADY_EXISTS:
                logger.info(
                    '%s request with json %s already accepted; uuid: %s',
                    method_name, request_data, exc.response_data['uuid'])
                return NewReceipt(uuid=exc.response_data['uuid'],
                                  data=exc.response_data)
            raise exceptions.AtolUnrecoverableError()
        except Exception as exc:
            logger.warning('%s request with json %s failed due to %s',
                           method_name,
                           request_data,
                           exc,
                           exc_info=True)
            raise exceptions.AtolRecoverableError()

        return NewReceipt(uuid=response_data['uuid'], data=response_data)
Ejemplo n.º 3
0
    def report(self, receipt_uuid):
        """
        The receipt may not yet be processed by the time of the request,
        the calling code should try this method again later.

        :param receipt_uuid: Receipt identifier previously returned by atol
        """
        try:
            response_data = self.request('get', 'report/{uuid}'.format(uuid=receipt_uuid))
        # check for recoverable errors
        except exceptions.AtolClientRequestException as exc:
            logger.info('report request for receipt %s failed with code %s', receipt_uuid, exc.error_data['code'])
            if exc.error_data['code'] in (7, 9, 12, 13, 14, 16):
                raise exceptions.AtolRecoverableError()
            # the rest of the errors are not recoverable
            raise exceptions.AtolUnrecoverableError()
        except Exception as exc:
            logger.info('report request for receipt %s failed due to %s', receipt_uuid, exc)
            raise exceptions.AtolRecoverableError()

        return ReceiptReport(uuid=receipt_uuid, data=response_data)
Ejemplo n.º 4
0
    def sell(self, **params):
        """
        Register a new receipt for given payment details on the atol side.
        Receive receipt uuid for the created receipt.

        :param timestamp: Payment datetime
        :param transaction_uuid: Unique payment id (potentically across all organization projects' payments.
                                 uuid4 should do fine.
        :param purchase_name: Human readable name of the purchased product
        :param purchase_price: The amount in roubles the user was billed with
        :param user_email: User supplied email
        :param user_phone: User supplied phone (may or may not start with +7)
        """
        user_email = params.get('user_email')
        user_phone = params.get('user_phone')
        # receipt must contain either of the two
        if not (user_email or user_phone):
            raise exceptions.AtolPrepRequestException()

        purchase_price = params['purchase_price']
        # convert decimals and strings to float, because atol does not accept those types
        if not isinstance(purchase_price, int):
            purchase_price = float(purchase_price)

        timestamp = params['timestamp']
        if isinstance(timestamp, str):
            timestamp = parse_date(timestamp)

        request_data = {
            'external_id': params['transaction_uuid'],
            'timestamp': timestamp.strftime('%d.%m.%Y %H:%M:%S'),
            'receipt': {
                # user supplied details
                'attributes': {
                    'email': user_email or u'',
                    'phone': user_phone or u'',
                },
                'items': [{
                    'name': params['purchase_name'],
                    'price': purchase_price,
                    'quantity': 1,
                    'sum': purchase_price,
                    'tax': settings.RECEIPTS_ATOL_TAX_NAME,
                }],
                'payments': [{
                    'sum': purchase_price,
                    'type': 1,
                }],
                'total': purchase_price,
            },
            'service': {
                'inn': settings.RECEIPTS_ATOL_INN,
                'callback_url': settings.RECEIPTS_ATOL_CALLBACK_URL or u'',
                'payment_address': settings.RECEIPTS_ATOL_PAYMENT_ADDRESS,
            }
        }

        try:
            response_data = self.request('post', 'sell', json=request_data)
        # check for recoverable errors
        except exceptions.AtolClientRequestException as exc:
            logger.info('sell request with json %s failed with code %s', request_data, exc.error_data['code'])
            if exc.error_data['code'] in (1, 4, 5, 6):
                raise exceptions.AtolRecoverableError()
            if exc.error_data['code'] == 10:
                logger.info('sell request with json %s already accepted; uuid: %s',
                            request_data, exc.response_data['uuid'])
                return NewReceipt(uuid=exc.response_data['uuid'], data=exc.response_data)
            # the rest of the errors are not recoverable
            raise exceptions.AtolUnrecoverableError()
        except Exception as exc:
            logger.warning('sell request with json %s failed due to %s', request_data, exc, exc_info=True)
            raise exceptions.AtolRecoverableError()

        return NewReceipt(uuid=response_data['uuid'], data=response_data)