paid-python 0.5.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 (54) hide show
  1. paid/__init__.py +33 -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 +445 -0
  11. paid/orders/raw_client.py +705 -0
  12. paid/plans/client.py +142 -0
  13. paid/plans/raw_client.py +238 -0
  14. paid/types/__init__.py +30 -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_group.py +60 -0
  25. paid/types/plan_plan_products_item.py +6 -0
  26. paid/types/plan_with_features.py +69 -0
  27. paid/types/plan_with_features_features_item.py +34 -0
  28. paid/types/proration_attribute_update.py +44 -0
  29. paid/types/proration_detail.py +49 -0
  30. paid/types/proration_upgrade_response.py +73 -0
  31. paid/types/signal_v_2.py +5 -5
  32. paid/usage/client.py +6 -6
  33. {paid_python-0.5.0.dist-info → paid_python-1.0.0a0.dist-info}/METADATA +6 -4
  34. {paid_python-0.5.0.dist-info → paid_python-1.0.0a0.dist-info}/RECORD +36 -36
  35. opentelemetry/instrumentation/openai/__init__.py +0 -54
  36. opentelemetry/instrumentation/openai/shared/__init__.py +0 -399
  37. opentelemetry/instrumentation/openai/shared/audio_wrappers.py +0 -247
  38. opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -1192
  39. opentelemetry/instrumentation/openai/shared/completion_wrappers.py +0 -292
  40. opentelemetry/instrumentation/openai/shared/config.py +0 -15
  41. opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -311
  42. opentelemetry/instrumentation/openai/shared/event_emitter.py +0 -108
  43. opentelemetry/instrumentation/openai/shared/event_models.py +0 -41
  44. opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +0 -68
  45. opentelemetry/instrumentation/openai/shared/span_utils.py +0 -0
  46. opentelemetry/instrumentation/openai/utils.py +0 -213
  47. opentelemetry/instrumentation/openai/v0/__init__.py +0 -176
  48. opentelemetry/instrumentation/openai/v1/__init__.py +0 -394
  49. opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +0 -329
  50. opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +0 -134
  51. opentelemetry/instrumentation/openai/v1/responses_wrappers.py +0 -1113
  52. opentelemetry/instrumentation/openai/version.py +0 -1
  53. {paid_python-0.5.0.dist-info → paid_python-1.0.0a0.dist-info}/LICENSE +0 -0
  54. {paid_python-0.5.0.dist-info → paid_python-1.0.0a0.dist-info}/WHEEL +0 -0
@@ -16,13 +16,17 @@ from ..errors.bad_request_error import BadRequestError
16
16
  from ..errors.forbidden_error import ForbiddenError
17
17
  from ..errors.not_found_error import NotFoundError
18
18
  from ..types.address import Address
19
+ from ..types.contact_create_for_customer import ContactCreateForCustomer
19
20
  from ..types.cost_traces_response import CostTracesResponse
20
21
  from ..types.creation_source import CreationSource
21
22
  from ..types.customer import Customer
22
23
  from ..types.entitlement_usage import EntitlementUsage
23
24
  from ..types.error import Error
25
+ from ..types.payment_method import PaymentMethod
24
26
  from ..types.tax_exempt_status import TaxExemptStatus
25
27
  from ..types.usage_summaries_response import UsageSummariesResponse
28
+ from .types.customers_check_entitlement_request_view import CustomersCheckEntitlementRequestView
29
+ from .types.customers_check_entitlement_response import CustomersCheckEntitlementResponse
26
30
 
27
31
  # this is used as the default value for optional parameters
28
32
  OMIT = typing.cast(typing.Any, ...)
@@ -77,6 +81,7 @@ class RawCustomersClient:
77
81
  website: typing.Optional[str] = OMIT,
78
82
  billing_address: typing.Optional[Address] = OMIT,
79
83
  metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
84
+ contacts: typing.Optional[typing.Sequence[ContactCreateForCustomer]] = OMIT,
80
85
  request_options: typing.Optional[RequestOptions] = None,
81
86
  ) -> HttpResponse[Customer]:
82
87
  """
@@ -103,13 +108,16 @@ class RawCustomersClient:
103
108
  metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
104
109
  Flexible JSON field for storing custom metadata about the customer
105
110
 
111
+ contacts : typing.Optional[typing.Sequence[ContactCreateForCustomer]]
112
+ Array of contacts to create for this customer
113
+
106
114
  request_options : typing.Optional[RequestOptions]
107
115
  Request-specific configuration.
108
116
 
109
117
  Returns
110
118
  -------
111
119
  HttpResponse[Customer]
112
- Success response
120
+ Success response - customer already exists with this externalId
113
121
  """
114
122
  _response = self._client_wrapper.httpx_client.request(
115
123
  "customers",
@@ -127,6 +135,9 @@ class RawCustomersClient:
127
135
  object_=billing_address, annotation=Address, direction="write"
128
136
  ),
129
137
  "metadata": metadata,
138
+ "contacts": convert_and_respect_annotation_metadata(
139
+ object_=contacts, annotation=typing.Sequence[ContactCreateForCustomer], direction="write"
140
+ ),
130
141
  },
131
142
  headers={
132
143
  "content-type": "application/json",
@@ -301,6 +312,80 @@ class RawCustomersClient:
301
312
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
302
313
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
303
314
 
315
+ def check_entitlement(
316
+ self,
317
+ customer_id: str,
318
+ *,
319
+ event_name: str,
320
+ view: typing.Optional[CustomersCheckEntitlementRequestView] = None,
321
+ request_options: typing.Optional[RequestOptions] = None,
322
+ ) -> HttpResponse[CustomersCheckEntitlementResponse]:
323
+ """
324
+ Parameters
325
+ ----------
326
+ customer_id : str
327
+ The customer ID
328
+
329
+ event_name : str
330
+ The name of the usage event to check entitlement for
331
+
332
+ view : typing.Optional[CustomersCheckEntitlementRequestView]
333
+ Filter view - 'all' returns all entitlements regardless of status, 'active_only' returns only currently active entitlements with available credits
334
+
335
+ request_options : typing.Optional[RequestOptions]
336
+ Request-specific configuration.
337
+
338
+ Returns
339
+ -------
340
+ HttpResponse[CustomersCheckEntitlementResponse]
341
+ Success response
342
+ """
343
+ _response = self._client_wrapper.httpx_client.request(
344
+ f"customers/{jsonable_encoder(customer_id)}/entitlement",
345
+ method="GET",
346
+ params={
347
+ "event_name": event_name,
348
+ "view": view,
349
+ },
350
+ request_options=request_options,
351
+ )
352
+ try:
353
+ if 200 <= _response.status_code < 300:
354
+ _data = typing.cast(
355
+ CustomersCheckEntitlementResponse,
356
+ parse_obj_as(
357
+ type_=CustomersCheckEntitlementResponse, # type: ignore
358
+ object_=_response.json(),
359
+ ),
360
+ )
361
+ return HttpResponse(response=_response, data=_data)
362
+ if _response.status_code == 400:
363
+ raise BadRequestError(
364
+ headers=dict(_response.headers),
365
+ body=typing.cast(
366
+ Error,
367
+ parse_obj_as(
368
+ type_=Error, # type: ignore
369
+ object_=_response.json(),
370
+ ),
371
+ ),
372
+ )
373
+ if _response.status_code == 404:
374
+ raise NotFoundError(
375
+ headers=dict(_response.headers),
376
+ body=typing.cast(
377
+ Error,
378
+ parse_obj_as(
379
+ type_=Error, # type: ignore
380
+ object_=_response.json(),
381
+ ),
382
+ ),
383
+ )
384
+ _response_json = _response.json()
385
+ except JSONDecodeError:
386
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
387
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
388
+
304
389
  def get_entitlements(
305
390
  self, customer_id: str, *, request_options: typing.Optional[RequestOptions] = None
306
391
  ) -> HttpResponse[typing.List[EntitlementUsage]]:
@@ -691,6 +776,219 @@ class RawCustomersClient:
691
776
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
692
777
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
693
778
 
779
+ def list_payment_methods(
780
+ self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None
781
+ ) -> HttpResponse[typing.List[PaymentMethod]]:
782
+ """
783
+ Retrieves all payment methods associated with a customer identified by their external ID.
784
+
785
+ Parameters
786
+ ----------
787
+ external_id : str
788
+ The external ID of the customer
789
+
790
+ request_options : typing.Optional[RequestOptions]
791
+ Request-specific configuration.
792
+
793
+ Returns
794
+ -------
795
+ HttpResponse[typing.List[PaymentMethod]]
796
+ Success response
797
+ """
798
+ _response = self._client_wrapper.httpx_client.request(
799
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods",
800
+ method="GET",
801
+ request_options=request_options,
802
+ )
803
+ try:
804
+ if 200 <= _response.status_code < 300:
805
+ _data = typing.cast(
806
+ typing.List[PaymentMethod],
807
+ parse_obj_as(
808
+ type_=typing.List[PaymentMethod], # type: ignore
809
+ object_=_response.json(),
810
+ ),
811
+ )
812
+ return HttpResponse(response=_response, data=_data)
813
+ if _response.status_code == 403:
814
+ raise ForbiddenError(
815
+ headers=dict(_response.headers),
816
+ body=typing.cast(
817
+ Error,
818
+ parse_obj_as(
819
+ type_=Error, # type: ignore
820
+ object_=_response.json(),
821
+ ),
822
+ ),
823
+ )
824
+ if _response.status_code == 404:
825
+ raise NotFoundError(
826
+ headers=dict(_response.headers),
827
+ body=typing.cast(
828
+ Error,
829
+ parse_obj_as(
830
+ type_=Error, # type: ignore
831
+ object_=_response.json(),
832
+ ),
833
+ ),
834
+ )
835
+ _response_json = _response.json()
836
+ except JSONDecodeError:
837
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
838
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
839
+
840
+ def create_payment_method(
841
+ self,
842
+ external_id: str,
843
+ *,
844
+ confirmation_token: str,
845
+ return_url: str,
846
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
847
+ request_options: typing.Optional[RequestOptions] = None,
848
+ ) -> HttpResponse[PaymentMethod]:
849
+ """
850
+ Creates a new payment method for a customer using a Stripe confirmation token.
851
+
852
+ Parameters
853
+ ----------
854
+ external_id : str
855
+ The external ID of the customer
856
+
857
+ confirmation_token : str
858
+ Stripe confirmation token for the payment method
859
+
860
+ return_url : str
861
+ URL to redirect to after payment method setup
862
+
863
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
864
+ Optional metadata to attach to the payment method
865
+
866
+ request_options : typing.Optional[RequestOptions]
867
+ Request-specific configuration.
868
+
869
+ Returns
870
+ -------
871
+ HttpResponse[PaymentMethod]
872
+ Payment method created successfully
873
+ """
874
+ _response = self._client_wrapper.httpx_client.request(
875
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods",
876
+ method="POST",
877
+ json={
878
+ "confirmationToken": confirmation_token,
879
+ "returnUrl": return_url,
880
+ "metadata": metadata,
881
+ },
882
+ headers={
883
+ "content-type": "application/json",
884
+ },
885
+ request_options=request_options,
886
+ omit=OMIT,
887
+ )
888
+ try:
889
+ if 200 <= _response.status_code < 300:
890
+ _data = typing.cast(
891
+ PaymentMethod,
892
+ parse_obj_as(
893
+ type_=PaymentMethod, # type: ignore
894
+ object_=_response.json(),
895
+ ),
896
+ )
897
+ return HttpResponse(response=_response, data=_data)
898
+ if _response.status_code == 400:
899
+ raise BadRequestError(
900
+ headers=dict(_response.headers),
901
+ body=typing.cast(
902
+ Error,
903
+ parse_obj_as(
904
+ type_=Error, # type: ignore
905
+ object_=_response.json(),
906
+ ),
907
+ ),
908
+ )
909
+ if _response.status_code == 403:
910
+ raise ForbiddenError(
911
+ headers=dict(_response.headers),
912
+ body=typing.cast(
913
+ Error,
914
+ parse_obj_as(
915
+ type_=Error, # type: ignore
916
+ object_=_response.json(),
917
+ ),
918
+ ),
919
+ )
920
+ if _response.status_code == 404:
921
+ raise NotFoundError(
922
+ headers=dict(_response.headers),
923
+ body=typing.cast(
924
+ Error,
925
+ parse_obj_as(
926
+ type_=Error, # type: ignore
927
+ object_=_response.json(),
928
+ ),
929
+ ),
930
+ )
931
+ _response_json = _response.json()
932
+ except JSONDecodeError:
933
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
934
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
935
+
936
+ def delete_payment_method(
937
+ self, external_id: str, payment_method_id: str, *, request_options: typing.Optional[RequestOptions] = None
938
+ ) -> HttpResponse[None]:
939
+ """
940
+ Deletes a specific payment method from a customer's account.
941
+
942
+ Parameters
943
+ ----------
944
+ external_id : str
945
+ The external ID of the customer
946
+
947
+ payment_method_id : str
948
+ The ID of the payment method to delete
949
+
950
+ request_options : typing.Optional[RequestOptions]
951
+ Request-specific configuration.
952
+
953
+ Returns
954
+ -------
955
+ HttpResponse[None]
956
+ """
957
+ _response = self._client_wrapper.httpx_client.request(
958
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods/{jsonable_encoder(payment_method_id)}",
959
+ method="DELETE",
960
+ request_options=request_options,
961
+ )
962
+ try:
963
+ if 200 <= _response.status_code < 300:
964
+ return HttpResponse(response=_response, data=None)
965
+ if _response.status_code == 403:
966
+ raise ForbiddenError(
967
+ headers=dict(_response.headers),
968
+ body=typing.cast(
969
+ Error,
970
+ parse_obj_as(
971
+ type_=Error, # type: ignore
972
+ object_=_response.json(),
973
+ ),
974
+ ),
975
+ )
976
+ if _response.status_code == 404:
977
+ raise NotFoundError(
978
+ headers=dict(_response.headers),
979
+ body=typing.cast(
980
+ Error,
981
+ parse_obj_as(
982
+ type_=Error, # type: ignore
983
+ object_=_response.json(),
984
+ ),
985
+ ),
986
+ )
987
+ _response_json = _response.json()
988
+ except JSONDecodeError:
989
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
990
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
991
+
694
992
 
695
993
  class AsyncRawCustomersClient:
696
994
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -743,6 +1041,7 @@ class AsyncRawCustomersClient:
743
1041
  website: typing.Optional[str] = OMIT,
744
1042
  billing_address: typing.Optional[Address] = OMIT,
745
1043
  metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
1044
+ contacts: typing.Optional[typing.Sequence[ContactCreateForCustomer]] = OMIT,
746
1045
  request_options: typing.Optional[RequestOptions] = None,
747
1046
  ) -> AsyncHttpResponse[Customer]:
748
1047
  """
@@ -769,13 +1068,16 @@ class AsyncRawCustomersClient:
769
1068
  metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
770
1069
  Flexible JSON field for storing custom metadata about the customer
771
1070
 
1071
+ contacts : typing.Optional[typing.Sequence[ContactCreateForCustomer]]
1072
+ Array of contacts to create for this customer
1073
+
772
1074
  request_options : typing.Optional[RequestOptions]
773
1075
  Request-specific configuration.
774
1076
 
775
1077
  Returns
776
1078
  -------
777
1079
  AsyncHttpResponse[Customer]
778
- Success response
1080
+ Success response - customer already exists with this externalId
779
1081
  """
780
1082
  _response = await self._client_wrapper.httpx_client.request(
781
1083
  "customers",
@@ -793,6 +1095,9 @@ class AsyncRawCustomersClient:
793
1095
  object_=billing_address, annotation=Address, direction="write"
794
1096
  ),
795
1097
  "metadata": metadata,
1098
+ "contacts": convert_and_respect_annotation_metadata(
1099
+ object_=contacts, annotation=typing.Sequence[ContactCreateForCustomer], direction="write"
1100
+ ),
796
1101
  },
797
1102
  headers={
798
1103
  "content-type": "application/json",
@@ -967,6 +1272,80 @@ class AsyncRawCustomersClient:
967
1272
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
968
1273
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
969
1274
 
1275
+ async def check_entitlement(
1276
+ self,
1277
+ customer_id: str,
1278
+ *,
1279
+ event_name: str,
1280
+ view: typing.Optional[CustomersCheckEntitlementRequestView] = None,
1281
+ request_options: typing.Optional[RequestOptions] = None,
1282
+ ) -> AsyncHttpResponse[CustomersCheckEntitlementResponse]:
1283
+ """
1284
+ Parameters
1285
+ ----------
1286
+ customer_id : str
1287
+ The customer ID
1288
+
1289
+ event_name : str
1290
+ The name of the usage event to check entitlement for
1291
+
1292
+ view : typing.Optional[CustomersCheckEntitlementRequestView]
1293
+ Filter view - 'all' returns all entitlements regardless of status, 'active_only' returns only currently active entitlements with available credits
1294
+
1295
+ request_options : typing.Optional[RequestOptions]
1296
+ Request-specific configuration.
1297
+
1298
+ Returns
1299
+ -------
1300
+ AsyncHttpResponse[CustomersCheckEntitlementResponse]
1301
+ Success response
1302
+ """
1303
+ _response = await self._client_wrapper.httpx_client.request(
1304
+ f"customers/{jsonable_encoder(customer_id)}/entitlement",
1305
+ method="GET",
1306
+ params={
1307
+ "event_name": event_name,
1308
+ "view": view,
1309
+ },
1310
+ request_options=request_options,
1311
+ )
1312
+ try:
1313
+ if 200 <= _response.status_code < 300:
1314
+ _data = typing.cast(
1315
+ CustomersCheckEntitlementResponse,
1316
+ parse_obj_as(
1317
+ type_=CustomersCheckEntitlementResponse, # type: ignore
1318
+ object_=_response.json(),
1319
+ ),
1320
+ )
1321
+ return AsyncHttpResponse(response=_response, data=_data)
1322
+ if _response.status_code == 400:
1323
+ raise BadRequestError(
1324
+ headers=dict(_response.headers),
1325
+ body=typing.cast(
1326
+ Error,
1327
+ parse_obj_as(
1328
+ type_=Error, # type: ignore
1329
+ object_=_response.json(),
1330
+ ),
1331
+ ),
1332
+ )
1333
+ if _response.status_code == 404:
1334
+ raise NotFoundError(
1335
+ headers=dict(_response.headers),
1336
+ body=typing.cast(
1337
+ Error,
1338
+ parse_obj_as(
1339
+ type_=Error, # type: ignore
1340
+ object_=_response.json(),
1341
+ ),
1342
+ ),
1343
+ )
1344
+ _response_json = _response.json()
1345
+ except JSONDecodeError:
1346
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1347
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1348
+
970
1349
  async def get_entitlements(
971
1350
  self, customer_id: str, *, request_options: typing.Optional[RequestOptions] = None
972
1351
  ) -> AsyncHttpResponse[typing.List[EntitlementUsage]]:
@@ -1356,3 +1735,216 @@ class AsyncRawCustomersClient:
1356
1735
  except JSONDecodeError:
1357
1736
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1358
1737
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1738
+
1739
+ async def list_payment_methods(
1740
+ self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None
1741
+ ) -> AsyncHttpResponse[typing.List[PaymentMethod]]:
1742
+ """
1743
+ Retrieves all payment methods associated with a customer identified by their external ID.
1744
+
1745
+ Parameters
1746
+ ----------
1747
+ external_id : str
1748
+ The external ID of the customer
1749
+
1750
+ request_options : typing.Optional[RequestOptions]
1751
+ Request-specific configuration.
1752
+
1753
+ Returns
1754
+ -------
1755
+ AsyncHttpResponse[typing.List[PaymentMethod]]
1756
+ Success response
1757
+ """
1758
+ _response = await self._client_wrapper.httpx_client.request(
1759
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods",
1760
+ method="GET",
1761
+ request_options=request_options,
1762
+ )
1763
+ try:
1764
+ if 200 <= _response.status_code < 300:
1765
+ _data = typing.cast(
1766
+ typing.List[PaymentMethod],
1767
+ parse_obj_as(
1768
+ type_=typing.List[PaymentMethod], # type: ignore
1769
+ object_=_response.json(),
1770
+ ),
1771
+ )
1772
+ return AsyncHttpResponse(response=_response, data=_data)
1773
+ if _response.status_code == 403:
1774
+ raise ForbiddenError(
1775
+ headers=dict(_response.headers),
1776
+ body=typing.cast(
1777
+ Error,
1778
+ parse_obj_as(
1779
+ type_=Error, # type: ignore
1780
+ object_=_response.json(),
1781
+ ),
1782
+ ),
1783
+ )
1784
+ if _response.status_code == 404:
1785
+ raise NotFoundError(
1786
+ headers=dict(_response.headers),
1787
+ body=typing.cast(
1788
+ Error,
1789
+ parse_obj_as(
1790
+ type_=Error, # type: ignore
1791
+ object_=_response.json(),
1792
+ ),
1793
+ ),
1794
+ )
1795
+ _response_json = _response.json()
1796
+ except JSONDecodeError:
1797
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1798
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1799
+
1800
+ async def create_payment_method(
1801
+ self,
1802
+ external_id: str,
1803
+ *,
1804
+ confirmation_token: str,
1805
+ return_url: str,
1806
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
1807
+ request_options: typing.Optional[RequestOptions] = None,
1808
+ ) -> AsyncHttpResponse[PaymentMethod]:
1809
+ """
1810
+ Creates a new payment method for a customer using a Stripe confirmation token.
1811
+
1812
+ Parameters
1813
+ ----------
1814
+ external_id : str
1815
+ The external ID of the customer
1816
+
1817
+ confirmation_token : str
1818
+ Stripe confirmation token for the payment method
1819
+
1820
+ return_url : str
1821
+ URL to redirect to after payment method setup
1822
+
1823
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
1824
+ Optional metadata to attach to the payment method
1825
+
1826
+ request_options : typing.Optional[RequestOptions]
1827
+ Request-specific configuration.
1828
+
1829
+ Returns
1830
+ -------
1831
+ AsyncHttpResponse[PaymentMethod]
1832
+ Payment method created successfully
1833
+ """
1834
+ _response = await self._client_wrapper.httpx_client.request(
1835
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods",
1836
+ method="POST",
1837
+ json={
1838
+ "confirmationToken": confirmation_token,
1839
+ "returnUrl": return_url,
1840
+ "metadata": metadata,
1841
+ },
1842
+ headers={
1843
+ "content-type": "application/json",
1844
+ },
1845
+ request_options=request_options,
1846
+ omit=OMIT,
1847
+ )
1848
+ try:
1849
+ if 200 <= _response.status_code < 300:
1850
+ _data = typing.cast(
1851
+ PaymentMethod,
1852
+ parse_obj_as(
1853
+ type_=PaymentMethod, # type: ignore
1854
+ object_=_response.json(),
1855
+ ),
1856
+ )
1857
+ return AsyncHttpResponse(response=_response, data=_data)
1858
+ if _response.status_code == 400:
1859
+ raise BadRequestError(
1860
+ headers=dict(_response.headers),
1861
+ body=typing.cast(
1862
+ Error,
1863
+ parse_obj_as(
1864
+ type_=Error, # type: ignore
1865
+ object_=_response.json(),
1866
+ ),
1867
+ ),
1868
+ )
1869
+ if _response.status_code == 403:
1870
+ raise ForbiddenError(
1871
+ headers=dict(_response.headers),
1872
+ body=typing.cast(
1873
+ Error,
1874
+ parse_obj_as(
1875
+ type_=Error, # type: ignore
1876
+ object_=_response.json(),
1877
+ ),
1878
+ ),
1879
+ )
1880
+ if _response.status_code == 404:
1881
+ raise NotFoundError(
1882
+ headers=dict(_response.headers),
1883
+ body=typing.cast(
1884
+ Error,
1885
+ parse_obj_as(
1886
+ type_=Error, # type: ignore
1887
+ object_=_response.json(),
1888
+ ),
1889
+ ),
1890
+ )
1891
+ _response_json = _response.json()
1892
+ except JSONDecodeError:
1893
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1894
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1895
+
1896
+ async def delete_payment_method(
1897
+ self, external_id: str, payment_method_id: str, *, request_options: typing.Optional[RequestOptions] = None
1898
+ ) -> AsyncHttpResponse[None]:
1899
+ """
1900
+ Deletes a specific payment method from a customer's account.
1901
+
1902
+ Parameters
1903
+ ----------
1904
+ external_id : str
1905
+ The external ID of the customer
1906
+
1907
+ payment_method_id : str
1908
+ The ID of the payment method to delete
1909
+
1910
+ request_options : typing.Optional[RequestOptions]
1911
+ Request-specific configuration.
1912
+
1913
+ Returns
1914
+ -------
1915
+ AsyncHttpResponse[None]
1916
+ """
1917
+ _response = await self._client_wrapper.httpx_client.request(
1918
+ f"customers/external/{jsonable_encoder(external_id)}/payment-methods/{jsonable_encoder(payment_method_id)}",
1919
+ method="DELETE",
1920
+ request_options=request_options,
1921
+ )
1922
+ try:
1923
+ if 200 <= _response.status_code < 300:
1924
+ return AsyncHttpResponse(response=_response, data=None)
1925
+ if _response.status_code == 403:
1926
+ raise ForbiddenError(
1927
+ headers=dict(_response.headers),
1928
+ body=typing.cast(
1929
+ Error,
1930
+ parse_obj_as(
1931
+ type_=Error, # type: ignore
1932
+ object_=_response.json(),
1933
+ ),
1934
+ ),
1935
+ )
1936
+ if _response.status_code == 404:
1937
+ raise NotFoundError(
1938
+ headers=dict(_response.headers),
1939
+ body=typing.cast(
1940
+ Error,
1941
+ parse_obj_as(
1942
+ type_=Error, # type: ignore
1943
+ object_=_response.json(),
1944
+ ),
1945
+ ),
1946
+ )
1947
+ _response_json = _response.json()
1948
+ except JSONDecodeError:
1949
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1950
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -0,0 +1,8 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
5
+ from .customers_check_entitlement_request_view import CustomersCheckEntitlementRequestView
6
+ from .customers_check_entitlement_response import CustomersCheckEntitlementResponse
7
+
8
+ __all__ = ["CustomersCheckEntitlementRequestView", "CustomersCheckEntitlementResponse"]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ CustomersCheckEntitlementRequestView = typing.Union[typing.Literal["all", "active_only"], typing.Any]