From a7495d9633f8463e0c2e8c61bcf99f39c07943b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Labeyrie?= Date: Thu, 1 Oct 2020 16:36:47 +0200 Subject: [PATCH 1/8] Update version number --- payplug/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payplug/__version__.py b/payplug/__version__.py index ea1a019..d14fa05 100644 --- a/payplug/__version__.py +++ b/payplug/__version__.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -__version__ = '1.3.0' +__version__ = '1.3.1' From 35fa9e530e982bea4980a675ed16a4dfd1268ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Labeyrie?= Date: Thu, 8 Oct 2020 18:54:57 +0200 Subject: [PATCH 2/8] Set correct API version in README example --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rst b/README.rst index 1bb0fac..8d9aef8 100644 --- a/README.rst +++ b/README.rst @@ -71,6 +71,8 @@ Here's how simple it is to create a payment request: .. sourcecode :: python + payplug.set_api_version("2019-08-06") + customer = { 'email': 'john.watson@example.net', 'first_name': 'John', @@ -80,6 +82,7 @@ Here's how simple it is to create a payment request: 'city': 'London', 'country': 'GB', } + payment_data = { 'amount': 3300, 'currency': 'EUR', @@ -94,6 +97,7 @@ Here's how simple it is to create a payment request: 'customer_id': 42710, }, } + payment = payplug.Payment.create(**payment_data) Go further: From b34de446d48a12add25b0cb00ed7ad6d091d3751 Mon Sep 17 00:00:00 2001 From: Florian Richard Date: Mon, 10 May 2021 17:56:33 +0200 Subject: [PATCH 3/8] add InstallmentPlan class, resource and tests --- payplug/__init__.py | 43 +++++++ payplug/resources.py | 29 +++++ payplug/routes.py | 1 + .../test_init/test_dao_installment_plans.py | 29 +++++ .../test_resources/test_installment_plans.py | 109 ++++++++++++++++++ 5 files changed, 211 insertions(+) create mode 100644 payplug/test/test_init/test_dao_installment_plans.py create mode 100644 payplug/test/test_resources/test_installment_plans.py diff --git a/payplug/__init__.py b/payplug/__init__.py index d2b64b9..6faedae 100644 --- a/payplug/__init__.py +++ b/payplug/__init__.py @@ -416,3 +416,46 @@ def get_simulation(**data): http_client = HttpClient() response, _ = http_client.post(routes.url(routes.ONEY_PAYMENT_SIMULATION), data) return resources.OneyPaymentSimulation(**response) + + +class InstallmentPlan: + """ + A DAO for resources.InstallmentPlans which provides a way to query installment plans. + """ + @staticmethod + def create(**data): + """ + Create an installment plan. + + :param data: data required to create an installment plan + + :return: The installment plan + :rtype resources.InstallmentPlan + """ + http_client = HttpClient() + response, _ = http_client.post(routes.url(routes.INSTALLMENT_PLANS), data) + return resources.InstallmentPlan(**response) + + @staticmethod + def update(installment_plan, **data): + + if isinstance(installment_plan, resources.InstallmentPlan): + installment_plan = installment_plan.id + + http_client = HttpClient() + response, _ = http_client.patch(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan), data) + return resources.InstallmentPlan(**response) + + @staticmethod + def get(installment_plan_id): + """ + Get an installment plan. + + :param data: data required to get an installment plan + + :return: The installment plan + :rtype resources.InstallmentPlan + """ + http_client = HttpClient() + response, _ = http_client.get(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan_id)) + return resources.InstallmentPlan(**response) diff --git a/payplug/resources.py b/payplug/resources.py index 81706a2..8615fdd 100644 --- a/payplug/resources.py +++ b/payplug/resources.py @@ -391,3 +391,32 @@ class Operation(APIResource): An operation. """ pass + + +class InstallmentPlan(APIResource): + """ + An InstallmentPlans Resource + """ + object_type = 'intallment_plan' + + """ + Create an InstallmentPlan + + :param data: the data to create the installment plan + """ + def create(self, **data): + return payplug.InstallmentPlans.create_installment_plan_endpoint(data) + + """ + Update an InstallmentPlan + + :param data: the data needed to update the installment plan + """ + def update(self, **data): + return payplug.InstallmentPlans.update_installment_plan_endpoint(self, data) + + """ + Get an InstallmentPlan + """ + def get(self): + return payplug.InstallmentPlans.get_installment_plan_endpoint(self) \ No newline at end of file diff --git a/payplug/routes.py b/payplug/routes.py index 60fe7e1..562c27b 100644 --- a/payplug/routes.py +++ b/payplug/routes.py @@ -8,6 +8,7 @@ CARD_RESOURCE = CUSTOMER_RESOURCE + '/{customer_id}/cards' ACCOUNTING_REPORT_RESOURCE = '/accounting_reports' ONEY_PAYMENT_SIMULATION = '/oney_payment_simulations' +INSTALLMENT_PLANS = '/installment_plans' # API base url API_BASE_URL = 'https://api.payplug.com' diff --git a/payplug/test/test_init/test_dao_installment_plans.py b/payplug/test/test_init/test_dao_installment_plans.py new file mode 100644 index 0000000..4bacc22 --- /dev/null +++ b/payplug/test/test_init/test_dao_installment_plans.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from mock import patch +import payplug +from payplug import resources +from payplug.test import TestBase + +@patch('payplug.config.secret_key', 'a_secret_key') +@patch.object(payplug.HttpClient, 'post', lambda *args, **kwargs: ({"some":"installment_plan", "da":"ta"}, 201)) +@patch.object(payplug.HttpClient, 'patch', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 200)) +@patch.object(payplug.HttpClient, 'get', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 200)) +class TestInstallmentPlanRetrieve(TestBase): + def test_get(self): + installment_plan = payplug.InstallmentPlan.get('installment_plan_id') + + assert isinstance(installment_plan, resources.InstallmentPlan) + assert installment_plan.id == 'installment_plan_id' + + def test_update(self): + installment_plan = payplug.InstallmentPlan.get('installment_plan_id') + installment_plan = payplug.InstallmentPlan.update(installment_plan) + + assert isinstance(installment_plan, resources.InstallmentPlan) + assert installment_plan.id == 'installment_plan_id' + + def test_create(self): + installment_plan = payplug.InstallmentPlan.create() + + assert isinstance(installment_plan, resources.InstallmentPlan) + assert installment_plan.some == 'installment_plan' \ No newline at end of file diff --git a/payplug/test/test_resources/test_installment_plans.py b/payplug/test/test_resources/test_installment_plans.py new file mode 100644 index 0000000..38b9dfb --- /dev/null +++ b/payplug/test/test_resources/test_installment_plans.py @@ -0,0 +1,109 @@ +from payplug.resources import InstallmentPlan +from payplug.test import TestBase + + +class TestInstallmentPlansResource(TestBase): + def test_initializer_installment_plans(self): + + null = None + true = True + false = False + + installment_plan_attributes = { + "id": "inst_1FTGSRWYHla7eDkfTo2Usd", + "object": "installment_plan", + "is_live": true, + "is_active": true, + "currency": "EUR", + "created_at": 1548326773, + "is_fully_paid": false, + "billing": { + "title": "mr", + "first_name": "John", + "last_name": "Watson", + "email": "john.watson@example.net", + "mobile_phone_number": null, + "landline_phone_number": null, + "address1": "221B Baker Street", + "address2": null, + "postcode": "NW16XE", + "city": "London", + "state": null, + "country": "GB", + "language": "en", + }, + "shipping": { + "title": "mr", + "first_name": "John", + "last_name": "Watson", + "email": "john.watson@example.net", + "mobile_phone_number": null, + "landline_phone_number": null, + "address1": "221B Baker Street", + "address2": null, + "postcode": "NW16XE", + "city": "London", + "state": null, + "country": "GB", + "language": "en", + "delivery_type": "BILLING", + }, + "hosted_payment": { + "payment_url": "https://secure.payplug.com/pay/1FTGSRWYHla7eDkfTo2Usd", + "return_url": "https://example.net/success?id=42", + "cancel_url": "https://example.net/cancel?id=42", + }, + "notification": {"url": "https://example.net/notifications?id=42"}, + "schedule": [ + { + "date": "2019-01-24", + "amount": 15000, + "payment_ids": ["pay_62VazeAbq5ttYietdC2QxR"], + }, + { + "date": "2019-02-24", + "amount": 15000, + "payment_ids": ["pay_12uazeAbq5ttYietdC2QxP"], + }, + {"date": "2019-03-24", "amount": 10000, "payment_ids": []}, + ], + "failure": null, + "metadata": {"customer_id": 42}, + } + + installment_plan_object = InstallmentPlan(**installment_plan_attributes) + + assert isinstance(installment_plan_object, InstallmentPlan) + assert installment_plan_object.created_at == 1548326773 + assert installment_plan_object.currency == "EUR" + assert installment_plan_object.billing == { + "title": "mr", + "first_name": "John", + "last_name": "Watson", + "email": "john.watson@example.net", + "mobile_phone_number": null, + "landline_phone_number": null, + "address1": "221B Baker Street", + "address2": null, + "postcode": "NW16XE", + "city": "London", + "state": null, + "country": "GB", + "language": "en", + } + assert installment_plan_object.shipping == { + "title": "mr", + "first_name": "John", + "last_name": "Watson", + "email": "john.watson@example.net", + "mobile_phone_number": null, + "landline_phone_number": null, + "address1": "221B Baker Street", + "address2": null, + "postcode": "NW16XE", + "city": "London", + "state": null, + "country": "GB", + "language": "en", + "delivery_type": "BILLING", + } From 88c1ae84bc7bb3f9be755d9ab4e866d81db677e2 Mon Sep 17 00:00:00 2001 From: Florian Richard Date: Tue, 18 May 2021 11:22:29 +0200 Subject: [PATCH 4/8] fix consistent resource --- payplug/__init__.py | 36 ++++--------------- payplug/resources.py | 33 ++++++----------- .../test_init/test_dao_installment_plans.py | 21 ++--------- 3 files changed, 21 insertions(+), 69 deletions(-) diff --git a/payplug/__init__.py b/payplug/__init__.py index 6faedae..bd27d59 100644 --- a/payplug/__init__.py +++ b/payplug/__init__.py @@ -422,40 +422,18 @@ class InstallmentPlan: """ A DAO for resources.InstallmentPlans which provides a way to query installment plans. """ - @staticmethod - def create(**data): - """ - Create an installment plan. - - :param data: data required to create an installment plan - - :return: The installment plan - :rtype resources.InstallmentPlan - """ - http_client = HttpClient() - response, _ = http_client.post(routes.url(routes.INSTALLMENT_PLANS), data) - return resources.InstallmentPlan(**response) - - @staticmethod - def update(installment_plan, **data): - - if isinstance(installment_plan, resources.InstallmentPlan): - installment_plan = installment_plan.id - - http_client = HttpClient() - response, _ = http_client.patch(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan), data) - return resources.InstallmentPlan(**response) @staticmethod - def get(installment_plan_id): + def retrieve(installment_plan_id): """ - Get an installment plan. + Retrieve an installment plan from its id. - :param data: data required to get an installment plan + :param installment_plan_id: The installment plan id + :type installment_plan_id: string - :return: The installment plan - :rtype resources.InstallmentPlan + :return: The installment plan resource + :rtype: resources.InstallmentPlan """ http_client = HttpClient() - response, _ = http_client.get(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan_id)) + response, __ = http_client.get(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan_id)) return resources.InstallmentPlan(**response) diff --git a/payplug/resources.py b/payplug/resources.py index 8615fdd..050c39e 100644 --- a/payplug/resources.py +++ b/payplug/resources.py @@ -393,30 +393,19 @@ class Operation(APIResource): pass -class InstallmentPlan(APIResource): +class InstallmentPlan(APIResource, VerifiableAPIResource, ReconstituableAPIResource): """ An InstallmentPlans Resource """ object_type = 'intallment_plan' - """ - Create an InstallmentPlan - - :param data: the data to create the installment plan - """ - def create(self, **data): - return payplug.InstallmentPlans.create_installment_plan_endpoint(data) - - """ - Update an InstallmentPlan - - :param data: the data needed to update the installment plan - """ - def update(self, **data): - return payplug.InstallmentPlans.update_installment_plan_endpoint(self, data) - - """ - Get an InstallmentPlan - """ - def get(self): - return payplug.InstallmentPlans.get_installment_plan_endpoint(self) \ No newline at end of file + def get_consistent_resource(self): + """ + :return an Installment Plan that you can trust. + :rtype InstallmentPlan + """ + http_client = HttpClient() + response, _ = http_client.get( + routes.url(routes.INSTALLMENT_PLANS, resource_id=self.id) + ) + return InstallmentPlan(**response) \ No newline at end of file diff --git a/payplug/test/test_init/test_dao_installment_plans.py b/payplug/test/test_init/test_dao_installment_plans.py index 4bacc22..9715d12 100644 --- a/payplug/test/test_init/test_dao_installment_plans.py +++ b/payplug/test/test_init/test_dao_installment_plans.py @@ -5,25 +5,10 @@ from payplug.test import TestBase @patch('payplug.config.secret_key', 'a_secret_key') -@patch.object(payplug.HttpClient, 'post', lambda *args, **kwargs: ({"some":"installment_plan", "da":"ta"}, 201)) -@patch.object(payplug.HttpClient, 'patch', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 200)) @patch.object(payplug.HttpClient, 'get', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 200)) class TestInstallmentPlanRetrieve(TestBase): - def test_get(self): - installment_plan = payplug.InstallmentPlan.get('installment_plan_id') + def test_retrieve(self): + installment_plan = payplug.InstallmentPlan.retrieve('installment_plan_id') assert isinstance(installment_plan, resources.InstallmentPlan) - assert installment_plan.id == 'installment_plan_id' - - def test_update(self): - installment_plan = payplug.InstallmentPlan.get('installment_plan_id') - installment_plan = payplug.InstallmentPlan.update(installment_plan) - - assert isinstance(installment_plan, resources.InstallmentPlan) - assert installment_plan.id == 'installment_plan_id' - - def test_create(self): - installment_plan = payplug.InstallmentPlan.create() - - assert isinstance(installment_plan, resources.InstallmentPlan) - assert installment_plan.some == 'installment_plan' \ No newline at end of file + assert installment_plan.id == 'installment_plan_id' \ No newline at end of file From 5dadbf4026dc1ae833400f500ec523e4c23515cb Mon Sep 17 00:00:00 2001 From: Florian Richard Date: Wed, 9 Jun 2021 18:46:03 +0200 Subject: [PATCH 5/8] add abort and create methods and tests --- payplug/__init__.py | 31 ++++++++++++++++++- .../test_init/test_dao_installment_plans.py | 21 ++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/payplug/__init__.py b/payplug/__init__.py index bd27d59..1ee40dd 100644 --- a/payplug/__init__.py +++ b/payplug/__init__.py @@ -420,7 +420,7 @@ def get_simulation(**data): class InstallmentPlan: """ - A DAO for resources.InstallmentPlans which provides a way to query installment plans. + A DAO for resources.InstallmentPlan which provides a way to query installment plans. """ @staticmethod @@ -437,3 +437,32 @@ def retrieve(installment_plan_id): http_client = HttpClient() response, __ = http_client.get(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan_id)) return resources.InstallmentPlan(**response) + + + @staticmethod + def create(**data): + """ + Create an installment plan. + :param data: data required to create an installment plan + :return: The installment plan + :rtype resources.InstallmentPlan + """ + http_client = HttpClient() + response, _ = http_client.post(routes.url(routes.INSTALLMENT_PLANS), data) + return resources.InstallmentPlan(**response) + + + @staticmethod + def abort(installment_plan_id): + """ + Abort an installment plan. + :param installment_plan_id: The installment plan id + :type installment_plan_id: string + + :return: The installment plan + :rtype resources.InstallmentPlan + """ + abort = {"aborted": True} + http_client = HttpClient() + response, _ = http_client.patch(routes.url(routes.INSTALLMENT_PLANS, resource_id=installment_plan_id), abort) + return resources.InstallmentPlan(**response) diff --git a/payplug/test/test_init/test_dao_installment_plans.py b/payplug/test/test_init/test_dao_installment_plans.py index 9715d12..f38742b 100644 --- a/payplug/test/test_init/test_dao_installment_plans.py +++ b/payplug/test/test_init/test_dao_installment_plans.py @@ -6,9 +6,28 @@ @patch('payplug.config.secret_key', 'a_secret_key') @patch.object(payplug.HttpClient, 'get', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 200)) +@patch.object(payplug.HttpClient, 'patch', lambda *args, **kwargs: ({'id': 'installment_plan_id', 'failure': {'code': 'aborted'}}, 204)) +@patch.object(payplug.HttpClient, 'post', lambda *args, **kwargs: ({'id': 'installment_plan_id'}, 201)) class TestInstallmentPlanRetrieve(TestBase): def test_retrieve(self): installment_plan = payplug.InstallmentPlan.retrieve('installment_plan_id') assert isinstance(installment_plan, resources.InstallmentPlan) - assert installment_plan.id == 'installment_plan_id' \ No newline at end of file + assert installment_plan.id == 'installment_plan_id' + + + def test_update(self): + installment_plan = payplug.InstallmentPlan.retrieve('installment_plan_id') + installment_plan = payplug.InstallmentPlan.abort(installment_plan) + + assert isinstance(installment_plan, resources.InstallmentPlan) + assert installment_plan.id == 'installment_plan_id' + assert installment_plan.failure['code'] == 'aborted' + + + def test_create(self): + installment_plan = payplug.InstallmentPlan.create() + + assert isinstance(installment_plan, resources.InstallmentPlan) + assert installment_plan.id == 'installment_plan_id' + \ No newline at end of file From c4b440774d649c916c98df7fc17032b094341a03 Mon Sep 17 00:00:00 2001 From: Philippe L'ATTENTION Date: Tue, 31 Aug 2021 09:22:06 +0400 Subject: [PATCH 6/8] [IMP] InstallmentPlans api resource - Fix object name "intallment_plan" - Refactor mapper InstallmentPlan data to have APIResource object like Payment - Adding Schedule APIResource and initializer to map list to list of Schedule(s) - Add tests notifications treat - Fix tests to use new APIResource objects - Bump version --- payplug/__version__.py | 2 +- payplug/resources.py | 39 ++++++- .../test_init/test_dao_installment_plans.py | 3 +- payplug/test/test_notifications.py | 108 ++++++++++++++++++ .../test_resources/test_installment_plans.py | 81 +++++++------ 5 files changed, 194 insertions(+), 39 deletions(-) diff --git a/payplug/__version__.py b/payplug/__version__.py index cf0bccd..b795e2c 100644 --- a/payplug/__version__.py +++ b/payplug/__version__.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -__version__ = '1.4.0' +__version__ = '1.4.1' diff --git a/payplug/resources.py b/payplug/resources.py index 050c39e..98842fc 100644 --- a/payplug/resources.py +++ b/payplug/resources.py @@ -397,7 +397,36 @@ class InstallmentPlan(APIResource, VerifiableAPIResource, ReconstituableAPIResou """ An InstallmentPlans Resource """ - object_type = 'intallment_plan' + object_type = 'installment_plan' + + @property + def _mapper(self): + """ + Maps payment attributes to their specific types. + + :see :func:`~APIResource._mapper` + """ + return { + 'hosted_payment': Payment.HostedPayment, + 'notification': Payment.Notification, + 'failure': Payment.Failure, + 'billing': Payment.Billing, + 'shipping': Payment.Shipping, + } + + def _initialize(self, **resource_attributes): + """ + Initialize a resource. + Default behavior is just to set all the attributes. You may want to override this. + + :param resource_attributes: The resource attributes + """ + + schedules = [] + for schedule in resource_attributes.get('schedule', []): + schedules.append(InstallmentPlan.Schedule(**schedule)) + resource_attributes["schedule"] = schedules + super(InstallmentPlan, self)._initialize(**resource_attributes) def get_consistent_resource(self): """ @@ -408,4 +437,10 @@ def get_consistent_resource(self): response, _ = http_client.get( routes.url(routes.INSTALLMENT_PLANS, resource_id=self.id) ) - return InstallmentPlan(**response) \ No newline at end of file + return InstallmentPlan(**response) + + class Schedule(APIResource): + """ + Schedule information + """ + pass diff --git a/payplug/test/test_init/test_dao_installment_plans.py b/payplug/test/test_init/test_dao_installment_plans.py index f38742b..7846d8c 100644 --- a/payplug/test/test_init/test_dao_installment_plans.py +++ b/payplug/test/test_init/test_dao_installment_plans.py @@ -22,7 +22,7 @@ def test_update(self): assert isinstance(installment_plan, resources.InstallmentPlan) assert installment_plan.id == 'installment_plan_id' - assert installment_plan.failure['code'] == 'aborted' + assert installment_plan.failure.code == 'aborted' def test_create(self): @@ -30,4 +30,3 @@ def test_create(self): assert isinstance(installment_plan, resources.InstallmentPlan) assert installment_plan.id == 'installment_plan_id' - \ No newline at end of file diff --git a/payplug/test/test_notifications.py b/payplug/test/test_notifications.py index 475e0c8..0227e3c 100644 --- a/payplug/test/test_notifications.py +++ b/payplug/test/test_notifications.py @@ -56,3 +56,111 @@ def test_treat_payment(self): def test_treat_binary_string(self): safe_payment = notifications.treat(b'{"id": "pay_test_unsafe", "object": "payment"}') assert safe_payment.id == 'pay_test' + + +@patch('payplug.config.secret_key', 'a_secret_key') +class TestTreatNotificationsInstallmentPlanSuccess(TestBase): + @classmethod + def setup_class(cls): + api_response = { + "hosted_payment": { + "cancel_url": "https://example.com/payment/payplug/cancel", + "return_url": "https://example.com/shop/payment/validate", + "payment_url": "https://secure.payplug.com/pay/test/59TXrYROSdmt0Y7W9Ubpg8" + }, + "customer": { + "phone_number": "None", + "city": "PARIS", + "first_name": "JOHN", + "last_name": "DOE", + "language": "fr", + "address1": "21 Elm Street", + "address2": "None", + "postcode": "75018", + "country": "France", + "email": "johndoe@example.com", + }, + "schedule": [ + {"date": "2021-08-04", "amount": 2600, "payment_ids": ["pay_59TXrYROSdmt0Y7W9Ubpg8"]}, + {"date": "2021-09-04", "amount": 2600, "payment_ids": []}, + {"date": "2021-10-04", "amount": 2600, "payment_ids": []}, + ], + "notification": {"url": "https://example.com/payment/payplug/ipn"}, + "created_at": 1628079236, + "object": "installment_plan", + "is_active": True, + "currency": "EUR", + "is_live": False, + "is_fully_paid": False, + "id": "inst_2aSCmLRZFtAA7arHJfGrE1", + "failure": "None", + "metadata": {"customer_id": "23", "acquirer_id": 5, "reference": "CMD0000123"}, + } + cls.patcher_get = patch.object(payplug.resources.HttpClient, 'get', return_value=(api_response, 200)) + cls.patcher_get.start() + + @classmethod + def teardown_class(cls): + cls.patcher_get.stop() + + def test_treat_installment_plan(self): + json_data = '''{ + "hosted_payment":{ + "cancel_url":"https://example.com/payment/payplug/cancel", + "return_url":"https://example.com/shop/payment/validate", + "payment_url":"https://secure.payplug.com/pay/test/59TXrYROSdmt0Y7W9Ubpg8" + }, + "customer":{ + "phone_number":"None", + "city":"PARIS", + "first_name":"JOHN", + "last_name":"DOE", + "language":"fr", + "address1":"21 Elm Street", + "address2":"None", + "postcode":"75018", + "country":"France", + "email":"johndoe@example.com" + }, + "schedule":[ + { + "date":"2021-08-04", + "amount":2600, + "payment_ids":[ + "pay_59TXrYROSdmt0Y7W9Ubpg8" + ] + }, + { + "date":"2021-09-04", + "amount":2600, + "payment_ids":[ + + ] + }, + { + "date":"2021-10-04", + "amount":2600, + "payment_ids":[ + + ] + } + ], + "notification":{ + "url":"https://example.com/payment/payplug/ipn" + }, + "created_at":1628079236, + "object":"installment_plan", + "is_active":true, + "currency":"EUR", + "is_live":false, + "is_fully_paid":false, + "id":"inst_2aSCmLRZFtAA7arHJfGrE1", + "failure":"None", + "metadata":{ + "customer_id":"23", + "acquirer_id":5, + "reference":"CMD0000123" + } + }''' + safe_installment_plan = notifications.treat(json_data) + assert safe_installment_plan.id == 'inst_2aSCmLRZFtAA7arHJfGrE1' diff --git a/payplug/test/test_resources/test_installment_plans.py b/payplug/test/test_resources/test_installment_plans.py index 38b9dfb..e13b080 100644 --- a/payplug/test/test_resources/test_installment_plans.py +++ b/payplug/test/test_resources/test_installment_plans.py @@ -1,4 +1,5 @@ -from payplug.resources import InstallmentPlan +# -*- coding: utf-8 -*- +from payplug.resources import InstallmentPlan, Payment from payplug.test import TestBase @@ -67,43 +68,55 @@ def test_initializer_installment_plans(self): }, {"date": "2019-03-24", "amount": 10000, "payment_ids": []}, ], - "failure": null, + "failure": { + "code": "a_failure_code", + "message": 'A weird failure message ®±' + }, "metadata": {"customer_id": 42}, } installment_plan_object = InstallmentPlan(**installment_plan_attributes) - + assert isinstance(installment_plan_object, InstallmentPlan) assert installment_plan_object.created_at == 1548326773 assert installment_plan_object.currency == "EUR" - assert installment_plan_object.billing == { - "title": "mr", - "first_name": "John", - "last_name": "Watson", - "email": "john.watson@example.net", - "mobile_phone_number": null, - "landline_phone_number": null, - "address1": "221B Baker Street", - "address2": null, - "postcode": "NW16XE", - "city": "London", - "state": null, - "country": "GB", - "language": "en", - } - assert installment_plan_object.shipping == { - "title": "mr", - "first_name": "John", - "last_name": "Watson", - "email": "john.watson@example.net", - "mobile_phone_number": null, - "landline_phone_number": null, - "address1": "221B Baker Street", - "address2": null, - "postcode": "NW16XE", - "city": "London", - "state": null, - "country": "GB", - "language": "en", - "delivery_type": "BILLING", - } + assert installment_plan_object.is_fully_paid == False + + assert type(installment_plan_object.billing) == Payment.Billing + assert installment_plan_object.billing.title == 'mr' + assert installment_plan_object.billing.first_name == "John" + assert installment_plan_object.billing.last_name == "Watson" + assert installment_plan_object.billing.email == "john.watson@example.net" + assert installment_plan_object.billing.address1 == '221B Baker Street' + assert installment_plan_object.billing.postcode == 'NW16XE' + assert installment_plan_object.billing.city == 'London' + assert installment_plan_object.billing.country == 'GB' + assert installment_plan_object.billing.language == 'en' + + assert type(installment_plan_object.shipping) == Payment.Shipping + assert installment_plan_object.shipping.title == 'mr' + assert installment_plan_object.shipping.first_name == "John" + assert installment_plan_object.shipping.last_name == "Watson" + assert installment_plan_object.shipping.email == "john.watson@example.net" + assert installment_plan_object.shipping.address1 == '221B Baker Street' + assert installment_plan_object.shipping.postcode == 'NW16XE' + assert installment_plan_object.shipping.city == 'London' + assert installment_plan_object.shipping.country == 'GB' + assert installment_plan_object.shipping.language == 'en' + assert installment_plan_object.shipping.delivery_type == 'BILLING' + + assert type(installment_plan_object.hosted_payment) == Payment.HostedPayment + assert installment_plan_object.hosted_payment.payment_url == "https://secure.payplug.com/pay/1FTGSRWYHla7eDkfTo2Usd" + assert installment_plan_object.hosted_payment.return_url == "https://example.net/success?id=42" + assert installment_plan_object.hosted_payment.cancel_url == "https://example.net/cancel?id=42" + + + assert installment_plan_object.notification.url == "https://example.net/notifications?id=42" + assert type(installment_plan_object.schedule) == list + for schedule in installment_plan_object.schedule: + assert type(schedule) == InstallmentPlan.Schedule + assert type(schedule.date) == str + assert type(schedule.amount) == int + assert type(schedule.payment_ids) == list + for payment_id in schedule.payment_ids: + assert type(payment_id) == str \ No newline at end of file From 6d293bf32bd0009ea8df79d16aac1ae285204357 Mon Sep 17 00:00:00 2001 From: Florian Richard Date: Wed, 24 Nov 2021 15:51:28 +0100 Subject: [PATCH 7/8] typo --- payplug/test/test_init/test_dao_installment_plans.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payplug/test/test_init/test_dao_installment_plans.py b/payplug/test/test_init/test_dao_installment_plans.py index 7846d8c..c2038f0 100644 --- a/payplug/test/test_init/test_dao_installment_plans.py +++ b/payplug/test/test_init/test_dao_installment_plans.py @@ -18,7 +18,7 @@ def test_retrieve(self): def test_update(self): installment_plan = payplug.InstallmentPlan.retrieve('installment_plan_id') - installment_plan = payplug.InstallmentPlan.abort(installment_plan) + installment_plan = payplug.InstallmentPlan.abort(installment_plan.id) assert isinstance(installment_plan, resources.InstallmentPlan) assert installment_plan.id == 'installment_plan_id' From 9dab701dea165dbacfbd393091446495a52a0113 Mon Sep 17 00:00:00 2001 From: alopez-pp <63304175+alopez-pp@users.noreply.github.com> Date: Fri, 17 Feb 2023 15:20:51 +0100 Subject: [PATCH 8/8] Update README.rst --- README.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 8d9aef8..960eb47 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -Python library for the PayPlug API +Python library for the Payplug API ================================== .. image:: https://github.com/payplug/payplug-python/workflows/CI/badge.svg @@ -9,15 +9,15 @@ Python library for the PayPlug API :target: https://pypi.python.org/pypi/payplug/ :alt: PyPi -This is the documentation of PayPlug's Python library. It is designed to help developers to use PayPlug as +This is the documentation of Payplug's Python library. It is designed to help developers to use Payplug as payment solution in a simple, yet robust way. -You can create a PayPlug account at https://www.payplug.com. +You can create a Payplug account at https://www.payplug.com. Prerequisites ------------- -PayPlug's library relies on **python-requests>=1.0.1** to perform HTTP requests and requires **OpenSSL** to secure +Payplug's library relies on **python-requests>=1.0.1** to perform HTTP requests and requires **OpenSSL** to secure transactions. You also need either a **Python 2.6+** or a **Python 3.3+**. The library is known to work with these versions, pypy and pypy3. It may work on older versions or other Python implementations without warranty. If you use an implementation that is not listed above, do not hesitate to let us known if it worked for you or not, so that we can @@ -61,7 +61,7 @@ To get started, add the following piece of code to the header of your Python pro import payplug -If everything runs without errors, congratulations. You installed PayPlug python library! You're ready to create your +If everything runs without errors, congratulations. You installed Payplug python library! You're ready to create your first payment. Usage