airwallex-sdk 0.1.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.
Files changed (39) hide show
  1. airwallex/__init__.py +74 -0
  2. airwallex/api/__init__.py +37 -0
  3. airwallex/api/account.py +107 -0
  4. airwallex/api/account_detail.py +469 -0
  5. airwallex/api/base.py +488 -0
  6. airwallex/api/beneficiary.py +156 -0
  7. airwallex/api/financial_transaction.py +123 -0
  8. airwallex/api/invoice.py +257 -0
  9. airwallex/api/issuing_authorization.py +313 -0
  10. airwallex/api/issuing_card.py +411 -0
  11. airwallex/api/issuing_cardholder.py +234 -0
  12. airwallex/api/issuing_config.py +80 -0
  13. airwallex/api/issuing_digital_wallet_token.py +249 -0
  14. airwallex/api/issuing_transaction.py +231 -0
  15. airwallex/api/issuing_transaction_dispute.py +339 -0
  16. airwallex/api/payment.py +148 -0
  17. airwallex/client.py +396 -0
  18. airwallex/exceptions.py +222 -0
  19. airwallex/models/__init__.py +69 -0
  20. airwallex/models/account.py +51 -0
  21. airwallex/models/account_detail.py +259 -0
  22. airwallex/models/base.py +121 -0
  23. airwallex/models/beneficiary.py +70 -0
  24. airwallex/models/financial_transaction.py +30 -0
  25. airwallex/models/fx.py +58 -0
  26. airwallex/models/invoice.py +102 -0
  27. airwallex/models/issuing_authorization.py +41 -0
  28. airwallex/models/issuing_card.py +135 -0
  29. airwallex/models/issuing_cardholder.py +52 -0
  30. airwallex/models/issuing_common.py +83 -0
  31. airwallex/models/issuing_config.py +62 -0
  32. airwallex/models/issuing_digital_wallet_token.py +38 -0
  33. airwallex/models/issuing_transaction.py +42 -0
  34. airwallex/models/issuing_transaction_dispute.py +59 -0
  35. airwallex/models/payment.py +81 -0
  36. airwallex/utils.py +107 -0
  37. airwallex_sdk-0.1.0.dist-info/METADATA +202 -0
  38. airwallex_sdk-0.1.0.dist-info/RECORD +39 -0
  39. airwallex_sdk-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,80 @@
1
+ """
2
+ Airwallex Issuing Config API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from ..models.issuing_config import IssuingConfig, IssuingConfigUpdateRequest
6
+ from .base import AirwallexAPIBase
7
+
8
+ T = TypeVar("T", bound=IssuingConfig)
9
+
10
+
11
+ class IssuingConfig(AirwallexAPIBase[IssuingConfig]):
12
+ """
13
+ Operations for Airwallex issuing configuration.
14
+
15
+ Configuration for issuance settings and controls.
16
+ """
17
+ endpoint = "issuing/config"
18
+ model_class = cast(Type[IssuingConfig], IssuingConfig)
19
+
20
+ def get_config(self) -> IssuingConfig:
21
+ """
22
+ Get the current issuing configuration.
23
+
24
+ Returns:
25
+ IssuingConfig: The current issuing configuration
26
+ """
27
+ if not self.client.__class__.__name__.startswith('Async'):
28
+ response = self.client._request("GET", self._build_url())
29
+ return self.model_class.from_api_response(response.json())
30
+ else:
31
+ raise ValueError("Use get_config_async for async clients")
32
+
33
+ async def get_config_async(self) -> IssuingConfig:
34
+ """
35
+ Get the current issuing configuration asynchronously.
36
+
37
+ Returns:
38
+ IssuingConfig: The current issuing configuration
39
+ """
40
+ if self.client.__class__.__name__.startswith('Async'):
41
+ response = await self.client._request("GET", self._build_url())
42
+ return self.model_class.from_api_response(response.json())
43
+ else:
44
+ raise ValueError("Use get_config for sync clients")
45
+
46
+ def update_config(self, update_data: IssuingConfigUpdateRequest) -> IssuingConfig:
47
+ """
48
+ Update the issuing configuration.
49
+
50
+ Args:
51
+ update_data: IssuingConfigUpdateRequest model with update details
52
+
53
+ Returns:
54
+ IssuingConfig: The updated issuing configuration
55
+ """
56
+ url = f"{self._build_url()}/update"
57
+
58
+ if not self.client.__class__.__name__.startswith('Async'):
59
+ response = self.client._request("POST", url, json=update_data.to_api_dict())
60
+ return self.model_class.from_api_response(response.json())
61
+ else:
62
+ raise ValueError("Use update_config_async for async clients")
63
+
64
+ async def update_config_async(self, update_data: IssuingConfigUpdateRequest) -> IssuingConfig:
65
+ """
66
+ Update the issuing configuration asynchronously.
67
+
68
+ Args:
69
+ update_data: IssuingConfigUpdateRequest model with update details
70
+
71
+ Returns:
72
+ IssuingConfig: The updated issuing configuration
73
+ """
74
+ url = f"{self._build_url()}/update"
75
+
76
+ if self.client.__class__.__name__.startswith('Async'):
77
+ response = await self.client._request("POST", url, json=update_data.to_api_dict())
78
+ return self.model_class.from_api_response(response.json())
79
+ else:
80
+ raise ValueError("Use update_config for sync clients")
@@ -0,0 +1,249 @@
1
+ """
2
+ Airwallex Issuing Digital Wallet Token API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.issuing_digital_wallet_token import DigitalWalletToken
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=DigitalWalletToken)
10
+
11
+
12
+ class IssuingDigitalWalletToken(AirwallexAPIBase[DigitalWalletToken]):
13
+ """
14
+ Operations for Airwallex issuing digital wallet tokens.
15
+
16
+ Digital wallet tokens represent tokenized cards in digital wallets.
17
+ """
18
+ endpoint = "issuing/digital_wallet_tokens"
19
+ model_class = cast(Type[DigitalWalletToken], DigitalWalletToken)
20
+
21
+ def list_with_filters(
22
+ self,
23
+ card_id: Optional[str] = None,
24
+ cardholder_id: Optional[str] = None,
25
+ from_created_at: Optional[Union[str, datetime]] = None,
26
+ from_token_expires_on: Optional[str] = None,
27
+ to_created_at: Optional[Union[str, datetime]] = None,
28
+ to_token_expires_on: Optional[str] = None,
29
+ token_reference_id: Optional[str] = None,
30
+ token_statuses: Optional[str] = None,
31
+ token_types: Optional[str] = None,
32
+ page_num: int = 0,
33
+ page_size: int = 10
34
+ ) -> List[DigitalWalletToken]:
35
+ """
36
+ List digital wallet tokens with filtering options.
37
+
38
+ Args:
39
+ card_id: Filter by card ID
40
+ cardholder_id: Filter by cardholder ID
41
+ from_created_at: Filter by creation date (start, inclusive)
42
+ from_token_expires_on: Filter by expiration date (start, inclusive, format MMyy)
43
+ to_created_at: Filter by creation date (end, inclusive)
44
+ to_token_expires_on: Filter by expiration date (end, inclusive, format MMyy)
45
+ token_reference_id: Filter by token reference ID
46
+ token_statuses: Filter by token statuses (comma-separated)
47
+ token_types: Filter by token types (comma-separated)
48
+ page_num: Page number, starts from 0
49
+ page_size: Number of results per page
50
+
51
+ Returns:
52
+ List[DigitalWalletToken]: List of matching digital wallet tokens
53
+ """
54
+ params = {
55
+ "page_num": page_num,
56
+ "page_size": page_size
57
+ }
58
+
59
+ if card_id:
60
+ params["card_id"] = card_id
61
+
62
+ if cardholder_id:
63
+ params["cardholder_id"] = cardholder_id
64
+
65
+ if from_created_at:
66
+ if isinstance(from_created_at, datetime):
67
+ from_created_at = from_created_at.isoformat()
68
+ params["from_created_at"] = from_created_at
69
+
70
+ if from_token_expires_on:
71
+ params["from_token_expires_on"] = from_token_expires_on
72
+
73
+ if to_created_at:
74
+ if isinstance(to_created_at, datetime):
75
+ to_created_at = to_created_at.isoformat()
76
+ params["to_created_at"] = to_created_at
77
+
78
+ if to_token_expires_on:
79
+ params["to_token_expires_on"] = to_token_expires_on
80
+
81
+ if token_reference_id:
82
+ params["token_reference_id"] = token_reference_id
83
+
84
+ if token_statuses:
85
+ params["token_statuses"] = token_statuses
86
+
87
+ if token_types:
88
+ params["token_types"] = token_types
89
+
90
+ if not self.client.__class__.__name__.startswith('Async'):
91
+ response = self.client._request("GET", self._build_url(), params=params)
92
+ data = response.json()
93
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
94
+ else:
95
+ raise ValueError("Use list_with_filters_async for async clients")
96
+
97
+ async def list_with_filters_async(
98
+ self,
99
+ card_id: Optional[str] = None,
100
+ cardholder_id: Optional[str] = None,
101
+ from_created_at: Optional[Union[str, datetime]] = None,
102
+ from_token_expires_on: Optional[str] = None,
103
+ to_created_at: Optional[Union[str, datetime]] = None,
104
+ to_token_expires_on: Optional[str] = None,
105
+ token_reference_id: Optional[str] = None,
106
+ token_statuses: Optional[str] = None,
107
+ token_types: Optional[str] = None,
108
+ page_num: int = 0,
109
+ page_size: int = 10
110
+ ) -> List[DigitalWalletToken]:
111
+ """
112
+ List digital wallet tokens with filtering options asynchronously.
113
+
114
+ Args:
115
+ card_id: Filter by card ID
116
+ cardholder_id: Filter by cardholder ID
117
+ from_created_at: Filter by creation date (start, inclusive)
118
+ from_token_expires_on: Filter by expiration date (start, inclusive, format MMyy)
119
+ to_created_at: Filter by creation date (end, inclusive)
120
+ to_token_expires_on: Filter by expiration date (end, inclusive, format MMyy)
121
+ token_reference_id: Filter by token reference ID
122
+ token_statuses: Filter by token statuses (comma-separated)
123
+ token_types: Filter by token types (comma-separated)
124
+ page_num: Page number, starts from 0
125
+ page_size: Number of results per page
126
+
127
+ Returns:
128
+ List[DigitalWalletToken]: List of matching digital wallet tokens
129
+ """
130
+ params = {
131
+ "page_num": page_num,
132
+ "page_size": page_size
133
+ }
134
+
135
+ if card_id:
136
+ params["card_id"] = card_id
137
+
138
+ if cardholder_id:
139
+ params["cardholder_id"] = cardholder_id
140
+
141
+ if from_created_at:
142
+ if isinstance(from_created_at, datetime):
143
+ from_created_at = from_created_at.isoformat()
144
+ params["from_created_at"] = from_created_at
145
+
146
+ if from_token_expires_on:
147
+ params["from_token_expires_on"] = from_token_expires_on
148
+
149
+ if to_created_at:
150
+ if isinstance(to_created_at, datetime):
151
+ to_created_at = to_created_at.isoformat()
152
+ params["to_created_at"] = to_created_at
153
+
154
+ if to_token_expires_on:
155
+ params["to_token_expires_on"] = to_token_expires_on
156
+
157
+ if token_reference_id:
158
+ params["token_reference_id"] = token_reference_id
159
+
160
+ if token_statuses:
161
+ params["token_statuses"] = token_statuses
162
+
163
+ if token_types:
164
+ params["token_types"] = token_types
165
+
166
+ if self.client.__class__.__name__.startswith('Async'):
167
+ response = await self.client._request("GET", self._build_url(), params=params)
168
+ data = response.json()
169
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
170
+ else:
171
+ raise ValueError("Use list_with_filters for sync clients")
172
+
173
+ def paginate(self, **params: Any) -> List[DigitalWalletToken]:
174
+ """
175
+ Fetch all pages of digital wallet tokens.
176
+
177
+ Args:
178
+ **params: Filter parameters to pass to the API
179
+
180
+ Returns:
181
+ List[DigitalWalletToken]: All digital wallet tokens matching the filters
182
+ """
183
+ if str(self.client.__class__.__name__).startswith('Async'):
184
+ raise ValueError("This method requires a sync client.")
185
+
186
+ all_items: List[Dict[str, Any]] = []
187
+ page_num = params.get("page_num", 0)
188
+ page_size = params.get("page_size", 10)
189
+
190
+ while True:
191
+ params["page_num"] = page_num
192
+ params["page_size"] = page_size
193
+
194
+ response = self.client._request("GET", self._build_url(), params=params)
195
+ data = response.json()
196
+
197
+ items = data.get("items", [])
198
+ has_more = data.get("has_more", False)
199
+
200
+ if not items:
201
+ break
202
+
203
+ all_items.extend(items)
204
+
205
+ if not has_more:
206
+ break
207
+
208
+ page_num += 1
209
+
210
+ return [self.model_class.from_api_response(item) for item in all_items]
211
+
212
+ async def paginate_async(self, **params: Any) -> List[DigitalWalletToken]:
213
+ """
214
+ Fetch all pages of digital wallet tokens asynchronously.
215
+
216
+ Args:
217
+ **params: Filter parameters to pass to the API
218
+
219
+ Returns:
220
+ List[DigitalWalletToken]: All digital wallet tokens matching the filters
221
+ """
222
+ if not self.client.__class__.__name__.startswith('Async'):
223
+ raise ValueError("This method requires an async client.")
224
+
225
+ all_items: List[Dict[str, Any]] = []
226
+ page_num = params.get("page_num", 0)
227
+ page_size = params.get("page_size", 10)
228
+
229
+ while True:
230
+ params["page_num"] = page_num
231
+ params["page_size"] = page_size
232
+
233
+ response = await self.client._request("GET", self._build_url(), params=params)
234
+ data = response.json()
235
+
236
+ items = data.get("items", [])
237
+ has_more = data.get("has_more", False)
238
+
239
+ if not items:
240
+ break
241
+
242
+ all_items.extend(items)
243
+
244
+ if not has_more:
245
+ break
246
+
247
+ page_num += 1
248
+
249
+ return [self.model_class.from_api_response(item) for item in all_items]
@@ -0,0 +1,231 @@
1
+ """
2
+ Airwallex Issuing Transaction API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.issuing_transaction import Transaction
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=Transaction)
10
+
11
+
12
+ class IssuingTransaction(AirwallexAPIBase[Transaction]):
13
+ """
14
+ Operations for Airwallex issuing transactions.
15
+
16
+ Transactions represent payments processed against cards.
17
+ """
18
+ endpoint = "issuing/transactions"
19
+ model_class = cast(Type[Transaction], Transaction)
20
+
21
+ def list_with_filters(
22
+ self,
23
+ billing_currency: Optional[str] = None,
24
+ card_id: Optional[str] = None,
25
+ digital_wallet_token_id: Optional[str] = None,
26
+ from_created_at: Optional[Union[str, datetime]] = None,
27
+ lifecycle_id: Optional[str] = None,
28
+ page_num: int = 0,
29
+ page_size: int = 10,
30
+ retrieval_ref: Optional[str] = None,
31
+ to_created_at: Optional[Union[str, datetime]] = None,
32
+ transaction_type: Optional[str] = None
33
+ ) -> List[Transaction]:
34
+ """
35
+ List transactions with filtering options.
36
+
37
+ Args:
38
+ billing_currency: Currency in which transition was billed (3-letter ISO-4217 code)
39
+ card_id: Unique Identifier for card
40
+ digital_wallet_token_id: Unique Identifier for digital token
41
+ from_created_at: Start of Transaction Date in ISO8601 format (inclusive)
42
+ lifecycle_id: Unique Identifier for lifecycle
43
+ page_num: Page number, starts from 0
44
+ page_size: Number of results per page
45
+ retrieval_ref: Retrieval reference number
46
+ to_created_at: End of Transaction Date in ISO8601 format (inclusive)
47
+ transaction_type: Transaction type (AUTHORIZATION, CLEARING, REFUND, REVERSAL, ORIGINAL_CREDIT)
48
+
49
+ Returns:
50
+ List[Transaction]: List of matching transactions
51
+ """
52
+ params = {
53
+ "page_num": page_num,
54
+ "page_size": page_size
55
+ }
56
+
57
+ if billing_currency:
58
+ params["billing_currency"] = billing_currency
59
+
60
+ if card_id:
61
+ params["card_id"] = card_id
62
+
63
+ if digital_wallet_token_id:
64
+ params["digital_wallet_token_id"] = digital_wallet_token_id
65
+
66
+ if from_created_at:
67
+ params["from_created_at"] = from_created_at
68
+
69
+ if lifecycle_id:
70
+ params["lifecycle_id"] = lifecycle_id
71
+
72
+ if retrieval_ref:
73
+ params["retrieval_ref"] = retrieval_ref
74
+
75
+ if to_created_at:
76
+ params["to_created_at"] = to_created_at
77
+
78
+ if transaction_type:
79
+ params["transaction_type"] = transaction_type
80
+
81
+ if not str(self.client.__class__.__name__).startswith('Async'):
82
+ response = self.client._request("GET", self._build_url(), params=params)
83
+ data = response.json()
84
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
85
+ else:
86
+ raise ValueError("Use list_with_filters_async for async clients")
87
+
88
+ async def list_with_filters_async(
89
+ self,
90
+ billing_currency: Optional[str] = None,
91
+ card_id: Optional[str] = None,
92
+ digital_wallet_token_id: Optional[str] = None,
93
+ from_created_at: Optional[Union[str, datetime]] = None,
94
+ lifecycle_id: Optional[str] = None,
95
+ page_num: int = 0,
96
+ page_size: int = 10,
97
+ retrieval_ref: Optional[str] = None,
98
+ to_created_at: Optional[Union[str, datetime]] = None,
99
+ transaction_type: Optional[str] = None
100
+ ) -> List[Transaction]:
101
+ """
102
+ List transactions with filtering options asynchronously.
103
+
104
+ Args:
105
+ billing_currency: Currency in which transition was billed (3-letter ISO-4217 code)
106
+ card_id: Unique Identifier for card
107
+ digital_wallet_token_id: Unique Identifier for digital token
108
+ from_created_at: Start of Transaction Date in ISO8601 format (inclusive)
109
+ lifecycle_id: Unique Identifier for lifecycle
110
+ page_num: Page number, starts from 0
111
+ page_size: Number of results per page
112
+ retrieval_ref: Retrieval reference number
113
+ to_created_at: End of Transaction Date in ISO8601 format (inclusive)
114
+ transaction_type: Transaction type (AUTHORIZATION, CLEARING, REFUND, REVERSAL, ORIGINAL_CREDIT)
115
+
116
+ Returns:
117
+ List[Transaction]: List of matching transactions
118
+ """
119
+ params = {
120
+ "page_num": page_num,
121
+ "page_size": page_size
122
+ }
123
+
124
+ if billing_currency:
125
+ params["billing_currency"] = billing_currency
126
+
127
+ if card_id:
128
+ params["card_id"] = card_id
129
+
130
+ if digital_wallet_token_id:
131
+ params["digital_wallet_token_id"] = digital_wallet_token_id
132
+
133
+ if from_created_at:
134
+ params["from_created_at"] = from_created_at
135
+
136
+ if lifecycle_id:
137
+ params["lifecycle_id"] = lifecycle_id
138
+
139
+ if retrieval_ref:
140
+ params["retrieval_ref"] = retrieval_ref
141
+
142
+ if to_created_at:
143
+ params["to_created_at"] = to_created_at
144
+
145
+ if transaction_type:
146
+ params["transaction_type"] = transaction_type
147
+
148
+ if str(self.client.__class__.__name__).startswith('Async'):
149
+ response = await self.client._request("GET", self._build_url(), params=params)
150
+ data = response.json()
151
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
152
+ else:
153
+ raise ValueError("Use list_with_filters for sync clients")
154
+
155
+ def paginate(self, **params: Any) -> List[Transaction]:
156
+ """
157
+ Fetch all pages of transactions.
158
+
159
+ Args:
160
+ **params: Filter parameters to pass to the API
161
+
162
+ Returns:
163
+ List[Transaction]: All transactions matching the filters
164
+ """
165
+ if str(self.client.__class__.__name__).startswith('Async'):
166
+ raise ValueError("This method requires a sync client.")
167
+
168
+ all_items: List[Dict[str, Any]] = []
169
+ page_num = params.get("page_num", 0)
170
+ page_size = params.get("page_size", 10)
171
+
172
+ while True:
173
+ params["page_num"] = page_num
174
+ params["page_size"] = page_size
175
+
176
+ response = self.client._request("GET", self._build_url(), params=params)
177
+ data = response.json()
178
+
179
+ items = data.get("items", [])
180
+ has_more = data.get("has_more", False)
181
+
182
+ if not items:
183
+ break
184
+
185
+ all_items.extend(items)
186
+
187
+ if not has_more:
188
+ break
189
+
190
+ page_num += 1
191
+
192
+ return [self.model_class.from_api_response(item) for item in all_items]
193
+
194
+ async def paginate_async(self, **params: Any) -> List[Transaction]:
195
+ """
196
+ Fetch all pages of transactions asynchronously.
197
+
198
+ Args:
199
+ **params: Filter parameters to pass to the API
200
+
201
+ Returns:
202
+ List[Transaction]: All transactions matching the filters
203
+ """
204
+ if not self.client.__class__.__name__.startswith('Async'):
205
+ raise ValueError("This method requires an async client.")
206
+
207
+ all_items: List[Dict[str, Any]] = []
208
+ page_num = params.get("page_num", 0)
209
+ page_size = params.get("page_size", 10)
210
+
211
+ while True:
212
+ params["page_num"] = page_num
213
+ params["page_size"] = page_size
214
+
215
+ response = await self.client._request("GET", self._build_url(), params=params)
216
+ data = response.json()
217
+
218
+ items = data.get("items", [])
219
+ has_more = data.get("has_more", False)
220
+
221
+ if not items:
222
+ break
223
+
224
+ all_items.extend(items)
225
+
226
+ if not has_more:
227
+ break
228
+
229
+ page_num += 1
230
+
231
+ return [self.model_class.from_api_response(item) for item in all_items]