Skip to content

Commit

Permalink
feat: Add support for adjustment type and VND currency (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgrayston-paddle authored Dec 17, 2024
1 parent 0ef3a03 commit 385c359
Show file tree
Hide file tree
Showing 21 changed files with 296 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
69 changes: 69 additions & 0 deletions examples/adjustments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from logging import getLogger
from os import getenv
from sys import exit # You should use classes/functions that returns instead of exits

from paddle_billing import Client, Environment, Options

from paddle_billing.Entities.Shared import (
Action,
AdjustmentType,
)

from paddle_billing.Exceptions.ApiError import ApiError

from paddle_billing.Resources.Adjustments.Operations import CreateAdjustment, CreateAdjustmentItem

log = getLogger("my_app")

# Verify your Paddle API key was provided by a PADDLE_SECRET_API_KEY environment variable
# It is strongly advised that you do not include secrets in your source code
# Use environment variables, and/or secrets management like Vault to obtain your secrets
api_key: str = getenv("PADDLE_SECRET_API_KEY", None)
if not api_key:
raise ValueError("You must provide the PADDLE_SECRET_API_KEY in your environment variables")

transaction_id: str = getenv("PADDLE_TRANSACTION_ID", None)
transaction_item_id: str = getenv("PADDLE_TRANSACTION_ITEM_ID", None)
full_adjustment_transaction_id: str = getenv("PADDLE_FULL_ADJUSTMENT_TRANSACTION_ID", None)

# Determine the environment, defaulting to sandbox
environment = Environment(getenv("PADDLE_ENVIRONMENT", "sandbox"))

# Initialize the Paddle client
paddle = Client(api_key, options=Options(environment), logger=log)


# ┌───
# │ Create Partial Adjustment │
# └───────────────────────────┘
try:
partial_adjustment = paddle.adjustments.create(
CreateAdjustment.partial(
Action.Refund,
[CreateAdjustmentItem(transaction_item_id, AdjustmentType.Partial, "100")],
"error",
transaction_id,
)
)
except ApiError as error:
print(error)
exit(1)

print(f"Partial Adjustment '{partial_adjustment.id}'")

# ┌───
# │ Create Full Adjustment │
# └────────────────────────┘
try:
full_adjustment = paddle.adjustments.create(
CreateAdjustment.full(
Action.Refund,
"error",
full_adjustment_transaction_id,
)
)
except ApiError as error:
print(error)
exit(1)

print(f"Full Adjustment '{full_adjustment.id}'")
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
Loading

0 comments on commit 385c359

Please sign in to comment.