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

from .basesdk import BaseSDK
from .sdkconfiguration import SDKConfiguration
from datetime import datetime
from gr4vy import errors, models, utils
from gr4vy._hooks import HookContext
from gr4vy.actions import Actions
from gr4vy.events import Events
from gr4vy.transactions_refunds import TransactionsRefunds
from gr4vy.transactions_settlements import TransactionsSettlements
from gr4vy.types import OptionalNullable, UNSET
from gr4vy.utils import get_security_from_env
from gr4vy.utils.unmarshal_json_response import unmarshal_json_response
from jsonpath import JSONPath
from typing import Any, Dict, List, Mapping, Optional, Union


class Transactions(BaseSDK):
    refunds: TransactionsRefunds
    actions: Actions
    events: Events
    settlements: TransactionsSettlements

    def __init__(
        self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
    ) -> None:
        BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
        self.sdk_configuration = sdk_config
        self._init_sdks()

    def _init_sdks(self):
        self.refunds = TransactionsRefunds(
            self.sdk_configuration, parent_ref=self.parent_ref
        )
        self.actions = Actions(self.sdk_configuration, parent_ref=self.parent_ref)
        self.events = Events(self.sdk_configuration, parent_ref=self.parent_ref)
        self.settlements = TransactionsSettlements(
            self.sdk_configuration, parent_ref=self.parent_ref
        )

    def list(
        self,
        *,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        created_at_lte: OptionalNullable[datetime] = UNSET,
        created_at_gte: OptionalNullable[datetime] = UNSET,
        updated_at_lte: OptionalNullable[datetime] = UNSET,
        updated_at_gte: OptionalNullable[datetime] = UNSET,
        search: OptionalNullable[str] = UNSET,
        buyer_external_identifier: OptionalNullable[str] = UNSET,
        buyer_id: OptionalNullable[str] = UNSET,
        buyer_email_address: OptionalNullable[str] = UNSET,
        ip_address: OptionalNullable[str] = UNSET,
        status: OptionalNullable[List[models.TransactionStatus]] = UNSET,
        id: OptionalNullable[str] = UNSET,
        payment_service_transaction_id: OptionalNullable[str] = UNSET,
        external_identifier: OptionalNullable[str] = UNSET,
        metadata: OptionalNullable[List[str]] = UNSET,
        amount_eq: OptionalNullable[int] = UNSET,
        amount_lte: OptionalNullable[int] = UNSET,
        amount_gte: OptionalNullable[int] = UNSET,
        currency: OptionalNullable[List[str]] = UNSET,
        country: OptionalNullable[List[str]] = UNSET,
        payment_service_id: OptionalNullable[List[str]] = UNSET,
        payment_method_id: OptionalNullable[str] = UNSET,
        payment_method_label: OptionalNullable[str] = UNSET,
        payment_method_scheme: OptionalNullable[List[str]] = UNSET,
        payment_method_country: OptionalNullable[str] = UNSET,
        payment_method_fingerprint: OptionalNullable[str] = UNSET,
        method: OptionalNullable[List[models.Method]] = UNSET,
        error_code: OptionalNullable[List[str]] = UNSET,
        has_refunds: OptionalNullable[bool] = UNSET,
        pending_review: OptionalNullable[bool] = UNSET,
        checkout_session_id: OptionalNullable[str] = UNSET,
        reconciliation_id: OptionalNullable[str] = UNSET,
        has_gift_card_redemptions: OptionalNullable[bool] = UNSET,
        gift_card_id: OptionalNullable[str] = UNSET,
        gift_card_last4: OptionalNullable[str] = UNSET,
        has_settlements: OptionalNullable[bool] = UNSET,
        payment_method_bin: OptionalNullable[str] = UNSET,
        payment_source: OptionalNullable[List[models.TransactionPaymentSource]] = UNSET,
        is_subsequent_payment: OptionalNullable[bool] = UNSET,
        merchant_initiated: OptionalNullable[bool] = UNSET,
        used_3ds: OptionalNullable[bool] = UNSET,
        disputed: OptionalNullable[bool] = UNSET,
        buyer_search: OptionalNullable[List[str]] = UNSET,
        merchant_account_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,
    ) -> Optional[models.ListTransactionsResponse]:
        r"""List transactions

        Returns a paginated list of transactions for the merchant account, sorted by most recently updated. You can filter, sort, and search transactions using query parameters.

        :param cursor: A pointer to the page of results to return.
        :param limit: The maximum number of items that are at returned.
        :param created_at_lte: Filters the results to only transactions created before this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param created_at_gte: Filters the results to only transactions created after this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param updated_at_lte: Filters the results to only transactions updated before this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param updated_at_gte: Filters the results to only transactions updated after this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param search:
        :param buyer_external_identifier:
        :param buyer_id:
        :param buyer_email_address:
        :param ip_address:
        :param status: Filters the results to only the transactions that have a `status` that matches with any of the provided status values.
        :param id:
        :param payment_service_transaction_id:
        :param external_identifier:
        :param metadata: Filters for transactions where their `metadata` values contain all of the provided `metadata` keys. The value sent for `metadata` must be formatted as a JSON string, and all keys and values must be strings. This value should also be URL encoded.
        :param amount_eq: Filters for transactions that have an `amount` that is equal to the provided `amount_eq` value.
        :param amount_lte: Filters for transactions that have an `amount` that is less than or equal to the `amount_lte` value.
        :param amount_gte: Filters for transactions that have an `amount` that is greater than or equal to the `amount_gte` value.
        :param currency: Filters for transactions that have matching `currency` values. The `currency` values provided must be formatted as 3-letter ISO currency code.
        :param country: Filters for transactions that have matching `country` values.
        :param payment_service_id: Filters for transactions that were processed by the provided `payment_service_id` values.
        :param payment_method_id:
        :param payment_method_label:
        :param payment_method_scheme: Filters for transactions where the `payment_method_scheme` matches one of the provided values.
        :param payment_method_country: Filters for transactions that have a payment method with a country that matches with the provided value.
        :param payment_method_fingerprint:
        :param method: Filters for transactions that have matching `method` values.
        :param error_code: Filters for transactions where the `error_code` matches one for the provided values.
        :param has_refunds: Filters for transactions with refunds.
        :param pending_review: Filters for transactions with a pending manual anti-fraud review.
        :param checkout_session_id: Filters for transactions where the `checkout_session_id` matches the provided value.
        :param reconciliation_id: Filters for transactions where the `reconciliation_id` matches the provided value.
        :param has_gift_card_redemptions: Filters for transactions with gift card redemptions.
        :param gift_card_id: Filters for transactions where a gift card used has an `id` that matches the provided value.
        :param gift_card_last4: Filters for transactions that have at least one gift card redemption where the last 4 digits of its gift card number matches exactly with the provided value.
        :param has_settlements: Filters for transactions that have at least one associated settlement record.
        :param payment_method_bin: Filter for transactions that have a card with a BIN that matches exactly with the provided value.
        :param payment_source: Filters the results to only the transactions that have a payment source that matches with any of the provided values.
        :param is_subsequent_payment: Filters for transactions where the `is_subsequent_payment` matches the provided value.
        :param merchant_initiated: Filters for transactions where the `merchant_initiated` matches the provided value.
        :param used_3ds: Filters for transactions that attempted 3DS authentication or not.
        :param disputed: Filters for transactions that have been disputed.
        :param buyer_search: Filters the results to only get the items for which some of the buyer data contains exactly the provided `buyer_search` values.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.ListTransactionsRequest(
            cursor=cursor,
            limit=limit,
            created_at_lte=created_at_lte,
            created_at_gte=created_at_gte,
            updated_at_lte=updated_at_lte,
            updated_at_gte=updated_at_gte,
            search=search,
            buyer_external_identifier=buyer_external_identifier,
            buyer_id=buyer_id,
            buyer_email_address=buyer_email_address,
            ip_address=ip_address,
            status=status,
            id=id,
            payment_service_transaction_id=payment_service_transaction_id,
            external_identifier=external_identifier,
            metadata=metadata,
            amount_eq=amount_eq,
            amount_lte=amount_lte,
            amount_gte=amount_gte,
            currency=currency,
            country=country,
            payment_service_id=payment_service_id,
            payment_method_id=payment_method_id,
            payment_method_label=payment_method_label,
            payment_method_scheme=payment_method_scheme,
            payment_method_country=payment_method_country,
            payment_method_fingerprint=payment_method_fingerprint,
            method=method,
            error_code=error_code,
            has_refunds=has_refunds,
            pending_review=pending_review,
            checkout_session_id=checkout_session_id,
            reconciliation_id=reconciliation_id,
            has_gift_card_redemptions=has_gift_card_redemptions,
            gift_card_id=gift_card_id,
            gift_card_last4=gift_card_last4,
            has_settlements=has_settlements,
            payment_method_bin=payment_method_bin,
            payment_source=payment_source,
            is_subsequent_payment=is_subsequent_payment,
            merchant_initiated=merchant_initiated,
            used_3ds=used_3ds,
            disputed=disputed,
            buyer_search=buyer_search,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request(
            method="GET",
            path="/transactions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.ListTransactionsGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(200, 200, 1, 1000), True
                )

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

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

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

            if len(next_cursor) == 0:
                return None

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

            return self.list(
                cursor=next_cursor,
                limit=limit,
                created_at_lte=created_at_lte,
                created_at_gte=created_at_gte,
                updated_at_lte=updated_at_lte,
                updated_at_gte=updated_at_gte,
                search=search,
                buyer_external_identifier=buyer_external_identifier,
                buyer_id=buyer_id,
                buyer_email_address=buyer_email_address,
                ip_address=ip_address,
                status=status,
                id=id,
                payment_service_transaction_id=payment_service_transaction_id,
                external_identifier=external_identifier,
                metadata=metadata,
                amount_eq=amount_eq,
                amount_lte=amount_lte,
                amount_gte=amount_gte,
                currency=currency,
                country=country,
                payment_service_id=payment_service_id,
                payment_method_id=payment_method_id,
                payment_method_label=payment_method_label,
                payment_method_scheme=payment_method_scheme,
                payment_method_country=payment_method_country,
                payment_method_fingerprint=payment_method_fingerprint,
                method=method,
                error_code=error_code,
                has_refunds=has_refunds,
                pending_review=pending_review,
                checkout_session_id=checkout_session_id,
                reconciliation_id=reconciliation_id,
                has_gift_card_redemptions=has_gift_card_redemptions,
                gift_card_id=gift_card_id,
                gift_card_last4=gift_card_last4,
                has_settlements=has_settlements,
                payment_method_bin=payment_method_bin,
                payment_source=payment_source,
                is_subsequent_payment=is_subsequent_payment,
                merchant_initiated=merchant_initiated,
                used_3ds=used_3ds,
                disputed=disputed,
                buyer_search=buyer_search,
                merchant_account_id=merchant_account_id,
                retries=retries,
            )

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

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

    async def list_async(
        self,
        *,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        created_at_lte: OptionalNullable[datetime] = UNSET,
        created_at_gte: OptionalNullable[datetime] = UNSET,
        updated_at_lte: OptionalNullable[datetime] = UNSET,
        updated_at_gte: OptionalNullable[datetime] = UNSET,
        search: OptionalNullable[str] = UNSET,
        buyer_external_identifier: OptionalNullable[str] = UNSET,
        buyer_id: OptionalNullable[str] = UNSET,
        buyer_email_address: OptionalNullable[str] = UNSET,
        ip_address: OptionalNullable[str] = UNSET,
        status: OptionalNullable[List[models.TransactionStatus]] = UNSET,
        id: OptionalNullable[str] = UNSET,
        payment_service_transaction_id: OptionalNullable[str] = UNSET,
        external_identifier: OptionalNullable[str] = UNSET,
        metadata: OptionalNullable[List[str]] = UNSET,
        amount_eq: OptionalNullable[int] = UNSET,
        amount_lte: OptionalNullable[int] = UNSET,
        amount_gte: OptionalNullable[int] = UNSET,
        currency: OptionalNullable[List[str]] = UNSET,
        country: OptionalNullable[List[str]] = UNSET,
        payment_service_id: OptionalNullable[List[str]] = UNSET,
        payment_method_id: OptionalNullable[str] = UNSET,
        payment_method_label: OptionalNullable[str] = UNSET,
        payment_method_scheme: OptionalNullable[List[str]] = UNSET,
        payment_method_country: OptionalNullable[str] = UNSET,
        payment_method_fingerprint: OptionalNullable[str] = UNSET,
        method: OptionalNullable[List[models.Method]] = UNSET,
        error_code: OptionalNullable[List[str]] = UNSET,
        has_refunds: OptionalNullable[bool] = UNSET,
        pending_review: OptionalNullable[bool] = UNSET,
        checkout_session_id: OptionalNullable[str] = UNSET,
        reconciliation_id: OptionalNullable[str] = UNSET,
        has_gift_card_redemptions: OptionalNullable[bool] = UNSET,
        gift_card_id: OptionalNullable[str] = UNSET,
        gift_card_last4: OptionalNullable[str] = UNSET,
        has_settlements: OptionalNullable[bool] = UNSET,
        payment_method_bin: OptionalNullable[str] = UNSET,
        payment_source: OptionalNullable[List[models.TransactionPaymentSource]] = UNSET,
        is_subsequent_payment: OptionalNullable[bool] = UNSET,
        merchant_initiated: OptionalNullable[bool] = UNSET,
        used_3ds: OptionalNullable[bool] = UNSET,
        disputed: OptionalNullable[bool] = UNSET,
        buyer_search: OptionalNullable[List[str]] = UNSET,
        merchant_account_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,
    ) -> Optional[models.ListTransactionsResponse]:
        r"""List transactions

        Returns a paginated list of transactions for the merchant account, sorted by most recently updated. You can filter, sort, and search transactions using query parameters.

        :param cursor: A pointer to the page of results to return.
        :param limit: The maximum number of items that are at returned.
        :param created_at_lte: Filters the results to only transactions created before this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param created_at_gte: Filters the results to only transactions created after this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param updated_at_lte: Filters the results to only transactions updated before this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param updated_at_gte: Filters the results to only transactions updated after this ISO date-time string. The time zone must be included. Ensure that the date-time string is URL encoded, e.g. `2022-01-01T12:00:00+08:00` must be encoded as `2022-01-01T12%3A00%3A00%2B08%3A00`.
        :param search:
        :param buyer_external_identifier:
        :param buyer_id:
        :param buyer_email_address:
        :param ip_address:
        :param status: Filters the results to only the transactions that have a `status` that matches with any of the provided status values.
        :param id:
        :param payment_service_transaction_id:
        :param external_identifier:
        :param metadata: Filters for transactions where their `metadata` values contain all of the provided `metadata` keys. The value sent for `metadata` must be formatted as a JSON string, and all keys and values must be strings. This value should also be URL encoded.
        :param amount_eq: Filters for transactions that have an `amount` that is equal to the provided `amount_eq` value.
        :param amount_lte: Filters for transactions that have an `amount` that is less than or equal to the `amount_lte` value.
        :param amount_gte: Filters for transactions that have an `amount` that is greater than or equal to the `amount_gte` value.
        :param currency: Filters for transactions that have matching `currency` values. The `currency` values provided must be formatted as 3-letter ISO currency code.
        :param country: Filters for transactions that have matching `country` values.
        :param payment_service_id: Filters for transactions that were processed by the provided `payment_service_id` values.
        :param payment_method_id:
        :param payment_method_label:
        :param payment_method_scheme: Filters for transactions where the `payment_method_scheme` matches one of the provided values.
        :param payment_method_country: Filters for transactions that have a payment method with a country that matches with the provided value.
        :param payment_method_fingerprint:
        :param method: Filters for transactions that have matching `method` values.
        :param error_code: Filters for transactions where the `error_code` matches one for the provided values.
        :param has_refunds: Filters for transactions with refunds.
        :param pending_review: Filters for transactions with a pending manual anti-fraud review.
        :param checkout_session_id: Filters for transactions where the `checkout_session_id` matches the provided value.
        :param reconciliation_id: Filters for transactions where the `reconciliation_id` matches the provided value.
        :param has_gift_card_redemptions: Filters for transactions with gift card redemptions.
        :param gift_card_id: Filters for transactions where a gift card used has an `id` that matches the provided value.
        :param gift_card_last4: Filters for transactions that have at least one gift card redemption where the last 4 digits of its gift card number matches exactly with the provided value.
        :param has_settlements: Filters for transactions that have at least one associated settlement record.
        :param payment_method_bin: Filter for transactions that have a card with a BIN that matches exactly with the provided value.
        :param payment_source: Filters the results to only the transactions that have a payment source that matches with any of the provided values.
        :param is_subsequent_payment: Filters for transactions where the `is_subsequent_payment` matches the provided value.
        :param merchant_initiated: Filters for transactions where the `merchant_initiated` matches the provided value.
        :param used_3ds: Filters for transactions that attempted 3DS authentication or not.
        :param disputed: Filters for transactions that have been disputed.
        :param buyer_search: Filters the results to only get the items for which some of the buyer data contains exactly the provided `buyer_search` values.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.ListTransactionsRequest(
            cursor=cursor,
            limit=limit,
            created_at_lte=created_at_lte,
            created_at_gte=created_at_gte,
            updated_at_lte=updated_at_lte,
            updated_at_gte=updated_at_gte,
            search=search,
            buyer_external_identifier=buyer_external_identifier,
            buyer_id=buyer_id,
            buyer_email_address=buyer_email_address,
            ip_address=ip_address,
            status=status,
            id=id,
            payment_service_transaction_id=payment_service_transaction_id,
            external_identifier=external_identifier,
            metadata=metadata,
            amount_eq=amount_eq,
            amount_lte=amount_lte,
            amount_gte=amount_gte,
            currency=currency,
            country=country,
            payment_service_id=payment_service_id,
            payment_method_id=payment_method_id,
            payment_method_label=payment_method_label,
            payment_method_scheme=payment_method_scheme,
            payment_method_country=payment_method_country,
            payment_method_fingerprint=payment_method_fingerprint,
            method=method,
            error_code=error_code,
            has_refunds=has_refunds,
            pending_review=pending_review,
            checkout_session_id=checkout_session_id,
            reconciliation_id=reconciliation_id,
            has_gift_card_redemptions=has_gift_card_redemptions,
            gift_card_id=gift_card_id,
            gift_card_last4=gift_card_last4,
            has_settlements=has_settlements,
            payment_method_bin=payment_method_bin,
            payment_source=payment_source,
            is_subsequent_payment=is_subsequent_payment,
            merchant_initiated=merchant_initiated,
            used_3ds=used_3ds,
            disputed=disputed,
            buyer_search=buyer_search,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/transactions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.ListTransactionsGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(200, 200, 1, 1000), True
                )

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

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

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

            if len(next_cursor) == 0:
                return None

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

            return self.list(
                cursor=next_cursor,
                limit=limit,
                created_at_lte=created_at_lte,
                created_at_gte=created_at_gte,
                updated_at_lte=updated_at_lte,
                updated_at_gte=updated_at_gte,
                search=search,
                buyer_external_identifier=buyer_external_identifier,
                buyer_id=buyer_id,
                buyer_email_address=buyer_email_address,
                ip_address=ip_address,
                status=status,
                id=id,
                payment_service_transaction_id=payment_service_transaction_id,
                external_identifier=external_identifier,
                metadata=metadata,
                amount_eq=amount_eq,
                amount_lte=amount_lte,
                amount_gte=amount_gte,
                currency=currency,
                country=country,
                payment_service_id=payment_service_id,
                payment_method_id=payment_method_id,
                payment_method_label=payment_method_label,
                payment_method_scheme=payment_method_scheme,
                payment_method_country=payment_method_country,
                payment_method_fingerprint=payment_method_fingerprint,
                method=method,
                error_code=error_code,
                has_refunds=has_refunds,
                pending_review=pending_review,
                checkout_session_id=checkout_session_id,
                reconciliation_id=reconciliation_id,
                has_gift_card_redemptions=has_gift_card_redemptions,
                gift_card_id=gift_card_id,
                gift_card_last4=gift_card_last4,
                has_settlements=has_settlements,
                payment_method_bin=payment_method_bin,
                payment_source=payment_source,
                is_subsequent_payment=is_subsequent_payment,
                merchant_initiated=merchant_initiated,
                used_3ds=used_3ds,
                disputed=disputed,
                buyer_search=buyer_search,
                merchant_account_id=merchant_account_id,
                retries=retries,
            )

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

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

    def create(
        self,
        *,
        amount: int,
        currency: str,
        merchant_account_id: Optional[str] = None,
        idempotency_key: OptionalNullable[str] = UNSET,
        x_forwarded_for: Optional[str] = None,
        country: OptionalNullable[str] = UNSET,
        payment_method: OptionalNullable[
            Union[
                models.TransactionCreatePaymentMethod,
                models.TransactionCreatePaymentMethodTypedDict,
            ]
        ] = UNSET,
        buyer: OptionalNullable[
            Union[models.GuestBuyer, models.GuestBuyerTypedDict]
        ] = UNSET,
        buyer_id: OptionalNullable[str] = UNSET,
        buyer_external_identifier: OptionalNullable[str] = UNSET,
        gift_cards: OptionalNullable[
            Union[List[models.GiftCardUnion], List[models.GiftCardUnionTypedDict]]
        ] = UNSET,
        external_identifier: OptionalNullable[str] = UNSET,
        intent: Optional[models.TransactionIntent] = None,
        store: Optional[bool] = False,
        three_d_secure_data: OptionalNullable[
            Union[models.ThreeDSecureData, models.ThreeDSecureDataTypedDict]
        ] = UNSET,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        is_subsequent_payment: Optional[bool] = False,
        merchant_initiated: Optional[bool] = False,
        payment_source: Optional[models.TransactionPaymentSource] = None,
        airline: OptionalNullable[
            Union[models.Airline, models.AirlineTypedDict]
        ] = UNSET,
        cart_items: OptionalNullable[
            Union[List[models.CartItem], List[models.CartItemTypedDict]]
        ] = UNSET,
        statement_descriptor: OptionalNullable[
            Union[models.StatementDescriptor, models.StatementDescriptorTypedDict]
        ] = UNSET,
        previous_scheme_transaction_id: OptionalNullable[str] = UNSET,
        browser_info: OptionalNullable[
            Union[models.BrowserInfo, models.BrowserInfoTypedDict]
        ] = UNSET,
        shipping_details_id: OptionalNullable[str] = UNSET,
        connection_options: OptionalNullable[
            Union[
                models.TransactionConnectionOptions,
                models.TransactionConnectionOptionsTypedDict,
            ]
        ] = UNSET,
        async_capture: Optional[bool] = False,
        anti_fraud_fingerprint: OptionalNullable[str] = UNSET,
        payment_service_id: OptionalNullable[str] = UNSET,
        account_funding_transaction: Optional[bool] = False,
        allow_partial_authorization: Optional[bool] = False,
        recipient: OptionalNullable[
            Union[models.Recipient, models.RecipientTypedDict]
        ] = UNSET,
        installment_count: OptionalNullable[int] = UNSET,
        tax_amount: OptionalNullable[int] = UNSET,
        merchant_tax_id: OptionalNullable[str] = UNSET,
        purchase_order_number: OptionalNullable[str] = UNSET,
        customer_reference_number: OptionalNullable[str] = UNSET,
        amount_includes_tax: OptionalNullable[bool] = UNSET,
        supplier_order_number: OptionalNullable[str] = UNSET,
        duty_amount: OptionalNullable[int] = UNSET,
        shipping_amount: OptionalNullable[int] = UNSET,
        integration_client: OptionalNullable[models.IntegrationClient] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Create transaction

        Create a new transaction using a supported payment method. If additional buyer authorization is required, an approval URL will be returned. Duplicated gift card numbers are not supported.

        :param amount: The monetary amount for this transaction, in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`. If the `intent` is set to `capture`, an amount greater than zero must be supplied. All gift card amounts are subtracted from this amount before the remainder is charged to the provided `payment_method`.
        :param currency: A supported ISO 4217 currency code. For redirect requests, this value must match the one specified for `currency` in `payment_method`.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param idempotency_key: A unique key that identifies this request. Providing this header will make this an idempotent request. We recommend using V4 UUIDs, or another random string with enough entropy to avoid collisions.
        :param x_forwarded_for: The IP address to forward from the customer. Use this when calling
            our API from the server side to ensure the customer's address is
            passed to downstream services, rather than your server IP.
        :param country: The 2-letter ISO code of the country where the transaction is processed. This is also used to filter the payment services that can process the transaction. If this value is provided for redirect requests and it's not `null`, it must match the one specified for `country` in `payment_method`. Otherwise, the value specified for `country` in `payment_method` will be assumed implicitly.
        :param payment_method: The optional payment method to use for this transaction. This field is required if no `gift_cards` have been added.
        :param buyer: Guest buyer details provided inline rather than creating a buyer resource beforehand and using the `buyer_id` or `buyer_external_identifier` keys. No buyer resource will be created on Gr4vy when used.
        :param buyer_id: The ID of the buyer to associate this payment method to. If this field is provided then the `buyer_external_identifier` field needs to be unset. If a stored payment method or gift card is provided, then the buyer for that payment method needs to match the buyer for this field.
        :param buyer_external_identifier: The `external_identifier` of the buyer to associate this payment method to. If this field is provided then the `buyer_id` field needs to be unset. If a stored payment method or gift card is provided, then the buyer for that payment method needs to match the buyer for this field.
        :param gift_cards: The optional gift card(s) to use for this transaction. At least one gift card is required if no other `payment_method` has been added. By default, only a maximum limit of 10 gift cards may be used in a single transaction. Please contact our team to change this limit.
        :param external_identifier: An external identifier that can be used to match the transaction against your own records.
        :param intent:
        :param store: Whether or not to also try and store the payment method with us so that it can be used again for future use. This is only supported for payment methods that support this feature. There are also a few restrictions on how the flag may be set:

            * The flag has to be set to `true` when the `payment_source` is set to `recurring` or `installment`, and `merchant_initiated` is set to `false`.
            * The flag has to be set to `false` (or not set) when using a previously vaulted payment method.
        :param three_d_secure_data: Pass through 3-D Secure data to support external 3-D Secure authorisation. If using an external 3-D Secure provider, you should not pass a `redirect_url` in the `payment_method` object for a transaction.
        :param metadata: Any additional information about the transaction that you would like to store as key-value pairs. This data is passed to payment service providers that support it.
        :param is_subsequent_payment: Indicates whether the transaction represents a subsequent payment coming from a setup recurring payment. Please note there are some restrictions on how this flag may be used.

            The flag can only be `false` (or not set) when the transaction meets one of the following criteria:

            * It is not `merchant_initiated`.
            * `payment_source` is set to `card_on_file`.

            The flag can only be set to `true` when the transaction meets one of the following criteria:
            * It is not `merchant_initiated`.
            * `payment_source` is set to `recurring` or `installment` and `merchant_initiated` is set to `true`.
            * `payment_source` is set to `card_on_file`.
        :param merchant_initiated: Indicates whether the transaction was initiated by the merchant (true) or customer (false).
        :param payment_source: The way payment method information made it to this transaction.
        :param airline: The airline addendum data which describes the airline booking associated with this transaction.
        :param cart_items: An array of cart items that represents the line items of a transaction.
        :param statement_descriptor: Details about the payment and the merchant which may end up on the (bank) statement for the payment.
        :param previous_scheme_transaction_id: A scheme's transaction identifier to use in connecting a merchant initiated transaction to a previous customer initiated transaction. If not provided, and a qualifying customer initiated transaction has been previously made with the stored payment method, then Gr4vy will populate this value with the identifier returned for that transaction. This field is also know as the Visa Transaction Identifier, or Mastercard Trace ID.
        :param browser_info: Information about the browser used by the buyer. This can be used by anti-fraud services.
        :param shipping_details_id: The unique identifier of a set of shipping details stored for the buyer. If provided, the created transaction will include a copy of the details at the point of transaction creation; i.e. it will not be affected by later changes to the detail in the database.
        :param connection_options: Allows for passing optional configuration per connection to take advantage of connection specific features. When provided, the data is only passed to the target connection type to prevent sharing configuration across connections. Please note that each of the keys this object are in kebab-case, for example `cybersource-anti-fraud` as they represent the ID of the connector. All the other keys will be snake case, for example `merchant_defined_data` or camel case to match an external API that the connector uses.
        :param async_capture: Whether to capture the transaction asynchronously.

            - When `async_capture` is `false` (default), the transaction is captured in the same request.
            - When `async_capture` is `true`, the transaction is automatically captured at a later time.

            Redirect transactions are not affected by this flag. This flag can only be set to `true` when `intent` is set to `capture`.
        :param anti_fraud_fingerprint: This field represents the fingerprint data to be passed to the active anti-fraud service.
        :param payment_service_id: The unique identifier of an existing payment service. When provided, the created transaction will be processed by the given payment service and any routing rules will be skipped.
        :param account_funding_transaction: Marks the transaction as an AFT. Requires the payment service to support this feature, and might `recipient` and `buyer` data
        :param allow_partial_authorization: Defines if the transaction will allow for a partial authorization.
        :param recipient: The recipient of any account to account funding. For use with AFTs.
        :param installment_count: The number of installments a buyer is required to make.
        :param tax_amount: The sales tax amount for this transaction, represented as a monetary amount in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`
        :param merchant_tax_id: Merchant tax ID (for example, EIN or VAT number).
        :param purchase_order_number: Invoice number or Purchase Order number.
        :param customer_reference_number: Customer code or reference.
        :param amount_includes_tax: Whether the tax is included in the amount.
        :param supplier_order_number: The merchant's unique identifier for the sales order or invoice.
        :param duty_amount: Total charges for import/export duties.
        :param shipping_amount: Total shipping amount.
        :param integration_client: Defines the client where the session for this transaction is going to be used. Please refer to the connections documentation for more guidance.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CreateTransactionRequest(
            merchant_account_id=merchant_account_id,
            idempotency_key=idempotency_key,
            x_forwarded_for=x_forwarded_for,
            transaction_create=models.TransactionCreate(
                amount=amount,
                currency=currency,
                country=country,
                payment_method=utils.get_pydantic_model(
                    payment_method,
                    OptionalNullable[models.TransactionCreatePaymentMethod],
                ),
                buyer=utils.get_pydantic_model(
                    buyer, OptionalNullable[models.GuestBuyer]
                ),
                buyer_id=buyer_id,
                buyer_external_identifier=buyer_external_identifier,
                gift_cards=utils.get_pydantic_model(
                    gift_cards, OptionalNullable[List[models.GiftCardUnion]]
                ),
                external_identifier=external_identifier,
                intent=intent,
                store=store,
                three_d_secure_data=utils.get_pydantic_model(
                    three_d_secure_data, OptionalNullable[models.ThreeDSecureData]
                ),
                metadata=metadata,
                is_subsequent_payment=is_subsequent_payment,
                merchant_initiated=merchant_initiated,
                payment_source=payment_source,
                airline=utils.get_pydantic_model(
                    airline, OptionalNullable[models.Airline]
                ),
                cart_items=utils.get_pydantic_model(
                    cart_items, OptionalNullable[List[models.CartItem]]
                ),
                statement_descriptor=utils.get_pydantic_model(
                    statement_descriptor, OptionalNullable[models.StatementDescriptor]
                ),
                previous_scheme_transaction_id=previous_scheme_transaction_id,
                browser_info=utils.get_pydantic_model(
                    browser_info, OptionalNullable[models.BrowserInfo]
                ),
                shipping_details_id=shipping_details_id,
                connection_options=utils.get_pydantic_model(
                    connection_options,
                    OptionalNullable[models.TransactionConnectionOptions],
                ),
                async_capture=async_capture,
                anti_fraud_fingerprint=anti_fraud_fingerprint,
                payment_service_id=payment_service_id,
                account_funding_transaction=account_funding_transaction,
                allow_partial_authorization=allow_partial_authorization,
                recipient=utils.get_pydantic_model(
                    recipient, OptionalNullable[models.Recipient]
                ),
                installment_count=installment_count,
                tax_amount=tax_amount,
                merchant_tax_id=merchant_tax_id,
                purchase_order_number=purchase_order_number,
                customer_reference_number=customer_reference_number,
                amount_includes_tax=amount_includes_tax,
                supplier_order_number=supplier_order_number,
                duty_amount=duty_amount,
                shipping_amount=shipping_amount,
                integration_client=integration_client,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/transactions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.CreateTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_create,
                False,
                False,
                "json",
                models.TransactionCreate,
            ),
            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="create_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def create_async(
        self,
        *,
        amount: int,
        currency: str,
        merchant_account_id: Optional[str] = None,
        idempotency_key: OptionalNullable[str] = UNSET,
        x_forwarded_for: Optional[str] = None,
        country: OptionalNullable[str] = UNSET,
        payment_method: OptionalNullable[
            Union[
                models.TransactionCreatePaymentMethod,
                models.TransactionCreatePaymentMethodTypedDict,
            ]
        ] = UNSET,
        buyer: OptionalNullable[
            Union[models.GuestBuyer, models.GuestBuyerTypedDict]
        ] = UNSET,
        buyer_id: OptionalNullable[str] = UNSET,
        buyer_external_identifier: OptionalNullable[str] = UNSET,
        gift_cards: OptionalNullable[
            Union[List[models.GiftCardUnion], List[models.GiftCardUnionTypedDict]]
        ] = UNSET,
        external_identifier: OptionalNullable[str] = UNSET,
        intent: Optional[models.TransactionIntent] = None,
        store: Optional[bool] = False,
        three_d_secure_data: OptionalNullable[
            Union[models.ThreeDSecureData, models.ThreeDSecureDataTypedDict]
        ] = UNSET,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        is_subsequent_payment: Optional[bool] = False,
        merchant_initiated: Optional[bool] = False,
        payment_source: Optional[models.TransactionPaymentSource] = None,
        airline: OptionalNullable[
            Union[models.Airline, models.AirlineTypedDict]
        ] = UNSET,
        cart_items: OptionalNullable[
            Union[List[models.CartItem], List[models.CartItemTypedDict]]
        ] = UNSET,
        statement_descriptor: OptionalNullable[
            Union[models.StatementDescriptor, models.StatementDescriptorTypedDict]
        ] = UNSET,
        previous_scheme_transaction_id: OptionalNullable[str] = UNSET,
        browser_info: OptionalNullable[
            Union[models.BrowserInfo, models.BrowserInfoTypedDict]
        ] = UNSET,
        shipping_details_id: OptionalNullable[str] = UNSET,
        connection_options: OptionalNullable[
            Union[
                models.TransactionConnectionOptions,
                models.TransactionConnectionOptionsTypedDict,
            ]
        ] = UNSET,
        async_capture: Optional[bool] = False,
        anti_fraud_fingerprint: OptionalNullable[str] = UNSET,
        payment_service_id: OptionalNullable[str] = UNSET,
        account_funding_transaction: Optional[bool] = False,
        allow_partial_authorization: Optional[bool] = False,
        recipient: OptionalNullable[
            Union[models.Recipient, models.RecipientTypedDict]
        ] = UNSET,
        installment_count: OptionalNullable[int] = UNSET,
        tax_amount: OptionalNullable[int] = UNSET,
        merchant_tax_id: OptionalNullable[str] = UNSET,
        purchase_order_number: OptionalNullable[str] = UNSET,
        customer_reference_number: OptionalNullable[str] = UNSET,
        amount_includes_tax: OptionalNullable[bool] = UNSET,
        supplier_order_number: OptionalNullable[str] = UNSET,
        duty_amount: OptionalNullable[int] = UNSET,
        shipping_amount: OptionalNullable[int] = UNSET,
        integration_client: OptionalNullable[models.IntegrationClient] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Create transaction

        Create a new transaction using a supported payment method. If additional buyer authorization is required, an approval URL will be returned. Duplicated gift card numbers are not supported.

        :param amount: The monetary amount for this transaction, in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`. If the `intent` is set to `capture`, an amount greater than zero must be supplied. All gift card amounts are subtracted from this amount before the remainder is charged to the provided `payment_method`.
        :param currency: A supported ISO 4217 currency code. For redirect requests, this value must match the one specified for `currency` in `payment_method`.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param idempotency_key: A unique key that identifies this request. Providing this header will make this an idempotent request. We recommend using V4 UUIDs, or another random string with enough entropy to avoid collisions.
        :param x_forwarded_for: The IP address to forward from the customer. Use this when calling
            our API from the server side to ensure the customer's address is
            passed to downstream services, rather than your server IP.
        :param country: The 2-letter ISO code of the country where the transaction is processed. This is also used to filter the payment services that can process the transaction. If this value is provided for redirect requests and it's not `null`, it must match the one specified for `country` in `payment_method`. Otherwise, the value specified for `country` in `payment_method` will be assumed implicitly.
        :param payment_method: The optional payment method to use for this transaction. This field is required if no `gift_cards` have been added.
        :param buyer: Guest buyer details provided inline rather than creating a buyer resource beforehand and using the `buyer_id` or `buyer_external_identifier` keys. No buyer resource will be created on Gr4vy when used.
        :param buyer_id: The ID of the buyer to associate this payment method to. If this field is provided then the `buyer_external_identifier` field needs to be unset. If a stored payment method or gift card is provided, then the buyer for that payment method needs to match the buyer for this field.
        :param buyer_external_identifier: The `external_identifier` of the buyer to associate this payment method to. If this field is provided then the `buyer_id` field needs to be unset. If a stored payment method or gift card is provided, then the buyer for that payment method needs to match the buyer for this field.
        :param gift_cards: The optional gift card(s) to use for this transaction. At least one gift card is required if no other `payment_method` has been added. By default, only a maximum limit of 10 gift cards may be used in a single transaction. Please contact our team to change this limit.
        :param external_identifier: An external identifier that can be used to match the transaction against your own records.
        :param intent:
        :param store: Whether or not to also try and store the payment method with us so that it can be used again for future use. This is only supported for payment methods that support this feature. There are also a few restrictions on how the flag may be set:

            * The flag has to be set to `true` when the `payment_source` is set to `recurring` or `installment`, and `merchant_initiated` is set to `false`.
            * The flag has to be set to `false` (or not set) when using a previously vaulted payment method.
        :param three_d_secure_data: Pass through 3-D Secure data to support external 3-D Secure authorisation. If using an external 3-D Secure provider, you should not pass a `redirect_url` in the `payment_method` object for a transaction.
        :param metadata: Any additional information about the transaction that you would like to store as key-value pairs. This data is passed to payment service providers that support it.
        :param is_subsequent_payment: Indicates whether the transaction represents a subsequent payment coming from a setup recurring payment. Please note there are some restrictions on how this flag may be used.

            The flag can only be `false` (or not set) when the transaction meets one of the following criteria:

            * It is not `merchant_initiated`.
            * `payment_source` is set to `card_on_file`.

            The flag can only be set to `true` when the transaction meets one of the following criteria:
            * It is not `merchant_initiated`.
            * `payment_source` is set to `recurring` or `installment` and `merchant_initiated` is set to `true`.
            * `payment_source` is set to `card_on_file`.
        :param merchant_initiated: Indicates whether the transaction was initiated by the merchant (true) or customer (false).
        :param payment_source: The way payment method information made it to this transaction.
        :param airline: The airline addendum data which describes the airline booking associated with this transaction.
        :param cart_items: An array of cart items that represents the line items of a transaction.
        :param statement_descriptor: Details about the payment and the merchant which may end up on the (bank) statement for the payment.
        :param previous_scheme_transaction_id: A scheme's transaction identifier to use in connecting a merchant initiated transaction to a previous customer initiated transaction. If not provided, and a qualifying customer initiated transaction has been previously made with the stored payment method, then Gr4vy will populate this value with the identifier returned for that transaction. This field is also know as the Visa Transaction Identifier, or Mastercard Trace ID.
        :param browser_info: Information about the browser used by the buyer. This can be used by anti-fraud services.
        :param shipping_details_id: The unique identifier of a set of shipping details stored for the buyer. If provided, the created transaction will include a copy of the details at the point of transaction creation; i.e. it will not be affected by later changes to the detail in the database.
        :param connection_options: Allows for passing optional configuration per connection to take advantage of connection specific features. When provided, the data is only passed to the target connection type to prevent sharing configuration across connections. Please note that each of the keys this object are in kebab-case, for example `cybersource-anti-fraud` as they represent the ID of the connector. All the other keys will be snake case, for example `merchant_defined_data` or camel case to match an external API that the connector uses.
        :param async_capture: Whether to capture the transaction asynchronously.

            - When `async_capture` is `false` (default), the transaction is captured in the same request.
            - When `async_capture` is `true`, the transaction is automatically captured at a later time.

            Redirect transactions are not affected by this flag. This flag can only be set to `true` when `intent` is set to `capture`.
        :param anti_fraud_fingerprint: This field represents the fingerprint data to be passed to the active anti-fraud service.
        :param payment_service_id: The unique identifier of an existing payment service. When provided, the created transaction will be processed by the given payment service and any routing rules will be skipped.
        :param account_funding_transaction: Marks the transaction as an AFT. Requires the payment service to support this feature, and might `recipient` and `buyer` data
        :param allow_partial_authorization: Defines if the transaction will allow for a partial authorization.
        :param recipient: The recipient of any account to account funding. For use with AFTs.
        :param installment_count: The number of installments a buyer is required to make.
        :param tax_amount: The sales tax amount for this transaction, represented as a monetary amount in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`
        :param merchant_tax_id: Merchant tax ID (for example, EIN or VAT number).
        :param purchase_order_number: Invoice number or Purchase Order number.
        :param customer_reference_number: Customer code or reference.
        :param amount_includes_tax: Whether the tax is included in the amount.
        :param supplier_order_number: The merchant's unique identifier for the sales order or invoice.
        :param duty_amount: Total charges for import/export duties.
        :param shipping_amount: Total shipping amount.
        :param integration_client: Defines the client where the session for this transaction is going to be used. Please refer to the connections documentation for more guidance.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CreateTransactionRequest(
            merchant_account_id=merchant_account_id,
            idempotency_key=idempotency_key,
            x_forwarded_for=x_forwarded_for,
            transaction_create=models.TransactionCreate(
                amount=amount,
                currency=currency,
                country=country,
                payment_method=utils.get_pydantic_model(
                    payment_method,
                    OptionalNullable[models.TransactionCreatePaymentMethod],
                ),
                buyer=utils.get_pydantic_model(
                    buyer, OptionalNullable[models.GuestBuyer]
                ),
                buyer_id=buyer_id,
                buyer_external_identifier=buyer_external_identifier,
                gift_cards=utils.get_pydantic_model(
                    gift_cards, OptionalNullable[List[models.GiftCardUnion]]
                ),
                external_identifier=external_identifier,
                intent=intent,
                store=store,
                three_d_secure_data=utils.get_pydantic_model(
                    three_d_secure_data, OptionalNullable[models.ThreeDSecureData]
                ),
                metadata=metadata,
                is_subsequent_payment=is_subsequent_payment,
                merchant_initiated=merchant_initiated,
                payment_source=payment_source,
                airline=utils.get_pydantic_model(
                    airline, OptionalNullable[models.Airline]
                ),
                cart_items=utils.get_pydantic_model(
                    cart_items, OptionalNullable[List[models.CartItem]]
                ),
                statement_descriptor=utils.get_pydantic_model(
                    statement_descriptor, OptionalNullable[models.StatementDescriptor]
                ),
                previous_scheme_transaction_id=previous_scheme_transaction_id,
                browser_info=utils.get_pydantic_model(
                    browser_info, OptionalNullable[models.BrowserInfo]
                ),
                shipping_details_id=shipping_details_id,
                connection_options=utils.get_pydantic_model(
                    connection_options,
                    OptionalNullable[models.TransactionConnectionOptions],
                ),
                async_capture=async_capture,
                anti_fraud_fingerprint=anti_fraud_fingerprint,
                payment_service_id=payment_service_id,
                account_funding_transaction=account_funding_transaction,
                allow_partial_authorization=allow_partial_authorization,
                recipient=utils.get_pydantic_model(
                    recipient, OptionalNullable[models.Recipient]
                ),
                installment_count=installment_count,
                tax_amount=tax_amount,
                merchant_tax_id=merchant_tax_id,
                purchase_order_number=purchase_order_number,
                customer_reference_number=customer_reference_number,
                amount_includes_tax=amount_includes_tax,
                supplier_order_number=supplier_order_number,
                duty_amount=duty_amount,
                shipping_amount=shipping_amount,
                integration_client=integration_client,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/transactions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.CreateTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_create,
                False,
                False,
                "json",
                models.TransactionCreate,
            ),
            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="create_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    def get(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Get transaction

        Retrieve the details of a transaction by its unique identifier.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.GetTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

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

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(200, 200, 1, 1000), True
                )

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

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

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

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

    async def get_async(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Get transaction

        Retrieve the details of a transaction by its unique identifier.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.GetTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

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

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(200, 200, 1, 1000), True
                )

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

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

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

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

    def update(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        external_identifier: OptionalNullable[str] = UNSET,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        connection_options: OptionalNullable[
            Union[
                models.TransactionConnectionOptions,
                models.TransactionConnectionOptionsTypedDict,
            ]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Manually update a transaction

        Manually updates a transaction.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param external_identifier: An external identifier that can be used to match the transaction against your own records.
        :param metadata: Additional information about the transaction stored as key-value pairs. If provided, the whole value will be overridden.
        :param connection_options: Allows for passing optional configuration per connection to take advantage of connection specific features. When provided, the data is only passed to the target connection type to prevent sharing configuration across connections. Please note that each of the keys this object are in kebab-case, for example `cybersource-anti-fraud` as they represent the ID of the connector. All the other keys will be snake case, for example `merchant_defined_data` or camel case to match an external API that the connector uses. If provided, the whole value will be overridden.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.UpdateTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
            transaction_update=models.TransactionUpdate(
                external_identifier=external_identifier,
                metadata=metadata,
                connection_options=utils.get_pydantic_model(
                    connection_options,
                    OptionalNullable[models.TransactionConnectionOptions],
                ),
            ),
        )

        req = self._build_request(
            method="PUT",
            path="/transactions/{transaction_id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.UpdateTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_update,
                False,
                False,
                "json",
                models.TransactionUpdate,
            ),
            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="update_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def update_async(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        external_identifier: OptionalNullable[str] = UNSET,
        metadata: OptionalNullable[Dict[str, str]] = UNSET,
        connection_options: OptionalNullable[
            Union[
                models.TransactionConnectionOptions,
                models.TransactionConnectionOptionsTypedDict,
            ]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Manually update a transaction

        Manually updates a transaction.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param external_identifier: An external identifier that can be used to match the transaction against your own records.
        :param metadata: Additional information about the transaction stored as key-value pairs. If provided, the whole value will be overridden.
        :param connection_options: Allows for passing optional configuration per connection to take advantage of connection specific features. When provided, the data is only passed to the target connection type to prevent sharing configuration across connections. Please note that each of the keys this object are in kebab-case, for example `cybersource-anti-fraud` as they represent the ID of the connector. All the other keys will be snake case, for example `merchant_defined_data` or camel case to match an external API that the connector uses. If provided, the whole value will be overridden.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.UpdateTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
            transaction_update=models.TransactionUpdate(
                external_identifier=external_identifier,
                metadata=metadata,
                connection_options=utils.get_pydantic_model(
                    connection_options,
                    OptionalNullable[models.TransactionConnectionOptions],
                ),
            ),
        )

        req = self._build_request_async(
            method="PUT",
            path="/transactions/{transaction_id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.UpdateTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_update,
                False,
                False,
                "json",
                models.TransactionUpdate,
            ),
            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="update_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    def capture(
        self,
        *,
        transaction_id: str,
        prefer: OptionalNullable[List[str]] = UNSET,
        merchant_account_id: Optional[str] = None,
        amount: OptionalNullable[int] = UNSET,
        airline: OptionalNullable[
            Union[models.Airline, models.AirlineTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ResponseCaptureTransaction:
        r"""Capture transaction

        Captures a previously authorized transaction. You can capture the full or a partial amount, as long as it does not exceed the authorized amount (unless over-capture is enabled).

        :param transaction_id: The ID of the transaction
        :param prefer: The preferred resource type in the response.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param amount: The amount to capture, in the smallest currency unit (e.g., cents). This must be less than or equal to the authorized amount, unless over-capture is available.
        :param airline: The airline data to submit to the payment service during the capture call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CaptureTransactionRequest(
            transaction_id=transaction_id,
            prefer=prefer,
            merchant_account_id=merchant_account_id,
            transaction_capture_create=models.TransactionCaptureCreate(
                amount=amount,
                airline=utils.get_pydantic_model(
                    airline, OptionalNullable[models.Airline]
                ),
            ),
        )

        req = self._build_request(
            method="POST",
            path="/transactions/{transaction_id}/capture",
            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=models.CaptureTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_capture_create,
                False,
                False,
                "json",
                models.TransactionCaptureCreate,
            ),
            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="capture_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def capture_async(
        self,
        *,
        transaction_id: str,
        prefer: OptionalNullable[List[str]] = UNSET,
        merchant_account_id: Optional[str] = None,
        amount: OptionalNullable[int] = UNSET,
        airline: OptionalNullable[
            Union[models.Airline, models.AirlineTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ResponseCaptureTransaction:
        r"""Capture transaction

        Captures a previously authorized transaction. You can capture the full or a partial amount, as long as it does not exceed the authorized amount (unless over-capture is enabled).

        :param transaction_id: The ID of the transaction
        :param prefer: The preferred resource type in the response.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param amount: The amount to capture, in the smallest currency unit (e.g., cents). This must be less than or equal to the authorized amount, unless over-capture is available.
        :param airline: The airline data to submit to the payment service during the capture call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CaptureTransactionRequest(
            transaction_id=transaction_id,
            prefer=prefer,
            merchant_account_id=merchant_account_id,
            transaction_capture_create=models.TransactionCaptureCreate(
                amount=amount,
                airline=utils.get_pydantic_model(
                    airline, OptionalNullable[models.Airline]
                ),
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/transactions/{transaction_id}/capture",
            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=models.CaptureTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.transaction_capture_create,
                False,
                False,
                "json",
                models.TransactionCaptureCreate,
            ),
            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="capture_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    def void(
        self,
        *,
        transaction_id: str,
        prefer: OptionalNullable[List[str]] = UNSET,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ResponseVoidTransaction:
        r"""Void transaction

        Voids a previously authorized transaction. If the transaction was not yet successfully authorized, or was already captured, the void will not be processed. This operation releases the hold on the buyer's funds. Captured transactions can be refunded instead.

        :param transaction_id: The ID of the transaction
        :param prefer: The preferred resource type in the response.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.VoidTransactionRequest(
            transaction_id=transaction_id,
            prefer=prefer,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request(
            method="POST",
            path="/transactions/{transaction_id}/void",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.VoidTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="void_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def void_async(
        self,
        *,
        transaction_id: str,
        prefer: OptionalNullable[List[str]] = UNSET,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ResponseVoidTransaction:
        r"""Void transaction

        Voids a previously authorized transaction. If the transaction was not yet successfully authorized, or was already captured, the void will not be processed. This operation releases the hold on the buyer's funds. Captured transactions can be refunded instead.

        :param transaction_id: The ID of the transaction
        :param prefer: The preferred resource type in the response.
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.VoidTransactionRequest(
            transaction_id=transaction_id,
            prefer=prefer,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/transactions/{transaction_id}/void",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.VoidTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="void_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    def cancel(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.TransactionCancel:
        r"""Cancel transaction

        Cancels a pending transaction. If the transaction was successfully authorized, or was already captured, the cancel will not be processed.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CancelTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request(
            method="POST",
            path="/transactions/{transaction_id}/cancel",
            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=models.CancelTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="cancel_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def cancel_async(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.TransactionCancel:
        r"""Cancel transaction

        Cancels a pending transaction. If the transaction was successfully authorized, or was already captured, the cancel will not be processed.

        :param transaction_id: The ID of the transaction
        :param merchant_account_id: The ID of the merchant account to use for this request.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.CancelTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/transactions/{transaction_id}/cancel",
            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=models.CancelTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="cancel_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    def sync(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Sync transaction

        Synchronizes the status of a transaction with the underlying payment service provider. This is useful for transactions in a pending state to check if they've been completed or failed. Only available for some payment service providers.

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

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

        request = models.SyncTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request(
            method="POST",
            path="/transactions/{transaction_id}/sync",
            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=models.SyncTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="sync_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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

    async def sync_async(
        self,
        *,
        transaction_id: str,
        merchant_account_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Transaction:
        r"""Sync transaction

        Synchronizes the status of a transaction with the underlying payment service provider. This is useful for transactions in a pending state to check if they've been completed or failed. Only available for some payment service providers.

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

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

        request = models.SyncTransactionRequest(
            transaction_id=transaction_id,
            merchant_account_id=merchant_account_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/transactions/{transaction_id}/sync",
            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=models.SyncTransactionGlobals(
                merchant_account_id=self.sdk_configuration.globals.merchant_account_id,
            ),
            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="sync_transaction",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "422",
                "425",
                "429",
                "4XX",
                "500",
                "502",
                "504",
                "5XX",
            ],
            retry_config=retry_config,
        )

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

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