paid-python 0.6.0__py3-none-any.whl → 1.0.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. paid/__init__.py +31 -0
  2. paid/client.py +1 -472
  3. paid/core/client_wrapper.py +3 -2
  4. paid/customers/__init__.py +3 -0
  5. paid/customers/client.py +428 -4
  6. paid/customers/raw_client.py +594 -2
  7. paid/customers/types/__init__.py +8 -0
  8. paid/customers/types/customers_check_entitlement_request_view.py +5 -0
  9. paid/customers/types/customers_check_entitlement_response.py +22 -0
  10. paid/orders/client.py +435 -0
  11. paid/orders/raw_client.py +695 -0
  12. paid/plans/client.py +71 -0
  13. paid/plans/raw_client.py +121 -2
  14. paid/types/__init__.py +28 -0
  15. paid/types/cancel_renewal_response.py +49 -0
  16. paid/types/contact_create_for_customer.py +37 -0
  17. paid/types/invoice.py +75 -0
  18. paid/types/invoice_status.py +5 -0
  19. paid/types/payment_method.py +58 -0
  20. paid/types/payment_method_card.py +49 -0
  21. paid/types/payment_method_type.py +5 -0
  22. paid/types/payment_method_us_bank_account.py +36 -0
  23. paid/types/payment_method_us_bank_account_account_type.py +5 -0
  24. paid/types/plan_plan_products_item.py +6 -0
  25. paid/types/plan_with_features.py +69 -0
  26. paid/types/plan_with_features_features_item.py +34 -0
  27. paid/types/proration_attribute_update.py +44 -0
  28. paid/types/proration_detail.py +49 -0
  29. paid/types/proration_upgrade_response.py +73 -0
  30. paid/types/signal_v_2.py +5 -5
  31. paid/usage/client.py +6 -6
  32. {paid_python-0.6.0.dist-info → paid_python-1.0.0a0.dist-info}/METADATA +6 -4
  33. {paid_python-0.6.0.dist-info → paid_python-1.0.0a0.dist-info}/RECORD +35 -36
  34. opentelemetry/instrumentation/openai/__init__.py +0 -54
  35. opentelemetry/instrumentation/openai/shared/__init__.py +0 -399
  36. opentelemetry/instrumentation/openai/shared/audio_wrappers.py +0 -247
  37. opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -1192
  38. opentelemetry/instrumentation/openai/shared/completion_wrappers.py +0 -292
  39. opentelemetry/instrumentation/openai/shared/config.py +0 -15
  40. opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -311
  41. opentelemetry/instrumentation/openai/shared/event_emitter.py +0 -108
  42. opentelemetry/instrumentation/openai/shared/event_models.py +0 -41
  43. opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +0 -68
  44. opentelemetry/instrumentation/openai/shared/span_utils.py +0 -0
  45. opentelemetry/instrumentation/openai/utils.py +0 -213
  46. opentelemetry/instrumentation/openai/v0/__init__.py +0 -176
  47. opentelemetry/instrumentation/openai/v1/__init__.py +0 -394
  48. opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +0 -329
  49. opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +0 -134
  50. opentelemetry/instrumentation/openai/v1/responses_wrappers.py +0 -1113
  51. opentelemetry/instrumentation/openai/version.py +0 -1
  52. {paid_python-0.6.0.dist-info → paid_python-1.0.0a0.dist-info}/LICENSE +0 -0
  53. {paid_python-0.6.0.dist-info → paid_python-1.0.0a0.dist-info}/WHEEL +0 -0
paid/plans/client.py CHANGED
@@ -7,6 +7,7 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
7
7
  from ..core.request_options import RequestOptions
8
8
  from ..types.plan import Plan
9
9
  from ..types.plan_group import PlanGroup
10
+ from ..types.plan_with_features import PlanWithFeatures
10
11
  from ..types.usage_summaries_response import UsageSummariesResponse
11
12
  from .raw_client import AsyncRawPlansClient, RawPlansClient
12
13
 
@@ -159,6 +160,37 @@ class PlansClient:
159
160
  _response = self._raw_client.get_group_by_id(plan_group_id, request_options=request_options)
160
161
  return _response.data
161
162
 
163
+ def get_group_plans(
164
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
165
+ ) -> typing.List[PlanWithFeatures]:
166
+ """
167
+ Parameters
168
+ ----------
169
+ plan_group_id : str
170
+ The ID of the plan group
171
+
172
+ request_options : typing.Optional[RequestOptions]
173
+ Request-specific configuration.
174
+
175
+ Returns
176
+ -------
177
+ typing.List[PlanWithFeatures]
178
+ Success response
179
+
180
+ Examples
181
+ --------
182
+ from paid import Paid
183
+
184
+ client = Paid(
185
+ token="YOUR_TOKEN",
186
+ )
187
+ client.plans.get_group_plans(
188
+ plan_group_id="planGroupId",
189
+ )
190
+ """
191
+ _response = self._raw_client.get_group_plans(plan_group_id, request_options=request_options)
192
+ return _response.data
193
+
162
194
 
163
195
  class AsyncPlansClient:
164
196
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -330,3 +362,42 @@ class AsyncPlansClient:
330
362
  """
331
363
  _response = await self._raw_client.get_group_by_id(plan_group_id, request_options=request_options)
332
364
  return _response.data
365
+
366
+ async def get_group_plans(
367
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
368
+ ) -> typing.List[PlanWithFeatures]:
369
+ """
370
+ Parameters
371
+ ----------
372
+ plan_group_id : str
373
+ The ID of the plan group
374
+
375
+ request_options : typing.Optional[RequestOptions]
376
+ Request-specific configuration.
377
+
378
+ Returns
379
+ -------
380
+ typing.List[PlanWithFeatures]
381
+ Success response
382
+
383
+ Examples
384
+ --------
385
+ import asyncio
386
+
387
+ from paid import AsyncPaid
388
+
389
+ client = AsyncPaid(
390
+ token="YOUR_TOKEN",
391
+ )
392
+
393
+
394
+ async def main() -> None:
395
+ await client.plans.get_group_plans(
396
+ plan_group_id="planGroupId",
397
+ )
398
+
399
+
400
+ asyncio.run(main())
401
+ """
402
+ _response = await self._raw_client.get_group_plans(plan_group_id, request_options=request_options)
403
+ return _response.data
paid/plans/raw_client.py CHANGED
@@ -17,6 +17,7 @@ from ..errors.not_found_error import NotFoundError
17
17
  from ..types.error import Error
18
18
  from ..types.plan import Plan
19
19
  from ..types.plan_group import PlanGroup
20
+ from ..types.plan_with_features import PlanWithFeatures
20
21
  from ..types.usage_summaries_response import UsageSummariesResponse
21
22
 
22
23
 
@@ -199,7 +200,7 @@ class RawPlansClient:
199
200
  Success response
200
201
  """
201
202
  _response = self._client_wrapper.httpx_client.request(
202
- f"plans/group/{jsonable_encoder(plan_group_id)}",
203
+ f"plans/planGroup/{jsonable_encoder(plan_group_id)}",
203
204
  method="GET",
204
205
  request_options=request_options,
205
206
  )
@@ -240,6 +241,65 @@ class RawPlansClient:
240
241
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
241
242
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
242
243
 
244
+ def get_group_plans(
245
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
246
+ ) -> HttpResponse[typing.List[PlanWithFeatures]]:
247
+ """
248
+ Parameters
249
+ ----------
250
+ plan_group_id : str
251
+ The ID of the plan group
252
+
253
+ request_options : typing.Optional[RequestOptions]
254
+ Request-specific configuration.
255
+
256
+ Returns
257
+ -------
258
+ HttpResponse[typing.List[PlanWithFeatures]]
259
+ Success response
260
+ """
261
+ _response = self._client_wrapper.httpx_client.request(
262
+ f"plans/planGroup/{jsonable_encoder(plan_group_id)}/plans",
263
+ method="GET",
264
+ request_options=request_options,
265
+ )
266
+ try:
267
+ if 200 <= _response.status_code < 300:
268
+ _data = typing.cast(
269
+ typing.List[PlanWithFeatures],
270
+ parse_obj_as(
271
+ type_=typing.List[PlanWithFeatures], # type: ignore
272
+ object_=_response.json(),
273
+ ),
274
+ )
275
+ return HttpResponse(response=_response, data=_data)
276
+ if _response.status_code == 403:
277
+ raise ForbiddenError(
278
+ headers=dict(_response.headers),
279
+ body=typing.cast(
280
+ Error,
281
+ parse_obj_as(
282
+ type_=Error, # type: ignore
283
+ object_=_response.json(),
284
+ ),
285
+ ),
286
+ )
287
+ if _response.status_code == 404:
288
+ raise NotFoundError(
289
+ headers=dict(_response.headers),
290
+ body=typing.cast(
291
+ Error,
292
+ parse_obj_as(
293
+ type_=Error, # type: ignore
294
+ object_=_response.json(),
295
+ ),
296
+ ),
297
+ )
298
+ _response_json = _response.json()
299
+ except JSONDecodeError:
300
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
301
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
302
+
243
303
 
244
304
  class AsyncRawPlansClient:
245
305
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -422,7 +482,7 @@ class AsyncRawPlansClient:
422
482
  Success response
423
483
  """
424
484
  _response = await self._client_wrapper.httpx_client.request(
425
- f"plans/group/{jsonable_encoder(plan_group_id)}",
485
+ f"plans/planGroup/{jsonable_encoder(plan_group_id)}",
426
486
  method="GET",
427
487
  request_options=request_options,
428
488
  )
@@ -462,3 +522,62 @@ class AsyncRawPlansClient:
462
522
  except JSONDecodeError:
463
523
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
464
524
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
525
+
526
+ async def get_group_plans(
527
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
528
+ ) -> AsyncHttpResponse[typing.List[PlanWithFeatures]]:
529
+ """
530
+ Parameters
531
+ ----------
532
+ plan_group_id : str
533
+ The ID of the plan group
534
+
535
+ request_options : typing.Optional[RequestOptions]
536
+ Request-specific configuration.
537
+
538
+ Returns
539
+ -------
540
+ AsyncHttpResponse[typing.List[PlanWithFeatures]]
541
+ Success response
542
+ """
543
+ _response = await self._client_wrapper.httpx_client.request(
544
+ f"plans/planGroup/{jsonable_encoder(plan_group_id)}/plans",
545
+ method="GET",
546
+ request_options=request_options,
547
+ )
548
+ try:
549
+ if 200 <= _response.status_code < 300:
550
+ _data = typing.cast(
551
+ typing.List[PlanWithFeatures],
552
+ parse_obj_as(
553
+ type_=typing.List[PlanWithFeatures], # type: ignore
554
+ object_=_response.json(),
555
+ ),
556
+ )
557
+ return AsyncHttpResponse(response=_response, data=_data)
558
+ if _response.status_code == 403:
559
+ raise ForbiddenError(
560
+ headers=dict(_response.headers),
561
+ body=typing.cast(
562
+ Error,
563
+ parse_obj_as(
564
+ type_=Error, # type: ignore
565
+ object_=_response.json(),
566
+ ),
567
+ ),
568
+ )
569
+ if _response.status_code == 404:
570
+ raise NotFoundError(
571
+ headers=dict(_response.headers),
572
+ body=typing.cast(
573
+ Error,
574
+ parse_obj_as(
575
+ type_=Error, # type: ignore
576
+ object_=_response.json(),
577
+ ),
578
+ ),
579
+ )
580
+ _response_json = _response.json()
581
+ except JSONDecodeError:
582
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
583
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
paid/types/__init__.py CHANGED
@@ -10,8 +10,10 @@ from .agent_price_point_tiers import AgentPricePointTiers
10
10
  from .agent_update import AgentUpdate
11
11
  from .api_error import ApiError
12
12
  from .billing_frequency import BillingFrequency
13
+ from .cancel_renewal_response import CancelRenewalResponse
13
14
  from .charge_type import ChargeType
14
15
  from .contact import Contact
16
+ from .contact_create_for_customer import ContactCreateForCustomer
15
17
  from .cost_amount import CostAmount
16
18
  from .cost_trace import CostTrace
17
19
  from .cost_traces_response import CostTracesResponse
@@ -21,6 +23,8 @@ from .customer import Customer
21
23
  from .customer_update import CustomerUpdate
22
24
  from .entitlement_usage import EntitlementUsage
23
25
  from .error import Error
26
+ from .invoice import Invoice
27
+ from .invoice_status import InvoiceStatus
24
28
  from .order import Order
25
29
  from .order_line import OrderLine
26
30
  from .order_line_attribute import OrderLineAttribute
@@ -28,10 +32,17 @@ from .order_line_attribute_create_one import OrderLineAttributeCreateOne
28
32
  from .order_line_attribute_pricing import OrderLineAttributePricing
29
33
  from .order_line_create import OrderLineCreate
30
34
  from .pagination_meta import PaginationMeta
35
+ from .payment_method import PaymentMethod
36
+ from .payment_method_card import PaymentMethodCard
37
+ from .payment_method_type import PaymentMethodType
38
+ from .payment_method_us_bank_account import PaymentMethodUsBankAccount
39
+ from .payment_method_us_bank_account_account_type import PaymentMethodUsBankAccountAccountType
31
40
  from .plan import Plan
32
41
  from .plan_group import PlanGroup
33
42
  from .plan_plan_products_item import PlanPlanProductsItem
34
43
  from .plan_plan_products_item_plan_product_attribute_item import PlanPlanProductsItemPlanProductAttributeItem
44
+ from .plan_with_features import PlanWithFeatures
45
+ from .plan_with_features_features_item import PlanWithFeaturesFeaturesItem
35
46
  from .price_point import PricePoint
36
47
  from .pricing import Pricing
37
48
  from .pricing_model_type import PricingModelType
@@ -39,6 +50,9 @@ from .product import Product
39
50
  from .product_type import ProductType
40
51
  from .product_update import ProductUpdate
41
52
  from .product_update_type import ProductUpdateType
53
+ from .proration_attribute_update import ProrationAttributeUpdate
54
+ from .proration_detail import ProrationDetail
55
+ from .proration_upgrade_response import ProrationUpgradeResponse
42
56
  from .salutation import Salutation
43
57
  from .signal import Signal
44
58
  from .signal_v_2 import SignalV2
@@ -61,8 +75,10 @@ __all__ = [
61
75
  "AgentUpdate",
62
76
  "ApiError",
63
77
  "BillingFrequency",
78
+ "CancelRenewalResponse",
64
79
  "ChargeType",
65
80
  "Contact",
81
+ "ContactCreateForCustomer",
66
82
  "CostAmount",
67
83
  "CostTrace",
68
84
  "CostTracesResponse",
@@ -72,6 +88,8 @@ __all__ = [
72
88
  "CustomerUpdate",
73
89
  "EntitlementUsage",
74
90
  "Error",
91
+ "Invoice",
92
+ "InvoiceStatus",
75
93
  "Order",
76
94
  "OrderLine",
77
95
  "OrderLineAttribute",
@@ -79,10 +97,17 @@ __all__ = [
79
97
  "OrderLineAttributePricing",
80
98
  "OrderLineCreate",
81
99
  "PaginationMeta",
100
+ "PaymentMethod",
101
+ "PaymentMethodCard",
102
+ "PaymentMethodType",
103
+ "PaymentMethodUsBankAccount",
104
+ "PaymentMethodUsBankAccountAccountType",
82
105
  "Plan",
83
106
  "PlanGroup",
84
107
  "PlanPlanProductsItem",
85
108
  "PlanPlanProductsItemPlanProductAttributeItem",
109
+ "PlanWithFeatures",
110
+ "PlanWithFeaturesFeaturesItem",
86
111
  "PricePoint",
87
112
  "Pricing",
88
113
  "PricingModelType",
@@ -90,6 +115,9 @@ __all__ = [
90
115
  "ProductType",
91
116
  "ProductUpdate",
92
117
  "ProductUpdateType",
118
+ "ProrationAttributeUpdate",
119
+ "ProrationDetail",
120
+ "ProrationUpgradeResponse",
93
121
  "Salutation",
94
122
  "Signal",
95
123
  "SignalV2",
@@ -0,0 +1,49 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ..core.serialization import FieldMetadata
10
+
11
+
12
+ class CancelRenewalResponse(UniversalBaseModel):
13
+ """
14
+ Response after successfully cancelling an order's renewal
15
+ """
16
+
17
+ order_id: typing_extensions.Annotated[str, FieldMetadata(alias="orderId")] = pydantic.Field()
18
+ """
19
+ The ID of the order
20
+ """
21
+
22
+ amendment_id: typing_extensions.Annotated[str, FieldMetadata(alias="amendmentId")] = pydantic.Field()
23
+ """
24
+ The ID of the amendment record
25
+ """
26
+
27
+ version: int = pydantic.Field()
28
+ """
29
+ The new version of the order after the amendment
30
+ """
31
+
32
+ end_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="endDate")] = pydantic.Field()
33
+ """
34
+ The new end date of the order
35
+ """
36
+
37
+ effective_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="effectiveDate")] = pydantic.Field()
38
+ """
39
+ The effective date of the cancellation
40
+ """
41
+
42
+ if IS_PYDANTIC_V2:
43
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
44
+ else:
45
+
46
+ class Config:
47
+ frozen = True
48
+ smart_union = True
49
+ extra = pydantic.Extra.allow
@@ -0,0 +1,37 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+ from .salutation import Salutation
10
+
11
+
12
+ class ContactCreateForCustomer(UniversalBaseModel):
13
+ external_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="externalId")] = None
14
+ salutation: Salutation
15
+ first_name: typing_extensions.Annotated[str, FieldMetadata(alias="firstName")]
16
+ last_name: typing_extensions.Annotated[str, FieldMetadata(alias="lastName")]
17
+ account_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="accountName")] = None
18
+ email: str
19
+ phone: typing.Optional[str] = None
20
+ billing_street: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="billingStreet")] = None
21
+ billing_city: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="billingCity")] = None
22
+ billing_state_province: typing_extensions.Annotated[
23
+ typing.Optional[str], FieldMetadata(alias="billingStateProvince")
24
+ ] = None
25
+ billing_country: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="billingCountry")] = None
26
+ billing_postal_code: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="billingPostalCode")] = (
27
+ None
28
+ )
29
+
30
+ if IS_PYDANTIC_V2:
31
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
32
+ else:
33
+
34
+ class Config:
35
+ frozen = True
36
+ smart_union = True
37
+ extra = pydantic.Extra.allow
paid/types/invoice.py ADDED
@@ -0,0 +1,75 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ..core.serialization import FieldMetadata
10
+ from .customer import Customer
11
+ from .invoice_status import InvoiceStatus
12
+
13
+
14
+ class Invoice(UniversalBaseModel):
15
+ """
16
+ An invoice for an order
17
+ """
18
+
19
+ id: typing.Optional[str] = None
20
+ display_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayId")] = pydantic.Field(
21
+ default=None
22
+ )
23
+ """
24
+ Human-readable invoice number
25
+ """
26
+
27
+ organization_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="organizationId")] = None
28
+ customer_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="customerId")] = None
29
+ order_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="orderId")] = None
30
+ status: typing.Optional[InvoiceStatus] = None
31
+ currency: typing.Optional[str] = None
32
+ subtotal: typing.Optional[float] = pydantic.Field(default=None)
33
+ """
34
+ Total before tax (in smallest currency unit)
35
+ """
36
+
37
+ tax: typing.Optional[float] = pydantic.Field(default=None)
38
+ """
39
+ Tax amount (in smallest currency unit)
40
+ """
41
+
42
+ total: typing.Optional[float] = pydantic.Field(default=None)
43
+ """
44
+ Total amount including tax (in smallest currency unit)
45
+ """
46
+
47
+ amount_paid: typing_extensions.Annotated[typing.Optional[float], FieldMetadata(alias="amountPaid")] = (
48
+ pydantic.Field(default=None)
49
+ )
50
+ """
51
+ Amount already paid (in smallest currency unit)
52
+ """
53
+
54
+ amount_due: typing_extensions.Annotated[typing.Optional[float], FieldMetadata(alias="amountDue")] = pydantic.Field(
55
+ default=None
56
+ )
57
+ """
58
+ Amount still due (in smallest currency unit)
59
+ """
60
+
61
+ due_date: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="dueDate")] = None
62
+ paid_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="paidAt")] = None
63
+ voided_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="voidedAt")] = None
64
+ created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = None
65
+ updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = None
66
+ customer: typing.Optional[Customer] = None
67
+
68
+ if IS_PYDANTIC_V2:
69
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
70
+ else:
71
+
72
+ class Config:
73
+ frozen = True
74
+ smart_union = True
75
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ InvoiceStatus = typing.Union[typing.Literal["draft", "open", "paid", "void", "uncollectible"], typing.Any]
@@ -0,0 +1,58 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ..core.serialization import FieldMetadata
10
+ from .payment_method_card import PaymentMethodCard
11
+ from .payment_method_type import PaymentMethodType
12
+ from .payment_method_us_bank_account import PaymentMethodUsBankAccount
13
+
14
+
15
+ class PaymentMethod(UniversalBaseModel):
16
+ """
17
+ A customer's payment method
18
+ """
19
+
20
+ id: typing.Optional[str] = pydantic.Field(default=None)
21
+ """
22
+ The payment method ID (typically from Stripe)
23
+ """
24
+
25
+ type: typing.Optional[PaymentMethodType] = pydantic.Field(default=None)
26
+ """
27
+ The type of payment method
28
+ """
29
+
30
+ card: typing.Optional[PaymentMethodCard] = pydantic.Field(default=None)
31
+ """
32
+ Card details (present when type is 'card')
33
+ """
34
+
35
+ us_bank_account: typing_extensions.Annotated[
36
+ typing.Optional[PaymentMethodUsBankAccount], FieldMetadata(alias="usBankAccount")
37
+ ] = pydantic.Field(default=None)
38
+ """
39
+ US bank account details (present when type is 'us_bank_account')
40
+ """
41
+
42
+ is_default: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isDefault")] = pydantic.Field(
43
+ default=None
44
+ )
45
+ """
46
+ Whether this is the customer's default payment method
47
+ """
48
+
49
+ created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = None
50
+
51
+ if IS_PYDANTIC_V2:
52
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
53
+ else:
54
+
55
+ class Config:
56
+ frozen = True
57
+ smart_union = True
58
+ extra = pydantic.Extra.allow
@@ -0,0 +1,49 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+
10
+
11
+ class PaymentMethodCard(UniversalBaseModel):
12
+ """
13
+ Card details (present when type is 'card')
14
+ """
15
+
16
+ brand: typing.Optional[str] = pydantic.Field(default=None)
17
+ """
18
+ Card brand (visa, mastercard, amex, etc.)
19
+ """
20
+
21
+ last_4: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="last4")] = pydantic.Field(
22
+ default=None
23
+ )
24
+ """
25
+ Last 4 digits of the card number
26
+ """
27
+
28
+ exp_month: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="expMonth")] = pydantic.Field(
29
+ default=None
30
+ )
31
+ """
32
+ Expiration month (1-12)
33
+ """
34
+
35
+ exp_year: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="expYear")] = pydantic.Field(
36
+ default=None
37
+ )
38
+ """
39
+ Expiration year
40
+ """
41
+
42
+ if IS_PYDANTIC_V2:
43
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
44
+ else:
45
+
46
+ class Config:
47
+ frozen = True
48
+ smart_union = True
49
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ PaymentMethodType = typing.Union[typing.Literal["card", "us_bank_account", "sepa_debit"], typing.Any]
@@ -0,0 +1,36 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+ from .payment_method_us_bank_account_account_type import PaymentMethodUsBankAccountAccountType
10
+
11
+
12
+ class PaymentMethodUsBankAccount(UniversalBaseModel):
13
+ """
14
+ US bank account details (present when type is 'us_bank_account')
15
+ """
16
+
17
+ bank_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="bankName")] = None
18
+ last_4: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="last4")] = pydantic.Field(
19
+ default=None
20
+ )
21
+ """
22
+ Last 4 digits of the account number
23
+ """
24
+
25
+ account_type: typing_extensions.Annotated[
26
+ typing.Optional[PaymentMethodUsBankAccountAccountType], FieldMetadata(alias="accountType")
27
+ ] = None
28
+
29
+ if IS_PYDANTIC_V2:
30
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
31
+ else:
32
+
33
+ class Config:
34
+ frozen = True
35
+ smart_union = True
36
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ PaymentMethodUsBankAccountAccountType = typing.Union[typing.Literal["checking", "savings"], typing.Any]
@@ -8,6 +8,7 @@ import typing_extensions
8
8
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
9
  from ..core.serialization import FieldMetadata
10
10
  from .plan_plan_products_item_plan_product_attribute_item import PlanPlanProductsItemPlanProductAttributeItem
11
+ from .product import Product
11
12
 
12
13
 
13
14
  class PlanPlanProductsItem(UniversalBaseModel):
@@ -17,6 +18,11 @@ class PlanPlanProductsItem(UniversalBaseModel):
17
18
  product_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="productId")] = None
18
19
  created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = None
19
20
  updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = None
21
+ product: typing.Optional[Product] = pydantic.Field(default=None)
22
+ """
23
+ The product associated with this plan product
24
+ """
25
+
20
26
  plan_product_attribute: typing_extensions.Annotated[
21
27
  typing.Optional[typing.List[PlanPlanProductsItemPlanProductAttributeItem]],
22
28
  FieldMetadata(alias="planProductAttribute"),