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,339 @@
1
+ """
2
+ Airwallex Issuing Transaction Dispute API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.issuing_transaction_dispute import TransactionDispute, TransactionDisputeCreateRequest, TransactionDisputeUpdateRequest
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=TransactionDispute)
10
+
11
+
12
+ class IssuingTransactionDispute(AirwallexAPIBase[TransactionDispute]):
13
+ """
14
+ Operations for Airwallex issuing transaction disputes.
15
+
16
+ Transaction disputes represent disputes against card transactions.
17
+ """
18
+ endpoint = "issuing/transaction_disputes"
19
+ model_class = cast(Type[TransactionDispute], TransactionDispute)
20
+
21
+ def create_dispute(self, dispute: TransactionDisputeCreateRequest) -> TransactionDispute:
22
+ """
23
+ Create a new transaction dispute.
24
+
25
+ Args:
26
+ dispute: TransactionDisputeCreateRequest model with dispute details
27
+
28
+ Returns:
29
+ TransactionDispute: The created transaction dispute
30
+ """
31
+ url = f"{self.base_path}/create"
32
+
33
+ if not self.client.__class__.__name__.startswith('Async'):
34
+ response = self.client._request("POST", url, json=dispute.to_api_dict())
35
+ return self.model_class.from_api_response(response.json())
36
+ else:
37
+ raise ValueError("Use create_dispute_async for async clients")
38
+
39
+ async def create_dispute_async(self, dispute: TransactionDisputeCreateRequest) -> TransactionDispute:
40
+ """
41
+ Create a new transaction dispute asynchronously.
42
+
43
+ Args:
44
+ dispute: TransactionDisputeCreateRequest model with dispute details
45
+
46
+ Returns:
47
+ TransactionDispute: The created transaction dispute
48
+ """
49
+ url = f"{self.base_path}/create"
50
+
51
+ if self.client.__class__.__name__.startswith('Async'):
52
+ response = await self.client._request("POST", url, json=dispute.to_api_dict())
53
+ return self.model_class.from_api_response(response.json())
54
+ else:
55
+ raise ValueError("Use create_dispute for sync clients")
56
+
57
+ def update_dispute(self, dispute_id: str, update_data: TransactionDisputeUpdateRequest) -> TransactionDispute:
58
+ """
59
+ Update a transaction dispute.
60
+
61
+ Args:
62
+ dispute_id: The ID of the dispute to update
63
+ update_data: TransactionDisputeUpdateRequest model with update details
64
+
65
+ Returns:
66
+ TransactionDispute: The updated transaction dispute
67
+ """
68
+ url = f"{self._build_url(dispute_id)}/update"
69
+
70
+ if not self.client.__class__.__name__.startswith('Async'):
71
+ response = self.client._request("POST", url, json=update_data.to_api_dict())
72
+ return self.model_class.from_api_response(response.json())
73
+ else:
74
+ raise ValueError("Use update_dispute_async for async clients")
75
+
76
+ async def update_dispute_async(self, dispute_id: str, update_data: TransactionDisputeUpdateRequest) -> TransactionDispute:
77
+ """
78
+ Update a transaction dispute asynchronously.
79
+
80
+ Args:
81
+ dispute_id: The ID of the dispute to update
82
+ update_data: TransactionDisputeUpdateRequest model with update details
83
+
84
+ Returns:
85
+ TransactionDispute: The updated transaction dispute
86
+ """
87
+ url = f"{self._build_url(dispute_id)}/update"
88
+
89
+ if self.client.__class__.__name__.startswith('Async'):
90
+ response = await self.client._request("POST", url, json=update_data.to_api_dict())
91
+ return self.model_class.from_api_response(response.json())
92
+ else:
93
+ raise ValueError("Use update_dispute for sync clients")
94
+
95
+ def submit_dispute(self, dispute_id: str) -> TransactionDispute:
96
+ """
97
+ Submit a transaction dispute.
98
+
99
+ Args:
100
+ dispute_id: The ID of the dispute to submit
101
+
102
+ Returns:
103
+ TransactionDispute: The submitted transaction dispute
104
+ """
105
+ url = f"{self._build_url(dispute_id)}/submit"
106
+
107
+ if not self.client.__class__.__name__.startswith('Async'):
108
+ response = self.client._request("POST", url)
109
+ return self.model_class.from_api_response(response.json())
110
+ else:
111
+ raise ValueError("Use submit_dispute_async for async clients")
112
+
113
+ async def submit_dispute_async(self, dispute_id: str) -> TransactionDispute:
114
+ """
115
+ Submit a transaction dispute asynchronously.
116
+
117
+ Args:
118
+ dispute_id: The ID of the dispute to submit
119
+
120
+ Returns:
121
+ TransactionDispute: The submitted transaction dispute
122
+ """
123
+ url = f"{self._build_url(dispute_id)}/submit"
124
+
125
+ if self.client.__class__.__name__.startswith('Async'):
126
+ response = await self.client._request("POST", url)
127
+ return self.model_class.from_api_response(response.json())
128
+ else:
129
+ raise ValueError("Use submit_dispute for sync clients")
130
+
131
+ def cancel_dispute(self, dispute_id: str) -> TransactionDispute:
132
+ """
133
+ Cancel a transaction dispute.
134
+
135
+ Args:
136
+ dispute_id: The ID of the dispute to cancel
137
+
138
+ Returns:
139
+ TransactionDispute: The cancelled transaction dispute
140
+ """
141
+ url = f"{self._build_url(dispute_id)}/cancel"
142
+
143
+ if not self.client.__class__.__name__.startswith('Async'):
144
+ response = self.client._request("POST", url)
145
+ return self.model_class.from_api_response(response.json())
146
+ else:
147
+ raise ValueError("Use cancel_dispute_async for async clients")
148
+
149
+ async def cancel_dispute_async(self, dispute_id: str) -> TransactionDispute:
150
+ """
151
+ Cancel a transaction dispute asynchronously.
152
+
153
+ Args:
154
+ dispute_id: The ID of the dispute to cancel
155
+
156
+ Returns:
157
+ TransactionDispute: The cancelled transaction dispute
158
+ """
159
+ url = f"{self._build_url(dispute_id)}/cancel"
160
+
161
+ if self.client.__class__.__name__.startswith('Async'):
162
+ response = await self.client._request("POST", url)
163
+ return self.model_class.from_api_response(response.json())
164
+ else:
165
+ raise ValueError("Use cancel_dispute for sync clients")
166
+
167
+ def list_with_filters(
168
+ self,
169
+ detailed_status: Optional[str] = None,
170
+ from_created_at: Optional[Union[str, datetime]] = None,
171
+ from_updated_at: Optional[Union[str, datetime]] = None,
172
+ page: Optional[str] = None,
173
+ page_size: int = 10,
174
+ reason: Optional[str] = None,
175
+ reference: Optional[str] = None,
176
+ status: Optional[str] = None,
177
+ to_created_at: Optional[Union[str, datetime]] = None,
178
+ to_updated_at: Optional[Union[str, datetime]] = None,
179
+ transaction_id: Optional[str] = None,
180
+ updated_by: Optional[str] = None
181
+ ) -> List[TransactionDispute]:
182
+ """
183
+ List transaction disputes with filtering options.
184
+
185
+ Args:
186
+ detailed_status: Filter by detailed status
187
+ from_created_at: Filter by creation date (start, inclusive)
188
+ from_updated_at: Filter by update date (start, inclusive)
189
+ page: Page bookmark for pagination
190
+ page_size: Number of results per page
191
+ reason: Filter by dispute reason
192
+ reference: Filter by reference
193
+ status: Filter by status
194
+ to_created_at: Filter by creation date (end, exclusive)
195
+ to_updated_at: Filter by update date (end, exclusive)
196
+ transaction_id: Filter by transaction ID
197
+ updated_by: Filter by who last updated the dispute
198
+
199
+ Returns:
200
+ List[TransactionDispute]: List of matching transaction disputes
201
+ """
202
+ params = {
203
+ "page_size": page_size
204
+ }
205
+
206
+ if detailed_status:
207
+ params["detailed_status"] = detailed_status
208
+
209
+ if from_created_at:
210
+ if isinstance(from_created_at, datetime):
211
+ from_created_at = from_created_at.isoformat()
212
+ params["from_created_at"] = from_created_at
213
+
214
+ if from_updated_at:
215
+ if isinstance(from_updated_at, datetime):
216
+ from_updated_at = from_updated_at.isoformat()
217
+ params["from_updated_at"] = from_updated_at
218
+
219
+ if page:
220
+ params["page"] = page
221
+
222
+ if reason:
223
+ params["reason"] = reason
224
+
225
+ if reference:
226
+ params["reference"] = reference
227
+
228
+ if status:
229
+ params["status"] = status
230
+
231
+ if to_created_at:
232
+ if isinstance(to_created_at, datetime):
233
+ to_created_at = to_created_at.isoformat()
234
+ params["to_created_at"] = to_created_at
235
+
236
+ if to_updated_at:
237
+ if isinstance(to_updated_at, datetime):
238
+ to_updated_at = to_updated_at.isoformat()
239
+ params["to_updated_at"] = to_updated_at
240
+
241
+ if transaction_id:
242
+ params["transaction_id"] = transaction_id
243
+
244
+ if updated_by:
245
+ params["updated_by"] = updated_by
246
+
247
+ if not self.client.__class__.__name__.startswith('Async'):
248
+ response = self.client._request("GET", self._build_url(), params=params)
249
+ data = response.json()
250
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
251
+ else:
252
+ raise ValueError("Use list_with_filters_async for async clients")
253
+
254
+ async def list_with_filters_async(
255
+ self,
256
+ detailed_status: Optional[str] = None,
257
+ from_created_at: Optional[Union[str, datetime]] = None,
258
+ from_updated_at: Optional[Union[str, datetime]] = None,
259
+ page: Optional[str] = None,
260
+ page_size: int = 10,
261
+ reason: Optional[str] = None,
262
+ reference: Optional[str] = None,
263
+ status: Optional[str] = None,
264
+ to_created_at: Optional[Union[str, datetime]] = None,
265
+ to_updated_at: Optional[Union[str, datetime]] = None,
266
+ transaction_id: Optional[str] = None,
267
+ updated_by: Optional[str] = None
268
+ ) -> List[TransactionDispute]:
269
+ """
270
+ List transaction disputes with filtering options asynchronously.
271
+
272
+ Args:
273
+ detailed_status: Filter by detailed status
274
+ from_created_at: Filter by creation date (start, inclusive)
275
+ from_updated_at: Filter by update date (start, inclusive)
276
+ page: Page bookmark for pagination
277
+ page_size: Number of results per page
278
+ reason: Filter by dispute reason
279
+ reference: Filter by reference
280
+ status: Filter by status
281
+ to_created_at: Filter by creation date (end, exclusive)
282
+ to_updated_at: Filter by update date (end, exclusive)
283
+ transaction_id: Filter by transaction ID
284
+ updated_by: Filter by who last updated the dispute
285
+
286
+ Returns:
287
+ List[TransactionDispute]: List of matching transaction disputes
288
+ """
289
+ params = {
290
+ "page_size": page_size
291
+ }
292
+
293
+ if detailed_status:
294
+ params["detailed_status"] = detailed_status
295
+
296
+ if from_created_at:
297
+ if isinstance(from_created_at, datetime):
298
+ from_created_at = from_created_at.isoformat()
299
+ params["from_created_at"] = from_created_at
300
+
301
+ if from_updated_at:
302
+ if isinstance(from_updated_at, datetime):
303
+ from_updated_at = from_updated_at.isoformat()
304
+ params["from_updated_at"] = from_updated_at
305
+
306
+ if page:
307
+ params["page"] = page
308
+
309
+ if reason:
310
+ params["reason"] = reason
311
+
312
+ if reference:
313
+ params["reference"] = reference
314
+
315
+ if status:
316
+ params["status"] = status
317
+
318
+ if to_created_at:
319
+ if isinstance(to_created_at, datetime):
320
+ to_created_at = to_created_at.isoformat()
321
+ params["to_created_at"] = to_created_at
322
+
323
+ if to_updated_at:
324
+ if isinstance(to_updated_at, datetime):
325
+ to_updated_at = to_updated_at.isoformat()
326
+ params["to_updated_at"] = to_updated_at
327
+
328
+ if transaction_id:
329
+ params["transaction_id"] = transaction_id
330
+
331
+ if updated_by:
332
+ params["updated_by"] = updated_by
333
+
334
+ if self.client.__class__.__name__.startswith('Async'):
335
+ response = await self.client._request("GET", self._build_url(), params=params)
336
+ data = response.json()
337
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
338
+ else:
339
+ raise ValueError("Use list_with_filters for sync clients")
@@ -0,0 +1,148 @@
1
+ """
2
+ Airwallex Payment API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from ..models.payment import Payment, PaymentCreateRequest, PaymentUpdateRequest, PaymentQuote
6
+ from .base import AirwallexAPIBase
7
+
8
+ T = TypeVar("T", bound=Payment)
9
+
10
+
11
+ class Payment(AirwallexAPIBase[Payment]):
12
+ """
13
+ Operations for Airwallex payments.
14
+
15
+ Payments represent money transfers to beneficiaries.
16
+ """
17
+ endpoint = "payments"
18
+ model_class = cast(Type[Payment], Payment)
19
+
20
+ def create_from_model(self, payment: PaymentCreateRequest) -> Payment:
21
+ """
22
+ Create a new payment using a Pydantic model.
23
+
24
+ Args:
25
+ payment: PaymentCreateRequest model with payment creation details.
26
+
27
+ Returns:
28
+ Payment: The created payment.
29
+ """
30
+ return self.create(payment)
31
+
32
+ async def create_from_model_async(self, payment: PaymentCreateRequest) -> Payment:
33
+ """
34
+ Create a new payment using a Pydantic model asynchronously.
35
+
36
+ Args:
37
+ payment: PaymentCreateRequest model with payment creation details.
38
+
39
+ Returns:
40
+ Payment: The created payment.
41
+ """
42
+ return await self.create_async(payment)
43
+
44
+ def update_from_model(self, payment_id: str, payment: PaymentUpdateRequest) -> Payment:
45
+ """
46
+ Update a payment using a Pydantic model.
47
+
48
+ Args:
49
+ payment_id: The ID of the payment to update.
50
+ payment: PaymentUpdateRequest model with payment update details.
51
+
52
+ Returns:
53
+ Payment: The updated payment.
54
+ """
55
+ return self.update(payment_id, payment)
56
+
57
+ async def update_from_model_async(self, payment_id: str, payment: PaymentUpdateRequest) -> Payment:
58
+ """
59
+ Update a payment using a Pydantic model asynchronously.
60
+
61
+ Args:
62
+ payment_id: The ID of the payment to update.
63
+ payment: PaymentUpdateRequest model with payment update details.
64
+
65
+ Returns:
66
+ Payment: The updated payment.
67
+ """
68
+ return await self.update_async(payment_id, payment)
69
+
70
+ def cancel(self, payment_id: str) -> Payment:
71
+ """
72
+ Cancel a payment.
73
+
74
+ Args:
75
+ payment_id: The ID of the payment to cancel.
76
+
77
+ Returns:
78
+ Payment: The cancelled payment.
79
+ """
80
+ update_request = PaymentUpdateRequest(status="cancelled")
81
+ return self.update(payment_id, update_request)
82
+
83
+ async def cancel_async(self, payment_id: str) -> Payment:
84
+ """
85
+ Cancel a payment asynchronously.
86
+
87
+ Args:
88
+ payment_id: The ID of the payment to cancel.
89
+
90
+ Returns:
91
+ Payment: The cancelled payment.
92
+ """
93
+ update_request = PaymentUpdateRequest(status="cancelled")
94
+ return await self.update_async(payment_id, update_request)
95
+
96
+ def get_quote(self, source_currency: str, target_currency: str, amount: float, source_type: str = "source") -> PaymentQuote:
97
+ """
98
+ Get a quote for a payment.
99
+
100
+ Args:
101
+ source_currency: Source currency code (ISO 4217)
102
+ target_currency: Target currency code (ISO 4217)
103
+ amount: Amount to convert
104
+ source_type: Whether the amount is in the source or target currency ('source' or 'target')
105
+
106
+ Returns:
107
+ PaymentQuote: The payment quote.
108
+ """
109
+ url = self._build_url(suffix="quote")
110
+ payload = {
111
+ "source_currency": source_currency,
112
+ "target_currency": target_currency,
113
+ "amount": amount,
114
+ "source_type": source_type
115
+ }
116
+
117
+ if not self.client.__class__.__name__.startswith('Async'):
118
+ response = self.client._request("POST", url, json=payload)
119
+ return PaymentQuote.from_api_response(response.json())
120
+ else:
121
+ raise ValueError("Use get_quote_async for async clients")
122
+
123
+ async def get_quote_async(self, source_currency: str, target_currency: str, amount: float, source_type: str = "source") -> PaymentQuote:
124
+ """
125
+ Get a quote for a payment asynchronously.
126
+
127
+ Args:
128
+ source_currency: Source currency code (ISO 4217)
129
+ target_currency: Target currency code (ISO 4217)
130
+ amount: Amount to convert
131
+ source_type: Whether the amount is in the source or target currency ('source' or 'target')
132
+
133
+ Returns:
134
+ PaymentQuote: The payment quote.
135
+ """
136
+ url = self._build_url(suffix="quote")
137
+ payload = {
138
+ "source_currency": source_currency,
139
+ "target_currency": target_currency,
140
+ "amount": amount,
141
+ "source_type": source_type
142
+ }
143
+
144
+ if self.client.__class__.__name__.startswith('Async'):
145
+ response = await self.client._request("POST", url, json=payload)
146
+ return PaymentQuote.from_api_response(response.json())
147
+ else:
148
+ raise ValueError("Use get_quote for sync clients")