Skip to content

Commit

Permalink
feat: Add support for adjustment type and VND currency
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgrayston-paddle committed Dec 17, 2024
1 parent 0ef3a03 commit e0999fc
Show file tree
Hide file tree
Showing 20 changed files with 227 additions and 5 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx&utm_medium=paddle-python-sdk) for information about changes to the Paddle Billing platform, the Paddle API, and other developer tools.

## 1.3.0 - 2024-12-17

### Added

- Support for adjustment type, see [related changelog](https://developer.paddle.com/changelog/2024/refund-credit-full-total?utm_source=dx&utm_medium=paddle-python-sdk)
- Added Vietnamese Dong (`VND`) as a supported currency for payments [related changelog](https://developer.paddle.com/changelog/2024/vietnamese-dong-vnd-supported-currency?utm_source=dx&utm_medium=paddle-python-sdk)

## 1.2.2 - 2024-12-17

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion paddle_billing/Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def build_request_session(self) -> Session:
"Authorization": f"Bearer {self.__api_key}",
"Content-Type": "application/json",
"Paddle-Version": str(self.use_api_version),
"User-Agent": "PaddleSDK/python 1.2.2",
"User-Agent": "PaddleSDK/python 1.3.0",
}
)

Expand Down
3 changes: 3 additions & 0 deletions paddle_billing/Entities/Adjustment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from paddle_billing.Entities.Adjustments import AdjustmentItem, AdjustmentTaxRatesUsed
from paddle_billing.Entities.Shared import (
Action,
AdjustmentActionType,
AdjustmentStatus,
CurrencyCode,
PayoutTotalsAdjustment,
Expand All @@ -30,6 +31,7 @@ class Adjustment(Entity):
created_at: datetime
updated_at: datetime | None
tax_rates_used: list[AdjustmentTaxRatesUsed]
type: AdjustmentActionType

@staticmethod
def from_dict(data: dict) -> Adjustment:
Expand All @@ -51,4 +53,5 @@ def from_dict(data: dict) -> Adjustment:
),
updated_at=datetime.fromisoformat(data["updated_at"]) if data.get("updated_at") else None,
tax_rates_used=[AdjustmentTaxRatesUsed.from_dict(item) for item in data["tax_rates_used"]],
type=AdjustmentStatus(data["type"]),
)
6 changes: 6 additions & 0 deletions paddle_billing/Entities/Shared/AdjustmentActionType.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from paddle_billing.PaddleStrEnum import PaddleStrEnum, PaddleStrEnumMeta


class AdjustmentActionType(PaddleStrEnum, metaclass=PaddleStrEnumMeta):
Full: "AdjustmentActionType" = "full"
Partial: "AdjustmentActionType" = "partial"
1 change: 1 addition & 0 deletions paddle_billing/Entities/Shared/CurrencyCode.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ class CurrencyCode(PaddleStrEnum, metaclass=PaddleStrEnumMeta):
TRY: "CurrencyCode" = "TRY"
TWD: "CurrencyCode" = "TWD"
UAH: "CurrencyCode" = "UAH"
VND: "CurrencyCode" = "VND"
ZAR: "CurrencyCode" = "ZAR"
1 change: 1 addition & 0 deletions paddle_billing/Entities/Shared/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from paddle_billing.Entities.Shared.Action import Action
from paddle_billing.Entities.Shared.AddressPreview import AddressPreview
from paddle_billing.Entities.Shared.AdjustmentActionType import AdjustmentActionType
from paddle_billing.Entities.Shared.AdjustmentItemTotals import AdjustmentItemTotals
from paddle_billing.Entities.Shared.AdjustmentStatus import AdjustmentStatus
from paddle_billing.Entities.Shared.AdjustmentTotals import AdjustmentTotals
Expand Down
3 changes: 3 additions & 0 deletions paddle_billing/Notifications/Entities/Adjustment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from paddle_billing.Notifications.Entities.Entity import Entity
from paddle_billing.Notifications.Entities.Shared import (
Action,
AdjustmentActionType,
AdjustmentStatus,
CurrencyCode,
PayoutTotalsAdjustment,
Expand All @@ -30,6 +31,7 @@ class Adjustment(Entity):
created_at: datetime
updated_at: datetime | None
tax_rates_used: list[AdjustmentTaxRatesUsed] | None
type: AdjustmentActionType | None

@staticmethod
def from_dict(data: dict) -> Adjustment:
Expand All @@ -55,4 +57,5 @@ def from_dict(data: dict) -> Adjustment:
if data.get("tax_rates_used")
else None
),
type=AdjustmentActionType(data["type"]) if data.get("type") else None,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from paddle_billing.PaddleStrEnum import PaddleStrEnum, PaddleStrEnumMeta


class AdjustmentActionType(PaddleStrEnum, metaclass=PaddleStrEnumMeta):
Full: "AdjustmentActionType" = "full"
Partial: "AdjustmentActionType" = "partial"
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ class CurrencyCode(PaddleStrEnum, metaclass=PaddleStrEnumMeta):
TRY: "CurrencyCode" = "TRY"
TWD: "CurrencyCode" = "TWD"
UAH: "CurrencyCode" = "UAH"
VND: "CurrencyCode" = "VND"
ZAR: "CurrencyCode" = "ZAR"
1 change: 1 addition & 0 deletions paddle_billing/Notifications/Entities/Shared/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from paddle_billing.Notifications.Entities.Shared.Action import Action
from paddle_billing.Notifications.Entities.Shared.AddressPreview import AddressPreview
from paddle_billing.Notifications.Entities.Shared.AdjustmentActionType import AdjustmentActionType
from paddle_billing.Notifications.Entities.Shared.AdjustmentItemTotals import AdjustmentItemTotals
from paddle_billing.Notifications.Entities.Shared.AdjustmentStatus import AdjustmentStatus
from paddle_billing.Notifications.Entities.Shared.AdjustmentTotals import AdjustmentTotals
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,58 @@
from dataclasses import dataclass

from paddle_billing.Undefined import Undefined

from paddle_billing.Operation import Operation

from paddle_billing.Entities.Shared import Action
from paddle_billing.Entities.Shared import Action, AdjustmentActionType

from paddle_billing.Resources.Adjustments.Operations import CreateAdjustmentItem

from paddle_billing.Exceptions.SdkExceptions.InvalidArgumentException import InvalidArgumentException


@dataclass
class CreateAdjustment(Operation):
action: Action
items: list[CreateAdjustmentItem]
items: list[CreateAdjustmentItem] | None | Undefined
reason: str
transaction_id: str
type: AdjustmentActionType | Undefined = Undefined()

def __post_init__(self):
if self.type != AdjustmentActionType.Full and (
self.items is None or isinstance(self.items, Undefined) or len(self.items) == 0
):
raise InvalidArgumentException.array_is_empty("items")

if self.type == AdjustmentActionType.Full and isinstance(self.items, list):
raise InvalidArgumentException("items are not allowed when the adjustment type is full")

@staticmethod
def full(
action: Action,
reason: str,
transaction_id: str,
) -> "CreateAdjustment":
return CreateAdjustment(
action=action,
reason=reason,
transaction_id=transaction_id,
items=Undefined(),
type=AdjustmentActionType.Full,
)

@staticmethod
def partial(
action: Action,
items: list[CreateAdjustmentItem],
reason: str,
transaction_id: str,
) -> "CreateAdjustment":
return CreateAdjustment(
action=action,
reason=reason,
transaction_id=transaction_id,
items=items,
type=AdjustmentActionType.Partial,
)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


setup(
version="1.2.2",
version="1.3.0",
author="Paddle and contributors",
author_email="[email protected]",
description="Paddle's Python SDK for Paddle Billing",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"action": "refund",
"type": "full",
"reason": "error",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"action": "refund",
"type": "full",
"items": null,
"reason": "error",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"action": "refund",
"type": "partial",
"items": [
{
"item_id": "txnitm_01h8bxryv3065dyh6103p3yg28",
"type": "partial",
"amount": "100"
}
],
"reason": "error",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"data": {
"id": "adj_01h8c65c2ggq5nxswnnwv78e75",
"action": "refund",
"type": "partial",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5",
"subscription_id": "sub_01h8bxswamxysj44zt5n48njwh",
"customer_id": "ctm_01h8441jn5pcwrfhwh78jqt8hk",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{
"id": "adj_01h8c65c2ggq5nxswnnwv78e75",
"action": "refund",
"type": "partial",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5",
"subscription_id": "sub_01h8bxswamxysj44zt5n48njwh",
"customer_id": "ctm_01h8441jn5pcwrfhwh78jqt8hk",
Expand Down Expand Up @@ -55,6 +56,7 @@
{
"id": "adj_01h8bxezh16gm6t8rx21dx271b",
"action": "credit",
"type": "partial",
"credit_applied_to_balance": true,
"transaction_id": "txn_01h8bx69629a16wwm9z8rjmak3",
"subscription_id": "sub_01h8bx8fmywym11t6swgzba704",
Expand Down Expand Up @@ -114,6 +116,7 @@
{
"id": "adj_01h7jgzjqt2s8sab70e03ptkhv",
"action": "credit",
"type": "partial",
"credit_applied_to_balance": true,
"transaction_id": "txn_01h7jgd9bkwjscj3ae15g5d3vs",
"subscription_id": "sub_01h7ht5z5wdg9pz18jx1fagp8k",
Expand Down Expand Up @@ -173,6 +176,7 @@
{
"id": "adj_01h7jf6ptkfsc93hzc20fgf8wy",
"action": "credit",
"type": "partial",
"credit_applied_to_balance": true,
"transaction_id": "txn_01h7je77vc1qmzxntem45ebb5q",
"subscription_id": "sub_01h7ht5z5wdg9pz18jx1fagp8k",
Expand Down Expand Up @@ -232,6 +236,7 @@
{
"id": "adj_01h468w41ttb2j2bh8av74gwt1",
"action": "credit",
"type": "partial",
"credit_applied_to_balance": true,
"transaction_id": "txn_01h468crc3b3fe98a5ft53recb",
"subscription_id": "sub_01h468kv3jhs5jk330gszncsgt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"data": {
"id": "adj_01h8c65c2ggq5nxswnnwv78e75",
"action": "refund",
"type": "partial",
"transaction_id": "txn_01h8bxpvx398a7zbawb77y0kp5",
"subscription_id": "sub_01h8bxswamxysj44zt5n48njwh",
"customer_id": "ctm_01h8441jn5pcwrfhwh78jqt8hk",
Expand Down
71 changes: 70 additions & 1 deletion tests/Functional/Resources/Adjustments/test_AdjustmentsClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from paddle_billing.Entities.Adjustment import Adjustment, AdjustmentTaxRatesUsed
from paddle_billing.Entities.Collections import AdjustmentCollection
from paddle_billing.Entities.AdjustmentCreditNote import AdjustmentCreditNote
from paddle_billing.Entities.Shared import Action, AdjustmentStatus, AdjustmentType, Disposition
from paddle_billing.Entities.Shared import Action, AdjustmentActionType, AdjustmentStatus, AdjustmentType, Disposition

from paddle_billing.Resources.Adjustments.Operations import (
CreateAdjustment,
Expand All @@ -15,6 +15,8 @@
)
from paddle_billing.Resources.Shared.Operations import Pager

from paddle_billing.Undefined import Undefined

from tests.Utils.ReadsFixture import ReadsFixtures


Expand Down Expand Up @@ -49,10 +51,77 @@ class TestAdjustmentsClient:
ReadsFixtures.read_raw_json_fixture("response/full_entity"),
"/adjustments",
),
(
CreateAdjustment(
Action.Refund,
[CreateAdjustmentItem("txnitm_01h8bxryv3065dyh6103p3yg28", AdjustmentType.Partial, "100")],
"error",
"txn_01h8bxpvx398a7zbawb77y0kp5",
AdjustmentActionType.Partial,
),
ReadsFixtures.read_raw_json_fixture("request/create_type_partial_with_items"),
200,
ReadsFixtures.read_raw_json_fixture("response/minimal_entity"),
"/adjustments",
),
(
CreateAdjustment.partial(
Action.Refund,
[CreateAdjustmentItem("txnitm_01h8bxryv3065dyh6103p3yg28", AdjustmentType.Partial, "100")],
"error",
"txn_01h8bxpvx398a7zbawb77y0kp5",
),
ReadsFixtures.read_raw_json_fixture("request/create_type_partial_with_items"),
200,
ReadsFixtures.read_raw_json_fixture("response/minimal_entity"),
"/adjustments",
),
(
CreateAdjustment.full(
Action.Refund,
"error",
"txn_01h8bxpvx398a7zbawb77y0kp5",
),
ReadsFixtures.read_raw_json_fixture("request/create_type_full_with_no_items"),
200,
ReadsFixtures.read_raw_json_fixture("response/minimal_entity"),
"/adjustments",
),
(
CreateAdjustment(
Action.Refund,
None,
"error",
"txn_01h8bxpvx398a7zbawb77y0kp5",
AdjustmentActionType.Full,
),
ReadsFixtures.read_raw_json_fixture("request/create_type_full_with_null_items"),
200,
ReadsFixtures.read_raw_json_fixture("response/minimal_entity"),
"/adjustments",
),
(
CreateAdjustment(
Action.Refund,
Undefined(),
"error",
"txn_01h8bxpvx398a7zbawb77y0kp5",
AdjustmentActionType.Full,
),
ReadsFixtures.read_raw_json_fixture("request/create_type_full_with_no_items"),
200,
ReadsFixtures.read_raw_json_fixture("response/minimal_entity"),
"/adjustments",
),
],
ids=[
"Create adjustment with basic data",
"Create adjustment with full data",
"Create adjustment with basic data with type",
"Create partial adjustment with items",
"Create full adjustment with no items",
"Create full adjustment with None items",
"Create full adjustment with Undefined items",
],
)
def test_create_adjustment_uses_expected_payload(
Expand Down
Loading

0 comments on commit e0999fc

Please sign in to comment.