"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
# @generated-id: c4cf042df32c

from .basesdk import BaseSDK
from jsonpath import JSONPath
from mollie import models, utils
from mollie._hooks import HookContext
from mollie.types import OptionalNullable, UNSET
from mollie.utils import get_security_from_env
from mollie.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union


class Mandates(BaseSDK):
    def create(
        self,
        *,
        customer_id: str,
        idempotency_key: Optional[str] = None,
        mandate_request: Optional[
            Union[models.MandateRequest, models.MandateRequestTypedDict]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MandateResponse:
        r"""Create mandate

        Create a mandate for a specific customer. Mandates allow you to charge a customer's card, PayPal account or bank
        account recurrently.

        It is only possible to create mandates for IBANs and PayPal billing agreements with this endpoint. To create
        mandates for cards, your customers need to perform a 'first payment' with their card.

        :param customer_id: Provide the ID of the related customer.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :param mandate_request:
        :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.CreateMandateRequest(
            customer_id=customer_id,
            idempotency_key=idempotency_key,
            mandate_request=utils.get_pydantic_model(
                mandate_request, Optional[models.MandateRequest]
            ),
        )

        req = self._build_request(
            method="POST",
            path="/customers/{customerId}/mandates",
            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/hal+json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.mandate_request if request is not None else None,
                False,
                True,
                "json",
                Optional[models.MandateRequest],
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="create-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/hal+json"):
            return unmarshal_json_response(models.MandateResponse, http_res)
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def create_async(
        self,
        *,
        customer_id: str,
        idempotency_key: Optional[str] = None,
        mandate_request: Optional[
            Union[models.MandateRequest, models.MandateRequestTypedDict]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MandateResponse:
        r"""Create mandate

        Create a mandate for a specific customer. Mandates allow you to charge a customer's card, PayPal account or bank
        account recurrently.

        It is only possible to create mandates for IBANs and PayPal billing agreements with this endpoint. To create
        mandates for cards, your customers need to perform a 'first payment' with their card.

        :param customer_id: Provide the ID of the related customer.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :param mandate_request:
        :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.CreateMandateRequest(
            customer_id=customer_id,
            idempotency_key=idempotency_key,
            mandate_request=utils.get_pydantic_model(
                mandate_request, Optional[models.MandateRequest]
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/customers/{customerId}/mandates",
            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/hal+json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.mandate_request if request is not None else None,
                False,
                True,
                "json",
                Optional[models.MandateRequest],
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="create-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/hal+json"):
            return unmarshal_json_response(models.MandateResponse, http_res)
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def list(
        self,
        *,
        customer_id: str,
        from_: Optional[str] = None,
        limit: OptionalNullable[int] = UNSET,
        sort: Optional[models.Sorting] = None,
        testmode: Optional[bool] = None,
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        url_override: Optional[str] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.ListMandatesResponse]:
        r"""List mandates

        Retrieve a list of all mandates.

        The results are paginated.

        :param customer_id: Provide the ID of the related customer.
        :param from_: Provide an ID to start the result set from the item with the given ID and onwards. This allows you to paginate the
            result set.
        :param limit: The maximum number of items to return. Defaults to 50 items.
        :param sort: Used for setting the direction of the result set. Defaults to descending order, meaning the results are ordered from
            newest to oldest.
        :param testmode: Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
            parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
            setting the `testmode` query parameter to `true`.

            Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :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.ListMandatesRequest(
            customer_id=customer_id,
            from_=from_,
            limit=limit,
            sort=sort,
            testmode=testmode,
            idempotency_key=idempotency_key,
        )

        req = self._build_request(
            method="GET",
            path="/customers/{customerId}/mandates",
            base_url=base_url,
            url_variables=url_variables,
            url_override=url_override,
            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/hal+json",
            http_headers=http_headers,
            _globals=models.ListMandatesGlobals(
                testmode=self.sdk_configuration.globals.testmode,
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="list-mandates",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.ListMandatesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_url_match = JSONPath("$._links.next.href").parse(body)
            if len(next_url_match) == 0:
                return None

            next_url = next_url_match[0]
            if not next_url:
                return None

            if next_url[0] == "/":
                url = self._get_url(base_url, url_variables)
                next_url = url + next_url

            return self.list(
                customer_id=customer_id,
                from_=from_,
                limit=limit,
                sort=sort,
                testmode=testmode,
                idempotency_key=idempotency_key,
                retries=retries,
                url_override=next_url,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/hal+json"):
            return models.ListMandatesResponse(
                result=unmarshal_json_response(
                    models.ListMandatesResponseBody, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, ["400", "404"], "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def list_async(
        self,
        *,
        customer_id: str,
        from_: Optional[str] = None,
        limit: OptionalNullable[int] = UNSET,
        sort: Optional[models.Sorting] = None,
        testmode: Optional[bool] = None,
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        url_override: Optional[str] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.ListMandatesResponse]:
        r"""List mandates

        Retrieve a list of all mandates.

        The results are paginated.

        :param customer_id: Provide the ID of the related customer.
        :param from_: Provide an ID to start the result set from the item with the given ID and onwards. This allows you to paginate the
            result set.
        :param limit: The maximum number of items to return. Defaults to 50 items.
        :param sort: Used for setting the direction of the result set. Defaults to descending order, meaning the results are ordered from
            newest to oldest.
        :param testmode: Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
            parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
            setting the `testmode` query parameter to `true`.

            Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :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.ListMandatesRequest(
            customer_id=customer_id,
            from_=from_,
            limit=limit,
            sort=sort,
            testmode=testmode,
            idempotency_key=idempotency_key,
        )

        req = self._build_request_async(
            method="GET",
            path="/customers/{customerId}/mandates",
            base_url=base_url,
            url_variables=url_variables,
            url_override=url_override,
            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/hal+json",
            http_headers=http_headers,
            _globals=models.ListMandatesGlobals(
                testmode=self.sdk_configuration.globals.testmode,
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

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

        def next_func() -> Awaitable[Optional[models.ListMandatesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_url_match = JSONPath("$._links.next.href").parse(body)
            if len(next_url_match) == 0:
                return empty_result()

            next_url = next_url_match[0]
            if not next_url:
                return empty_result()

            if next_url[0] == "/":
                url = self._get_url(base_url, url_variables)
                next_url = url + next_url

            return self.list_async(
                customer_id=customer_id,
                from_=from_,
                limit=limit,
                sort=sort,
                testmode=testmode,
                idempotency_key=idempotency_key,
                retries=retries,
                url_override=next_url,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/hal+json"):
            return models.ListMandatesResponse(
                result=unmarshal_json_response(
                    models.ListMandatesResponseBody, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, ["400", "404"], "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def get(
        self,
        *,
        customer_id: str,
        mandate_id: str,
        testmode: Optional[bool] = None,
        idempotency_key: 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.MandateResponse:
        r"""Get mandate

        Retrieve a single mandate by its ID. Depending on the type of mandate, the object will contain the customer's bank
        account details, card details, or PayPal account details.

        :param customer_id: Provide the ID of the related customer.
        :param mandate_id: Provide the ID of the related mandate.
        :param testmode: Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
            parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
            setting the `testmode` query parameter to `true`.

            Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :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.GetMandateRequest(
            customer_id=customer_id,
            mandate_id=mandate_id,
            testmode=testmode,
            idempotency_key=idempotency_key,
        )

        req = self._build_request(
            method="GET",
            path="/customers/{customerId}/mandates/{mandateId}",
            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/hal+json",
            http_headers=http_headers,
            _globals=models.GetMandateGlobals(
                testmode=self.sdk_configuration.globals.testmode,
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="get-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/hal+json"):
            return unmarshal_json_response(models.MandateResponse, http_res)
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def get_async(
        self,
        *,
        customer_id: str,
        mandate_id: str,
        testmode: Optional[bool] = None,
        idempotency_key: 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.MandateResponse:
        r"""Get mandate

        Retrieve a single mandate by its ID. Depending on the type of mandate, the object will contain the customer's bank
        account details, card details, or PayPal account details.

        :param customer_id: Provide the ID of the related customer.
        :param mandate_id: Provide the ID of the related mandate.
        :param testmode: Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
            parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
            setting the `testmode` query parameter to `true`.

            Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :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.GetMandateRequest(
            customer_id=customer_id,
            mandate_id=mandate_id,
            testmode=testmode,
            idempotency_key=idempotency_key,
        )

        req = self._build_request_async(
            method="GET",
            path="/customers/{customerId}/mandates/{mandateId}",
            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/hal+json",
            http_headers=http_headers,
            _globals=models.GetMandateGlobals(
                testmode=self.sdk_configuration.globals.testmode,
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="get-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/hal+json"):
            return unmarshal_json_response(models.MandateResponse, http_res)
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def revoke(
        self,
        *,
        customer_id: str,
        mandate_id: str,
        idempotency_key: Optional[str] = None,
        request_body: Optional[
            Union[
                models.RevokeMandateRequestBody,
                models.RevokeMandateRequestBodyTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ):
        r"""Revoke mandate

        Revoke a customer's mandate. You will no longer be able to charge the customer's bank account or card with this
        mandate, and all connected subscriptions will be canceled.

        :param customer_id: Provide the ID of the related customer.
        :param mandate_id: Provide the ID of the related mandate.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :param request_body:
        :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.RevokeMandateRequest(
            customer_id=customer_id,
            mandate_id=mandate_id,
            idempotency_key=idempotency_key,
            request_body=utils.get_pydantic_model(
                request_body, Optional[models.RevokeMandateRequestBody]
            ),
        )

        req = self._build_request(
            method="DELETE",
            path="/customers/{customerId}/mandates/{mandateId}",
            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/hal+json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body if request is not None else None,
                False,
                True,
                "json",
                Optional[models.RevokeMandateRequestBody],
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="revoke-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "204", "*"):
            return
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def revoke_async(
        self,
        *,
        customer_id: str,
        mandate_id: str,
        idempotency_key: Optional[str] = None,
        request_body: Optional[
            Union[
                models.RevokeMandateRequestBody,
                models.RevokeMandateRequestBodyTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ):
        r"""Revoke mandate

        Revoke a customer's mandate. You will no longer be able to charge the customer's bank account or card with this
        mandate, and all connected subscriptions will be canceled.

        :param customer_id: Provide the ID of the related customer.
        :param mandate_id: Provide the ID of the related mandate.
        :param idempotency_key: A unique key to ensure idempotent requests. This key should be a UUID v4 string.
        :param request_body:
        :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.RevokeMandateRequest(
            customer_id=customer_id,
            mandate_id=mandate_id,
            idempotency_key=idempotency_key,
            request_body=utils.get_pydantic_model(
                request_body, Optional[models.RevokeMandateRequestBody]
            ),
        )

        req = self._build_request_async(
            method="DELETE",
            path="/customers/{customerId}/mandates/{mandateId}",
            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/hal+json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body if request is not None else None,
                False,
                True,
                "json",
                Optional[models.RevokeMandateRequestBody],
            ),
            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
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 5000, 2, 7500), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5xx"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="revoke-mandate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "204", "*"):
            return
        if utils.match_response(http_res, "404", "application/hal+json"):
            response_data = unmarshal_json_response(models.ErrorResponseData, http_res)
            raise models.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("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 models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)
