"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""

import requests as requests_http
from .availability import Availability
from .coupon import Coupon
from .credit import Credit
from .credit_note import CreditNote
from .customer import Customer
from .event import Event
from .invoice import Invoice
from .plan import Plan
from .sdkconfiguration import SDKConfiguration
from .subscription import Subscription
from orb import utils
from orb.models import shared

class Orb:
    r"""API Reference: Orb's API is built with the following principles in mind:

    1. **Predictable developer experience**: Where applicable, the Orb API uses industry-standard patterns such as cursor-based pagination and standardized error output. To help with debugging in critical API actions, the API always strives to provide detailed and actionable error messages. Aliases such as external customer IDs aid in fast integration times.
    2. **Reliably real time**: Orb's event-based APIs, such as event ingestion are designed to handle extremely high throughput and scale with concurrent load. Orb also provides a real-time event-level credits ledger and a highly performant webhooks architecture.
    3. **Flexibility at the forefront**: Features like timezone localization and the ability to amend historical usage show the flexible nature of the platform. 

    You can download the latest OpenAPI spec [here](../../examples/spec-3.0.json).
    """
    availability: Availability
    r"""The Availability resource represents a customer's availability. Availability is created when a customer's invoice is paid, and is updated when a customer's transaction is refunded."""
    coupon: Coupon
    r"""A coupon represents a reusable discount configuration, and have an attached redemption code that can be issued to your end users. Coupons are most often used in self-serve signup or upgrade flows in your checkout experience or billing portal.

    To redeem a coupon, pass the `redemption_code` property in the [create subscription](create-subscription.api.mdx) or [schedule plan change](schedule-plan-change.api.mdx) request.
    """
    credit: Credit
    r"""The Credits resource represents a customer's credits. Credits are created when a customer's invoice is paid, and are updated when a customer's transaction is refunded."""
    credit_note: CreditNote
    r"""The Credit Note resource represents a credit note that has been generated for a customer. Credit Notes are generated when a customer's billing interval has elapsed, and are updated when a customer's invoice is paid."""
    customer: Customer
    r"""A customer is a buyer of your products, and the other party to the billing relationship.

    In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an `external_customer_id` with your own identifier. See [Customer ID Aliases](../guides/events-and-metrics/customer-aliases) for further information about how these aliases work in Orb.

    In addition to having an identifier in your system, a customer may exist in a payment provider solution like Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.

    A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which defaults to your account's timezone. See [Timezone localization](../guides/product-catalog/timezones.md) for information on what this timezone parameter influences within Orb.
    """
    event: Event
    r"""The [Event](../guides/core-concepts.mdx#event) resource represents an event that has been created for a customer. Events are created when a customer's invoice is paid, and are updated when a customer's transaction is refunded."""
    invoice: Invoice
    r"""An [`Invoice`](../guides/concepts#invoice) is a fundamental billing entity, representing the request for payment for a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as the result of an action, such as a cancellation."""
    plan: Plan
    r"""The [Plan](../guides/core-concepts.mdx#plan-and-price) resource represents a plan that can be subscribed to by a customer. Plans define the billing behavior of the subscription.
     Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a given Price object. The model_type field determines the key for the configuration object that is present.

    ## Unit pricing
    With unit pricing, each unit costs a fixed amount.
    ```json
    {
        ...
        \"model_type\": \"unit\",
        \"unit_config\": {
            \"unit_amount\": \"0.50\"
        }
        ...
    }
    ```

    ## Tiered pricing
    In tiered pricing, the cost of a given unit depends on the tier range that it falls into, where each tier range is defined by an upper and lower bound. For example, the first ten units may cost $0.50 each and all units thereafter may cost $0.10 each.
    ```json
    {
        ...
        \"model_type\": \"tiered\",
        \"tiered_config\": {
            \"tiers\": [ 
               {
                    \"first_unit\": 1,
                    \"last_unit\": 10,
                    \"unit_amount\": \"0.50\"
                },
                {
                    \"first_unit\": 11,
                    \"last_unit\": null,
                    \"unit_amount\": \"0.10\"
                }
            ]
        }
        ...
    }
    ```

    ## Bulk pricing
    Bulk pricing applies when the number of units determine the cost of all units. For example, if you've bought less than 10 units, they may each be $0.50 for a total of $5.00. Once you've bought more than 10 units, all units may now be priced at $0.40 (i.e. 101 units total would be $40.40).
    ```json
    {
        ...
        \"model_type\": \"bulk\",
        \"bulk_config\": {
            \"tiers\": [ 
                {
                    \"maximum_units\": 10,
                    \"unit_amount\": \"0.50\"
                },
                {
                    \"maximum_units\": 1000,
                    \"unit_amount\": \"0.40\"
                }
              ]
        }
        ...
    }
    ```

    ## Package pricing
    Package pricing defines the size or granularity of a unit for billing purposes. For example, if the package size is set to 5, then 4 units will be billed as 5 and 6 units will be billed at 10.
    ```json
    {
        ...
        \"model_type\": \"package\",
        \"package_config\": {
           \"package_amount\": \"0.80\",
           \"package_size\": 10
        }
        ...
     }
    ```

    ## BPS pricing
    BPS pricing specifies a per-event (e.g. per-payment) rate in one hundredth of a percent (the number of basis points to charge), as well as a cap per event to assess. For example, this would allow you to assess a fee of 0.25% on every payment you process, with a maximum charge of $25 per payment.
    ```json
    {
        ...
        \"model_type\": \"bps\",
        \"bps_config\": {
           \"bps\": 125,
           \"per_unit_maximum\": \"11.00\"
        }
        ...
     }
    ```

    ## Bulk BPS pricing
    Bulk BPS pricing specifies BPS parameters in a tiered manner, dependent on the total quantity across all events. Similar to bulk pricing, the BPS parameters of a given event depends on the tier range that the billing period falls into. Each tier range is defined by an upper bound. For example, after $1.5M of payment volume is reached, each individual payment may have a lower cap or a smaller take-rate.
    ```json
        ...
        \"model_type\": \"bulk_bps\",
        \"bulk_bps_config\": {
            \"tiers\": [ 
               {
                    \"maximum_amount\": \"1000000.00\",
                    \"bps\": 125,
                    \"per_unit_maximum\": \"19.00\"
               },
              {
                    \"maximum_amount\": null,
                    \"bps\": 115,
                    \"per_unit_maximum\": \"4.00\"
                }
            ]
        }
        ...
    }
    ```

    ## Tiered BPS pricing
    Tiered BPS pricing specifies BPS parameters in a graduated manner, where an event's applicable parameter is a function of its marginal addition to the period total. Similar to tiered pricing, the BPS parameters of a given event depends on the tier range that it falls into, where each tier range is defined by an upper and lower bound. For example, the first few payments may have a 0.8 BPS take-rate and all payments after a specific volume may incur a take-rate of 0.5 BPS each.
    ```json
        ...
        \"model_type\": \"tiered_bps\",
        \"tiered_bps_config\": {
            \"tiers\": [ 
               {
                    \"minimum_amount\": \"0\",
                    \"maximum_amount\": \"1000000.00\",
                    \"bps\": 125,
                    \"per_unit_maximum\": \"19.00\"
               },
              {
                    \"minimum_amount\": \"1000000.00\",
                    \"maximum_amount\": null,
                    \"bps\": 115,
                    \"per_unit_maximum\": \"4.00\"
                }
            ]
        }
        ...
    }
    ```

    ## Matrix pricing
    Matrix pricing defines a set of unit prices in a one or two-dimensional matrix. `dimensions` defines the two event property values evaluated in this pricing model. In a one-dimensional matrix, the second value is `null`. Every configuration has a list of `matrix_values` which give the unit prices for specified property values. In a one-dimensional matrix, the matrix values will have `dimension_values` where the second value of the pair is null. If an event does not match any of the dimension values in the matrix, it will resort to the `default_unit_amount`.
    ```json
    ...
    \"model_type\": \"matrix\"
    \"matrix_config\": {
        \"default_unit_amount\": \"3.00\",
        \"dimensions\": [
            \"cluster_name\",
            \"region\"
        ],
        \"matrix_values\": [
            {
                \"dimension_values\": [
                    \"alpha\",
                    \"west\"
                ],
                \"unit_amount\": \"2.00\"
            },
            ...
        ]
    }
    ...
    ```

    ### Fixed fees
    Fixed fees are prices that are applied independent of usage quantites, and follow unit pricing. They also have an additional parameter `fixed_price_quantity`. If the Price represents a fixed cost, this represents the quantity of units applied.
    ```json
    {
        ...
        \"id\": \"price_id\",
        \"model_type\": \"unit\",
        \"unit_config\": {
           \"unit_amount\": \"2.00\"
        },
        \"fixed_price_quantity\": 3.0
        ...
    }
    ```
    """
    subscription: Subscription
    r"""A [subscription](../guides/core-concepts.mdx#subscription) represents the purchase of a plan by a customer.

    By default, subscriptions begin on the day that they're created and renew automatically for each billing cycle at the cadence that's configured in the plan definition.

    Subscriptions also default to **beginning of month alignment**, which means the first invoice issued for the subscription will have pro-rated charges between the `start_date` and the first of the following month. Subsequent billing periods will always start and end on a month boundary (e.g. subsequent month starts for monthly billing).

    Depending on the plan configuration, any _flat_ recurring fees will be billed either at the beginning (in-advance) or end (in-arrears) of each billing cycle. Plans default to **in-advance billing**. Usage-based fees are billed in arrears as usage is accumulated. In the normal course of events, you can expect an invoice to contain usage-based charges for the previous period, and a recurring fee for the following period.
    """

    sdk_configuration: SDKConfiguration

    def __init__(self,
                 security: shared.Security = None,
                 server_idx: int = None,
                 server_url: str = None,
                 url_params: dict[str, str] = None,
                 client: requests_http.Session = None,
                 retry_config: utils.RetryConfig = None
                 ) -> None:
        """Instantiates the SDK configuring it with the provided parameters.
        
        :param security: The security details required for authentication
        :type security: shared.Security
        :param server_idx: The index of the server to use for all operations
        :type server_idx: int
        :param server_url: The server URL to use for all operations
        :type server_url: str
        :param url_params: Parameters to optionally template the server URL with
        :type url_params: dict[str, str]
        :param client: The requests.Session HTTP client to use for all operations
        :type client: requests_http.Session
        :param retry_config: The utils.RetryConfig to use globally
        :type retry_config: utils.RetryConfig
        """
        if client is None:
            client = requests_http.Session()
        
        security_client = utils.configure_security_client(client, security)
        
        if server_url is not None:
            if url_params is not None:
                server_url = utils.template_url(server_url, url_params)

        self.sdk_configuration = SDKConfiguration(client, security_client, server_url, server_idx, retry_config=retry_config)
       
        self._init_sdks()
    
    def _init_sdks(self):
        self.availability = Availability(self.sdk_configuration)
        self.coupon = Coupon(self.sdk_configuration)
        self.credit = Credit(self.sdk_configuration)
        self.credit_note = CreditNote(self.sdk_configuration)
        self.customer = Customer(self.sdk_configuration)
        self.event = Event(self.sdk_configuration)
        self.invoice = Invoice(self.sdk_configuration)
        self.plan = Plan(self.sdk_configuration)
        self.subscription = Subscription(self.sdk_configuration)
    