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: 1 addition & 1 deletion payplug/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# -*- coding: utf-8 -*-
__version__ = '1.4.0'
__version__ = '1.4.1'
39 changes: 37 additions & 2 deletions payplug/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand All @@ -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)
return InstallmentPlan(**response)

class Schedule(APIResource):
"""
Schedule information
"""
pass
3 changes: 1 addition & 2 deletions payplug/test/test_init/test_dao_installment_plans.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ 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):
installment_plan = payplug.InstallmentPlan.create()

assert isinstance(installment_plan, resources.InstallmentPlan)
assert installment_plan.id == 'installment_plan_id'

108 changes: 108 additions & 0 deletions payplug/test/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
81 changes: 47 additions & 34 deletions payplug/test/test_resources/test_installment_plans.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from payplug.resources import InstallmentPlan
# -*- coding: utf-8 -*-
from payplug.resources import InstallmentPlan, Payment
from payplug.test import TestBase


Expand Down Expand Up @@ -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