"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from flexprice_py import errors, models, utils
from flexprice_py._hooks import HookContext
from flexprice_py.types import OptionalNullable, UNSET
from flexprice_py.utils.unmarshal_json_response import unmarshal_json_response
import httpx
from typing import Any, Dict, List, Mapping, Optional, Union


class Invoices(BaseSDK):
    def get_customer_invoice_summary(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoCustomerMultiCurrencyInvoiceSummary:
        r"""Get customer invoice summary

        Use when showing a customer's invoice overview (e.g. billing portal or balance summary). Includes totals and multi-currency breakdown.

        :param id: Customer ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetCustomerInvoiceSummaryRequest(
            id=id,
        )

        req = self._build_request(
            method="GET",
            path="/customers/{id}/invoices/summary",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getCustomerInvoiceSummary",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoCustomerMultiCurrencyInvoiceSummary, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def get_customer_invoice_summary_async(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoCustomerMultiCurrencyInvoiceSummary:
        r"""Get customer invoice summary

        Use when showing a customer's invoice overview (e.g. billing portal or balance summary). Includes totals and multi-currency breakdown.

        :param id: Customer ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetCustomerInvoiceSummaryRequest(
            id=id,
        )

        req = self._build_request_async(
            method="GET",
            path="/customers/{id}/invoices/summary",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getCustomerInvoiceSummary",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoCustomerMultiCurrencyInvoiceSummary, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def create_invoice(
        self,
        *,
        amount_due: str,
        currency: str,
        customer_id: str,
        subtotal: str,
        total: str,
        amount_paid: Optional[str] = None,
        billing_period: Optional[str] = None,
        billing_reason: Optional[models.components.InvoiceBillingReason] = None,
        coupons: Optional[List[str]] = None,
        description: Optional[str] = None,
        due_date: Optional[str] = None,
        idempotency_key: Optional[str] = None,
        invoice_coupons: Optional[
            Union[
                List[models.components.DtoInvoiceCoupon],
                List[models.components.DtoInvoiceCouponTypedDict],
            ]
        ] = None,
        invoice_number: Optional[str] = None,
        invoice_pdf_url: Optional[str] = None,
        invoice_status: Optional[models.components.InvoiceStatus] = None,
        invoice_type: Optional[models.components.InvoiceType] = None,
        line_item_coupons: Optional[
            Union[
                List[models.components.DtoInvoiceLineItemCoupon],
                List[models.components.DtoInvoiceLineItemCouponTypedDict],
            ]
        ] = None,
        line_items: Optional[
            Union[
                List[models.components.DtoCreateInvoiceLineItemRequest],
                List[models.components.DtoCreateInvoiceLineItemRequestTypedDict],
            ]
        ] = None,
        metadata: Optional[Dict[str, str]] = None,
        payment_status: Optional[models.components.PaymentStatus] = None,
        period_end: Optional[str] = None,
        period_start: Optional[str] = None,
        prepared_tax_rates: Optional[
            Union[
                List[models.components.DtoTaxRateResponse],
                List[models.components.DtoTaxRateResponseTypedDict],
            ]
        ] = None,
        subscription_id: Optional[str] = None,
        tax_rate_overrides: Optional[
            Union[
                List[models.components.DtoTaxRateOverride],
                List[models.components.DtoTaxRateOverrideTypedDict],
            ]
        ] = None,
        tax_rates: Optional[List[str]] = None,
        total_prepaid_applied: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Create one-off invoice

        Use when creating a manual or one-off invoice (e.g. custom charge or non-recurring billing). Invoice is created in draft; finalize when ready.

        :param amount_due: amount_due is the total amount that needs to be paid for this invoice
        :param currency: currency is the three-letter ISO currency code (e.g., USD, EUR) for the invoice
        :param customer_id: customer_id is the unique identifier of the customer this invoice belongs to
        :param subtotal: subtotal is the amount before taxes and discounts are applied
        :param total: total is the total amount of the invoice including taxes and discounts
        :param amount_paid: amount_paid is the amount that has been paid towards this invoice
        :param billing_period: billing_period is the period this invoice covers (e.g., \"monthly\", \"yearly\")
        :param billing_reason:
        :param coupons: coupons
        :param description: description is an optional text description of the invoice
        :param due_date: due_date is the date by which payment is expected
        :param idempotency_key: idempotency_key is an optional key used to prevent duplicate invoice creation
        :param invoice_coupons: Invoice Coupons
        :param invoice_number: invoice_number is an optional human-readable identifier for the invoice
        :param invoice_pdf_url: invoice_pdf_url is the URL where customers can download the PDF version of this invoice
        :param invoice_status:
        :param invoice_type:
        :param line_item_coupons: Invoice Line Item Coupons
        :param line_items: line_items contains the individual items that make up this invoice
        :param metadata:
        :param payment_status:
        :param period_end: period_end is the end date of the billing period
        :param period_start: period_start is the start date of the billing period
        :param prepared_tax_rates: prepared_tax_rates contains the tax rates pre-resolved by the caller (e.g., billing service)
        :param subscription_id: subscription_id is the optional unique identifier of the subscription associated with this invoice
        :param tax_rate_overrides: tax_rate_overrides is the tax rate overrides to be applied to the invoice
        :param tax_rates: tax_rates
        :param total_prepaid_applied: total_prepaid_applied is the total amount of prepaid applied to this invoice.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.DtoCreateInvoiceRequest(
            amount_due=amount_due,
            amount_paid=amount_paid,
            billing_period=billing_period,
            billing_reason=billing_reason,
            coupons=coupons,
            currency=currency,
            customer_id=customer_id,
            description=description,
            due_date=due_date,
            idempotency_key=idempotency_key,
            invoice_coupons=utils.get_pydantic_model(
                invoice_coupons, Optional[List[models.components.DtoInvoiceCoupon]]
            ),
            invoice_number=invoice_number,
            invoice_pdf_url=invoice_pdf_url,
            invoice_status=invoice_status,
            invoice_type=invoice_type,
            line_item_coupons=utils.get_pydantic_model(
                line_item_coupons,
                Optional[List[models.components.DtoInvoiceLineItemCoupon]],
            ),
            line_items=utils.get_pydantic_model(
                line_items,
                Optional[List[models.components.DtoCreateInvoiceLineItemRequest]],
            ),
            metadata=metadata,
            payment_status=payment_status,
            period_end=period_end,
            period_start=period_start,
            prepared_tax_rates=utils.get_pydantic_model(
                prepared_tax_rates, Optional[List[models.components.DtoTaxRateResponse]]
            ),
            subscription_id=subscription_id,
            subtotal=subtotal,
            tax_rate_overrides=utils.get_pydantic_model(
                tax_rate_overrides, Optional[List[models.components.DtoTaxRateOverride]]
            ),
            tax_rates=tax_rates,
            total=total,
            total_prepaid_applied=total_prepaid_applied,
        )

        req = self._build_request(
            method="POST",
            path="/invoices",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.components.DtoCreateInvoiceRequest
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def create_invoice_async(
        self,
        *,
        amount_due: str,
        currency: str,
        customer_id: str,
        subtotal: str,
        total: str,
        amount_paid: Optional[str] = None,
        billing_period: Optional[str] = None,
        billing_reason: Optional[models.components.InvoiceBillingReason] = None,
        coupons: Optional[List[str]] = None,
        description: Optional[str] = None,
        due_date: Optional[str] = None,
        idempotency_key: Optional[str] = None,
        invoice_coupons: Optional[
            Union[
                List[models.components.DtoInvoiceCoupon],
                List[models.components.DtoInvoiceCouponTypedDict],
            ]
        ] = None,
        invoice_number: Optional[str] = None,
        invoice_pdf_url: Optional[str] = None,
        invoice_status: Optional[models.components.InvoiceStatus] = None,
        invoice_type: Optional[models.components.InvoiceType] = None,
        line_item_coupons: Optional[
            Union[
                List[models.components.DtoInvoiceLineItemCoupon],
                List[models.components.DtoInvoiceLineItemCouponTypedDict],
            ]
        ] = None,
        line_items: Optional[
            Union[
                List[models.components.DtoCreateInvoiceLineItemRequest],
                List[models.components.DtoCreateInvoiceLineItemRequestTypedDict],
            ]
        ] = None,
        metadata: Optional[Dict[str, str]] = None,
        payment_status: Optional[models.components.PaymentStatus] = None,
        period_end: Optional[str] = None,
        period_start: Optional[str] = None,
        prepared_tax_rates: Optional[
            Union[
                List[models.components.DtoTaxRateResponse],
                List[models.components.DtoTaxRateResponseTypedDict],
            ]
        ] = None,
        subscription_id: Optional[str] = None,
        tax_rate_overrides: Optional[
            Union[
                List[models.components.DtoTaxRateOverride],
                List[models.components.DtoTaxRateOverrideTypedDict],
            ]
        ] = None,
        tax_rates: Optional[List[str]] = None,
        total_prepaid_applied: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Create one-off invoice

        Use when creating a manual or one-off invoice (e.g. custom charge or non-recurring billing). Invoice is created in draft; finalize when ready.

        :param amount_due: amount_due is the total amount that needs to be paid for this invoice
        :param currency: currency is the three-letter ISO currency code (e.g., USD, EUR) for the invoice
        :param customer_id: customer_id is the unique identifier of the customer this invoice belongs to
        :param subtotal: subtotal is the amount before taxes and discounts are applied
        :param total: total is the total amount of the invoice including taxes and discounts
        :param amount_paid: amount_paid is the amount that has been paid towards this invoice
        :param billing_period: billing_period is the period this invoice covers (e.g., \"monthly\", \"yearly\")
        :param billing_reason:
        :param coupons: coupons
        :param description: description is an optional text description of the invoice
        :param due_date: due_date is the date by which payment is expected
        :param idempotency_key: idempotency_key is an optional key used to prevent duplicate invoice creation
        :param invoice_coupons: Invoice Coupons
        :param invoice_number: invoice_number is an optional human-readable identifier for the invoice
        :param invoice_pdf_url: invoice_pdf_url is the URL where customers can download the PDF version of this invoice
        :param invoice_status:
        :param invoice_type:
        :param line_item_coupons: Invoice Line Item Coupons
        :param line_items: line_items contains the individual items that make up this invoice
        :param metadata:
        :param payment_status:
        :param period_end: period_end is the end date of the billing period
        :param period_start: period_start is the start date of the billing period
        :param prepared_tax_rates: prepared_tax_rates contains the tax rates pre-resolved by the caller (e.g., billing service)
        :param subscription_id: subscription_id is the optional unique identifier of the subscription associated with this invoice
        :param tax_rate_overrides: tax_rate_overrides is the tax rate overrides to be applied to the invoice
        :param tax_rates: tax_rates
        :param total_prepaid_applied: total_prepaid_applied is the total amount of prepaid applied to this invoice.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.DtoCreateInvoiceRequest(
            amount_due=amount_due,
            amount_paid=amount_paid,
            billing_period=billing_period,
            billing_reason=billing_reason,
            coupons=coupons,
            currency=currency,
            customer_id=customer_id,
            description=description,
            due_date=due_date,
            idempotency_key=idempotency_key,
            invoice_coupons=utils.get_pydantic_model(
                invoice_coupons, Optional[List[models.components.DtoInvoiceCoupon]]
            ),
            invoice_number=invoice_number,
            invoice_pdf_url=invoice_pdf_url,
            invoice_status=invoice_status,
            invoice_type=invoice_type,
            line_item_coupons=utils.get_pydantic_model(
                line_item_coupons,
                Optional[List[models.components.DtoInvoiceLineItemCoupon]],
            ),
            line_items=utils.get_pydantic_model(
                line_items,
                Optional[List[models.components.DtoCreateInvoiceLineItemRequest]],
            ),
            metadata=metadata,
            payment_status=payment_status,
            period_end=period_end,
            period_start=period_start,
            prepared_tax_rates=utils.get_pydantic_model(
                prepared_tax_rates, Optional[List[models.components.DtoTaxRateResponse]]
            ),
            subscription_id=subscription_id,
            subtotal=subtotal,
            tax_rate_overrides=utils.get_pydantic_model(
                tax_rate_overrides, Optional[List[models.components.DtoTaxRateOverride]]
            ),
            tax_rates=tax_rates,
            total=total,
            total_prepaid_applied=total_prepaid_applied,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.components.DtoCreateInvoiceRequest
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def get_invoice_preview(
        self,
        *,
        subscription_id: str,
        period_end: Optional[str] = None,
        period_start: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Get invoice preview

        Use when showing a customer what they will be charged (e.g. preview before checkout or plan change). No invoice is created.

        :param subscription_id: subscription_id is the unique identifier of the subscription to preview invoice for
        :param period_end: period_end is the optional end date of the period to preview
        :param period_start: period_start is the optional start date of the period to preview
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.DtoGetPreviewInvoiceRequest(
            period_end=period_end,
            period_start=period_start,
            subscription_id=subscription_id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/preview",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.components.DtoGetPreviewInvoiceRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoicePreview",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def get_invoice_preview_async(
        self,
        *,
        subscription_id: str,
        period_end: Optional[str] = None,
        period_start: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Get invoice preview

        Use when showing a customer what they will be charged (e.g. preview before checkout or plan change). No invoice is created.

        :param subscription_id: subscription_id is the unique identifier of the subscription to preview invoice for
        :param period_end: period_end is the optional end date of the period to preview
        :param period_start: period_start is the optional start date of the period to preview
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.DtoGetPreviewInvoiceRequest(
            period_end=period_end,
            period_start=period_start,
            subscription_id=subscription_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/preview",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.components.DtoGetPreviewInvoiceRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoicePreview",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def query_invoice(
        self,
        *,
        amount_due_gt: Optional[float] = None,
        amount_remaining_gt: Optional[float] = None,
        customer_id: Optional[str] = None,
        end_time: Optional[str] = None,
        expand: Optional[str] = None,
        external_customer_id: Optional[str] = None,
        filters: Optional[
            Union[
                List[models.components.FilterCondition],
                List[models.components.FilterConditionTypedDict],
            ]
        ] = None,
        invoice_ids: Optional[List[str]] = None,
        invoice_status: Optional[List[models.components.InvoiceStatus]] = None,
        invoice_type: Optional[models.components.InvoiceType] = None,
        limit: Optional[int] = None,
        offset: Optional[int] = None,
        order: Optional[models.components.InvoiceFilterOrder] = None,
        payment_status: Optional[List[models.components.PaymentStatus]] = None,
        period_end_gte: Optional[str] = None,
        period_end_lte: Optional[str] = None,
        period_start_gte: Optional[str] = None,
        period_start_lte: Optional[str] = None,
        skip_line_items: Optional[bool] = None,
        sort: Optional[
            Union[
                List[models.components.SortCondition],
                List[models.components.SortConditionTypedDict],
            ]
        ] = None,
        start_time: Optional[str] = None,
        status: Optional[models.components.Status] = None,
        subscription_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoListInvoicesResponse:
        r"""Query invoices

        Use when listing or searching invoices (e.g. admin view or customer history). Returns a paginated list; supports filtering by customer, status, date range.

        :param amount_due_gt: amount_due_gt filters invoices with a total amount due greater than the specified value
            Useful for finding invoices above a certain threshold or identifying high-value invoices
        :param amount_remaining_gt: amount_remaining_gt filters invoices with an outstanding balance greater than the specified value
            Useful for finding invoices that still have significant unpaid amounts
        :param customer_id: customer_id filters invoices for a specific customer using FlexPrice's internal customer ID
            This is the ID returned by FlexPrice when creating or retrieving customers
        :param end_time:
        :param expand:
        :param external_customer_id: external_customer_id filters invoices for a customer using your system's customer identifier
            This is the ID you provided when creating the customer in FlexPrice
        :param filters:
        :param invoice_ids: invoice_ids restricts results to invoices with the specified IDs
            Use this to retrieve specific invoices when you know their exact identifiers
        :param invoice_status: invoice_status filters by the current state of invoices in their lifecycle
            Multiple statuses can be specified to include invoices in any of the listed states
        :param invoice_type:
        :param limit:
        :param offset:
        :param order:
        :param payment_status: payment_status filters by the payment state of invoices
            Multiple statuses can be specified to include invoices with any of the listed payment states
        :param period_end_gte: period_end_gte filters invoices with period_end >= value
        :param period_end_lte: period_end_lte filters invoices with period_end <= value
        :param period_start_gte: period_start_gte filters invoices with period_start >= value
        :param period_start_lte: period_start_lte filters invoices with period_start <= value
        :param skip_line_items: SkipLineItems if true, will not include line items in the response
        :param sort:
        :param start_time:
        :param status:
        :param subscription_id: subscription_id filters invoices generated for a specific subscription
            Only returns invoices that were created as part of the specified subscription's billing
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.InvoiceFilter(
            amount_due_gt=amount_due_gt,
            amount_remaining_gt=amount_remaining_gt,
            customer_id=customer_id,
            end_time=end_time,
            expand=expand,
            external_customer_id=external_customer_id,
            filters=utils.get_pydantic_model(
                filters, Optional[List[models.components.FilterCondition]]
            ),
            invoice_ids=invoice_ids,
            invoice_status=invoice_status,
            invoice_type=invoice_type,
            limit=limit,
            offset=offset,
            order=order,
            payment_status=payment_status,
            period_end_gte=period_end_gte,
            period_end_lte=period_end_lte,
            period_start_gte=period_start_gte,
            period_start_lte=period_start_lte,
            skip_line_items=skip_line_items,
            sort=utils.get_pydantic_model(
                sort, Optional[List[models.components.SortCondition]]
            ),
            start_time=start_time,
            status=status,
            subscription_id=subscription_id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/search",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.components.InvoiceFilter
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="queryInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoListInvoicesResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def query_invoice_async(
        self,
        *,
        amount_due_gt: Optional[float] = None,
        amount_remaining_gt: Optional[float] = None,
        customer_id: Optional[str] = None,
        end_time: Optional[str] = None,
        expand: Optional[str] = None,
        external_customer_id: Optional[str] = None,
        filters: Optional[
            Union[
                List[models.components.FilterCondition],
                List[models.components.FilterConditionTypedDict],
            ]
        ] = None,
        invoice_ids: Optional[List[str]] = None,
        invoice_status: Optional[List[models.components.InvoiceStatus]] = None,
        invoice_type: Optional[models.components.InvoiceType] = None,
        limit: Optional[int] = None,
        offset: Optional[int] = None,
        order: Optional[models.components.InvoiceFilterOrder] = None,
        payment_status: Optional[List[models.components.PaymentStatus]] = None,
        period_end_gte: Optional[str] = None,
        period_end_lte: Optional[str] = None,
        period_start_gte: Optional[str] = None,
        period_start_lte: Optional[str] = None,
        skip_line_items: Optional[bool] = None,
        sort: Optional[
            Union[
                List[models.components.SortCondition],
                List[models.components.SortConditionTypedDict],
            ]
        ] = None,
        start_time: Optional[str] = None,
        status: Optional[models.components.Status] = None,
        subscription_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoListInvoicesResponse:
        r"""Query invoices

        Use when listing or searching invoices (e.g. admin view or customer history). Returns a paginated list; supports filtering by customer, status, date range.

        :param amount_due_gt: amount_due_gt filters invoices with a total amount due greater than the specified value
            Useful for finding invoices above a certain threshold or identifying high-value invoices
        :param amount_remaining_gt: amount_remaining_gt filters invoices with an outstanding balance greater than the specified value
            Useful for finding invoices that still have significant unpaid amounts
        :param customer_id: customer_id filters invoices for a specific customer using FlexPrice's internal customer ID
            This is the ID returned by FlexPrice when creating or retrieving customers
        :param end_time:
        :param expand:
        :param external_customer_id: external_customer_id filters invoices for a customer using your system's customer identifier
            This is the ID you provided when creating the customer in FlexPrice
        :param filters:
        :param invoice_ids: invoice_ids restricts results to invoices with the specified IDs
            Use this to retrieve specific invoices when you know their exact identifiers
        :param invoice_status: invoice_status filters by the current state of invoices in their lifecycle
            Multiple statuses can be specified to include invoices in any of the listed states
        :param invoice_type:
        :param limit:
        :param offset:
        :param order:
        :param payment_status: payment_status filters by the payment state of invoices
            Multiple statuses can be specified to include invoices with any of the listed payment states
        :param period_end_gte: period_end_gte filters invoices with period_end >= value
        :param period_end_lte: period_end_lte filters invoices with period_end <= value
        :param period_start_gte: period_start_gte filters invoices with period_start >= value
        :param period_start_lte: period_start_lte filters invoices with period_start <= value
        :param skip_line_items: SkipLineItems if true, will not include line items in the response
        :param sort:
        :param start_time:
        :param status:
        :param subscription_id: subscription_id filters invoices generated for a specific subscription
            Only returns invoices that were created as part of the specified subscription's billing
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.components.InvoiceFilter(
            amount_due_gt=amount_due_gt,
            amount_remaining_gt=amount_remaining_gt,
            customer_id=customer_id,
            end_time=end_time,
            expand=expand,
            external_customer_id=external_customer_id,
            filters=utils.get_pydantic_model(
                filters, Optional[List[models.components.FilterCondition]]
            ),
            invoice_ids=invoice_ids,
            invoice_status=invoice_status,
            invoice_type=invoice_type,
            limit=limit,
            offset=offset,
            order=order,
            payment_status=payment_status,
            period_end_gte=period_end_gte,
            period_end_lte=period_end_lte,
            period_start_gte=period_start_gte,
            period_start_lte=period_start_lte,
            skip_line_items=skip_line_items,
            sort=utils.get_pydantic_model(
                sort, Optional[List[models.components.SortCondition]]
            ),
            start_time=start_time,
            status=status,
            subscription_id=subscription_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/search",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.components.InvoiceFilter
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="queryInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoListInvoicesResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def get_invoice(
        self,
        *,
        id: str,
        expand_by_source: Optional[bool] = None,
        group_by: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Get invoice

        Use when loading an invoice for display or editing (e.g. portal or reconciliation). Supports group_by for usage breakdown and force_runtime_recalculation.

        :param id: Invoice ID
        :param expand_by_source: Include source-level price breakdown for usage line items (legacy)
        :param group_by: Group usage breakdown by specified fields (e.g., source, feature_id, properties.org_id)
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetInvoiceRequest(
            id=id,
            expand_by_source=expand_by_source,
            group_by=group_by,
        )

        req = self._build_request(
            method="GET",
            path="/invoices/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def get_invoice_async(
        self,
        *,
        id: str,
        expand_by_source: Optional[bool] = None,
        group_by: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Get invoice

        Use when loading an invoice for display or editing (e.g. portal or reconciliation). Supports group_by for usage breakdown and force_runtime_recalculation.

        :param id: Invoice ID
        :param expand_by_source: Include source-level price breakdown for usage line items (legacy)
        :param group_by: Group usage breakdown by specified fields (e.g., source, feature_id, properties.org_id)
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetInvoiceRequest(
            id=id,
            expand_by_source=expand_by_source,
            group_by=group_by,
        )

        req = self._build_request_async(
            method="GET",
            path="/invoices/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def update_invoice(
        self,
        *,
        id: str,
        due_date: Optional[str] = None,
        invoice_pdf_url: Optional[str] = None,
        metadata: Optional[Dict[str, str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Update invoice

        Use when updating invoice metadata or due date (e.g. PDF URL, net terms). For paid invoices only safe fields can be updated.

        :param id: Invoice ID
        :param due_date:
        :param invoice_pdf_url: invoice_pdf_url is the URL where customers can download the PDF version of this invoice
        :param metadata:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.UpdateInvoiceRequest(
            id=id,
            body=models.components.DtoUpdateInvoiceRequest(
                due_date=due_date,
                invoice_pdf_url=invoice_pdf_url,
                metadata=metadata,
            ),
        )

        req = self._build_request(
            method="PUT",
            path="/invoices/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.components.DtoUpdateInvoiceRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def update_invoice_async(
        self,
        *,
        id: str,
        due_date: Optional[str] = None,
        invoice_pdf_url: Optional[str] = None,
        metadata: Optional[Dict[str, str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Update invoice

        Use when updating invoice metadata or due date (e.g. PDF URL, net terms). For paid invoices only safe fields can be updated.

        :param id: Invoice ID
        :param due_date:
        :param invoice_pdf_url: invoice_pdf_url is the URL where customers can download the PDF version of this invoice
        :param metadata:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.UpdateInvoiceRequest(
            id=id,
            body=models.components.DtoUpdateInvoiceRequest(
                due_date=due_date,
                invoice_pdf_url=invoice_pdf_url,
                metadata=metadata,
            ),
        )

        req = self._build_request_async(
            method="PUT",
            path="/invoices/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.components.DtoUpdateInvoiceRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def trigger_invoice_comms_webhook(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Trigger invoice communication webhook

        Use when sending an invoice to the customer (e.g. trigger email or Slack). Payload includes full invoice details for your integration.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.TriggerInvoiceCommsWebhookRequest(
            id=id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/{id}/comms/trigger",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="triggerInvoiceCommsWebhook",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def trigger_invoice_comms_webhook_async(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Trigger invoice communication webhook

        Use when sending an invoice to the customer (e.g. trigger email or Slack). Payload includes full invoice details for your integration.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.TriggerInvoiceCommsWebhookRequest(
            id=id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/{id}/comms/trigger",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="triggerInvoiceCommsWebhook",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def finalize_invoice(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Finalize invoice

        Use when locking an invoice for payment (e.g. after review). Once finalized, line items are locked; invoice can be paid or voided.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.FinalizeInvoiceRequest(
            id=id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/{id}/finalize",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="finalizeInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def finalize_invoice_async(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Finalize invoice

        Use when locking an invoice for payment (e.g. after review). Once finalized, line items are locked; invoice can be paid or voided.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.FinalizeInvoiceRequest(
            id=id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/{id}/finalize",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="finalizeInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def update_invoice_payment_status(
        self,
        *,
        id: str,
        payment_status: models.components.PaymentStatus,
        amount: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Update invoice payment status

        Use when reconciling payment status from an external gateway or manual entry (e.g. mark paid after bank confirmation).

        :param id: Invoice ID
        :param payment_status:
        :param amount: amount is the optional payment amount to record
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.UpdateInvoicePaymentStatusRequest(
            id=id,
            body=models.components.DtoUpdatePaymentStatusRequest(
                amount=amount,
                payment_status=payment_status,
            ),
        )

        req = self._build_request(
            method="PUT",
            path="/invoices/{id}/payment",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.components.DtoUpdatePaymentStatusRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateInvoicePaymentStatus",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def update_invoice_payment_status_async(
        self,
        *,
        id: str,
        payment_status: models.components.PaymentStatus,
        amount: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Update invoice payment status

        Use when reconciling payment status from an external gateway or manual entry (e.g. mark paid after bank confirmation).

        :param id: Invoice ID
        :param payment_status:
        :param amount: amount is the optional payment amount to record
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.UpdateInvoicePaymentStatusRequest(
            id=id,
            body=models.components.DtoUpdatePaymentStatusRequest(
                amount=amount,
                payment_status=payment_status,
            ),
        )

        req = self._build_request_async(
            method="PUT",
            path="/invoices/{id}/payment",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.components.DtoUpdatePaymentStatusRequest,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateInvoicePaymentStatus",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def attempt_invoice_payment(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Attempt invoice payment

        Use when paying an invoice with the customer's wallet balance (e.g. prepaid credits or balance applied at checkout).

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.AttemptInvoicePaymentRequest(
            id=id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/{id}/payment/attempt",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="attemptInvoicePayment",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def attempt_invoice_payment_async(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Attempt invoice payment

        Use when paying an invoice with the customer's wallet balance (e.g. prepaid credits or balance applied at checkout).

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.AttemptInvoicePaymentRequest(
            id=id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/{id}/payment/attempt",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="attemptInvoicePayment",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def get_invoice_pdf(
        self,
        *,
        id: str,
        url: Optional[bool] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> httpx.Response:
        r"""Get invoice PDF

        Use when delivering an invoice PDF to the customer (e.g. email attachment or download). Use url=true for a presigned URL instead of binary.

        :param id: Invoice ID
        :param url: Return presigned URL from s3 instead of PDF
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetInvoicePdfRequest(
            id=id,
            url=url,
        )

        req = self._build_request(
            method="GET",
            path="/invoices/{id}/pdf",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="*/*",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoicePdf",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            stream=True,
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "*/*"):
            return http_res
        if utils.match_response(http_res, ["400", "404", "4XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, ["500", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        http_res_text = utils.stream_to_text(http_res)
        raise errors.FlexpriceDefaultError(
            "Unexpected response received", http_res, http_res_text
        )

    async def get_invoice_pdf_async(
        self,
        *,
        id: str,
        url: Optional[bool] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> httpx.Response:
        r"""Get invoice PDF

        Use when delivering an invoice PDF to the customer (e.g. email attachment or download). Use url=true for a presigned URL instead of binary.

        :param id: Invoice ID
        :param url: Return presigned URL from s3 instead of PDF
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.GetInvoicePdfRequest(
            id=id,
            url=url,
        )

        req = self._build_request_async(
            method="GET",
            path="/invoices/{id}/pdf",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="*/*",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getInvoicePdf",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            stream=True,
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "*/*"):
            return http_res
        if utils.match_response(http_res, ["400", "404", "4XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, ["500", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        http_res_text = await utils.stream_to_text_async(http_res)
        raise errors.FlexpriceDefaultError(
            "Unexpected response received", http_res, http_res_text
        )

    def recalculate_invoice(
        self,
        *,
        id: str,
        finalize: Optional[bool] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Recalculate invoice

        Use when subscription or usage data changed and you need to refresh a draft invoice before finalizing. Optional finalize=true to lock after recalc.

        :param id: Invoice ID
        :param finalize: Whether to finalize the invoice after recalculation (default: true)
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.RecalculateInvoiceRequest(
            id=id,
            finalize=finalize,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/{id}/recalculate",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="recalculateInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def recalculate_invoice_async(
        self,
        *,
        id: str,
        finalize: Optional[bool] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoInvoiceResponse:
        r"""Recalculate invoice

        Use when subscription or usage data changed and you need to refresh a draft invoice before finalizing. Optional finalize=true to lock after recalc.

        :param id: Invoice ID
        :param finalize: Whether to finalize the invoice after recalculation (default: true)
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.RecalculateInvoiceRequest(
            id=id,
            finalize=finalize,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/{id}/recalculate",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="recalculateInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoInvoiceResponse, http_res
            )
        if utils.match_response(http_res, ["400", "404"], "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    def void_invoice(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Void invoice

        Use when cancelling an invoice (e.g. order cancelled or duplicate). Only unpaid invoices can be voided.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.VoidInvoiceRequest(
            id=id,
        )

        req = self._build_request(
            method="POST",
            path="/invoices/{id}/void",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="voidInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)

    async def void_invoice_async(
        self,
        *,
        id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.components.DtoSuccessResponse:
        r"""Void invoice

        Use when cancelling an invoice (e.g. order cancelled or duplicate). Only unpaid invoices can be voided.

        :param id: Invoice ID
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.operations.VoidInvoiceRequest(
            id=id,
        )

        req = self._build_request_async(
            method="POST",
            path="/invoices/{id}/void",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="voidInvoice",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.components.DtoSuccessResponse, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.ErrorsErrorResponseData, http_res
            )
            raise errors.ErrorsErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.FlexpriceDefaultError(
                "API error occurred", http_res, http_res_text
            )

        raise errors.FlexpriceDefaultError("Unexpected response received", http_res)
