# -*- coding: utf-8 -*-

"""
paypalserversdk

This file was automatically generated by APIMATIC v3.0 (
 https://www.apimatic.io ).
"""

from paypalserversdk.api_helper import APIHelper
from paypalserversdk.configuration import Server
from paypalserversdk.http.api_response import ApiResponse
from paypalserversdk.controllers.base_controller import BaseController
from apimatic_core.request_builder import RequestBuilder
from apimatic_core.response_handler import ResponseHandler
from apimatic_core.types.parameter import Parameter
from paypalserversdk.http.http_method_enum import HttpMethodEnum
from apimatic_core.authentication.multiple.single_auth import Single
from paypalserversdk.models.billing_plan import BillingPlan
from paypalserversdk.models.plan_collection import PlanCollection
from paypalserversdk.models.subscription import Subscription
from paypalserversdk.models.subscription_collection import SubscriptionCollection
from paypalserversdk.models.modify_subscription_response import ModifySubscriptionResponse
from paypalserversdk.models.subscription_transaction_details import SubscriptionTransactionDetails
from paypalserversdk.models.transactions_list import TransactionsList
from paypalserversdk.exceptions.subscription_error_exception import SubscriptionErrorException


class SubscriptionsController(BaseController):

    """A Controller to access Endpoints in the paypalserversdk API."""
    def __init__(self, config):
        super(SubscriptionsController, self).__init__(config)

    def create_billing_plan(self,
                            options=dict()):
        """Does a POST request to /v1/billing/plans.

        Creates a plan that defines pricing and billing cycle details for
        subscriptions.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    prefer -- str -- The preferred server response upon
                        successful completion of the request. Value is:
                        return=minimal. The server returns a minimal response
                        to optimize communication between the API caller and
                        the server. A minimal response includes the id, status
                        and HATEOAS links. return=representation. The server
                        returns a complete resource representation, including
                        the current state of the resource.
                    paypal_request_id -- str -- The server stores keys for 72
                        hours.
                    body -- PlanRequest -- The request body parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows billing plan details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans')
            .http_method(HttpMethodEnum.POST)
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .header_param(Parameter()
                          .key('Prefer')
                          .value(options.get('prefer', None)))
            .header_param(Parameter()
                          .key('PayPal-Request-Id')
                          .value(options.get('paypal_request_id', None)))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(BillingPlan.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def list_billing_plans(self,
                           options=dict()):
        """Does a GET request to /v1/billing/plans.

        Lists billing plans.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    prefer -- str -- The preferred server response upon
                        successful completion of the request. Value is:
                        return=minimal. The server returns a minimal response
                        to optimize communication between the API caller and
                        the server. A minimal response includes the id, name,
                        description and HATEOAS links. return=representation.
                        The server returns a complete resource representation,
                        including the current state of the resource.
                    product_id -- str -- Filters the response by a Product ID.
                    page_size -- int -- The number of items to return in the
                        response.
                    page -- int -- A non-zero integer which is the start index
                        of the entire list of items to return in the response.
                        The combination of `page=1` and `page_size=20` returns
                        the first 20 items. The combination of `page=2` and
                        `page_size=20` returns the next 20 items.
                    total_required -- bool -- Indicates whether to show the
                        total count in the response.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that lists billing plans.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans')
            .http_method(HttpMethodEnum.GET)
            .header_param(Parameter()
                          .key('Prefer')
                          .value(options.get('prefer', None)))
            .query_param(Parameter()
                         .key('product_id')
                         .value(options.get('product_id', None)))
            .query_param(Parameter()
                         .key('page_size')
                         .value(options.get('page_size', None)))
            .query_param(Parameter()
                         .key('page')
                         .value(options.get('page', None)))
            .query_param(Parameter()
                         .key('total_required')
                         .value(options.get('total_required', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(PlanCollection.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def get_billing_plan(self,
                         id):
        """Does a GET request to /v1/billing/plans/{id}.

        Shows details for a plan, by ID.

        Args:
            id (str): The ID of the plan.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows plan details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans/{id}')
            .http_method(HttpMethodEnum.GET)
            .template_param(Parameter()
                            .key('id')
                            .value(id)
                            .should_encode(True))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(BillingPlan.from_dictionary)
            .is_api_response(True)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def patch_billing_plan(self,
                           options=dict()):
        """Does a PATCH request to /v1/billing/plans/{id}.

        Updates a plan with the `CREATED` or `ACTIVE` status. For an
        `INACTIVE` plan, you can make only status updates. You can patch these
        attributes and objects: Attribute or object Operations description
        replace payment_preferences.auto_bill_outstanding replace
        taxes.percentage replace payment_preferences.payment_failure_threshold
        replace payment_preferences.setup_fee replace
        payment_preferences.setup_fee_failure_action replace name replace

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the plan.
                    body -- List[Patch] -- The request body parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans/{id}')
            .http_method(HttpMethodEnum.PATCH)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def activate_billing_plan(self,
                              id):
        """Does a POST request to /v1/billing/plans/{id}/activate.

        Activates a plan, by ID.

        Args:
            id (str): The ID of the plan.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans/{id}/activate')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(id)
                            .should_encode(True))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def deactivate_billing_plan(self,
                                id):
        """Does a POST request to /v1/billing/plans/{id}/deactivate.

        Deactivates a plan, by ID.

        Args:
            id (str): The ID of the plan.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans/{id}/deactivate')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(id)
                            .should_encode(True))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def update_billing_plan_pricing_schemes(self,
                                            options=dict()):
        """Does a POST request to /v1/billing/plans/{id}/update-pricing-schemes.

        Updates pricing for a plan. For example, you can update a regular
        billing cycle from $5 per month to $7 per month.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID for the plan.
                    body -- UpdatePricingSchemesRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/plans/{id}/update-pricing-schemes')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def create_subscription(self,
                            options=dict()):
        """Does a POST request to /v1/billing/subscriptions.

        Creates a subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    prefer -- str -- The preferred server response upon
                        successful completion of the request. Value is:
                        return=minimal. The server returns a minimal response
                        to optimize communication between the API caller and
                        the server. A minimal response includes the id, status
                        and HATEOAS links. return=representation. The server
                        returns a complete resource representation, including
                        the current state of the resource.
                    paypal_request_id -- str -- The server stores keys for 72
                        hours.
                    paypal_client_metadata_id -- str -- The PayPal Client
                        Metadata Id(CMID) is used to provide device-specific
                        information to PayPal's risk engine. This is crucial
                        for transactions that require device-specific risk
                        assessments. Merchants typically use the Paypal SDK
                        that automatically submits the CMID or they use tools
                        like Fraudnet JS for web or Magnes JS for mobile to
                        generate the CMID on the frontend and then pass it to
                        the API as part of the request headers.
                    body -- CreateSubscriptionRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows subscription details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions')
            .http_method(HttpMethodEnum.POST)
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .header_param(Parameter()
                          .key('Prefer')
                          .value(options.get('prefer', None)))
            .header_param(Parameter()
                          .key('PayPal-Request-Id')
                          .value(options.get('paypal_request_id', None)))
            .header_param(Parameter()
                          .key('PayPal-Client-Metadata-Id')
                          .value(options.get('paypal_client_metadata_id', None)))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(Subscription.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def list_subscriptions(self,
                           options=dict()):
        """Does a GET request to /v1/billing/subscriptions.

        List all subscriptions for merchant account.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    plan_ids -- str -- Filters the response by list of plan
                        IDs. Filter supports upto 70 plan IDs. URLs should not
                        exceed a length of 2000 characters.
                    statuses -- str -- Filters the response by list of
                        subscription statuses.
                    created_after -- str -- Filters the response by
                        subscription creation start time for a range of
                        subscriptions.
                    created_before -- str -- Filters the response by
                        subscription creation end time for a range of
                        subscriptions.
                    status_updated_before -- str -- Filters the response by
                        status update start time for a range of subscriptions.
                    status_updated_after -- str -- Filters the response by
                        status update end time for a range of subscriptions.
                    filter -- str -- Filter the response using complex
                        expressions that could use comparison operators like
                        ge, gt, le, lt and logical operators such as 'and' and
                        'or'.
                    page_size -- int -- The number of items to return in the
                        response.
                    page -- int -- A non-zero integer which is the start index
                        of the entire list of items to return in the response.
                        The combination of `page=1` and `page_size=20` returns
                        the first 20 items. The combination of `page=2` and
                        `page_size=20` returns the next 20 items.
                    customer_ids -- List[str] -- Filters the response by comma
                        separated vault customer IDs (FSS subscriptions only).

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that lists the subscriptions.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions')
            .http_method(HttpMethodEnum.GET)
            .query_param(Parameter()
                         .key('plan_ids')
                         .value(options.get('plan_ids', None)))
            .query_param(Parameter()
                         .key('statuses')
                         .value(options.get('statuses', None)))
            .query_param(Parameter()
                         .key('created_after')
                         .value(options.get('created_after', None)))
            .query_param(Parameter()
                         .key('created_before')
                         .value(options.get('created_before', None)))
            .query_param(Parameter()
                         .key('status_updated_before')
                         .value(options.get('status_updated_before', None)))
            .query_param(Parameter()
                         .key('status_updated_after')
                         .value(options.get('status_updated_after', None)))
            .query_param(Parameter()
                         .key('filter')
                         .value(options.get('filter', None)))
            .query_param(Parameter()
                         .key('page_size')
                         .value(options.get('page_size', None)))
            .query_param(Parameter()
                         .key('page')
                         .value(options.get('page', None)))
            .query_param(Parameter()
                         .key('customer_ids')
                         .value(options.get('customer_ids', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(SubscriptionCollection.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def get_subscription(self,
                         options=dict()):
        """Does a GET request to /v1/billing/subscriptions/{id}.

        Shows details for a subscription, by ID.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    fields -- str -- List of fields that are to be returned in
                        the response. Possible value for fields are
                        last_failed_payment and plan.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows subscription details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}')
            .http_method(HttpMethodEnum.GET)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .query_param(Parameter()
                         .key('fields')
                         .value(options.get('fields', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(Subscription.from_dictionary)
            .is_api_response(True)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def patch_subscription(self,
                           options=dict()):
        """Does a PATCH request to /v1/billing/subscriptions/{id}.

        Updates a subscription which could be in ACTIVE or SUSPENDED status.
        You can override plan level default attributes by providing customised
        values for plan path in the patch request. You cannot update
        attributes that have already completed (Example - trial cycles can’t
        be updated if completed). Once overridden, changes to plan resource
        will not impact subscription. Any price update will not impact billing
        cycles within next 10 days (Applicable only for subscriptions funded
        by PayPal account). Following are the fields eligible for patch.
        Attribute or object Operations billing_info.outstanding_balance
        replace custom_id add,replace plan.billing_cycles[@sequence==n].
        pricing_scheme.fixed_price add,replace
        plan.billing_cycles[@sequence==n]. pricing_scheme.tiers replace
        plan.billing_cycles[@sequence==n]. total_cycles replace
        plan.payment_preferences. auto_bill_outstanding replace
        plan.payment_preferences. payment_failure_threshold replace
        plan.taxes.inclusive add,replace plan.taxes.percentage add,replace
        shipping_amount add,replace start_time replace
        subscriber.shipping_address add,replace subscriber.payment_source (for
        subscriptions funded by card payments) replace

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID for the subscription.
                    body -- List[Patch] -- The request body parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}')
            .http_method(HttpMethodEnum.PATCH)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def revise_subscription(self,
                            options=dict()):
        """Does a POST request to /v1/billing/subscriptions/{id}/revise.

        Updates the quantity of the product or service in a subscription. You
        can also use this method to switch the plan and update the
        `shipping_amount`, `shipping_address` values for the subscription.
        This type of update requires the buyer's consent.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    body -- ModifySubscriptionRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows subscription details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/revise')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(ModifySubscriptionResponse.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def suspend_subscription(self,
                             options=dict()):
        """Does a POST request to /v1/billing/subscriptions/{id}/suspend.

        Suspends the subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    body -- SuspendSubscription -- The request body parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/suspend')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def cancel_subscription(self,
                            options=dict()):
        """Does a POST request to /v1/billing/subscriptions/{id}/cancel.

        Cancels the subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    body -- CancelSubscriptionRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/cancel')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def activate_subscription(self,
                              options=dict()):
        """Does a POST request to /v1/billing/subscriptions/{id}/activate.

        Activates the subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    body -- ActivateSubscriptionRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `204 No Content` status
                code with no JSON response body.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/activate')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def capture_subscription(self,
                             options=dict()):
        """Does a POST request to /v1/billing/subscriptions/{id}/capture.

        Captures an authorized payment from the subscriber on the subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    paypal_request_id -- str -- The server stores keys for 72
                        hours.
                    body -- CaptureSubscriptionRequest -- The request body
                        parameter.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows subscription details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/capture')
            .http_method(HttpMethodEnum.POST)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .header_param(Parameter()
                          .key('Content-Type')
                          .value('application/json'))
            .header_param(Parameter()
                          .key('PayPal-Request-Id')
                          .value(options.get('paypal_request_id', None)))
            .body_param(Parameter()
                        .value(options.get('body', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .body_serializer(APIHelper.json_serialize)
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(SubscriptionTransactionDetails.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('422', 'The requested action could not be performed, semantically incorrect, or failed business validation.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()

    def list_subscription_transactions(self,
                                       options=dict()):
        """Does a GET request to /v1/billing/subscriptions/{id}/transactions.

        Lists transactions for a subscription.

        Args:
            options (dict, optional): Key-value pairs for any of the
                parameters to this API Endpoint. All parameters to the
                endpoint are supplied through the dictionary with their names
                being the key and their desired values being the value. A list
                of parameters that can be used are::

                    id -- str -- The ID of the subscription.
                    start_time -- str -- The start time of the range of
                        transactions to list.
                    end_time -- str -- The end time of the range of
                        transactions to list.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. A
                successful request returns the HTTP `200 OK` status code and a
                JSON response body that shows subscription details.

        Raises:
            ApiException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        return super().new_api_call_builder.request(
            RequestBuilder().server(Server.DEFAULT)
            .path('/v1/billing/subscriptions/{id}/transactions')
            .http_method(HttpMethodEnum.GET)
            .template_param(Parameter()
                            .key('id')
                            .value(options.get('id', None))
                            .should_encode(True))
            .query_param(Parameter()
                         .key('start_time')
                         .value(options.get('start_time', None)))
            .query_param(Parameter()
                         .key('end_time')
                         .value(options.get('end_time', None)))
            .header_param(Parameter()
                          .key('accept')
                          .value('application/json'))
            .auth(Single('Oauth2'))
        ).response(
            ResponseHandler()
            .deserializer(APIHelper.json_deserialize)
            .deserialize_into(TransactionsList.from_dictionary)
            .is_api_response(True)
            .local_error('400', 'Bad Request. Request is not well-formed, syntactically incorrect, or violates schema.', SubscriptionErrorException)
            .local_error('401', 'Authentication failed due to missing authorization header, or invalid authentication credentials.', SubscriptionErrorException)
            .local_error('403', 'Authorization failed due to insufficient permissions.', SubscriptionErrorException)
            .local_error('404', 'The specified resource does not exist.', SubscriptionErrorException)
            .local_error('500', 'An internal server error has occurred.', SubscriptionErrorException)
            .local_error('default', 'The error response.', SubscriptionErrorException)
        ).execute()
