class ZyndPayError(Exception):
    def __init__(self, message, status_code=None, request_id=None, code=None, raw_body=None):
        super().__init__(message)
        self.message = message
        self.status_code = status_code
        self.request_id = request_id
        self.code = code
        self.raw_body = raw_body


class AuthenticationError(ZyndPayError):
    def __init__(self, message, request_id=None, code='UNAUTHORIZED', raw_body=None):
        super().__init__(message, status_code=401, request_id=request_id, code=code, raw_body=raw_body)


class ValidationError(ZyndPayError):
    def __init__(self, message, request_id=None, code='VALIDATION_ERROR', details=None, raw_body=None):
        super().__init__(message, status_code=400, request_id=request_id, code=code, raw_body=raw_body)
        self.details = details


class NotFoundError(ZyndPayError):
    def __init__(self, message, request_id=None, code='NOT_FOUND', raw_body=None):
        super().__init__(message, status_code=404, request_id=request_id, code=code, raw_body=raw_body)


class RateLimitError(ZyndPayError):
    def __init__(self, message, retry_after=None, request_id=None, code='RATE_LIMIT_EXCEEDED', raw_body=None):
        super().__init__(message, status_code=429, request_id=request_id, code=code, raw_body=raw_body)
        self.retry_after = retry_after


class ConflictError(ZyndPayError):
    def __init__(self, message, request_id=None, code='CONFLICT', raw_body=None):
        super().__init__(message, status_code=409, request_id=request_id, code=code, raw_body=raw_body)
