Skip to content

Commit c326e13

Browse files
authored
Merge pull request #11 from paywithextend/check-validity-of-status-strings
2 parents f88ccc6 + 4174c35 commit c326e13

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

extend/models.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,50 @@
22
from typing import TypedDict, Literal, NotRequired
33

44

5+
class ValidatableEnum(Enum):
6+
@classmethod
7+
def is_valid(cls, value: str) -> bool:
8+
try:
9+
cls(value)
10+
return True
11+
except ValueError:
12+
return False
13+
14+
15+
class CreditCardStatus(ValidatableEnum):
16+
ACTIVE = "ACTIVE"
17+
PENDING = "PENDING"
18+
INACTIVE = "INACTIVE"
19+
EXPIRED = "EXPIRED"
20+
BLOCKED = "BLOCKED"
21+
CLOSED = "CLOSED"
22+
23+
24+
class VirtualCardStatus(ValidatableEnum):
25+
ACTIVE = "ACTIVE"
26+
CANCELLED = "CANCELLED"
27+
EXPIRED = "EXPIRED"
28+
PENDING = "PENDING"
29+
CLOSED = "CLOSED"
30+
CONSUMED = "CONSUMED"
31+
32+
33+
class TransactionStatus(ValidatableEnum):
34+
PENDING = "PENDING"
35+
CLEARED = "CLEARED"
36+
DECLINED = "DECLINED"
37+
NO_MATCH = "NO_MATCH"
38+
AVS_PASS = "AVS_PASS"
39+
AVS_FAIL = "AVS_FAIL"
40+
AUTH_REVERSAL = "AUTH_REVERSAL"
41+
42+
43+
class TransactionType(ValidatableEnum):
44+
DEBIT = "DEBIT"
45+
CREDIT = "CREDIT"
46+
AVS = "AVS"
47+
48+
549
class VirtualCard(TypedDict):
650
"""Type definition for Virtual Card data.
751

extend/resources/credit_cards.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from extend.client import APIClient
44
from .resource import Resource
5+
from ..models import CreditCardStatus
56

67

78
class CreditCards(Resource):
@@ -18,6 +19,7 @@ async def get_credit_cards(
1819
per_page: Optional[int] = None,
1920
status: Optional[str] = None,
2021
search_term: Optional[str] = None,
22+
sort_direction: Optional[str] = None,
2123
) -> Dict:
2224
"""Get a list of all credit cards associated with your account.
2325
@@ -26,6 +28,7 @@ async def get_credit_cards(
2628
per_page (Optional[int]): Number of items per page
2729
status (Optional[str]): Filter cards by status (e.g., "ACTIVE", "CANCELLED")
2830
search_term (Optional[str]): Filter cards by search term (e.g., "Marketing")
31+
sort_direction (Optional[str]): Direction to sort (ASC or DESC)
2932
3033
Returns:
3134
Dict: A dictionary containing:
@@ -40,13 +43,16 @@ async def get_credit_cards(
4043
httpx.HTTPError: If the request fails
4144
"""
4245

46+
if status and not CreditCardStatus.is_valid(status.upper()):
47+
raise ValueError(f"{status} is not a valid status")
48+
4349
params = {
4450
"page": page,
4551
"count": per_page,
46-
"statuses": status,
52+
"statuses": status.upper() if status else None,
4753
"search": search_term,
54+
"sortDirection": sort_direction,
4855
}
49-
params = {k: v for k, v in params.items() if v is not None}
5056

5157
return await self._request(method="get", params=params)
5258

extend/resources/transactions.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from extend.client import APIClient
44
from .resource import Resource
5+
from ..models import TransactionStatus
56

67

78
class Transactions(Resource):
@@ -18,6 +19,7 @@ async def get_transactions(
1819
per_page: Optional[int] = None,
1920
from_date: Optional[str] = None,
2021
to_date: Optional[str] = None,
22+
status: Optional[str] = None,
2123
virtual_card_id: Optional[str] = None,
2224
min_amount_cents: Optional[int] = None,
2325
max_amount_cents: Optional[int] = None,
@@ -31,10 +33,11 @@ async def get_transactions(
3133
per_page (Optional[int]): Number of items per page
3234
from_date (Optional[str]): Start date in YYYY-MM-DD format
3335
to_date (Optional[str]): End date in YYYY-MM-DD format
36+
status (Optional[str]): Filter transactions by status (e.g., "PENDING", "CLEARED", "DECLINED", "NO_MATCH", "AVS_PASS", "AVS_FAIL", "AUTH_REVERSAL")
3437
virtual_card_id (str): Filter by specific virtual card
3538
min_amount_cents (int): Minimum clearing amount in cents
3639
max_amount_cents (int): Maximum clearing amount in cents
37-
search_term (Optional[str]): Filter cards by search term (e.g., "Marketing")
40+
search_term (Optional[str]): Filter transactions by search term (e.g., "Subscription")
3841
sort_field (Optional[str]): Field to sort by, with optional direction
3942
Use "recipientName", "merchantName", "amount", "date" for ASC
4043
Use "-recipientName", "-merchantName", "-amount", "-date" for DESC
@@ -52,11 +55,15 @@ async def get_transactions(
5255
httpx.HTTPError: If the request fails
5356
"""
5457

58+
if status and not TransactionStatus.is_valid(status.upper()):
59+
raise ValueError(f"{status} is not a valid status")
60+
5561
params = {
5662
"page": page,
5763
"count": per_page,
5864
"fromDate": from_date,
5965
"toDate": to_date,
66+
"statuses": status.upper() if status else None,
6067
"virtualCardId": virtual_card_id,
6168
"minClearingBillingCents": min_amount_cents,
6269
"maxClearingBillingCents": max_amount_cents,

extend/resources/virtual_cards.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Optional, Dict
22

33
from extend.client import APIClient
4-
from extend.models import CardCreationRequest
4+
from extend.models import CardCreationRequest, VirtualCardStatus
55
from extend.validations import validate_card_creation_data, validate_card_update_data
66
from .resource import Resource
77

@@ -29,7 +29,7 @@ async def get_virtual_cards(
2929
Args:
3030
page (Optional[int]): The page number for pagination (1-based)
3131
per_page (Optional[int]): Number of items per page
32-
status (Optional[str]): Filter cards by status (e.g., "ACTIVE", "CANCELLED")
32+
status (Optional[str]): Filter cards by status (e.g., "ACTIVE", "CANCELLED", "PENDING", "EXPIRED", "CLOSED", "CONSUMED")
3333
recipient (Optional[str]): Filter cards by recipient id (e.g., "u_1234")
3434
search_term (Optional[str]): Filter cards by search term (e.g., "Marketing")
3535
sort_field (Optional[str]): Field to sort by "createdAt", "updatedAt", "balanceCents", "displayName", "type", or "status"
@@ -47,10 +47,14 @@ async def get_virtual_cards(
4747
Raises:
4848
httpx.HTTPError: If the request fails
4949
"""
50+
51+
if status and not VirtualCardStatus.is_valid(status.upper()):
52+
raise ValueError(f"{status} is not a valid status")
53+
5054
params = {
5155
"page": page,
5256
"count": per_page,
53-
"statuses": status,
57+
"statuses": status.upper() if status else None,
5458
"recipient": recipient,
5559
"search": search_term,
5660
"sortField": sort_field,

0 commit comments

Comments
 (0)