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

from .basesdk import BaseSDK
from datetime import datetime
from paygentic_sdk import errors, models, utils
from paygentic_sdk._hooks import HookContext
from paygentic_sdk.types import BaseModel, OptionalNullable, UNSET
from paygentic_sdk.utils import get_security_from_env
from paygentic_sdk.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Mapping, Optional, Union, cast


class Subscriptions(BaseSDK):
    r"""A `Subscription` is a customer's commitment to purchase a `Product` following the terms of a `Plan` and its linked `Prices`."""

    def list(
        self,
        *,
        request: Union[
            models.ListSubscriptionsRequest, models.ListSubscriptionsRequestTypedDict
        ] = models.ListSubscriptionsRequest(),
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ListSubscriptionsResponse:
        r"""List

        :param request: The request object to send.
        :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)

        if not isinstance(request, BaseModel):
            request = utils.unmarshal(request, models.ListSubscriptionsRequest)
        request = cast(models.ListSubscriptionsRequest, request)

        req = self._build_request(
            method="GET",
            path="/v0/subscriptions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            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="listSubscriptions",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.ListSubscriptionsResponse, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    async def list_async(
        self,
        *,
        request: Union[
            models.ListSubscriptionsRequest, models.ListSubscriptionsRequestTypedDict
        ] = models.ListSubscriptionsRequest(),
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ListSubscriptionsResponse:
        r"""List

        :param request: The request object to send.
        :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)

        if not isinstance(request, BaseModel):
            request = utils.unmarshal(request, models.ListSubscriptionsRequest)
        request = cast(models.ListSubscriptionsRequest, request)

        req = self._build_request_async(
            method="GET",
            path="/v0/subscriptions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            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="listSubscriptions",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.ListSubscriptionsResponse, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    def create(
        self,
        *,
        name: str,
        plan_id: str,
        started_at: datetime,
        auto_charge: Optional[bool] = False,
        tax_exempt: Optional[bool] = False,
        customer: Optional[
            Union[
                models.CreateSubscriptionCustomer,
                models.CreateSubscriptionCustomerTypedDict,
            ]
        ] = None,
        customer_id: Optional[str] = None,
        ending_at: Optional[datetime] = None,
        prefund_amount: Optional[str] = None,
        minimum_account_balance: Optional[str] = None,
        redirect_urls: Optional[
            Union[models.RedirectUrls, models.RedirectUrlsTypedDict]
        ] = None,
        test_clock_id: Optional[str] = None,
        renewal_reminder_enabled: OptionalNullable[bool] = UNSET,
        renewal_reminder_days: OptionalNullable[int] = UNSET,
        session_expiry_minutes: Optional[float] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Subscription:
        r"""Create

        Creates a subscription for an existing customer or creates a new customer as part of the action.

        :param name: Subscription identifier combining customer and service details. Sample values: 'TechCorp - LLM API Access', 'Analytics Co - Data Platform Enterprise', 'StartupXYZ - Image Generation Service', 'Enterprise Inc - ML Training Platform'
        :param plan_id: Unique identifier for a plan
        :param started_at: Subscription activation timestamp in ISO 8601 format. Sample values: '2024-01-15T10:30:00Z', '2024-02-01T00:00:00Z'
        :param auto_charge: Enable automatic charging of invoices using stored payment methods. When true, invoices will be automatically paid using off-session payment. Defaults to false.
        :param tax_exempt: When true, forces tax rate to 0%. Use for customers with verified tax-exempt status.
        :param customer: Fields to create a new customer and consumer. Will use an existing consumer if one exists with the same email address. Required if `customerId` is not provided. Address with complete tax information (country, state, zipCode) is required for tax calculation when using Paygentic Tax.
        :param customer_id: Unique identifier for a customer
        :param ending_at: Subscription expiration timestamp in ISO 8601 format. Sample values: '2024-12-31T23:59:59Z', '2025-01-15T10:30:00Z'. Omit for indefinite subscriptions.
        :param prefund_amount: @deprecated Use minimumAccountBalance instead. Required initial wallet deposit amount. Sample values: '200.00' requires $200 prepaid balance for metered LLM usage, '1000.00' requires $1000 prepaid credits for data processing services, '50.00' requires $50 minimum for API call consumption
        :param minimum_account_balance: Minimum wallet balance requirement in decimal dollars (e.g., '100.00'). Can be set to '0' to disable. The system will calculate the difference between this minimum and the customer's current balance, charging only what's needed to reach the minimum. If the customer already has sufficient balance, no charge is made. Note: If the calculated charge amount is below payment processor minimums (typically $1.00), it will be automatically adjusted upward to meet the minimum requirement. Sample values: '200.00' requires minimum $200 balance for metered LLM usage, '1000.00' requires minimum $1000 balance for data processing services
        :param redirect_urls: Optional redirect URLs after payment completion or failure. If not provided, uses default platform behavior.
        :param test_clock_id: Test clock identifier for simulating time-based billing scenarios. Sample values: 'tc_abc123xyz', 'tc_789def456'. Restricted to non-production environments (local, dev, sandbox). Must belong to the same merchant organization.
        :param renewal_reminder_enabled: Override plan setting for renewal reminder emails. When set, this subscription's setting takes precedence over the plan default. Set to true to enable reminders, false to disable, or null/omit to use plan default.
        :param renewal_reminder_days: Override plan setting for number of days before renewal to send the reminder. Only used if renewalReminderEnabled is true (or inherited from plan). Set to null to use plan default.
        :param session_expiry_minutes: Number of minutes until the payment session expires. Defaults to 240 minutes (4 hours) if not provided.
        :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.CreateSubscriptionRequest(
            auto_charge=auto_charge,
            tax_exempt=tax_exempt,
            customer=utils.get_pydantic_model(
                customer, Optional[models.CreateSubscriptionCustomer]
            ),
            customer_id=customer_id,
            ending_at=ending_at,
            name=name,
            plan_id=plan_id,
            prefund_amount=prefund_amount,
            minimum_account_balance=minimum_account_balance,
            redirect_urls=utils.get_pydantic_model(
                redirect_urls, Optional[models.RedirectUrls]
            ),
            started_at=started_at,
            test_clock_id=test_clock_id,
            renewal_reminder_enabled=renewal_reminder_enabled,
            renewal_reminder_days=renewal_reminder_days,
            session_expiry_minutes=session_expiry_minutes,
        )

        req = self._build_request(
            method="POST",
            path="/v0/subscriptions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.CreateSubscriptionRequest
            ),
            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="createSubscription",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "201"], "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    async def create_async(
        self,
        *,
        name: str,
        plan_id: str,
        started_at: datetime,
        auto_charge: Optional[bool] = False,
        tax_exempt: Optional[bool] = False,
        customer: Optional[
            Union[
                models.CreateSubscriptionCustomer,
                models.CreateSubscriptionCustomerTypedDict,
            ]
        ] = None,
        customer_id: Optional[str] = None,
        ending_at: Optional[datetime] = None,
        prefund_amount: Optional[str] = None,
        minimum_account_balance: Optional[str] = None,
        redirect_urls: Optional[
            Union[models.RedirectUrls, models.RedirectUrlsTypedDict]
        ] = None,
        test_clock_id: Optional[str] = None,
        renewal_reminder_enabled: OptionalNullable[bool] = UNSET,
        renewal_reminder_days: OptionalNullable[int] = UNSET,
        session_expiry_minutes: Optional[float] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Subscription:
        r"""Create

        Creates a subscription for an existing customer or creates a new customer as part of the action.

        :param name: Subscription identifier combining customer and service details. Sample values: 'TechCorp - LLM API Access', 'Analytics Co - Data Platform Enterprise', 'StartupXYZ - Image Generation Service', 'Enterprise Inc - ML Training Platform'
        :param plan_id: Unique identifier for a plan
        :param started_at: Subscription activation timestamp in ISO 8601 format. Sample values: '2024-01-15T10:30:00Z', '2024-02-01T00:00:00Z'
        :param auto_charge: Enable automatic charging of invoices using stored payment methods. When true, invoices will be automatically paid using off-session payment. Defaults to false.
        :param tax_exempt: When true, forces tax rate to 0%. Use for customers with verified tax-exempt status.
        :param customer: Fields to create a new customer and consumer. Will use an existing consumer if one exists with the same email address. Required if `customerId` is not provided. Address with complete tax information (country, state, zipCode) is required for tax calculation when using Paygentic Tax.
        :param customer_id: Unique identifier for a customer
        :param ending_at: Subscription expiration timestamp in ISO 8601 format. Sample values: '2024-12-31T23:59:59Z', '2025-01-15T10:30:00Z'. Omit for indefinite subscriptions.
        :param prefund_amount: @deprecated Use minimumAccountBalance instead. Required initial wallet deposit amount. Sample values: '200.00' requires $200 prepaid balance for metered LLM usage, '1000.00' requires $1000 prepaid credits for data processing services, '50.00' requires $50 minimum for API call consumption
        :param minimum_account_balance: Minimum wallet balance requirement in decimal dollars (e.g., '100.00'). Can be set to '0' to disable. The system will calculate the difference between this minimum and the customer's current balance, charging only what's needed to reach the minimum. If the customer already has sufficient balance, no charge is made. Note: If the calculated charge amount is below payment processor minimums (typically $1.00), it will be automatically adjusted upward to meet the minimum requirement. Sample values: '200.00' requires minimum $200 balance for metered LLM usage, '1000.00' requires minimum $1000 balance for data processing services
        :param redirect_urls: Optional redirect URLs after payment completion or failure. If not provided, uses default platform behavior.
        :param test_clock_id: Test clock identifier for simulating time-based billing scenarios. Sample values: 'tc_abc123xyz', 'tc_789def456'. Restricted to non-production environments (local, dev, sandbox). Must belong to the same merchant organization.
        :param renewal_reminder_enabled: Override plan setting for renewal reminder emails. When set, this subscription's setting takes precedence over the plan default. Set to true to enable reminders, false to disable, or null/omit to use plan default.
        :param renewal_reminder_days: Override plan setting for number of days before renewal to send the reminder. Only used if renewalReminderEnabled is true (or inherited from plan). Set to null to use plan default.
        :param session_expiry_minutes: Number of minutes until the payment session expires. Defaults to 240 minutes (4 hours) if not provided.
        :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.CreateSubscriptionRequest(
            auto_charge=auto_charge,
            tax_exempt=tax_exempt,
            customer=utils.get_pydantic_model(
                customer, Optional[models.CreateSubscriptionCustomer]
            ),
            customer_id=customer_id,
            ending_at=ending_at,
            name=name,
            plan_id=plan_id,
            prefund_amount=prefund_amount,
            minimum_account_balance=minimum_account_balance,
            redirect_urls=utils.get_pydantic_model(
                redirect_urls, Optional[models.RedirectUrls]
            ),
            started_at=started_at,
            test_clock_id=test_clock_id,
            renewal_reminder_enabled=renewal_reminder_enabled,
            renewal_reminder_days=renewal_reminder_days,
            session_expiry_minutes=session_expiry_minutes,
        )

        req = self._build_request_async(
            method="POST",
            path="/v0/subscriptions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.CreateSubscriptionRequest
            ),
            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="createSubscription",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "201"], "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

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

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

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

        request = models.GetSubscriptionRequest(
            id=id,
        )

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

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

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

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

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

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

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

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

        request = models.GetSubscriptionRequest(
            id=id,
        )

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

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

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

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

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, ["401", "403", "404"], "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    def generate_portal_link(
        self,
        *,
        id: str,
        expires_in: 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.SubscriptionPortal:
        r"""Generate Portal Link

        Generates a secure, time-limited URL that allows customers to access their subscription data without authentication.

        :param id: The subscription ID
        :param expires_in: Token lifetime as an ISO 8601 duration. Defaults to PT10M (10 minutes). Maximum is P7D (7 days). Examples: PT10M, PT1H, P1D, P7D.
        :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.GeneratePortalLinkRequest(
            id=id,
            request_body=models.GeneratePortalLinkRequestBody(
                expires_in=expires_in,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v0/subscriptions/{id}/portal",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body if request is not None else None,
                False,
                True,
                "json",
                Optional[models.GeneratePortalLinkRequestBody],
            ),
            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="generatePortalLink",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.SubscriptionPortal, http_res)
        if utils.match_response(
            http_res, ["401", "403", "404", "429"], "application/json"
        ):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    async def generate_portal_link_async(
        self,
        *,
        id: str,
        expires_in: 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.SubscriptionPortal:
        r"""Generate Portal Link

        Generates a secure, time-limited URL that allows customers to access their subscription data without authentication.

        :param id: The subscription ID
        :param expires_in: Token lifetime as an ISO 8601 duration. Defaults to PT10M (10 minutes). Maximum is P7D (7 days). Examples: PT10M, PT1H, P1D, P7D.
        :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.GeneratePortalLinkRequest(
            id=id,
            request_body=models.GeneratePortalLinkRequestBody(
                expires_in=expires_in,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v0/subscriptions/{id}/portal",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body if request is not None else None,
                False,
                True,
                "json",
                Optional[models.GeneratePortalLinkRequestBody],
            ),
            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="generatePortalLink",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["401", "403", "404", "429", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.SubscriptionPortal, http_res)
        if utils.match_response(
            http_res, ["401", "403", "404", "429"], "application/json"
        ):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    def terminate(
        self,
        *,
        id: str,
        reason: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Subscription:
        r"""Terminate

        Terminates a subscription with a required reason. This endpoint is for merchant-initiated termination only.

        :param id: The subscription ID
        :param reason: Cancellation explanation text. Sample values: 'Customer requested cancellation', 'Payment failure', 'Service migration', 'Contract expiration'
        :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.TerminateSubscriptionRequest(
            id=id,
            request_body=models.TerminateSubscriptionRequestBody(
                reason=reason,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v0/subscriptions/{id}/termination",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body,
                False,
                False,
                "json",
                models.TerminateSubscriptionRequestBody,
            ),
            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="terminateSubscription",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "409", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(
            http_res, ["401", "403", "404", "409"], "application/json"
        ):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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

    async def terminate_async(
        self,
        *,
        id: str,
        reason: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.Subscription:
        r"""Terminate

        Terminates a subscription with a required reason. This endpoint is for merchant-initiated termination only.

        :param id: The subscription ID
        :param reason: Cancellation explanation text. Sample values: 'Customer requested cancellation', 'Payment failure', 'Service migration', 'Contract expiration'
        :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.TerminateSubscriptionRequest(
            id=id,
            request_body=models.TerminateSubscriptionRequestBody(
                reason=reason,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v0/subscriptions/{id}/termination",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.request_body,
                False,
                False,
                "json",
                models.TerminateSubscriptionRequestBody,
            ),
            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="terminateSubscription",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "409", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(models.Subscription, http_res)
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(errors.BadRequestUnion, http_res)
            raise errors.BadRequest(response_data, http_res)
        if utils.match_response(
            http_res, ["401", "403", "404", "409"], "application/json"
        ):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(errors.ErrorData, http_res)
            raise errors.Error(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.PaygenticDefaultError(
                "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.PaygenticDefaultError(
                "API error occurred", http_res, http_res_text
            )

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