Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fintoc/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
InvoicesManager,
LinksManager,
PaymentIntentsManager,
PaymentLinksManager,
RefreshIntentsManager,
RefundsManager,
SubscriptionIntentsManager,
Expand Down Expand Up @@ -50,6 +51,7 @@ def __init__(self, api_key, api_version=None, jws_private_key=None):
self.payment_intents = PaymentIntentsManager(
"/v1/payment_intents", self._client
)
self.payment_links = PaymentLinksManager("/v1/payment_links", self._client)
self.refunds = RefundsManager("/v1/refunds", self._client)
self.subscriptions = SubscriptionsManager("/v1/subscriptions", self._client)
self.subscription_intents = SubscriptionIntentsManager(
Expand Down
1 change: 1 addition & 0 deletions fintoc/managers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .links_manager import LinksManager
from .movements_manager import MovementsManager
from .payment_intents_manager import PaymentIntentsManager
from .payment_links_manager import PaymentLinksManager
from .refresh_intents_manager import RefreshIntentsManager
from .refunds_manager import RefundsManager
from .subscription_intents_manager import SubscriptionIntentsManager
Expand Down
7 changes: 6 additions & 1 deletion fintoc/managers/payment_intents_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ class PaymentIntentsManager(ManagerMixin):
"""Represents a payment_intents manager."""

resource = "payment_intent"
methods = ["list", "get", "create", "expire"]
methods = ["list", "get", "create", "expire", "check_eligibility"]

def _expire(self, identifier, **kwargs):
"""Expire a payment intent."""
path = f"{self._build_path(**kwargs)}/{identifier}/expire"
return self._create(path_=path, **kwargs)

def _check_eligibility(self, **kwargs):
"""Check eligibility for a payment intent."""
path = f"{self._build_path(**kwargs)}/check_eligibility"
return self._create(path_=path, **kwargs)
16 changes: 16 additions & 0 deletions fintoc/managers/payment_links_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Module to hold the payment_links manager."""

from fintoc.mixins import ManagerMixin


class PaymentLinksManager(ManagerMixin):

"""Represents a payment_links manager."""

resource = "payment_link"
methods = ["list", "get", "create", "cancel"]

def _cancel(self, identifier, **kwargs):
"""Cancel a payment link."""
path = f"{self._build_path(**kwargs)}/{identifier}/cancel"
return self._update(identifier, path_=path, **kwargs)
4 changes: 3 additions & 1 deletion fintoc/mixins/manager_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,14 @@ def _create(self, idempotency_key=None, path_=None, **kwargs):
return self.post_create_handler(object_, **kwargs)

@can_raise_fintoc_error
def _update(self, identifier, **kwargs):
def _update(self, identifier, path_=None, **kwargs):
"""
Update an instance of the resource being handled by the manager,
identified by :identifier:. Data is passed using :kwargs:, as
specified by the API.
"""
klass = get_resource_class(self.__class__.resource)
custom_path = path_ if path_ else None
object_ = resource_update(
client=self._client,
path=self._build_path(**kwargs),
Expand All @@ -133,6 +134,7 @@ def _update(self, identifier, **kwargs):
handlers=self._handlers,
methods=self.__class__.methods,
params=kwargs,
custom_path=custom_path,
)
return self.post_update_handler(object_, identifier, **kwargs)

Expand Down
5 changes: 4 additions & 1 deletion fintoc/mixins/resource_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ def serialize(self):
return serialized

@can_raise_fintoc_error
def _update(self, **kwargs):
def _update(self, path_=None, **kwargs):
"""Update the resource."""
id_ = getattr(self, self.__class__.resource_identifier)
custom_path = path_ if path_ else None
object_ = resource_update(
client=self._client,
path=self._path,
Expand All @@ -71,6 +73,7 @@ def _update(self, **kwargs):
handlers=self._handlers,
methods=self._methods,
params=kwargs,
custom_path=custom_path,
)
object_ = self._handlers.get("update")(object_, id_, **kwargs)
self.__dict__.update(object_.__dict__)
Expand Down
7 changes: 5 additions & 2 deletions fintoc/resource_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ def resource_create(
)


def resource_update(client, path, id_, klass, handlers, methods, params):
def resource_update(
client, path, id_, klass, handlers, methods, params, custom_path=None
):
"""Update a specific instance of a resource."""
data = client.request(f"{path}/{id_}", method="patch", json=params)
update_path = custom_path if custom_path else f"{path}/{id_}"
data = client.request(update_path, method="patch", json=params)
return objetize(
klass,
client,
Expand Down
1 change: 1 addition & 0 deletions fintoc/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .movement import Movement
from .other_taxes import OtherTaxes
from .payment_intent import PaymentIntent
from .payment_link import PaymentLink
from .refresh_intent import RefreshIntent
from .services_invoice import ServicesInvoice
from .subscription import Subscription
Expand Down
7 changes: 7 additions & 0 deletions fintoc/resources/payment_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Module to hold the PaymentLink resource."""

from fintoc.mixins import ResourceMixin


class PaymentLink(ResourceMixin):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Es necesario tener esto?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, esto es necesario bajo la arquitectura que se siguió para armar el sdk. Dejo una pequeña explicación de esta:

Ocurre que esta clase al final termina siendo el tipo de objeto con el que responde la api cuando por ejemplo se hace un client.payment_links, en donde esto respondería un objeto del tipo PaymentLink. Esto ocurre gracias a que nosotros dentro de PaymentLinksManager (fintoc/managers/payment_links_manager.py) definimos cual es el resource y con esto define el objeto que antes mencionaba.

Este proceso es seguido por todos los recursos creados dentro de este sdk por lo que estuve revisando al hacer la implementación

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aaaaa buenisimo! gracias por explicarr

"""Represents a Fintoc PaymentLink."""
6 changes: 6 additions & 0 deletions tests/mixins/test_manager_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ def test_update_method(self):
assert isinstance(object_, ResourceMixin)
assert object_.method == "patch"

def test_update_update_method_with_custom_path(self):
object_ = self.manager.update("my_id", path_="/resources/my_id/cancel")
assert isinstance(object_, ResourceMixin)
assert object_.method == "patch"
assert object_.url == "resources/my_id/cancel"

def test_delete_method(self):
id_ = self.manager.delete("my_id")
isinstance(id_, str)
Expand Down
17 changes: 17 additions & 0 deletions tests/mixins/test_resource_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,20 @@ def test_empty_mock_resource_update_method(self, capsys):

assert data["id"] not in resource.url
assert data["identifier"] in resource.url

def test_resource_update_with_custom_path(self, capsys):
methods = ["update"]
data = {
"id": "id0",
"identifier": "identifier0",
}
resource = EmptyMockResource(
self.client, self.handlers, methods, self.path, **data
)

custom_path = f"{self.path}/id0/cancel"
resource.update(path_=custom_path)

captured = capsys.readouterr().out
assert "update" in captured
assert resource.url == custom_path.lstrip("/")
55 changes: 55 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,61 @@ def test_payment_intent_expire(self):
assert result.method == "post"
assert result.url == f"v1/payment_intents/{payment_intent_id}/expire"

def test_payment_intent_check_eligibility(self):
"""Test checking eligibility for a payment intent."""
eligibility_data = {
"amount": 1000,
"currency": "CLP",
}

result = self.fintoc.payment_intents.check_eligibility(**eligibility_data)

assert result.method == "post"
assert result.url == "v1/payment_intents/check_eligibility"

def test_payment_links_list(self):
"""Test getting all payment links."""
payment_links = list(self.fintoc.payment_links.list())

assert len(payment_links) > 0
for payment_link in payment_links:
assert payment_link.method == "get"
assert payment_link.url == "v1/payment_links"

def test_payment_link_get(self):
"""Test getting a specific payment link."""
payment_link_id = "test_payment_link_id"

payment_link = self.fintoc.payment_links.get(payment_link_id)

assert payment_link.method == "get"
assert payment_link.url == f"v1/payment_links/{payment_link_id}"

def test_payment_link_create(self):
"""Test creating a payment link."""
payment_link_data = {
"amount": 1000,
"currency": "CLP",
"description": "Test payment link",
}

payment_link = self.fintoc.payment_links.create(**payment_link_data)

assert payment_link.method == "post"
assert payment_link.url == "v1/payment_links"
assert payment_link.json.amount == payment_link_data["amount"]
assert payment_link.json.currency == payment_link_data["currency"]
assert payment_link.json.description == payment_link_data["description"]

def test_payment_link_cancel(self):
"""Test canceling a payment link."""
payment_link_id = "test_payment_link_id"

result = self.fintoc.payment_links.cancel(payment_link_id)

assert result.method == "patch"
assert result.url == f"v1/payment_links/{payment_link_id}/cancel"

def test_refund_list(self):
"""Test getting all refunds."""
refunds = list(self.fintoc.refunds.list())
Expand Down