Skip to content

Commit

Permalink
Add plan and subscription resources
Browse files Browse the repository at this point in the history
  • Loading branch information
gustav0 committed Sep 13, 2022
1 parent c65b2cd commit 10a937b
Show file tree
Hide file tree
Showing 6 changed files with 449 additions and 3 deletions.
8 changes: 6 additions & 2 deletions mercadopago/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,38 @@
from mercadopago.resources.advanced_payment import AdvancedPayment
from mercadopago.resources.card import Card
from mercadopago.resources.card_token import CardToken
from mercadopago.resources.chargeback import Chargeback
from mercadopago.resources.customer import Customer
from mercadopago.resources.disbursement_refund import DisbursementRefund
from mercadopago.resources.identification_type import IdentificationType
from mercadopago.resources.merchant_order import MerchantOrder
from mercadopago.resources.payment import Payment
from mercadopago.resources.payment_methods import PaymentMethods
from mercadopago.resources.plan import Plan
from mercadopago.resources.preapproval import PreApproval
from mercadopago.resources.preference import Preference
from mercadopago.resources.refund import Refund
from mercadopago.resources.subscription import Subscription
from mercadopago.resources.user import User
from mercadopago.resources.chargeback import Chargeback


__all__ = (
'AdvancedPayment',
'Card',
'CardToken',
'Chargeback',
'Customer',
'DisbursementRefund',
'HttpClient',
'IdentificationType',
'MerchantOrder',
'Payment',
'PaymentMethods',
'Plan',
'PreApproval',
'Preference',
'Refund',
'RequestOptions',
'Subscription',
'User',
'Chargeback',
)
84 changes: 84 additions & 0 deletions mercadopago/resources/plan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Module: plan
"""
from mercadopago.core import MPBase


class Plan(MPBase):
"""
This class provides the methods to access the API that will allow you to create, search, get and update Plans to be
used as templates for Subscriptions.
[Click here for more info](https://www.mercadopago.com.br/developers/en/docs/subscriptions/integration-configuration/subscriptions-associated-plan) # pylint: disable=line-too-long
"""

def search(self, filters=None, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_plan_search/get) # pylint: disable=line-too-long
Args:
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Returns:
dict: Plans found
"""
return self._get(uri="/preapproval_plan/search", filters=filters,
request_options=request_options)

def get(self, plan_id, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_plan_id/get) # pylint: disable=line-too-long
Args:
plan_id (str): The plan ID
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Returns:
dict: Plan found
"""
return self._get(uri="/preapproval_plan/" + str(plan_id), request_options=request_options)

def create(self, plan_object, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_plan/post) # pylint: disable=line-too-long
Args:
plan_object (dict): Plan to be created
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Raises:
ValueError: Param plan_object must be a Dictionary
Returns:
dict: Plan creation response
"""
if not isinstance(plan_object, dict):
raise ValueError("Param plan_object must be a Dictionary")

return self._post(uri="/preapproval_plan", data=plan_object,
request_options=request_options)

def update(self, plan_id, plan_object, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_plan_id/put) # pylint: disable=line-too-long
Args:
plan_id (str): The plan ID to be updated
plan_object (dict): Plan information to be updated
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Raises:
ValueError: Param plan_object must be a Dictionary
Returns:
dict: Plan modification response
"""
if not isinstance(plan_object, dict):
raise ValueError("Param plan_object must be a Dictionary")

return self._put(uri="/preapproval_plan/" + str(plan_id),
data=plan_object, request_options=request_options)
83 changes: 83 additions & 0 deletions mercadopago/resources/subscription.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
Module: subscriptions
"""
from mercadopago.core import MPBase


class Subscription(MPBase):
"""
This class provides the methods to access the API that will allow you to create, search, get and update
Subscriptions.
[Click here for more info](https://www.mercadopago.com.br/developers/en/docs/subscriptions/landing) # pylint: disable=line-too-long
"""

def search(self, filters=None, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/en/reference/subscriptions/_preapproval_search/get) # pylint: disable=line-too-long
Args:
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Returns:
dict: Subscriptions found
"""
return self._get(uri="/preapproval/search", filters=filters, request_options=request_options)

def get(self, subscription_id, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_id/get) # pylint: disable=line-too-long
Args:
subscription_id (str): The subscription ID
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Returns:
dict: Subscription found
"""
return self._get(uri="/preapproval/" + str(subscription_id), request_options=request_options)

def create(self, subscription_object, request_options=None):
"""[Click here for more info](https://www.mercadopago.com/developers/en/reference/payments/_payments/post/) # pylint: disable=line-too-long
Args:
subscription_object (dict): Subscription to be created
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Raises:
ValueError: Param payment_object must be a Dictionary
Returns:
dict: Subscription creation response
"""
if not isinstance(subscription_object, dict):
raise ValueError("Param subscription_object must be a Dictionary")

return self._post(uri="/preapproval", data=subscription_object, request_options=request_options)

def update(self, subscription_id, subscription_object, request_options=None):
"""[Click here for more info](https://www.mercadopago.com.co/developers/es/reference/subscriptions/_preapproval_id/put) # pylint: disable=line-too-long
Args:
subscription_id (str): The subscription ID to be updated
subscription_object (dict): Subscription information to be updated
request_options (mercadopago.config.request_options, optional): An instance of
RequestOptions can be pass changing or adding custom options to ur REST call.
Defaults to None.
Raises:
ValueError: Param subscription_object must be a Dictionary
Returns:
dict: Subscription modification response
"""
if not isinstance(subscription_object, dict):
raise ValueError("Param subscription_object must be a Dictionary")

return self._put(
uri="/preapproval_plan/" + str(subscription_id), data=subscription_object, request_options=request_options
)
20 changes: 19 additions & 1 deletion mercadopago/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@
AdvancedPayment,
Card,
CardToken,
Chargeback,
Customer,
DisbursementRefund,
IdentificationType,
MerchantOrder,
Payment,
PaymentMethods,
Plan,
PreApproval,
Preference,
Refund,
Subscription,
User,
Chargeback,
)


Expand All @@ -38,6 +40,8 @@ class SDK:
12. Refund
13. User
14. Chargeback
15. Subscription
16. Plan
"""

def __init__(
Expand Down Expand Up @@ -166,6 +170,20 @@ def chargeback(self, request_options=None):
return Chargeback(request_options is not None and request_options
or self.request_options, self.http_client)

def subscription(self, request_options=None):
"""
Returns the attribute value of the function
"""
return Subscription(request_options is not None and request_options
or self.request_options, self.http_client)

def plan(self, request_options=None):
"""
Returns the attribute value of the function
"""
return Plan(request_options is not None and request_options
or self.request_options, self.http_client)

@property
def request_options(self):
"""
Expand Down
84 changes: 84 additions & 0 deletions tests/test_plan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Module: test_plan
"""
import unittest

import mercadopago
import random


class TestPlan(unittest.TestCase):
"""
Test Module: Preference
"""

sdk = mercadopago.SDK(
"APP_USR-558881221729581-091712-44fdc612e60e3e638775d8b4003edd51-471763966")

def test_all(self):
"""
Test Module: Plan
"""
random_reason_number = random.randint(100000, 999999)
plan_object_all_options_payload = {
"auto_recurring": {
"frequency": 1,
"frequency_type": "months",
"repetitions": 12,
"billing_day": 5,
"free_trial": {
"frequency": 2,
"frequency_type": "days"
},
"transaction_amount": 60,
"currency_id": "BRL",
},
"back_url": "https://www.mercadopago.com.co/subscriptions",
"reason": f"Test Plan #{random_reason_number}",
}
plan_object_mandatory_options_payload = {
"auto_recurring": {
"frequency": 1,
"frequency_type": "months",
"transaction_amount": 60,
"currency_id": "BRL",
},
"back_url": "https://www.mercadopago.com.co/subscriptions",
"reason": f"Test Plan (mandatory) #{random_reason_number}",
}

plan_response = self.sdk.plan().create(plan_object_all_options_payload)
self.assertEqual(plan_response["status"], 201)

plan_object = plan_response["response"]
self.assertEqual(plan_object["status"], "active")

# Validate it works with minimal required options
plan_mandatory_options = self.sdk.plan().create(
plan_object_mandatory_options_payload)
self.assertEqual(plan_mandatory_options["status"], 201)
self.assertEqual(
plan_mandatory_options["response"]["status"], "active")

plan_object["reason"] = "MercadoPago API Test"
update_response = self.sdk.plan().update(
plan_object["id"], plan_object)
self.assertEqual(update_response["status"], 200)
update_object = update_response["response"]
self.assertEqual(update_object["reason"], plan_object["reason"])
self.assertEqual(update_object["status"], "active")

get_response = self.sdk.plan().get(plan_object["id"])
self.assertEqual(get_response["status"], 200)
get_object = get_response["response"]
self.assertEqual(get_object["id"], plan_object["id"])

search_response = self.sdk.plan().search()
self.assertEqual(search_response["status"], 200)
search_object = search_response["response"]
self.assertTrue("results" in search_object)
self.assertTrue(isinstance(search_object["results"], list))


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit 10a937b

Please sign in to comment.