from core.Errors import InvoiceExpiredError, InvoicePaymentFailedError, InvoiceNotFoundError from core.observers.ConnectionObserver import ConnectionObserver from core.observers.InvoiceObserver import InvoiceObserver from core.services.WebServiceApiService import WebServiceApiService from typing import Optional import time class InvoiceController: @staticmethod def get(billing_code: str, proxies: Optional[dict] = None): return WebServiceApiService.get_invoice(billing_code, proxies) @staticmethod def handle_payment(billing_code: str, invoice_observer: InvoiceObserver = None, connection_observer: ConnectionObserver = None): from core.controllers.ConnectionController import ConnectionController return ConnectionController.with_preferred_connection(billing_code, task=InvoiceController.__handle_payment, invoice_observer=invoice_observer, connection_observer=connection_observer) @staticmethod def __handle_payment(billing_code: str, invoice_observer: Optional[InvoiceObserver] = None, proxies: Optional[dict] = None): invoice = None for index in range(1, 10): invoice = WebServiceApiService.get_invoice(billing_code, proxies) if invoice is None: time.sleep(5.0) else: break if invoice is None: raise InvoiceNotFoundError('The invoice in question could not be found.') invoice.status = 'new' if invoice_observer is not None: invoice_observer.notify('retrieved', invoice) while invoice.status == 'new': invoice = WebServiceApiService.get_invoice(billing_code, proxies) time.sleep(15.0) if invoice.status == 'expired': raise InvoiceExpiredError('The invoice in question has expired.') if invoice.status == 'processing': if invoice_observer is not None: invoice_observer.notify('processing', invoice) while invoice.status == 'processing': invoice = WebServiceApiService.get_invoice(billing_code, proxies) time.sleep(15.0) if invoice.status != 'settled': raise InvoicePaymentFailedError('The invoice payment has failed. Please contact support.') else: if invoice_observer is not None: invoice_observer.notify('settled', invoice) for attempt in range(1, 10): subscription = WebServiceApiService.get_subscription(billing_code, proxies) if subscription is not None: return subscription else: time.sleep(15.0) return None