From 9e69678a3211e7747f549c4788bd2b3b83c653c1 Mon Sep 17 00:00:00 2001 From: Avery Kushner Date: Thu, 11 Jun 2026 14:39:26 -0400 Subject: [PATCH] Add sandbox authorization increase/cancel simulation methods Adds AuthorizationResource.sandbox_increase and sandbox_cancel (POST sandbox/authorizations/{id}/increase|cancel) plus the SimulateAuthorizationIncrease / SimulateAuthorizationCancel request models. Used by the Truss card purchase E2E harness to drive authorization.amountChanged and authorization.canceled flows in the Unit sandbox. Co-authored-by: Cursor --- unit/api/authorization_resource.py | 16 +++++++++++++ unit/models/authorization.py | 38 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/unit/api/authorization_resource.py b/unit/api/authorization_resource.py index 3991bce1..567b3cbe 100644 --- a/unit/api/authorization_resource.py +++ b/unit/api/authorization_resource.py @@ -21,6 +21,22 @@ def get(self, authorization_id: str, include_non_authorized: Optional[bool] = Fa def list(self, params: ListAuthorizationParams = None) -> Union[UnitResponse[List[AuthorizationDTO]], UnitError]: params = params or ListAuthorizationParams() response = super().get(self.resource, params.to_dict()) + if super().is_20x(response.status_code): + data = response.json().get("data") + return UnitResponse[AuthorizationDTO](DtoDecoder.decode(data), None) + else: + return UnitError.from_json_api(response.json()) + + def sandbox_increase(self, request: SimulateAuthorizationIncrease) -> Union[UnitResponse[AuthorizationDTO], UnitError]: + response = super().post(f"sandbox/{self.resource}/{request.authorization_id}/increase", request.to_json_api()) + if super().is_20x(response.status_code): + data = response.json().get("data") + return UnitResponse[AuthorizationDTO](DtoDecoder.decode(data), None) + else: + return UnitError.from_json_api(response.json()) + + def sandbox_cancel(self, request: SimulateAuthorizationCancel) -> Union[UnitResponse[AuthorizationDTO], UnitError]: + response = super().post(f"sandbox/{self.resource}/{request.authorization_id}/cancel", request.to_json_api()) if super().is_20x(response.status_code): data = response.json().get("data") return UnitResponse[AuthorizationDTO](DtoDecoder.decode(data), None) diff --git a/unit/models/authorization.py b/unit/models/authorization.py index b32c88a0..be012e9a 100644 --- a/unit/models/authorization.py +++ b/unit/models/authorization.py @@ -121,3 +121,41 @@ def to_dict(self) -> Dict: if self.sort: parameters["sort"] = self.sort return parameters + + +class SimulateAuthorizationIncrease(UnitRequest): + def __init__(self, authorization_id: str, amount: int, card_last_4_digits: str, account_id: str): + self.authorization_id = authorization_id + self.amount = amount + self.card_last_4_digits = card_last_4_digits + self.account_id = account_id + + def to_json_api(self) -> Dict: + return { + "data": { + "type": "authorization", + "attributes": { + "amount": self.amount, + "cardLast4Digits": self.card_last_4_digits, + }, + "relationships": { + "account": {"data": {"type": "depositAccount", "id": self.account_id}} + }, + } + } + + +class SimulateAuthorizationCancel(UnitRequest): + def __init__(self, authorization_id: str, account_id: str): + self.authorization_id = authorization_id + self.account_id = account_id + + def to_json_api(self) -> Dict: + return { + "data": { + "type": "authorization", + "relationships": { + "account": {"data": {"type": "depositAccount", "id": self.account_id}} + }, + } + }