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

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


class MerchantAccountsSDK(BaseSDK):
    def list(
        self,
        *,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        search: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.ListMerchantAccountsResponse]:
        r"""List all merchant accounts

        List all merchant accounts in an instance.

        :param cursor: A pointer to the page of results to return.
        :param limit: The maximum number of items that are at returned.
        :param search: The search term to filter merchant accounts by.
        :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.ListMerchantAccountsRequest(
            cursor=cursor,
            limit=limit,
            search=search,
        )

        req = self._build_request(
            method="GET",
            path="/merchant-accounts",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            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,
            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(200, 200, 1, 1000), 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_merchant_accounts",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.ListMerchantAccountsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.next_cursor").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.list(
                cursor=next_cursor,
                limit=limit,
                search=search,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ListMerchantAccountsResponse(
                result=unmarshal_json_response(models.MerchantAccounts, http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    async def list_async(
        self,
        *,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        search: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.ListMerchantAccountsResponse]:
        r"""List all merchant accounts

        List all merchant accounts in an instance.

        :param cursor: A pointer to the page of results to return.
        :param limit: The maximum number of items that are at returned.
        :param search: The search term to filter merchant accounts by.
        :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.ListMerchantAccountsRequest(
            cursor=cursor,
            limit=limit,
            search=search,
        )

        req = self._build_request_async(
            method="GET",
            path="/merchant-accounts",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            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,
            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(200, 200, 1, 1000), 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_merchant_accounts",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.ListMerchantAccountsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.next_cursor").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.list(
                cursor=next_cursor,
                limit=limit,
                search=search,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ListMerchantAccountsResponse(
                result=unmarshal_json_response(models.MerchantAccounts, http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    def create(
        self,
        *,
        id: str,
        display_name: str,
        account_updater_enabled: Optional[bool] = False,
        account_updater_request_encryption_key: OptionalNullable[str] = UNSET,
        account_updater_request_encryption_key_id: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key_id: OptionalNullable[str] = UNSET,
        over_capture_amount: OptionalNullable[int] = UNSET,
        over_capture_percentage: OptionalNullable[int] = UNSET,
        loon_client_key: OptionalNullable[str] = UNSET,
        loon_secret_key: OptionalNullable[str] = UNSET,
        loon_accepted_schemes: OptionalNullable[List[models.CardScheme]] = UNSET,
        visa_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        visa_network_tokens_app_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_app_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_app_id: OptionalNullable[str] = UNSET,
        async_network_tokens_enabled: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MerchantAccount:
        r"""Create a merchant account

        Create a new merchant account in an instance.

        :param id: The ID for the merchant account.
        :param display_name: The display name for the merchant account.
        :param account_updater_enabled: Whether the Real-Time Account Updater service is enabled for this merchant account. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `false`, the Account Updater service doesn't get called if a payment fails with expired or invalid card details. If the field is set to `true`, the service is called. Please note that for this to work the other `account_updater_* fields` must be set as well.
        :param account_updater_request_encryption_key: The public key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_request_encryption_key_id: The ID of the key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key: The key used to decrypt the response from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key_id: The ID of the key used to decrypt the request from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param over_capture_amount: The maximum monetary amount allowed for over-capture, in the smallest currency unit, for example `1299` cents to allow for an over-capture of `$12.99`.
        :param over_capture_percentage: The maximum percentage allowed for over-capture, for example `25` to allow for an over-capture of `25%` of the original transaction amount.
        :param loon_client_key: Client key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_secret_key: Secret key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_accepted_schemes: Card schemes accepted when creating jobs using this set of Loon API keys. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param visa_network_tokens_requestor_id: Requestor ID provided for Visa after onboarding to use Network Tokens.
        :param visa_network_tokens_app_id: Application ID provided for Visa after onboarding to use Network Tokens.
        :param amex_network_tokens_requestor_id: Requestor ID provided for American Express after onboarding to use Network Tokens.
        :param amex_network_tokens_app_id: Application ID provided for American Express after onboarding to use Network Tokens.
        :param mastercard_network_tokens_requestor_id: Requestor ID provided for Mastercard after onboarding to use Network Tokens.
        :param mastercard_network_tokens_app_id: Application ID provided for Mastercard after onboarding to use Network Tokens.
        :param async_network_tokens_enabled: When enabled network tokens will be generated asynchronously and only used on subsequent transactions to speed up transaction processing.
        :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.MerchantAccountCreate(
            account_updater_enabled=account_updater_enabled,
            account_updater_request_encryption_key=account_updater_request_encryption_key,
            account_updater_request_encryption_key_id=account_updater_request_encryption_key_id,
            account_updater_response_decryption_key=account_updater_response_decryption_key,
            account_updater_response_decryption_key_id=account_updater_response_decryption_key_id,
            over_capture_amount=over_capture_amount,
            over_capture_percentage=over_capture_percentage,
            loon_client_key=loon_client_key,
            loon_secret_key=loon_secret_key,
            loon_accepted_schemes=loon_accepted_schemes,
            visa_network_tokens_requestor_id=visa_network_tokens_requestor_id,
            visa_network_tokens_app_id=visa_network_tokens_app_id,
            amex_network_tokens_requestor_id=amex_network_tokens_requestor_id,
            amex_network_tokens_app_id=amex_network_tokens_app_id,
            mastercard_network_tokens_requestor_id=mastercard_network_tokens_requestor_id,
            mastercard_network_tokens_app_id=mastercard_network_tokens_app_id,
            async_network_tokens_enabled=async_network_tokens_enabled,
            id=id,
            display_name=display_name,
        )

        req = self._build_request(
            method="POST",
            path="/merchant-accounts",
            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.MerchantAccountCreate
            ),
            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="create_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    async def create_async(
        self,
        *,
        id: str,
        display_name: str,
        account_updater_enabled: Optional[bool] = False,
        account_updater_request_encryption_key: OptionalNullable[str] = UNSET,
        account_updater_request_encryption_key_id: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key_id: OptionalNullable[str] = UNSET,
        over_capture_amount: OptionalNullable[int] = UNSET,
        over_capture_percentage: OptionalNullable[int] = UNSET,
        loon_client_key: OptionalNullable[str] = UNSET,
        loon_secret_key: OptionalNullable[str] = UNSET,
        loon_accepted_schemes: OptionalNullable[List[models.CardScheme]] = UNSET,
        visa_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        visa_network_tokens_app_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_app_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_app_id: OptionalNullable[str] = UNSET,
        async_network_tokens_enabled: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MerchantAccount:
        r"""Create a merchant account

        Create a new merchant account in an instance.

        :param id: The ID for the merchant account.
        :param display_name: The display name for the merchant account.
        :param account_updater_enabled: Whether the Real-Time Account Updater service is enabled for this merchant account. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `false`, the Account Updater service doesn't get called if a payment fails with expired or invalid card details. If the field is set to `true`, the service is called. Please note that for this to work the other `account_updater_* fields` must be set as well.
        :param account_updater_request_encryption_key: The public key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_request_encryption_key_id: The ID of the key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key: The key used to decrypt the response from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key_id: The ID of the key used to decrypt the request from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param over_capture_amount: The maximum monetary amount allowed for over-capture, in the smallest currency unit, for example `1299` cents to allow for an over-capture of `$12.99`.
        :param over_capture_percentage: The maximum percentage allowed for over-capture, for example `25` to allow for an over-capture of `25%` of the original transaction amount.
        :param loon_client_key: Client key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_secret_key: Secret key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_accepted_schemes: Card schemes accepted when creating jobs using this set of Loon API keys. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param visa_network_tokens_requestor_id: Requestor ID provided for Visa after onboarding to use Network Tokens.
        :param visa_network_tokens_app_id: Application ID provided for Visa after onboarding to use Network Tokens.
        :param amex_network_tokens_requestor_id: Requestor ID provided for American Express after onboarding to use Network Tokens.
        :param amex_network_tokens_app_id: Application ID provided for American Express after onboarding to use Network Tokens.
        :param mastercard_network_tokens_requestor_id: Requestor ID provided for Mastercard after onboarding to use Network Tokens.
        :param mastercard_network_tokens_app_id: Application ID provided for Mastercard after onboarding to use Network Tokens.
        :param async_network_tokens_enabled: When enabled network tokens will be generated asynchronously and only used on subsequent transactions to speed up transaction processing.
        :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.MerchantAccountCreate(
            account_updater_enabled=account_updater_enabled,
            account_updater_request_encryption_key=account_updater_request_encryption_key,
            account_updater_request_encryption_key_id=account_updater_request_encryption_key_id,
            account_updater_response_decryption_key=account_updater_response_decryption_key,
            account_updater_response_decryption_key_id=account_updater_response_decryption_key_id,
            over_capture_amount=over_capture_amount,
            over_capture_percentage=over_capture_percentage,
            loon_client_key=loon_client_key,
            loon_secret_key=loon_secret_key,
            loon_accepted_schemes=loon_accepted_schemes,
            visa_network_tokens_requestor_id=visa_network_tokens_requestor_id,
            visa_network_tokens_app_id=visa_network_tokens_app_id,
            amex_network_tokens_requestor_id=amex_network_tokens_requestor_id,
            amex_network_tokens_app_id=amex_network_tokens_app_id,
            mastercard_network_tokens_requestor_id=mastercard_network_tokens_requestor_id,
            mastercard_network_tokens_app_id=mastercard_network_tokens_app_id,
            async_network_tokens_enabled=async_network_tokens_enabled,
            id=id,
            display_name=display_name,
        )

        req = self._build_request_async(
            method="POST",
            path="/merchant-accounts",
            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.MerchantAccountCreate
            ),
            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="create_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    def get(
        self,
        *,
        merchant_account_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.MerchantAccount:
        r"""Get a merchant account

        Get info about a merchant account in an instance.

        :param merchant_account_id: The ID of the merchant account
        :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.GetMerchantAccountRequest(
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request(
            method="GET",
            path="/merchant-accounts/{merchant_account_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,
            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(200, 200, 1, 1000), 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_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    async def get_async(
        self,
        *,
        merchant_account_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.MerchantAccount:
        r"""Get a merchant account

        Get info about a merchant account in an instance.

        :param merchant_account_id: The ID of the merchant account
        :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.GetMerchantAccountRequest(
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/merchant-accounts/{merchant_account_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,
            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(200, 200, 1, 1000), 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_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    def update(
        self,
        *,
        merchant_account_id: str,
        account_updater_enabled: Optional[bool] = False,
        account_updater_request_encryption_key: OptionalNullable[str] = UNSET,
        account_updater_request_encryption_key_id: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key_id: OptionalNullable[str] = UNSET,
        over_capture_amount: OptionalNullable[int] = UNSET,
        over_capture_percentage: OptionalNullable[int] = UNSET,
        loon_client_key: OptionalNullable[str] = UNSET,
        loon_secret_key: OptionalNullable[str] = UNSET,
        loon_accepted_schemes: OptionalNullable[List[models.CardScheme]] = UNSET,
        visa_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        visa_network_tokens_app_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_app_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_app_id: OptionalNullable[str] = UNSET,
        async_network_tokens_enabled: Optional[bool] = False,
        display_name: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MerchantAccount:
        r"""Update a merchant account

        Update info for a merchant account in an instance.

        :param merchant_account_id: The ID of the merchant account
        :param account_updater_enabled: Whether the Real-Time Account Updater service is enabled for this merchant account. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `false`, the Account Updater service doesn't get called if a payment fails with expired or invalid card details. If the field is set to `true`, the service is called. Please note that for this to work the other `account_updater_* fields` must be set as well.
        :param account_updater_request_encryption_key: The public key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_request_encryption_key_id: The ID of the key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key: The key used to decrypt the response from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key_id: The ID of the key used to decrypt the request from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param over_capture_amount: The maximum monetary amount allowed for over-capture, in the smallest currency unit, for example `1299` cents to allow for an over-capture of `$12.99`.
        :param over_capture_percentage: The maximum percentage allowed for over-capture, for example `25` to allow for an over-capture of `25%` of the original transaction amount.
        :param loon_client_key: Client key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_secret_key: Secret key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_accepted_schemes: Card schemes accepted when creating jobs using this set of Loon API keys. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param visa_network_tokens_requestor_id: Requestor ID provided for Visa after onboarding to use Network Tokens.
        :param visa_network_tokens_app_id: Application ID provided for Visa after onboarding to use Network Tokens.
        :param amex_network_tokens_requestor_id: Requestor ID provided for American Express after onboarding to use Network Tokens.
        :param amex_network_tokens_app_id: Application ID provided for American Express after onboarding to use Network Tokens.
        :param mastercard_network_tokens_requestor_id: Requestor ID provided for Mastercard after onboarding to use Network Tokens.
        :param mastercard_network_tokens_app_id: Application ID provided for Mastercard after onboarding to use Network Tokens.
        :param async_network_tokens_enabled: When enabled network tokens will be generated asynchronously and only used on subsequent transactions to speed up transaction processing.
        :param display_name: The display name for the merchant account.
        :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.UpdateMerchantAccountRequest(
            merchant_account_id=merchant_account_id,
            merchant_account_update=models.MerchantAccountUpdate(
                account_updater_enabled=account_updater_enabled,
                account_updater_request_encryption_key=account_updater_request_encryption_key,
                account_updater_request_encryption_key_id=account_updater_request_encryption_key_id,
                account_updater_response_decryption_key=account_updater_response_decryption_key,
                account_updater_response_decryption_key_id=account_updater_response_decryption_key_id,
                over_capture_amount=over_capture_amount,
                over_capture_percentage=over_capture_percentage,
                loon_client_key=loon_client_key,
                loon_secret_key=loon_secret_key,
                loon_accepted_schemes=loon_accepted_schemes,
                visa_network_tokens_requestor_id=visa_network_tokens_requestor_id,
                visa_network_tokens_app_id=visa_network_tokens_app_id,
                amex_network_tokens_requestor_id=amex_network_tokens_requestor_id,
                amex_network_tokens_app_id=amex_network_tokens_app_id,
                mastercard_network_tokens_requestor_id=mastercard_network_tokens_requestor_id,
                mastercard_network_tokens_app_id=mastercard_network_tokens_app_id,
                async_network_tokens_enabled=async_network_tokens_enabled,
                display_name=display_name,
            ),
        )

        req = self._build_request(
            method="PUT",
            path="/merchant-accounts/{merchant_account_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.merchant_account_update,
                False,
                False,
                "json",
                models.MerchantAccountUpdate,
            ),
            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="update_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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

    async def update_async(
        self,
        *,
        merchant_account_id: str,
        account_updater_enabled: Optional[bool] = False,
        account_updater_request_encryption_key: OptionalNullable[str] = UNSET,
        account_updater_request_encryption_key_id: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key: OptionalNullable[str] = UNSET,
        account_updater_response_decryption_key_id: OptionalNullable[str] = UNSET,
        over_capture_amount: OptionalNullable[int] = UNSET,
        over_capture_percentage: OptionalNullable[int] = UNSET,
        loon_client_key: OptionalNullable[str] = UNSET,
        loon_secret_key: OptionalNullable[str] = UNSET,
        loon_accepted_schemes: OptionalNullable[List[models.CardScheme]] = UNSET,
        visa_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        visa_network_tokens_app_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        amex_network_tokens_app_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_requestor_id: OptionalNullable[str] = UNSET,
        mastercard_network_tokens_app_id: OptionalNullable[str] = UNSET,
        async_network_tokens_enabled: Optional[bool] = False,
        display_name: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.MerchantAccount:
        r"""Update a merchant account

        Update info for a merchant account in an instance.

        :param merchant_account_id: The ID of the merchant account
        :param account_updater_enabled: Whether the Real-Time Account Updater service is enabled for this merchant account. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `false`, the Account Updater service doesn't get called if a payment fails with expired or invalid card details. If the field is set to `true`, the service is called. Please note that for this to work the other `account_updater_* fields` must be set as well.
        :param account_updater_request_encryption_key: The public key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_request_encryption_key_id: The ID of the key used to encrypt the request to the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key: The key used to decrypt the response from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param account_updater_response_decryption_key_id: The ID of the key used to decrypt the request from the Real-Time Account Updater service. The Account Updater service is used to update card details when cards are lost, stolen or expired. If the field is not set or if it's set to `null`, the Account Updater service doesn't get called. If the field is set, the other `account_updater_*` fields must be set as well.
        :param over_capture_amount: The maximum monetary amount allowed for over-capture, in the smallest currency unit, for example `1299` cents to allow for an over-capture of `$12.99`.
        :param over_capture_percentage: The maximum percentage allowed for over-capture, for example `25` to allow for an over-capture of `25%` of the original transaction amount.
        :param loon_client_key: Client key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_secret_key: Secret key provided by Pagos to authenticate to the Loon API. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param loon_accepted_schemes: Card schemes accepted when creating jobs using this set of Loon API keys. Loon is the Account Updater service we use and if the field is not set or if it's set to null, the Account Updater service doesn't get configured. If the field is set to `null`, the other `loon_*` fields must be set to null as well.
        :param visa_network_tokens_requestor_id: Requestor ID provided for Visa after onboarding to use Network Tokens.
        :param visa_network_tokens_app_id: Application ID provided for Visa after onboarding to use Network Tokens.
        :param amex_network_tokens_requestor_id: Requestor ID provided for American Express after onboarding to use Network Tokens.
        :param amex_network_tokens_app_id: Application ID provided for American Express after onboarding to use Network Tokens.
        :param mastercard_network_tokens_requestor_id: Requestor ID provided for Mastercard after onboarding to use Network Tokens.
        :param mastercard_network_tokens_app_id: Application ID provided for Mastercard after onboarding to use Network Tokens.
        :param async_network_tokens_enabled: When enabled network tokens will be generated asynchronously and only used on subsequent transactions to speed up transaction processing.
        :param display_name: The display name for the merchant account.
        :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.UpdateMerchantAccountRequest(
            merchant_account_id=merchant_account_id,
            merchant_account_update=models.MerchantAccountUpdate(
                account_updater_enabled=account_updater_enabled,
                account_updater_request_encryption_key=account_updater_request_encryption_key,
                account_updater_request_encryption_key_id=account_updater_request_encryption_key_id,
                account_updater_response_decryption_key=account_updater_response_decryption_key,
                account_updater_response_decryption_key_id=account_updater_response_decryption_key_id,
                over_capture_amount=over_capture_amount,
                over_capture_percentage=over_capture_percentage,
                loon_client_key=loon_client_key,
                loon_secret_key=loon_secret_key,
                loon_accepted_schemes=loon_accepted_schemes,
                visa_network_tokens_requestor_id=visa_network_tokens_requestor_id,
                visa_network_tokens_app_id=visa_network_tokens_app_id,
                amex_network_tokens_requestor_id=amex_network_tokens_requestor_id,
                amex_network_tokens_app_id=amex_network_tokens_app_id,
                mastercard_network_tokens_requestor_id=mastercard_network_tokens_requestor_id,
                mastercard_network_tokens_app_id=mastercard_network_tokens_app_id,
                async_network_tokens_enabled=async_network_tokens_enabled,
                display_name=display_name,
            ),
        )

        req = self._build_request_async(
            method="PUT",
            path="/merchant-accounts/{merchant_account_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.merchant_account_update,
                False,
                False,
                "json",
                models.MerchantAccountUpdate,
            ),
            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="update_merchant_account",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.MerchantAccount, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.Error400Data, http_res)
            raise errors.Error400(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(errors.Error401Data, http_res)
            raise errors.Error401(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(errors.Error403Data, http_res)
            raise errors.Error403(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(errors.Error404Data, http_res)
            raise errors.Error404(response_data, http_res)
        if utils.match_response(http_res, "405", "application/json"):
            response_data = unmarshal_json_response(errors.Error405Data, http_res)
            raise errors.Error405(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.Error409Data, http_res)
            raise errors.Error409(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.HTTPValidationErrorData, http_res
            )
            raise errors.HTTPValidationError(response_data, http_res)
        if utils.match_response(http_res, "425", "application/json"):
            response_data = unmarshal_json_response(errors.Error425Data, http_res)
            raise errors.Error425(response_data, http_res)
        if utils.match_response(http_res, "429", "application/json"):
            response_data = unmarshal_json_response(errors.Error429Data, http_res)
            raise errors.Error429(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.Error500Data, http_res)
            raise errors.Error500(response_data, http_res)
        if utils.match_response(http_res, "502", "application/json"):
            response_data = unmarshal_json_response(errors.Error502Data, http_res)
            raise errors.Error502(response_data, http_res)
        if utils.match_response(http_res, "504", "application/json"):
            response_data = unmarshal_json_response(errors.Error504Data, http_res)
            raise errors.Error504(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.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 errors.APIError("API error occurred", http_res, http_res_text)

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