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

from .basesdk import BaseSDK
from datetime import datetime
from moovio_sdk import utils
from moovio_sdk._hooks import HookContext
from moovio_sdk.models import components, errors, operations
from moovio_sdk.types import OptionalNullable, UNSET
from moovio_sdk.utils import get_security_from_env
from moovio_sdk.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Dict, List, Mapping, Optional, Union


class Transfers(BaseSDK):
    def generate_options(
        self,
        *,
        account_id: str,
        source: Union[
            components.SourceDestinationOptions,
            components.SourceDestinationOptionsTypedDict,
        ],
        destination: Union[
            components.SourceDestinationOptions,
            components.SourceDestinationOptionsTypedDict,
        ],
        amount: Union[components.Amount, components.AmountTypedDict],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateTransferOptionsResponse:
        r"""Generate available payment method options for one or multiple transfer participants depending on the accountID or paymentMethodID you
        supply in the request body.

        The accountID in the route should the partner's accountID.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param account_id: The partner's Moov account ID.
        :param source:
        :param destination:
        :param amount:
        :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 = operations.CreateTransferOptionsRequest(
            account_id=account_id,
            create_transfer_options=components.CreateTransferOptions(
                source=utils.get_pydantic_model(
                    source, components.SourceDestinationOptions
                ),
                destination=utils.get_pydantic_model(
                    destination, components.SourceDestinationOptions
                ),
                amount=utils.get_pydantic_model(amount, components.Amount),
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounts/{accountID}/transfer-options",
            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,
            _globals=operations.CreateTransferOptionsGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_transfer_options,
                False,
                False,
                "json",
                components.CreateTransferOptions,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createTransferOptions",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.CreateTransferOptionsResponse(
                result=unmarshal_json_response(components.TransferOptions, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.TransferOptionsValidationErrorData, http_res
            )
            raise errors.TransferOptionsValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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 generate_options_async(
        self,
        *,
        account_id: str,
        source: Union[
            components.SourceDestinationOptions,
            components.SourceDestinationOptionsTypedDict,
        ],
        destination: Union[
            components.SourceDestinationOptions,
            components.SourceDestinationOptionsTypedDict,
        ],
        amount: Union[components.Amount, components.AmountTypedDict],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateTransferOptionsResponse:
        r"""Generate available payment method options for one or multiple transfer participants depending on the accountID or paymentMethodID you
        supply in the request body.

        The accountID in the route should the partner's accountID.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param account_id: The partner's Moov account ID.
        :param source:
        :param destination:
        :param amount:
        :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 = operations.CreateTransferOptionsRequest(
            account_id=account_id,
            create_transfer_options=components.CreateTransferOptions(
                source=utils.get_pydantic_model(
                    source, components.SourceDestinationOptions
                ),
                destination=utils.get_pydantic_model(
                    destination, components.SourceDestinationOptions
                ),
                amount=utils.get_pydantic_model(amount, components.Amount),
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounts/{accountID}/transfer-options",
            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,
            _globals=operations.CreateTransferOptionsGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_transfer_options,
                False,
                False,
                "json",
                components.CreateTransferOptions,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createTransferOptions",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.CreateTransferOptionsResponse(
                result=unmarshal_json_response(components.TransferOptions, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.TransferOptionsValidationErrorData, http_res
            )
            raise errors.TransferOptionsValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        x_idempotency_key: str,
        account_id: str,
        source: Union[
            components.CreateTransferSource, components.CreateTransferSourceTypedDict
        ],
        destination: Union[
            components.CreateTransferDestination,
            components.CreateTransferDestinationTypedDict,
        ],
        amount: Union[components.Amount, components.AmountTypedDict],
        x_wait_for: Optional[components.TransferWaitFor] = None,
        facilitator_fee: Optional[
            Union[components.FacilitatorFee, components.FacilitatorFeeTypedDict]
        ] = None,
        description: Optional[str] = None,
        metadata: Optional[Dict[str, str]] = None,
        sales_tax_amount: Optional[
            Union[components.Amount, components.AmountTypedDict]
        ] = None,
        foreign_id: Optional[str] = None,
        line_items: Optional[
            Union[
                components.CreateTransferLineItems,
                components.CreateTransferLineItemsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateTransferResponse:
        r"""Move money by providing the source, destination, and amount in the request body.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Identifies a unique request to create a transfer.
            In order to avoid creating duplicate transfers, the same idempotency key should be reused when retrying a request.
        :param account_id: Your Moov account ID.
        :param source: Where funds for a transfer originate. For the source, you must include either a `paymentMethodID` or a `transferID`.
        :param destination: The final stage of a transfer and the ultimate recipient of the funds.
        :param amount:
        :param x_wait_for: Optional header that indicates whether to return a synchronous response that includes full transfer and rail-specific details or an
            asynchronous response indicating the transfer was created (this is the default response if the header is omitted). A timeout will occur after 15 seconds.
        :param facilitator_fee: Total or markup fee.
        :param description: An optional description of the transfer that is used on receipts and for your own internal use.
        :param metadata: Free-form key-value pair list. Useful for storing information that is not captured elsewhere.
        :param sales_tax_amount: Optional sales tax amount. `transfer.amount.value` should be inclusive of any sales tax and represents the total amount charged.
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :param line_items: An optional collection of line items for a transfer.
            When line items are provided, their total plus sales tax must equal the transfer amount.
        :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 = operations.CreateTransferRequest(
            x_idempotency_key=x_idempotency_key,
            x_wait_for=x_wait_for,
            account_id=account_id,
            create_transfer=components.CreateTransfer(
                source=utils.get_pydantic_model(
                    source, components.CreateTransferSource
                ),
                destination=utils.get_pydantic_model(
                    destination, components.CreateTransferDestination
                ),
                amount=utils.get_pydantic_model(amount, components.Amount),
                facilitator_fee=utils.get_pydantic_model(
                    facilitator_fee, Optional[components.FacilitatorFee]
                ),
                description=description,
                metadata=metadata,
                sales_tax_amount=utils.get_pydantic_model(
                    sales_tax_amount, Optional[components.Amount]
                ),
                foreign_id=foreign_id,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[components.CreateTransferLineItems]
                ),
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounts/{accountID}/transfers",
            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,
            _globals=operations.CreateTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_transfer, False, False, "json", components.CreateTransfer
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.CreatedTransfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "201", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.AsyncTransfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "202", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.TransferData, http_res)
            raise errors.Transfer(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.TransferValidationErrorData, http_res
            )
            raise errors.TransferValidationError(response_data, http_res)
        if utils.match_response(http_res, ["404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        x_idempotency_key: str,
        account_id: str,
        source: Union[
            components.CreateTransferSource, components.CreateTransferSourceTypedDict
        ],
        destination: Union[
            components.CreateTransferDestination,
            components.CreateTransferDestinationTypedDict,
        ],
        amount: Union[components.Amount, components.AmountTypedDict],
        x_wait_for: Optional[components.TransferWaitFor] = None,
        facilitator_fee: Optional[
            Union[components.FacilitatorFee, components.FacilitatorFeeTypedDict]
        ] = None,
        description: Optional[str] = None,
        metadata: Optional[Dict[str, str]] = None,
        sales_tax_amount: Optional[
            Union[components.Amount, components.AmountTypedDict]
        ] = None,
        foreign_id: Optional[str] = None,
        line_items: Optional[
            Union[
                components.CreateTransferLineItems,
                components.CreateTransferLineItemsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateTransferResponse:
        r"""Move money by providing the source, destination, and amount in the request body.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Identifies a unique request to create a transfer.
            In order to avoid creating duplicate transfers, the same idempotency key should be reused when retrying a request.
        :param account_id: Your Moov account ID.
        :param source: Where funds for a transfer originate. For the source, you must include either a `paymentMethodID` or a `transferID`.
        :param destination: The final stage of a transfer and the ultimate recipient of the funds.
        :param amount:
        :param x_wait_for: Optional header that indicates whether to return a synchronous response that includes full transfer and rail-specific details or an
            asynchronous response indicating the transfer was created (this is the default response if the header is omitted). A timeout will occur after 15 seconds.
        :param facilitator_fee: Total or markup fee.
        :param description: An optional description of the transfer that is used on receipts and for your own internal use.
        :param metadata: Free-form key-value pair list. Useful for storing information that is not captured elsewhere.
        :param sales_tax_amount: Optional sales tax amount. `transfer.amount.value` should be inclusive of any sales tax and represents the total amount charged.
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :param line_items: An optional collection of line items for a transfer.
            When line items are provided, their total plus sales tax must equal the transfer amount.
        :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 = operations.CreateTransferRequest(
            x_idempotency_key=x_idempotency_key,
            x_wait_for=x_wait_for,
            account_id=account_id,
            create_transfer=components.CreateTransfer(
                source=utils.get_pydantic_model(
                    source, components.CreateTransferSource
                ),
                destination=utils.get_pydantic_model(
                    destination, components.CreateTransferDestination
                ),
                amount=utils.get_pydantic_model(amount, components.Amount),
                facilitator_fee=utils.get_pydantic_model(
                    facilitator_fee, Optional[components.FacilitatorFee]
                ),
                description=description,
                metadata=metadata,
                sales_tax_amount=utils.get_pydantic_model(
                    sales_tax_amount, Optional[components.Amount]
                ),
                foreign_id=foreign_id,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[components.CreateTransferLineItems]
                ),
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounts/{accountID}/transfers",
            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,
            _globals=operations.CreateTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_transfer, False, False, "json", components.CreateTransfer
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.CreatedTransfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "201", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.AsyncTransfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "202", "application/json"):
            return operations.CreateTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(errors.TransferData, http_res)
            raise errors.Transfer(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.TransferValidationErrorData, http_res
            )
            raise errors.TransferValidationError(response_data, http_res)
        if utils.match_response(http_res, ["404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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 list(
        self,
        *,
        account_id: str,
        account_i_ds: Optional[List[str]] = None,
        status: Optional[components.TransferStatus] = None,
        start_date_time: Optional[datetime] = None,
        end_date_time: Optional[datetime] = None,
        group_id: Optional[str] = None,
        schedule_id: Optional[str] = None,
        payment_link_code: Optional[str] = None,
        refunded: Optional[bool] = None,
        disputed: Optional[bool] = None,
        foreign_id: Optional[str] = None,
        skip: Optional[int] = None,
        count: Optional[int] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.ListTransfersResponse:
        r"""List all the transfers associated with a particular Moov account.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        When you run this request, you retrieve 200 transfers at a time. You can advance past a results set of 200 transfers by using the `skip` parameter (for example,
        if you set `skip`= 10, you will see a results set of 200 transfers after the first 10). If you are searching a high volume of transfers, the request will likely
        process very slowly. To achieve faster performance, restrict the data as much as you can by using the `StartDateTime` and `EndDateTime` parameters for a limited
        period of time. You can run multiple requests in smaller time window increments until you've retrieved all the transfers you need.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id:
        :param account_i_ds: Optional, comma-separated account IDs by which the response is filtered based on whether the account ID is the source or destination.
        :param status: Optional parameter for filtering transfers by status.
        :param start_date_time: Optional date-time which inclusively filters all transfers created after this date-time.
        :param end_date_time: Optional date-time which exclusively filters all transfers created before this date-time.
        :param group_id: Optional ID to filter for transfers in the same group.
        :param schedule_id: Optional ID to filter for transfer occurrences belonging to the same schedule.
        :param payment_link_code: Optional code to filter for transfers associated with the payment link.
        :param refunded: Optional parameter to only return refunded transfers.
        :param disputed: Optional parameter to only return disputed transfers.
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :param skip:
        :param count:
        :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 = operations.ListTransfersRequest(
            account_i_ds=account_i_ds,
            status=status,
            start_date_time=start_date_time,
            end_date_time=end_date_time,
            group_id=group_id,
            schedule_id=schedule_id,
            payment_link_code=payment_link_code,
            refunded=refunded,
            disputed=disputed,
            foreign_id=foreign_id,
            skip=skip,
            count=count,
            account_id=account_id,
        )

        req = self._build_request(
            method="GET",
            path="/accounts/{accountID}/transfers",
            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,
            _globals=operations.ListTransfersGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="listTransfers",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "422", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.ListTransfersResponse(
                result=unmarshal_json_response(List[components.Transfer], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.ListTransfersValidationErrorData, http_res
            )
            raise errors.ListTransfersValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        account_id: str,
        account_i_ds: Optional[List[str]] = None,
        status: Optional[components.TransferStatus] = None,
        start_date_time: Optional[datetime] = None,
        end_date_time: Optional[datetime] = None,
        group_id: Optional[str] = None,
        schedule_id: Optional[str] = None,
        payment_link_code: Optional[str] = None,
        refunded: Optional[bool] = None,
        disputed: Optional[bool] = None,
        foreign_id: Optional[str] = None,
        skip: Optional[int] = None,
        count: Optional[int] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.ListTransfersResponse:
        r"""List all the transfers associated with a particular Moov account.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        When you run this request, you retrieve 200 transfers at a time. You can advance past a results set of 200 transfers by using the `skip` parameter (for example,
        if you set `skip`= 10, you will see a results set of 200 transfers after the first 10). If you are searching a high volume of transfers, the request will likely
        process very slowly. To achieve faster performance, restrict the data as much as you can by using the `StartDateTime` and `EndDateTime` parameters for a limited
        period of time. You can run multiple requests in smaller time window increments until you've retrieved all the transfers you need.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id:
        :param account_i_ds: Optional, comma-separated account IDs by which the response is filtered based on whether the account ID is the source or destination.
        :param status: Optional parameter for filtering transfers by status.
        :param start_date_time: Optional date-time which inclusively filters all transfers created after this date-time.
        :param end_date_time: Optional date-time which exclusively filters all transfers created before this date-time.
        :param group_id: Optional ID to filter for transfers in the same group.
        :param schedule_id: Optional ID to filter for transfer occurrences belonging to the same schedule.
        :param payment_link_code: Optional code to filter for transfers associated with the payment link.
        :param refunded: Optional parameter to only return refunded transfers.
        :param disputed: Optional parameter to only return disputed transfers.
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :param skip:
        :param count:
        :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 = operations.ListTransfersRequest(
            account_i_ds=account_i_ds,
            status=status,
            start_date_time=start_date_time,
            end_date_time=end_date_time,
            group_id=group_id,
            schedule_id=schedule_id,
            payment_link_code=payment_link_code,
            refunded=refunded,
            disputed=disputed,
            foreign_id=foreign_id,
            skip=skip,
            count=count,
            account_id=account_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounts/{accountID}/transfers",
            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,
            _globals=operations.ListTransfersGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="listTransfers",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "422", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.ListTransfersResponse(
                result=unmarshal_json_response(List[components.Transfer], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.ListTransfersValidationErrorData, http_res
            )
            raise errors.ListTransfersValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        transfer_id: str,
        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,
    ) -> operations.GetTransferResponse:
        r"""Retrieve full transfer details for an individual transfer of a particular Moov account.

        Payment rail-specific details are included in the source and destination. Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/)
        to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

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

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

        request = operations.GetTransferRequest(
            transfer_id=transfer_id,
            account_id=account_id,
        )

        req = self._build_request(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}",
            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,
            _globals=operations.GetTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        transfer_id: str,
        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,
    ) -> operations.GetTransferResponse:
        r"""Retrieve full transfer details for an individual transfer of a particular Moov account.

        Payment rail-specific details are included in the source and destination. Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/)
        to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

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

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

        request = operations.GetTransferRequest(
            transfer_id=transfer_id,
            account_id=account_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}",
            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,
            _globals=operations.GetTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        transfer_id: str,
        account_id: str,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        foreign_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.UpdateTransferResponse:
        r"""Update the metadata contained on a transfer.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param transfer_id: Identifier for the transfer.
        :param account_id:
        :param metadata:
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :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 = operations.UpdateTransferRequest(
            transfer_id=transfer_id,
            account_id=account_id,
            patch_transfer=components.PatchTransfer(
                metadata=metadata,
                foreign_id=foreign_id,
            ),
        )

        req = self._build_request(
            method="PATCH",
            path="/accounts/{accountID}/transfers/{transferID}",
            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,
            _globals=operations.UpdateTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.patch_transfer, False, False, "json", components.PatchTransfer
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "401",
                "403",
                "404",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.UpdateTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.PatchTransferValidationErrorData, http_res
            )
            raise errors.PatchTransferValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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,
        *,
        transfer_id: str,
        account_id: str,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        foreign_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.UpdateTransferResponse:
        r"""Update the metadata contained on a transfer.

        Read our [transfers overview guide](https://docs.moov.io/guides/money-movement/overview/) to learn more.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param transfer_id: Identifier for the transfer.
        :param account_id:
        :param metadata:
        :param foreign_id: Optional alias from a foreign/external system which can be used to reference this resource.
        :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 = operations.UpdateTransferRequest(
            transfer_id=transfer_id,
            account_id=account_id,
            patch_transfer=components.PatchTransfer(
                metadata=metadata,
                foreign_id=foreign_id,
            ),
        )

        req = self._build_request_async(
            method="PATCH",
            path="/accounts/{accountID}/transfers/{transferID}",
            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,
            _globals=operations.UpdateTransferGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.patch_transfer, False, False, "json", components.PatchTransfer
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="updateTransfer",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "401",
                "403",
                "404",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.UpdateTransferResponse(
                result=unmarshal_json_response(components.Transfer, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.PatchTransferValidationErrorData, http_res
            )
            raise errors.PatchTransferValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_cancellation(
        self,
        *,
        account_id: str,
        transfer_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateCancellationResponse:
        r"""Initiate a cancellation for a card, ACH, or queued transfer.

          To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
          to specify the `/accounts/{accountID}/transfers.write` scope.

        :param account_id: The partner's Moov account ID.
        :param transfer_id: The transfer ID to cancel.
        :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 = operations.CreateCancellationRequest(
            account_id=account_id,
            transfer_id=transfer_id,
        )

        req = self._build_request(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/cancellations",
            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,
            _globals=operations.CreateCancellationGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createCancellation",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "202"], "application/json"):
            return operations.CreateCancellationResponse(
                result=unmarshal_json_response(components.Cancellation, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_cancellation_async(
        self,
        *,
        account_id: str,
        transfer_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateCancellationResponse:
        r"""Initiate a cancellation for a card, ACH, or queued transfer.

          To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
          to specify the `/accounts/{accountID}/transfers.write` scope.

        :param account_id: The partner's Moov account ID.
        :param transfer_id: The transfer ID to cancel.
        :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 = operations.CreateCancellationRequest(
            account_id=account_id,
            transfer_id=transfer_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/cancellations",
            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,
            _globals=operations.CreateCancellationGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createCancellation",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "202"], "application/json"):
            return operations.CreateCancellationResponse(
                result=unmarshal_json_response(components.Cancellation, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_cancellation(
        self,
        *,
        account_id: str,
        transfer_id: str,
        cancellation_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.GetCancellationResponse:
        r"""Get details of a cancellation for a transfer.

          To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
          to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id: Moov account ID of the partner or transfer's source or destination.
        :param transfer_id: Identifier for the transfer.
        :param cancellation_id: Identifier for the cancellation.
        :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 = operations.GetCancellationRequest(
            account_id=account_id,
            transfer_id=transfer_id,
            cancellation_id=cancellation_id,
        )

        req = self._build_request(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/cancellations/{cancellationID}",
            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,
            _globals=operations.GetCancellationGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getCancellation",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetCancellationResponse(
                result=unmarshal_json_response(components.Cancellation, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_cancellation_async(
        self,
        *,
        account_id: str,
        transfer_id: str,
        cancellation_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.GetCancellationResponse:
        r"""Get details of a cancellation for a transfer.

          To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
          to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id: Moov account ID of the partner or transfer's source or destination.
        :param transfer_id: Identifier for the transfer.
        :param cancellation_id: Identifier for the cancellation.
        :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 = operations.GetCancellationRequest(
            account_id=account_id,
            transfer_id=transfer_id,
            cancellation_id=cancellation_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/cancellations/{cancellationID}",
            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,
            _globals=operations.GetCancellationGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getCancellation",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetCancellationResponse(
                result=unmarshal_json_response(components.Cancellation, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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 initiate_refund(
        self,
        *,
        x_idempotency_key: str,
        account_id: str,
        transfer_id: str,
        x_wait_for: Optional[components.TransferWaitFor] = None,
        amount: Optional[int] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.InitiateRefundResponse:
        r"""Initiate a refund for a card transfer.

        **Use the [Cancel or refund a card transfer](https://docs.moov.io/api/money-movement/refunds/cancel/) endpoint for more comprehensive cancel and refund options.**
        See the [reversals](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/) guide for more information.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Prevents duplicate refunds from being created.
        :param account_id: The merchant's Moov account ID.
        :param transfer_id: Identifier for the transfer.
        :param x_wait_for: Optional header that indicates whether to return a synchronous response that includes full transfer and rail-specific details or an
            asynchronous response indicating the transfer was created (this is the default response if the header is omitted). A timeout will occur after 15 seconds.
        :param amount: Amount to refund in cents. If null, the original transfer's full amount will be refunded.
        :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 = operations.InitiateRefundRequest(
            x_idempotency_key=x_idempotency_key,
            x_wait_for=x_wait_for,
            account_id=account_id,
            transfer_id=transfer_id,
            create_refund=components.CreateRefund(
                amount=amount,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/refunds",
            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,
            _globals=operations.InitiateRefundGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_refund if request is not None else None,
                False,
                True,
                "json",
                Optional[components.CreateRefund],
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="initiateRefund",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.InitiateRefundResponse(
                result=unmarshal_json_response(
                    components.CreateRefundResponse, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "202", "application/json"):
            return operations.InitiateRefundResponse(
                result=unmarshal_json_response(
                    components.CardAcquiringRefund, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(
                errors.CardAcquiringRefundData, http_res
            )
            raise errors.CardAcquiringRefund(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.RefundValidationErrorData, http_res
            )
            raise errors.RefundValidationError(response_data, http_res)
        if utils.match_response(http_res, ["404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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 initiate_refund_async(
        self,
        *,
        x_idempotency_key: str,
        account_id: str,
        transfer_id: str,
        x_wait_for: Optional[components.TransferWaitFor] = None,
        amount: Optional[int] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.InitiateRefundResponse:
        r"""Initiate a refund for a card transfer.

        **Use the [Cancel or refund a card transfer](https://docs.moov.io/api/money-movement/refunds/cancel/) endpoint for more comprehensive cancel and refund options.**
        See the [reversals](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/) guide for more information.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Prevents duplicate refunds from being created.
        :param account_id: The merchant's Moov account ID.
        :param transfer_id: Identifier for the transfer.
        :param x_wait_for: Optional header that indicates whether to return a synchronous response that includes full transfer and rail-specific details or an
            asynchronous response indicating the transfer was created (this is the default response if the header is omitted). A timeout will occur after 15 seconds.
        :param amount: Amount to refund in cents. If null, the original transfer's full amount will be refunded.
        :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 = operations.InitiateRefundRequest(
            x_idempotency_key=x_idempotency_key,
            x_wait_for=x_wait_for,
            account_id=account_id,
            transfer_id=transfer_id,
            create_refund=components.CreateRefund(
                amount=amount,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/refunds",
            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,
            _globals=operations.InitiateRefundGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_refund if request is not None else None,
                False,
                True,
                "json",
                Optional[components.CreateRefund],
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="initiateRefund",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return operations.InitiateRefundResponse(
                result=unmarshal_json_response(
                    components.CreateRefundResponse, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "202", "application/json"):
            return operations.InitiateRefundResponse(
                result=unmarshal_json_response(
                    components.CardAcquiringRefund, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(
                errors.CardAcquiringRefundData, http_res
            )
            raise errors.CardAcquiringRefund(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.RefundValidationErrorData, http_res
            )
            raise errors.RefundValidationError(response_data, http_res)
        if utils.match_response(http_res, ["404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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 list_refunds(
        self,
        *,
        account_id: str,
        transfer_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.ListRefundsResponse:
        r"""Get a list of refunds for a card transfer.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id:
        :param transfer_id: Identifier for the transfer.
        :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 = operations.ListRefundsRequest(
            account_id=account_id,
            transfer_id=transfer_id,
        )

        req = self._build_request(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/refunds",
            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,
            _globals=operations.ListRefundsGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="listRefunds",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.ListRefundsResponse(
                result=unmarshal_json_response(
                    List[components.CardAcquiringRefund], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_refunds_async(
        self,
        *,
        account_id: str,
        transfer_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.ListRefundsResponse:
        r"""Get a list of refunds for a card transfer.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param account_id:
        :param transfer_id: Identifier for the transfer.
        :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 = operations.ListRefundsRequest(
            account_id=account_id,
            transfer_id=transfer_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/refunds",
            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,
            _globals=operations.ListRefundsGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="listRefunds",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.ListRefundsResponse(
                result=unmarshal_json_response(
                    List[components.CardAcquiringRefund], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_refund(
        self,
        *,
        transfer_id: str,
        account_id: str,
        refund_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.GetRefundResponse:
        r"""Get details of a refund for a card transfer.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param transfer_id: Identifier for the transfer.
        :param account_id:
        :param refund_id: Identifier for the refund.
        :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 = operations.GetRefundRequest(
            transfer_id=transfer_id,
            account_id=account_id,
            refund_id=refund_id,
        )

        req = self._build_request(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/refunds/{refundID}",
            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,
            _globals=operations.GetRefundGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getRefund",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetRefundResponse(
                result=unmarshal_json_response(
                    components.CardAcquiringRefund, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_refund_async(
        self,
        *,
        transfer_id: str,
        account_id: str,
        refund_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.GetRefundResponse:
        r"""Get details of a refund for a card transfer.

        To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/)
        you'll need to specify the `/accounts/{accountID}/transfers.read` scope.

        :param transfer_id: Identifier for the transfer.
        :param account_id:
        :param refund_id: Identifier for the refund.
        :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 = operations.GetRefundRequest(
            transfer_id=transfer_id,
            account_id=account_id,
            refund_id=refund_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounts/{accountID}/transfers/{transferID}/refunds/{refundID}",
            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,
            _globals=operations.GetRefundGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getRefund",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "504", "5XX"],
            retry_config=retry_config,
        )

        if utils.match_response(http_res, "200", "application/json"):
            return operations.GetRefundResponse(
                result=unmarshal_json_response(
                    components.CardAcquiringRefund, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_reversal(
        self,
        *,
        x_idempotency_key: str,
        account_id: str,
        transfer_id: str,
        amount: int,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateReversalResponse:
        r"""Reverses a card transfer by initiating a cancellation or refund depending on the transaction status.
        Read our [reversals guide](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/)
        to learn more.

        To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
        to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Prevents duplicate reversals from being created.
        :param account_id: The Moov account ID.
        :param transfer_id: The transfer ID to reverse.
        :param amount: Amount to reverse in cents. Partial amounts will automatically trigger a refund instead of a cancellation.
        :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 = operations.CreateReversalRequest(
            x_idempotency_key=x_idempotency_key,
            account_id=account_id,
            transfer_id=transfer_id,
            create_reversal=components.CreateReversal(
                amount=amount,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/reversals",
            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,
            _globals=operations.CreateReversalGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_reversal if request is not None else None,
                False,
                True,
                "json",
                Optional[components.CreateReversal],
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createReversal",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "202"], "application/json"):
            return operations.CreateReversalResponse(
                result=unmarshal_json_response(components.Reversal, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["400", "409"], "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.ReversalValidationErrorData, http_res
            )
            raise errors.ReversalValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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_reversal_async(
        self,
        *,
        x_idempotency_key: str,
        account_id: str,
        transfer_id: str,
        amount: int,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.CreateReversalResponse:
        r"""Reverses a card transfer by initiating a cancellation or refund depending on the transaction status.
        Read our [reversals guide](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/)
        to learn more.

        To access this endpoint using a [token](https://docs.moov.io/api/authentication/access-tokens/) you'll need
        to specify the `/accounts/{accountID}/transfers.write` scope.

        :param x_idempotency_key: Prevents duplicate reversals from being created.
        :param account_id: The Moov account ID.
        :param transfer_id: The transfer ID to reverse.
        :param amount: Amount to reverse in cents. Partial amounts will automatically trigger a refund instead of a cancellation.
        :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 = operations.CreateReversalRequest(
            x_idempotency_key=x_idempotency_key,
            account_id=account_id,
            transfer_id=transfer_id,
            create_reversal=components.CreateReversal(
                amount=amount,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounts/{accountID}/transfers/{transferID}/reversals",
            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,
            _globals=operations.CreateReversalGlobals(
                x_moov_version=self.sdk_configuration.globals.x_moov_version,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.create_reversal if request is not None else None,
                False,
                True,
                "json",
                Optional[components.CreateReversal],
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

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

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="createReversal",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "409",
                "422",
                "429",
                "4XX",
                "500",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "202"], "application/json"):
            return operations.CreateReversalResponse(
                result=unmarshal_json_response(components.Reversal, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, ["400", "409"], "application/json"):
            response_data = unmarshal_json_response(errors.GenericErrorData, http_res)
            raise errors.GenericError(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                errors.ReversalValidationErrorData, http_res
            )
            raise errors.ReversalValidationError(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404", "429"], "*"):
            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, ["500", "504"], "*"):
            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, "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)
