python-terminusgps 23.0.0__py3-none-any.whl → 24.0.0__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.
- {python_terminusgps-23.0.0.dist-info → python_terminusgps-24.0.0.dist-info}/METADATA +1 -1
- {python_terminusgps-23.0.0.dist-info → python_terminusgps-24.0.0.dist-info}/RECORD +14 -12
- terminusgps/authorizenet/__init__.py +9 -0
- terminusgps/authorizenet/auth.py +21 -0
- terminusgps/authorizenet/errors.py +31 -0
- terminusgps/authorizenet/profiles/addresses.py +44 -36
- terminusgps/authorizenet/profiles/base.py +2 -2
- terminusgps/authorizenet/profiles/customers.py +25 -29
- terminusgps/authorizenet/profiles/payments.py +88 -55
- terminusgps/authorizenet/subscriptions/__init__.py +0 -0
- terminusgps/authorizenet/{subscriptions.py → subscriptions/subscriptions.py} +11 -7
- terminusgps/authorizenet/utils.py +5 -12
- {python_terminusgps-23.0.0.dist-info → python_terminusgps-24.0.0.dist-info}/WHEEL +0 -0
- {python_terminusgps-23.0.0.dist-info → python_terminusgps-24.0.0.dist-info}/licenses/COPYING +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-terminusgps
|
|
3
|
-
Version:
|
|
3
|
+
Version: 24.0.0
|
|
4
4
|
Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
|
|
5
5
|
Project-URL: Documentation, https://app.terminusgps.com/docs/apps/python-terminusgps/index.html
|
|
6
6
|
Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
terminusgps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
terminusgps/settings.py,sha256=UBj2tvuBzQDEz05PeFqHG4_ise3Bl6Iu7pxcrtjNaYE,568
|
|
3
|
-
terminusgps/authorizenet/__init__.py,sha256=
|
|
4
|
-
terminusgps/authorizenet/auth.py,sha256=
|
|
5
|
-
terminusgps/authorizenet/
|
|
6
|
-
terminusgps/authorizenet/utils.py,sha256=
|
|
3
|
+
terminusgps/authorizenet/__init__.py,sha256=LiGLlWNNiqS7RSOP4Apabx-b9EBYyNbxRY_a0mvJoaE,466
|
|
4
|
+
terminusgps/authorizenet/auth.py,sha256=ICxPPzoUc64VbsIIemEWKrn8xjHGwbNdo2VbtaFCFss,1107
|
|
5
|
+
terminusgps/authorizenet/errors.py,sha256=HG5NwVxQCtOYidVl30y49PC0Ovw5VYdsy9wTgUFMw9M,949
|
|
6
|
+
terminusgps/authorizenet/utils.py,sha256=5aczO2EcMX2bi-kRg8_fnzLzE7qMA9K1qBxAo2AJz1c,2021
|
|
7
7
|
terminusgps/authorizenet/profiles/__init__.py,sha256=QKjMKcXpCSCEhv6LBCz0yGP8t0VxAyKyYRS4_HLYnxQ,114
|
|
8
|
-
terminusgps/authorizenet/profiles/addresses.py,sha256=
|
|
9
|
-
terminusgps/authorizenet/profiles/base.py,sha256=
|
|
10
|
-
terminusgps/authorizenet/profiles/customers.py,sha256=
|
|
11
|
-
terminusgps/authorizenet/profiles/payments.py,sha256=
|
|
8
|
+
terminusgps/authorizenet/profiles/addresses.py,sha256=uowUkrr4fa4g7pjgNDrjW0es5t_gH9B8VHI74PbTWFc,6303
|
|
9
|
+
terminusgps/authorizenet/profiles/base.py,sha256=TOUHr22QRQBLErdysOkfcpJBusTjrUTqOmWEyNvMacA,2240
|
|
10
|
+
terminusgps/authorizenet/profiles/customers.py,sha256=xe7LNsqSB_oRCY-teojDTt0O6a5yVf0dyuu86ftc4hA,8377
|
|
11
|
+
terminusgps/authorizenet/profiles/payments.py,sha256=O_oZGUwO8XTApzr0itu-1XQYnWFR4gDpNCusWNzBh7A,11152
|
|
12
|
+
terminusgps/authorizenet/subscriptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
terminusgps/authorizenet/subscriptions/subscriptions.py,sha256=JQHo2FxQyRPJp1jlbD2mIt9RKEJZbADZcfozNTKWbz0,1514
|
|
12
14
|
terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
15
|
terminusgps/aws/secrets.py,sha256=MxQEmmBLpMUQ2tYAsHdCYf-7RZ84LiogdKcTsACX5dw,361
|
|
14
16
|
terminusgps/aws/ses.py,sha256=sDca2GjMaZvUt3kUPtGCpcqHiOkij9lMV1ogZofgYUU,2372
|
|
@@ -28,7 +30,7 @@ terminusgps/wialon/items/route.py,sha256=PTJx1gmT_PGz7nlSSUS2VzjYD-aAuvkEOIdIFne
|
|
|
28
30
|
terminusgps/wialon/items/unit.py,sha256=-jQL5Alvz77FZWteYNM9VNX15jtCufI-DWRRj3hRsgA,8539
|
|
29
31
|
terminusgps/wialon/items/unit_group.py,sha256=vGVJMBY1BrKK0tP-C1DCIz4Bh6P-HKRnKY1g8g95UIs,5031
|
|
30
32
|
terminusgps/wialon/items/user.py,sha256=INwAibQVmjNNelepQXMfDevgJqMvIjHHgEjAMLRvhB0,7082
|
|
31
|
-
python_terminusgps-
|
|
32
|
-
python_terminusgps-
|
|
33
|
-
python_terminusgps-
|
|
34
|
-
python_terminusgps-
|
|
33
|
+
python_terminusgps-24.0.0.dist-info/METADATA,sha256=QU-Do0pVNWwhy5D08Y5-n2nKz_mknj6sQMRHgHWpf5s,946
|
|
34
|
+
python_terminusgps-24.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
35
|
+
python_terminusgps-24.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
36
|
+
python_terminusgps-24.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from django.conf import settings
|
|
2
|
+
from django.core.exceptions import ImproperlyConfigured
|
|
3
|
+
|
|
4
|
+
if not hasattr(settings, "DEBUG"):
|
|
5
|
+
raise ImproperlyConfigured("'DEBUG' setting is required.")
|
|
6
|
+
if not hasattr(settings, "MERCHANT_AUTH_LOGIN_ID"):
|
|
7
|
+
raise ImproperlyConfigured("'MERCHANT_AUTH_LOGIN_ID' setting is required.")
|
|
8
|
+
if not hasattr(settings, "MERCHANT_AUTH_TRANSACTION_KEY"):
|
|
9
|
+
raise ImproperlyConfigured("'MERCHANT_AUTH_TRANSACTION_KEY' setting is required.")
|
terminusgps/authorizenet/auth.py
CHANGED
|
@@ -4,6 +4,13 @@ from django.conf import settings
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def get_merchant_auth() -> merchantAuthenticationType:
|
|
7
|
+
"""
|
|
8
|
+
Returns the merchant authentication information for Authorizenet API requests.
|
|
9
|
+
|
|
10
|
+
:returns: A merchant authentication object.
|
|
11
|
+
:rtype: :py:obj:`~authorizenet.apicontractsv1.merchantAuthenticationType`
|
|
12
|
+
|
|
13
|
+
"""
|
|
7
14
|
return merchantAuthenticationType(
|
|
8
15
|
name=str(settings.MERCHANT_AUTH_LOGIN_ID),
|
|
9
16
|
transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
|
|
@@ -11,8 +18,22 @@ def get_merchant_auth() -> merchantAuthenticationType:
|
|
|
11
18
|
|
|
12
19
|
|
|
13
20
|
def get_environment() -> str:
|
|
21
|
+
"""
|
|
22
|
+
Returns the environment for Authorizenet API requests.
|
|
23
|
+
|
|
24
|
+
:returns: An Authorizenet API environment string.
|
|
25
|
+
:rtype: :py:obj:`str`
|
|
26
|
+
|
|
27
|
+
"""
|
|
14
28
|
return constants.SANDBOX if settings.DEBUG else constants.PRODUCTION
|
|
15
29
|
|
|
16
30
|
|
|
17
31
|
def get_validation_mode() -> str:
|
|
32
|
+
"""
|
|
33
|
+
Returns the validation mode for Authorizenet API requests.
|
|
34
|
+
|
|
35
|
+
:returns: An Authorizenet API validation string.
|
|
36
|
+
:rtype: :py:obj:`str`
|
|
37
|
+
|
|
38
|
+
"""
|
|
18
39
|
return "testMode" if settings.DEBUG else "liveMode"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class ControllerExecutionError(Exception):
|
|
2
|
+
"""Raised when an Authorizenet API controller fails to execute."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, message: str, code: str, *args, **kwargs) -> None:
|
|
5
|
+
"""
|
|
6
|
+
Sets :py:attr:`message` and :py:attr`code` for the exception.
|
|
7
|
+
|
|
8
|
+
:param message: An Authorizenet API error message.
|
|
9
|
+
:type message: :py:obj:`str`
|
|
10
|
+
:param code: An Authorizenet API error code.
|
|
11
|
+
:type code: :py:obj:`str`
|
|
12
|
+
:returns: Nothing.
|
|
13
|
+
:rtype: :py:obj:`None`
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
super().__init__(message, *args, **kwargs)
|
|
17
|
+
self._message = message
|
|
18
|
+
self._code = code
|
|
19
|
+
|
|
20
|
+
def __str__(self) -> str:
|
|
21
|
+
return f"{self.code}: {self.message}"
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def message(self) -> str:
|
|
25
|
+
"""An Authorizenet API error message."""
|
|
26
|
+
return self._message
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def code(self) -> str:
|
|
30
|
+
"""An Authorizenet API error code."""
|
|
31
|
+
return self._code
|
|
@@ -1,57 +1,62 @@
|
|
|
1
1
|
from authorizenet import apicontractsv1, apicontrollers
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from .base import AuthorizenetSubProfileBase
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class AddressProfile(AuthorizenetSubProfileBase):
|
|
7
7
|
"""An Authorizenet customer address profile."""
|
|
8
8
|
|
|
9
|
-
def create(self,
|
|
9
|
+
def create(self, address: apicontractsv1.customerAddressType) -> int:
|
|
10
10
|
"""
|
|
11
11
|
Creates an Authorizenet address profile.
|
|
12
12
|
|
|
13
|
-
:param
|
|
14
|
-
:type
|
|
13
|
+
:param address: A customer address.
|
|
14
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
15
15
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
16
|
+
:raises ValueError: If the Authorizenet API response was not retrieved.
|
|
16
17
|
:returns: A new address profile id.
|
|
17
18
|
:rtype: :py:obj:`int`
|
|
18
19
|
|
|
19
20
|
"""
|
|
20
|
-
response = self._authorizenet_create_shipping_address(
|
|
21
|
+
response = self._authorizenet_create_shipping_address(address)
|
|
22
|
+
if response is None:
|
|
23
|
+
raise ValueError("Failed to retrieve Authorizenet API response.")
|
|
21
24
|
return int(response.customerAddressId)
|
|
22
25
|
|
|
23
|
-
def update(self,
|
|
26
|
+
def update(self, address: apicontractsv1.customerAddressType) -> dict | None:
|
|
24
27
|
"""
|
|
25
28
|
Updates the Authorizenet address profile.
|
|
26
29
|
|
|
27
|
-
:param
|
|
28
|
-
:type
|
|
30
|
+
:param address: A customer shipping address.
|
|
31
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
29
32
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
30
|
-
:returns: An Authorizenet API response.
|
|
31
|
-
:rtype: :py:obj:`dict`
|
|
33
|
+
:returns: An Authorizenet API response, if any.
|
|
34
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
32
35
|
|
|
33
36
|
"""
|
|
34
|
-
return self._authorizenet_update_shipping_address(
|
|
37
|
+
return self._authorizenet_update_shipping_address(address)
|
|
35
38
|
|
|
36
|
-
def delete(self) -> dict:
|
|
39
|
+
def delete(self) -> dict | None:
|
|
37
40
|
"""
|
|
38
41
|
Deletes the Authorizenet address profile.
|
|
39
42
|
|
|
40
43
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
41
44
|
:returns: An Authorizenet API response, if any.
|
|
42
|
-
:rtype: :py:obj:`dict`
|
|
45
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
43
46
|
|
|
44
47
|
"""
|
|
45
48
|
return self._authorizenet_delete_shipping_address()
|
|
46
49
|
|
|
47
|
-
def _authorizenet_get_shipping_address(self) -> dict:
|
|
50
|
+
def _authorizenet_get_shipping_address(self) -> dict | None:
|
|
48
51
|
"""
|
|
49
52
|
Executes a :py:obj:`~authorizenet.apicontractsv1.getCustomerShippingAddressRequest` using the Authorizenet API.
|
|
50
53
|
|
|
54
|
+
`getCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-shipping-address>`_
|
|
55
|
+
|
|
51
56
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
52
57
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
53
|
-
:returns: An Authorizenet API response.
|
|
54
|
-
:rtype: :py:obj:`dict`
|
|
58
|
+
:returns: An Authorizenet API response, if any.
|
|
59
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
55
60
|
|
|
56
61
|
"""
|
|
57
62
|
assert self.id, "'id' was not set."
|
|
@@ -62,63 +67,67 @@ class AddressProfile(AuthorizenetSubProfileBase):
|
|
|
62
67
|
customerAddressId=self.id,
|
|
63
68
|
)
|
|
64
69
|
controller = apicontrollers.getCustomerShippingAddressController(request)
|
|
65
|
-
|
|
66
|
-
return response
|
|
70
|
+
return self.execute_controller(controller)
|
|
67
71
|
|
|
68
72
|
def _authorizenet_create_shipping_address(
|
|
69
|
-
self,
|
|
70
|
-
) -> dict:
|
|
73
|
+
self, address: apicontractsv1.customerAddressType
|
|
74
|
+
) -> dict | None:
|
|
71
75
|
"""
|
|
72
76
|
Executes a :py:obj:`~authorizenet.apicontractsv1.createCustomerShippingAddressRequest` using the Authorizenet API.
|
|
73
77
|
|
|
78
|
+
`createCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-create-customer-shipping-address>`_
|
|
79
|
+
|
|
74
80
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
75
81
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
76
|
-
:returns: An Authorizenet API response.
|
|
77
|
-
:rtype: :py:obj:`dict`
|
|
82
|
+
:returns: An Authorizenet API response, if any.
|
|
83
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
78
84
|
|
|
79
85
|
"""
|
|
80
86
|
request = apicontractsv1.createCustomerShippingAddressRequest(
|
|
81
87
|
merchantAuthentication=self.merchantAuthentication,
|
|
82
88
|
customerProfileId=self.customerProfileId,
|
|
83
|
-
address=
|
|
89
|
+
address=address,
|
|
84
90
|
defaultShippingAddress=self.default,
|
|
85
91
|
)
|
|
86
92
|
controller = apicontrollers.createCustomerShippingAddressController(request)
|
|
87
|
-
|
|
88
|
-
return response
|
|
93
|
+
return self.execute_controller(controller)
|
|
89
94
|
|
|
90
95
|
def _authorizenet_update_shipping_address(
|
|
91
|
-
self,
|
|
92
|
-
) -> dict:
|
|
96
|
+
self, address: apicontractsv1.customerAddressType
|
|
97
|
+
) -> dict | None:
|
|
93
98
|
"""
|
|
94
99
|
Executes a :py:obj:`~authorizenet.apicontractsv1.updateCustomerShippingAddressRequest` using the Authorizenet API.
|
|
95
100
|
|
|
101
|
+
`updateCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-shipping-address>`_
|
|
102
|
+
|
|
96
103
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
97
104
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
98
|
-
:returns: An Authorizenet API response.
|
|
99
|
-
:rtype: :py:obj:`dict`
|
|
105
|
+
:returns: An Authorizenet API response, if any.
|
|
106
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
100
107
|
|
|
101
108
|
"""
|
|
102
109
|
assert self.id, "'id' was not set."
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
address.customerAddressId = self.id
|
|
105
112
|
request = apicontractsv1.updateCustomerShippingAddressRequest(
|
|
106
113
|
merchantAuthentication=self.merchantAuthentication,
|
|
107
114
|
customerProfileId=self.customerProfileId,
|
|
108
|
-
address=
|
|
115
|
+
address=address,
|
|
109
116
|
default=self.default,
|
|
110
117
|
)
|
|
111
118
|
controller = apicontrollers.updateCustomerShippingAddressController(request)
|
|
112
119
|
return self.execute_controller(controller)
|
|
113
120
|
|
|
114
|
-
def _authorizenet_delete_shipping_address(self) -> dict:
|
|
121
|
+
def _authorizenet_delete_shipping_address(self) -> dict | None:
|
|
115
122
|
"""
|
|
116
123
|
Executes a :py:obj:`~authorizenet.apicontractsv1.deleteCustomerShippingAddressRequest` using the Authorizenet API.
|
|
117
124
|
|
|
125
|
+
`deleteCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-delete-customer-shipping-address>`_
|
|
126
|
+
|
|
118
127
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
119
128
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
120
|
-
:returns: An Authorizenet API response.
|
|
121
|
-
:rtype: :py:obj:`dict`
|
|
129
|
+
:returns: An Authorizenet API response, if any.
|
|
130
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
122
131
|
|
|
123
132
|
"""
|
|
124
133
|
assert self.id, "'id' was not set."
|
|
@@ -129,5 +138,4 @@ class AddressProfile(AuthorizenetSubProfileBase):
|
|
|
129
138
|
customerAddressId=self.id,
|
|
130
139
|
)
|
|
131
140
|
controller = apicontrollers.deleteCustomerShippingAddressController(request)
|
|
132
|
-
|
|
133
|
-
return response
|
|
141
|
+
return self.execute_controller(controller)
|
|
@@ -3,8 +3,8 @@ from typing import override
|
|
|
3
3
|
|
|
4
4
|
from authorizenet import apicontractsv1
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
6
|
+
from ..auth import get_merchant_auth, get_validation_mode
|
|
7
|
+
from ..utils import ControllerExecutionMixin
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class AuthorizenetProfileBase(ControllerExecutionMixin):
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
from authorizenet import apicontractsv1, apicontrollers
|
|
2
2
|
from authorizenet.apicontractsv1 import customerProfileType
|
|
3
3
|
|
|
4
|
-
from
|
|
5
|
-
from
|
|
4
|
+
from ..utils import ControllerExecutionError, get_customer_profile_ids
|
|
5
|
+
from .base import AuthorizenetProfileBase
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class CustomerProfile(AuthorizenetProfileBase):
|
|
9
9
|
"""An Authorizenet customer profile."""
|
|
10
10
|
|
|
11
|
-
def create(self, email: str, desc: str
|
|
11
|
+
def create(self, email: str, desc: str = "") -> int:
|
|
12
12
|
"""
|
|
13
|
-
Creates a customer profile
|
|
13
|
+
Creates a customer profile and returns its id.
|
|
14
14
|
|
|
15
15
|
:param email: An email address.
|
|
16
16
|
:type email: :py:obj:`str`
|
|
17
17
|
:param desc: An optional description.
|
|
18
|
-
:type desc: :py:obj:`str`
|
|
18
|
+
:type desc: :py:obj:`str`
|
|
19
19
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
20
|
+
:raises ValueError: If the Authorizenet API response was not retrieved.
|
|
20
21
|
:returns: The new customer profile id.
|
|
21
22
|
:rtype: :py:obj:`int`
|
|
22
23
|
|
|
23
24
|
"""
|
|
24
25
|
response = self._authorizenet_create_customer_profile(email=email, desc=desc)
|
|
26
|
+
if response is None:
|
|
27
|
+
raise ValueError("Failed to retrieve Authorizenet API response.")
|
|
25
28
|
return int(response.customerProfileId)
|
|
26
29
|
|
|
27
30
|
def update(self, email: str, desc: str = "") -> None:
|
|
@@ -30,7 +33,7 @@ class CustomerProfile(AuthorizenetProfileBase):
|
|
|
30
33
|
|
|
31
34
|
:param email: An email address.
|
|
32
35
|
:type email: :py:obj:`str`
|
|
33
|
-
:param desc: An optional description.
|
|
36
|
+
:param desc: An optional description.
|
|
34
37
|
:type desc: :py:obj:`str`
|
|
35
38
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
36
39
|
:returns: Nothing.
|
|
@@ -50,29 +53,23 @@ class CustomerProfile(AuthorizenetProfileBase):
|
|
|
50
53
|
"""
|
|
51
54
|
self._authorizenet_delete_customer_profile()
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"""
|
|
62
|
-
response = self._authorizenet_get_customer_profile(issuer_info=False)
|
|
63
|
-
return response.get("paymentProfiles") if response else None
|
|
64
|
-
|
|
65
|
-
def get_addresses(self) -> list[dict] | None:
|
|
66
|
-
"""
|
|
67
|
-
Returns a list of the customer's address profiles.
|
|
68
|
-
|
|
69
|
-
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
70
|
-
:returns: A list of customer shipping addresses, if they exist.
|
|
71
|
-
:rtype: :py:obj:`list` | :py:obj:`None`
|
|
56
|
+
@property
|
|
57
|
+
def payment_profiles(self) -> list[dict] | None:
|
|
58
|
+
"""A list of the customer's payment profiles, if any."""
|
|
59
|
+
try:
|
|
60
|
+
response = self._authorizenet_get_customer_profile(issuer_info=False)
|
|
61
|
+
return response.get("paymentProfiles") if response else None
|
|
62
|
+
except ControllerExecutionError:
|
|
63
|
+
return
|
|
72
64
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
@property
|
|
66
|
+
def address_profiles(self) -> list[dict] | None:
|
|
67
|
+
"""A list of the customer's address profiles, if any."""
|
|
68
|
+
try:
|
|
69
|
+
response = self._authorizenet_get_customer_profile(issuer_info=False)
|
|
70
|
+
return response.get("shipToList") if response else None
|
|
71
|
+
except ControllerExecutionError:
|
|
72
|
+
return
|
|
76
73
|
|
|
77
74
|
@property
|
|
78
75
|
def exists(self) -> bool:
|
|
@@ -109,7 +106,6 @@ class CustomerProfile(AuthorizenetProfileBase):
|
|
|
109
106
|
:type email: :py:obj:`str`
|
|
110
107
|
:param desc: An optional description.
|
|
111
108
|
:type desc: :py:obj:`str`
|
|
112
|
-
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
113
109
|
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
114
110
|
:returns: An Authorizenet API response, if any.
|
|
115
111
|
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from authorizenet import apicontractsv1, apicontrollers
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from .base import AuthorizenetSubProfileBase
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class PaymentProfile(AuthorizenetSubProfileBase):
|
|
@@ -8,36 +8,58 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
8
8
|
|
|
9
9
|
def create(
|
|
10
10
|
self,
|
|
11
|
-
|
|
11
|
+
address: apicontractsv1.customerAddressType,
|
|
12
12
|
payment: apicontractsv1.paymentType,
|
|
13
13
|
) -> int:
|
|
14
14
|
"""
|
|
15
15
|
Creates an Authorizenet payment profile and returns its id.
|
|
16
16
|
|
|
17
|
-
:param
|
|
18
|
-
:type
|
|
17
|
+
:param address: A billing address.
|
|
18
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
19
19
|
:param payment: A payment object.
|
|
20
20
|
:type payment: :py:obj:`~authorizenet.apicontractsv1.paymentType`
|
|
21
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
22
|
+
:raises ValueError: If the Authorizenet API response was not retrieved.
|
|
21
23
|
:returns: The new payment profile's id.
|
|
22
24
|
:rtype: :py:obj:`int`
|
|
23
25
|
|
|
24
26
|
"""
|
|
25
|
-
response = self._authorizenet_create_payment_profile(
|
|
27
|
+
response = self._authorizenet_create_payment_profile(address, payment)
|
|
28
|
+
if response is None:
|
|
29
|
+
raise ValueError("Failed to retrieve Authorizenet API response.")
|
|
26
30
|
return int(response.customerPaymentProfileId)
|
|
27
31
|
|
|
28
32
|
def update(
|
|
29
33
|
self,
|
|
30
|
-
|
|
34
|
+
address: apicontractsv1.customerAddressType,
|
|
31
35
|
payment: apicontractsv1.paymentType,
|
|
32
|
-
) -> dict:
|
|
33
|
-
"""
|
|
34
|
-
|
|
36
|
+
) -> dict | None:
|
|
37
|
+
"""
|
|
38
|
+
Updates the Authorizenet payment profile.
|
|
39
|
+
|
|
40
|
+
:param address: A billing address.
|
|
41
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
42
|
+
:param payment: A payment method.
|
|
43
|
+
:type payment: :py:obj:`~authorizenet.apicontractsv1.paymentType`
|
|
44
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
45
|
+
:returns: An Authorizenet API reponse, if any.
|
|
46
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
return self._authorizenet_update_payment_profile(address, payment)
|
|
35
50
|
|
|
36
|
-
def delete(self) -> dict:
|
|
37
|
-
"""
|
|
51
|
+
def delete(self) -> dict | None:
|
|
52
|
+
"""
|
|
53
|
+
Deletes the Authorizenet payment profile.
|
|
54
|
+
|
|
55
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
56
|
+
:returns: An Authorizenet API response, if any.
|
|
57
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
58
|
+
|
|
59
|
+
"""
|
|
38
60
|
return self._authorizenet_delete_payment_profile()
|
|
39
61
|
|
|
40
|
-
def get_details(self, issuer_info: bool = False) -> dict:
|
|
62
|
+
def get_details(self, issuer_info: bool = False) -> dict | None:
|
|
41
63
|
return self._authorizenet_get_payment_profile(issuer_info)
|
|
42
64
|
|
|
43
65
|
def _authorizenet_get_transaction_list_for_customer(
|
|
@@ -46,10 +68,12 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
46
68
|
ordering: str = "submitTimeUTC",
|
|
47
69
|
offset: int = 1,
|
|
48
70
|
descending: bool = False,
|
|
49
|
-
) -> dict:
|
|
71
|
+
) -> dict | None:
|
|
50
72
|
"""
|
|
51
73
|
Executes a :py:obj:`~authorizenet.apicontractsv1.getTransactionListForCustomerRequest` using the Authorizenet API.
|
|
52
74
|
|
|
75
|
+
`getTransactionListForCustomerRequest <https://developer.authorize.net/api/reference/index.html#transaction-reporting-get-transaction-list>`_
|
|
76
|
+
|
|
53
77
|
:param limit: Total number of transactions to retrieve. Default is ``100``.
|
|
54
78
|
:type limit: :py:obj:`int`
|
|
55
79
|
:param ordering: A field to order the transactions by. Default is ``"submitTimeUTC"``.
|
|
@@ -60,8 +84,9 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
60
84
|
:type descending: :py:obj:`bool`
|
|
61
85
|
:raises ValueError: If ``ordering`` is invalid.
|
|
62
86
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
63
|
-
:
|
|
64
|
-
:
|
|
87
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
88
|
+
:returns: An Authorizenet API response, if any.
|
|
89
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
65
90
|
|
|
66
91
|
"""
|
|
67
92
|
ordering_options: tuple[str, str] = ("id", "submitTimeUTC")
|
|
@@ -78,52 +103,55 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
78
103
|
paging={"limit": str(limit), "offset": str(offset)},
|
|
79
104
|
)
|
|
80
105
|
controller = apicontrollers.getTransactionListForCustomerController(request)
|
|
81
|
-
|
|
82
|
-
return response
|
|
106
|
+
return self.execute_controller(controller)
|
|
83
107
|
|
|
84
108
|
def _authorizenet_create_payment_profile(
|
|
85
109
|
self,
|
|
86
|
-
|
|
110
|
+
address: apicontractsv1.customerAddressType,
|
|
87
111
|
payment: apicontractsv1.paymentType,
|
|
88
|
-
) -> dict:
|
|
112
|
+
) -> dict | None:
|
|
89
113
|
"""
|
|
90
114
|
Executes a :py:obj:`~authorizenet.apicontractsv1.createCustomerPaymentProfileRequest` using the Authorizenet API.
|
|
91
115
|
|
|
92
|
-
|
|
93
|
-
|
|
116
|
+
`createCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-create-customer-payment-profile>`_
|
|
117
|
+
|
|
118
|
+
:param address: A billing address.
|
|
119
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
94
120
|
:param payment: A payment method.
|
|
95
121
|
:type payment: :py:obj:`~authorizenet.apicontractsv1.paymentType`
|
|
96
|
-
:raises
|
|
97
|
-
:
|
|
98
|
-
:
|
|
99
|
-
:rtype: :py:obj:`dict`
|
|
122
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
123
|
+
:returns: An Authorizenet API response, if any.
|
|
124
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
100
125
|
|
|
101
126
|
"""
|
|
102
127
|
request = apicontractsv1.createCustomerPaymentProfileRequest(
|
|
103
128
|
customerProfileId=self.customerProfileId,
|
|
104
129
|
merchantAuthentication=self.merchantAuthentication,
|
|
105
130
|
paymentProfile=apicontractsv1.customerPaymentProfileType(
|
|
106
|
-
billTo=
|
|
131
|
+
billTo=address, payment=payment, defaultPaymentProfile=self.default
|
|
107
132
|
),
|
|
108
133
|
validationMode=self.validationMode,
|
|
109
134
|
)
|
|
110
135
|
controller = apicontrollers.createCustomerPaymentProfileController(request)
|
|
111
|
-
|
|
112
|
-
return response
|
|
136
|
+
return self.execute_controller(controller)
|
|
113
137
|
|
|
114
|
-
def _authorizenet_get_payment_profile(
|
|
138
|
+
def _authorizenet_get_payment_profile(
|
|
139
|
+
self, issuer_info: bool = False
|
|
140
|
+
) -> dict | None:
|
|
115
141
|
"""
|
|
116
142
|
Executes a :py:obj:`~authorizenet.apicontractsv1.getCustomerPaymentProfileRequest` using the Authorizenet API.
|
|
117
143
|
|
|
144
|
+
`getCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-payment-profile>`_
|
|
145
|
+
|
|
118
146
|
:param issuer_info: Whether or not to include issuer information in the response.
|
|
119
147
|
:type issuer_info: :py:obj:`bool`
|
|
120
148
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
121
|
-
:
|
|
122
|
-
:
|
|
149
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
150
|
+
:returns: An Authorizenet API response, if any.
|
|
151
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
123
152
|
|
|
124
153
|
"""
|
|
125
154
|
assert self.id, "'id' was not set."
|
|
126
|
-
|
|
127
155
|
request = apicontractsv1.getCustomerPaymentProfileRequest(
|
|
128
156
|
merchantAuthentication=self.merchantAuthentication,
|
|
129
157
|
customerProfileId=self.customerProfileId,
|
|
@@ -131,24 +159,26 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
131
159
|
includeIssuerInfo=str(issuer_info).lower(),
|
|
132
160
|
)
|
|
133
161
|
controller = apicontrollers.getCustomerPaymentProfileController(request)
|
|
134
|
-
|
|
135
|
-
return response
|
|
162
|
+
return self.execute_controller(controller)
|
|
136
163
|
|
|
137
164
|
def _authorizenet_update_payment_profile(
|
|
138
165
|
self,
|
|
139
|
-
|
|
166
|
+
address: apicontractsv1.customerAddressType,
|
|
140
167
|
payment: apicontractsv1.paymentType,
|
|
141
|
-
) -> dict:
|
|
168
|
+
) -> dict | None:
|
|
142
169
|
"""
|
|
143
|
-
Executes a :py:obj:`~authorizenet.apicontractsv1.
|
|
170
|
+
Executes a :py:obj:`~authorizenet.apicontractsv1.updateCustomerPaymentProfileRequest` using the Authorizenet API.
|
|
144
171
|
|
|
145
|
-
|
|
146
|
-
|
|
172
|
+
`updateCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-payment-profile>`_
|
|
173
|
+
|
|
174
|
+
:param address: A customer address.
|
|
175
|
+
:type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
|
|
147
176
|
:param payment: A payment method.
|
|
148
177
|
:type payment: :py:obj:`~authorizenet.apicontractsv1.paymentType`
|
|
149
178
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
150
|
-
:
|
|
151
|
-
:
|
|
179
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
180
|
+
:returns: An Authorizenet API response, if any.
|
|
181
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
152
182
|
|
|
153
183
|
"""
|
|
154
184
|
assert self.id, "'id' was not set."
|
|
@@ -157,7 +187,7 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
157
187
|
merchantAuthentication=self.merchantAuthentication,
|
|
158
188
|
customerProfileId=self.customerProfileId,
|
|
159
189
|
paymentProfile=apicontractsv1.customerPaymentProfileType(
|
|
160
|
-
billTo=
|
|
190
|
+
billTo=address,
|
|
161
191
|
payment=payment,
|
|
162
192
|
defaultPaymentProfile=self.default,
|
|
163
193
|
customerPaymentProfileId=self.id,
|
|
@@ -165,20 +195,22 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
165
195
|
validationMode=self.validationMode,
|
|
166
196
|
)
|
|
167
197
|
controller = apicontrollers.updateCustomerPaymentProfileController(request)
|
|
168
|
-
|
|
169
|
-
return response
|
|
198
|
+
return self.execute_controller(controller)
|
|
170
199
|
|
|
171
|
-
def _authorizenet_validate_payment_profile(self) -> dict:
|
|
200
|
+
def _authorizenet_validate_payment_profile(self) -> dict | None:
|
|
172
201
|
"""
|
|
173
202
|
Executes a :py:obj:`~authorizenet.apicontractsv1.validateCustomerPaymentProfileRequest` using the Authorizenet API.
|
|
174
203
|
|
|
204
|
+
`validateCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-validate-customer-payment-profile>`_
|
|
205
|
+
|
|
175
206
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
176
|
-
:
|
|
177
|
-
:
|
|
207
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
208
|
+
:returns: An Authorizenet API response, if any.
|
|
209
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
210
|
+
|
|
178
211
|
|
|
179
212
|
"""
|
|
180
213
|
assert self.id, "'id' was not set."
|
|
181
|
-
|
|
182
214
|
request = apicontractsv1.validateCustomerPaymentProfileRequest(
|
|
183
215
|
merchantAuthentication=self.merchantAuthentication,
|
|
184
216
|
customerProfileId=self.customerProfileId,
|
|
@@ -186,16 +218,18 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
186
218
|
validationMode=self.validationMode,
|
|
187
219
|
)
|
|
188
220
|
controller = apicontrollers.validateCustomerPaymentProfileController(request)
|
|
189
|
-
|
|
190
|
-
return response
|
|
221
|
+
return self.execute_controller(controller)
|
|
191
222
|
|
|
192
|
-
def _authorizenet_delete_payment_profile(self) -> dict:
|
|
223
|
+
def _authorizenet_delete_payment_profile(self) -> dict | None:
|
|
193
224
|
"""
|
|
194
225
|
Executes a :py:obj:`~authorizenet.apicontractsv1.deleteCustomerPaymentProfileRequest` using the Authorizenet API.
|
|
195
226
|
|
|
227
|
+
`deleteCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-delete-customer-payment-profile>`_
|
|
228
|
+
|
|
196
229
|
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
197
|
-
:
|
|
198
|
-
:
|
|
230
|
+
:raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
|
|
231
|
+
:returns: An Authorizenet API response, if any.
|
|
232
|
+
:rtype: :py:obj:`dict` | :py:obj:`None`
|
|
199
233
|
|
|
200
234
|
"""
|
|
201
235
|
assert self.id, "'id' was not set."
|
|
@@ -206,5 +240,4 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
206
240
|
customerPaymentProfileId=self.id,
|
|
207
241
|
)
|
|
208
242
|
controller = apicontrollers.deleteCustomerPaymentProfileController(request)
|
|
209
|
-
|
|
210
|
-
return response
|
|
243
|
+
return self.execute_controller(controller)
|
|
File without changes
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from authorizenet import apicontractsv1, apicontrollers
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from
|
|
3
|
+
from ..auth import get_merchant_auth
|
|
4
|
+
from ..utils import ControllerExecutionMixin
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Subscription(ControllerExecutionMixin):
|
|
8
8
|
def __init__(self, id: str | int | None = None, *args, **kwargs) -> None:
|
|
9
|
-
if id and isinstance(id, str) and not id.isdigit():
|
|
9
|
+
if id is not None and isinstance(id, str) and not id.isdigit():
|
|
10
10
|
raise ValueError(f"'id' must be a digit, got '{id}'.")
|
|
11
11
|
self.id = int(id) if id else self.create(*args, **kwargs)
|
|
12
12
|
|
|
@@ -15,8 +15,9 @@ class Subscription(ControllerExecutionMixin):
|
|
|
15
15
|
name: str,
|
|
16
16
|
amount: str,
|
|
17
17
|
schedule: apicontractsv1.paymentScheduleType,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
profile_id: int | str,
|
|
19
|
+
payment_id: int | str,
|
|
20
|
+
address_id: int | str,
|
|
20
21
|
trial_amount: str = "0.00",
|
|
21
22
|
) -> int:
|
|
22
23
|
request = apicontractsv1.ARBCreateSubscriptionRequest(
|
|
@@ -26,8 +27,11 @@ class Subscription(ControllerExecutionMixin):
|
|
|
26
27
|
paymentSchedule=schedule,
|
|
27
28
|
amount=amount,
|
|
28
29
|
trialAmount=trial_amount,
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
profile=apicontractsv1.customerProfileIdType(
|
|
31
|
+
customerProfileId=str(profile_id),
|
|
32
|
+
customerPaymentProfileId=str(payment_id),
|
|
33
|
+
customerAddressId=str(address_id),
|
|
34
|
+
),
|
|
31
35
|
),
|
|
32
36
|
)
|
|
33
37
|
controller = apicontrollers.ARBCreateSubscriptionController(request)
|
|
@@ -2,17 +2,7 @@ from authorizenet import apicontractsv1, apicontrollers
|
|
|
2
2
|
from authorizenet.apicontrollersbase import APIOperationBase
|
|
3
3
|
|
|
4
4
|
from .auth import get_environment, get_merchant_auth
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ControllerExecutionError(Exception):
|
|
8
|
-
"""Raised when an Authorizenet API controller fails to execute."""
|
|
9
|
-
|
|
10
|
-
def __init__(self, message: str, code: str, *args, **kwargs) -> None:
|
|
11
|
-
self.code = code
|
|
12
|
-
super().__init__(message, *args, **kwargs)
|
|
13
|
-
|
|
14
|
-
def __str__(self) -> str:
|
|
15
|
-
return f"{self.code}: {self.message}"
|
|
5
|
+
from .errors import ControllerExecutionError
|
|
16
6
|
|
|
17
7
|
|
|
18
8
|
class ControllerExecutionMixin:
|
|
@@ -57,5 +47,8 @@ def get_customer_profile_ids() -> list[int]:
|
|
|
57
47
|
response = controller.getresponse()
|
|
58
48
|
|
|
59
49
|
if response is not None and response.messages.resultCode != "Ok":
|
|
60
|
-
raise
|
|
50
|
+
raise ControllerExecutionError(
|
|
51
|
+
message=response.messages.message[0]["text"].text,
|
|
52
|
+
code=response.messages.message[0]["code"].text,
|
|
53
|
+
)
|
|
61
54
|
return [int(id) for id in response.ids.getchildren()]
|
|
File without changes
|
{python_terminusgps-23.0.0.dist-info → python_terminusgps-24.0.0.dist-info}/licenses/COPYING
RENAMED
|
File without changes
|