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.
- airwallex/__init__.py +74 -0
- airwallex/api/__init__.py +37 -0
- airwallex/api/account.py +107 -0
- airwallex/api/account_detail.py +469 -0
- airwallex/api/base.py +488 -0
- airwallex/api/beneficiary.py +156 -0
- airwallex/api/financial_transaction.py +123 -0
- airwallex/api/invoice.py +257 -0
- airwallex/api/issuing_authorization.py +313 -0
- airwallex/api/issuing_card.py +411 -0
- airwallex/api/issuing_cardholder.py +234 -0
- airwallex/api/issuing_config.py +80 -0
- airwallex/api/issuing_digital_wallet_token.py +249 -0
- airwallex/api/issuing_transaction.py +231 -0
- airwallex/api/issuing_transaction_dispute.py +339 -0
- airwallex/api/payment.py +148 -0
- airwallex/client.py +396 -0
- airwallex/exceptions.py +222 -0
- airwallex/models/__init__.py +69 -0
- airwallex/models/account.py +51 -0
- airwallex/models/account_detail.py +259 -0
- airwallex/models/base.py +121 -0
- airwallex/models/beneficiary.py +70 -0
- airwallex/models/financial_transaction.py +30 -0
- airwallex/models/fx.py +58 -0
- airwallex/models/invoice.py +102 -0
- airwallex/models/issuing_authorization.py +41 -0
- airwallex/models/issuing_card.py +135 -0
- airwallex/models/issuing_cardholder.py +52 -0
- airwallex/models/issuing_common.py +83 -0
- airwallex/models/issuing_config.py +62 -0
- airwallex/models/issuing_digital_wallet_token.py +38 -0
- airwallex/models/issuing_transaction.py +42 -0
- airwallex/models/issuing_transaction_dispute.py +59 -0
- airwallex/models/payment.py +81 -0
- airwallex/utils.py +107 -0
- airwallex_sdk-0.1.0.dist-info/METADATA +202 -0
- airwallex_sdk-0.1.0.dist-info/RECORD +39 -0
- 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")
|
airwallex/api/payment.py
ADDED
@@ -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")
|