From 60ec06e6ffb1c16a4677da4938138a644159c1ea Mon Sep 17 00:00:00 2001 From: renanneri01 Date: Mon, 27 Jan 2025 10:05:59 -0300 Subject: [PATCH 01/11] [Feature] Initial implementation of the creation order (#1) * Initial implementation of the creation order * Adjust reference devsite --- .pre-commit-config.yaml | 16 +++++++++ mercadopago/resources/__init__.py | 2 ++ mercadopago/resources/order.py | 35 ++++++++++++++++++ mercadopago/sdk.py | 27 +++++++++----- tests/test_order.py | 60 +++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 mercadopago/resources/order.py create mode 100644 tests/test_order.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9f72a15 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +repos: + - repo: https://github.com/melisource/fury_websec-git-hooks + rev: v2.0.0 + hooks: + - id: pre_commit_hook + stages: [commit] + - id: post_commit_hook + stages: [post-commit] + + - repo: https://github.com/melisource/fury_datasec-git-hooks + rev: 1.2.2 + hooks: + - id: pre_commit_hook + stages: [commit] + - id: post_commit_hook + stages: [post-commit] diff --git a/mercadopago/resources/__init__.py b/mercadopago/resources/__init__.py index ac555f8..407b471 100644 --- a/mercadopago/resources/__init__.py +++ b/mercadopago/resources/__init__.py @@ -11,6 +11,7 @@ from mercadopago.resources.disbursement_refund import DisbursementRefund from mercadopago.resources.identification_type import IdentificationType from mercadopago.resources.merchant_order import MerchantOrder +from mercadopago.resources.order import Order from mercadopago.resources.payment import Payment from mercadopago.resources.payment_methods import PaymentMethods from mercadopago.resources.plan import Plan @@ -31,6 +32,7 @@ 'HttpClient', 'IdentificationType', 'MerchantOrder', + 'Order', 'Payment', 'PaymentMethods', 'Plan', diff --git a/mercadopago/resources/order.py b/mercadopago/resources/order.py new file mode 100644 index 0000000..cfd370c --- /dev/null +++ b/mercadopago/resources/order.py @@ -0,0 +1,35 @@ +""" + Module: order +""" +from mercadopago.core import MPBase + + +class Order(MPBase): + """ + This class provides the methods to access the API that will allow you to create + your own order experience on your website. + + From basic to advanced configurations, you control the whole experience. + + [Click here for more info](https://www.mercadopago.com/developers/en/guides/online-payments/checkout-api/introduction/) # pylint: disable=line-too-long + """ + + def create(self, order_object, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/create/post/) # pylint: disable=line-too-long + + Args: + order_object (dict): Order 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 order_object must be a Dictionary + + Returns: + dict: Order creation response + """ + if not isinstance(order_object, dict): + raise ValueError("Param order_object must be a Dictionary") + + return self._post(uri="/v1/orders", data=order_object, request_options=request_options) diff --git a/mercadopago/sdk.py b/mercadopago/sdk.py index 0536b58..13afaeb 100644 --- a/mercadopago/sdk.py +++ b/mercadopago/sdk.py @@ -12,6 +12,7 @@ DisbursementRefund, IdentificationType, MerchantOrder, + Order, Payment, PaymentMethods, Plan, @@ -33,15 +34,16 @@ class SDK: 5. Disbursement Refund 6. Identification Type 7. Merchant Order - 8. Payment Methods - 9. Payment - 10. Preapproval - 11. Preference - 12. Refund - 13. User - 14. Chargeback - 15. Subscription - 16. Plan + 8. Order + 9. Payment Methods + 10. Payment + 11. Preapproval + 12. Preference + 13. Refund + 14. User + 15. Chargeback + 16. Subscription + 17. Plan """ def __init__( @@ -120,6 +122,13 @@ def merchant_order(self, request_options=None): """ return MerchantOrder(request_options is not None and request_options or self.request_options, self.http_client) + + def order(self, request_options=None): + """ + Returns the attribute value of the function + """ + return Order(request_options is not None and request_options + or self.request_options, self.http_client) def payment(self, request_options=None): """ diff --git a/tests/test_order.py b/tests/test_order.py new file mode 100644 index 0000000..dda7dee --- /dev/null +++ b/tests/test_order.py @@ -0,0 +1,60 @@ +""" + Module: test_order +""" +from datetime import datetime +import os +import unittest +import random +import mercadopago + + +class TestOrder(unittest.TestCase): + """ + Test Module: Order + """ + sdk = mercadopago.SDK(os.environ['ACCESS_TOKEN']) + + def test_create(self): + """ + Test Function: Order + """ + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2025", + "expiration_month": "11", + "cardholder": { + "name": "APRO" + } + } + + card_token_created = self.sdk.card_token().create(card_token_object) + random_email_id = random.randint(100000, 999999) + order_object = { + "type": "online", + "total_amount": "1000.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "1000.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_created["response"]["id"], + "installments": 12 + } + } + ] + }, + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + } + } + + order_created = self.sdk.order().create(order_object) + self.assertEqual(order_created["status"], 201) + self.assertEqual(order_created["response"]["status"], "processed") + +if __name__ == "__main__": + unittest.main() From 5d04786b590935e75e7e6c749fdf4ca4fe61ad15 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Mon, 10 Feb 2025 10:02:37 -0300 Subject: [PATCH 02/11] [Feature] Endpoints Order (#5) * create endpoint get and process by id * update * update order tests * fix process method * endpoint cancel and capture * fixes * updates * update link doc dev site * create endpoints create and update transaction * update * fix indentation * fix some tests * update testes * fix test * include sleep * create methods * update methods and tests * update delete * fixes * fix * Update mercadopago/resources/order.py Co-authored-by: renanneri01 --------- Co-authored-by: renanneri01 --- mercadopago/http/http_client.py | 14 +- mercadopago/resources/order.py | 176 ++++++++++++++++++++- tests/test_order.py | 269 ++++++++++++++++++++++++++++++-- 3 files changed, 440 insertions(+), 19 deletions(-) diff --git a/mercadopago/http/http_client.py b/mercadopago/http/http_client.py index 81d7040..6fe628f 100644 --- a/mercadopago/http/http_client.py +++ b/mercadopago/http/http_client.py @@ -24,12 +24,16 @@ def request(self, method, url, maxretries=None, **kwargs): http.mount("https://", HTTPAdapter(max_retries=retry_strategy)) with http as session: api_result = session.request(method, url, **kwargs) - response = { - "status": api_result.status_code, - "response": api_result.json() - } + response = {"status": api_result.status_code, "response": None} - return response + if api_result.status_code != 204 and api_result.content: + try: + response["response"] = api_result.json() + except ValueError as e: + print(f"Failed to parse JSON: {str(e)}") + response["response"] = None + + return response def get(self, url, headers, params=None, timeout=None, maxretries=None): # pylint: disable=too-many-arguments """Makes a GET request to the API""" diff --git a/mercadopago/resources/order.py b/mercadopago/resources/order.py index cfd370c..d21c4b4 100644 --- a/mercadopago/resources/order.py +++ b/mercadopago/resources/order.py @@ -3,7 +3,6 @@ """ from mercadopago.core import MPBase - class Order(MPBase): """ This class provides the methods to access the API that will allow you to create @@ -20,7 +19,7 @@ def create(self, order_object, request_options=None): Args: order_object (dict): Order 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. + RequestOptions can be pass changing or adding custom options to the REST call. Defaults to None. Raises: @@ -33,3 +32,176 @@ def create(self, order_object, request_options=None): raise ValueError("Param order_object must be a Dictionary") return self._post(uri="/v1/orders", data=order_object, request_options=request_options) + + def get(self, order_id, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/get-order/get ) # pylint: disable=line-too-long + + Args: + order_id (str): The Order ID + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + + Raises: + ValueError: Param order_id must be a string + + Returns: + dict: Order returned in the response to the request made for its creation. + """ + + if not isinstance(order_id, str): + raise ValueError("Param order_id must be a string") + + return self._get(uri="/v1/orders/" + str(order_id), request_options=request_options) + + def process(self, order_id, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online/process-order/post) # pylint: disable=line-too-long + Args: + order_id (str): ID of the order to be processed. This value is returned in the response to the Create order request. + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + + Raises: + ValueError: Param order_id must be a string + Returns: + dict: Order returned in the response to the request made for its creation. + """ + + if not isinstance(order_id, str): + raise ValueError("Param order_id must be a string") + + return self._post(uri="/v1/orders/" + str(order_id) + "/process", request_options=request_options) + + def cancel(self, order_id, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/cancel-order/post) # pylint: disable=line-too-long + Args: + order_id (str): Order ID + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + + Raises: + ValueError: Param order_id must be a string + + Returns: + dict: Order cancellation response + """ + if not isinstance(order_id, str): + raise ValueError("Param order_id must be a string") + + return self._post(uri="/v1/orders/" + str(order_id) + "/cancel", request_options=request_options) + + def capture(self, order_id, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/capture/post) # pylint: disable=line-too-long + Args: + order_id (str): ID of the order to be captured. This value is returned in the response to the Create order request. + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + Raises: + ValueError: Param order_id must be a string + Returns: + dict: Order returned in the response to the request made for its creation. + """ + + if not isinstance(order_id, str): + raise ValueError("Param order_id must be a string") + + return self._post(uri="/v1/orders/" + str(order_id) + "/capture", request_options=request_options) + + def create_transaction(self, order_id, transaction_object, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/add-transaction/post) # pylint: disable=line-too-long + + Args: + order_id (str): The ID of the order to which the transaction will be added + transaction_object (dict): Transaction to be added + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + + Raises: + ValueError: Param transaction_object must be a Dictionary + + Returns: + dict: Transaction created response + """ + if not isinstance(transaction_object, dict): + raise ValueError("Param transaction_object must be a Dictionary") + + response = self._post(uri=f"/v1/orders/{order_id}/transactions", data=transaction_object, + request_options=request_options) + if response.get("status") != 201: + raise Exception(f"Failed to add transaction: {response}") + return response + + def update_transaction(self, order_id, transaction_id, transaction_object, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/update-transaction/put) # pylint: disable=line-too-long + + Args: + order_id (str): The ID of the order to which the transaction belongs + transaction_id (str): The ID of the transaction to be updated + transaction_object (dict): Transaction details to be updated + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + + Raises: + ValueError: Param transaction_object must be a Dictionary + + Returns: + dict: Transaction update response + """ + if not isinstance(transaction_object, dict): + raise ValueError("Param transaction_object must be a Dictionary") + + response = self._put(uri=f"/v1/orders/{order_id}/transactions/{transaction_id}", data=transaction_object, + request_options=request_options) + if response.get("status") != 200: + raise Exception(f"Failed to update transaction: {response}") + return response + + def refund_transaction(self, order_id, transaction_object=None, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/refund/post) # pylint: disable=line-too-long + Args: + order_id (str): The ID of the order to which the transaction belongs + transaction_object (dict, optional): Transaction details to be updated + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + Raises: + ValueError: Param transaction_object must be a Dictionary + Returns: + dict: Order refunded response + """ + if transaction_object is not None and not isinstance(transaction_object, dict): + raise ValueError("Param transaction_object must be a Dictionary") + + response = self._post(uri=f"/v1/orders/{order_id}/refund", data=transaction_object, + request_options=request_options) + if response.get("status") != 201: + raise Exception(f"Failed to refund transaction: {response}") + return response + + def delete_transaction(self, order_id, transaction_id, request_options=None): + """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/delete-transaction/delete) # pylint: disable=line-too-long + Args: + order_id (str): The ID of the order to which the transaction belongs + transaction_id (str): The ID of the transaction to be deleted + request_options (mercadopago.config.request_options, optional): An instance of + RequestOptions can be pass changing or adding custom options to the REST call. + Defaults to None. + Raises: + ValueError: Params order_id and transaction_id must be strings + Returns: + Status 204 - No Content - if deleted successfully + """ + if not isinstance(order_id, str) or not isinstance(transaction_id, str): + raise ValueError("Params order_id and transaction_id must be strings") + + response = self._delete(uri=f"/v1/orders/{order_id}/transactions/{transaction_id}", + request_options=request_options) + + if response.get("status") != 204: + raise Exception(f"Failed to delete transaction: {response}") + return response \ No newline at end of file diff --git a/tests/test_order.py b/tests/test_order.py index dda7dee..d4bcd6e 100644 --- a/tests/test_order.py +++ b/tests/test_order.py @@ -1,10 +1,13 @@ """ Module: test_order """ -from datetime import datetime +import json import os +import time import unittest import random +from time import sleep + import mercadopago @@ -14,21 +17,132 @@ class TestOrder(unittest.TestCase): """ sdk = mercadopago.SDK(os.environ['ACCESS_TOKEN']) - def test_create(self): - """ - Test Function: Order - """ + def create_test_card(self, status="APRO"): card_token_object = { "card_number": "5031433215406351", "security_code": "123", - "expiration_year": "2025", + "expiration_year": "2030", "expiration_month": "11", - "cardholder": { - "name": "APRO" + "cardholder": {"name": status} + } + card_token_created = self.sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + def create_order_canceled_or_captured(self, card_token_id): + random_email_id = random.randint(100000, 999999) + order_object_cc = { + "type": "online", + "processing_mode": "automatic", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + }, + "capture_mode": "manual", + "transactions": { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 1 + } + } + ] } } + order_created = self.sdk.order().create(order_object_cc) + if order_created.get("status") != 201 or not order_created.get("response"): + self.fail(f"Failed to create order: {order_created}") + return order_created["response"]["id"] - card_token_created = self.sdk.card_token().create(card_token_object) + def create_order_builder_mode(self, card_token_id): + random_email_id = random.randint(100000, 999999) + order_object_cc = { + "type": "online", + "processing_mode": "manual", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + }, + } + order_created = self.sdk.order().create(order_object_cc) + if order_created.get("status") != 201 or not order_created.get("response"): + self.fail(f"Failed to create order: {order_created}") + return order_created["response"]["id"] + + def create_order_oneshot_mode_complete(self, card_token_id): + random_email_id = random.randint(100000, 999999) + order_mode_oneshot_complete = { + "type": "online", + "processing_mode": "automatic", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 1 + } + } + ] + }, + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + } + } + + order_created = self.sdk.order().create(order_mode_oneshot_complete) + + + if order_created.get("status") != 201 or not order_created.get("response"): + self.fail(f"Failed to create order: {order_created}") + return order_created["response"] + + def create_order_builder_mode_complete(self, card_token_id): + random_email_id = random.randint(100000, 999999) + order_mode_builder_complete = { + "type": "online", + "processing_mode": "manual", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 12 + } + } + ] + }, + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + } + } + + order_created = self.sdk.order().create(order_mode_builder_complete) + + + if order_created.get("status") != 201 or not order_created.get("response"): + self.fail(f"Failed to create order: {order_created}") + return order_created["response"] + + def test_create_order_and_get_by_id(self): + """ + Test Function: Create an Order and Get an Order by ID + """ + card_token_id = self.create_test_card() random_email_id = random.randint(100000, 999999) order_object = { "type": "online", @@ -41,7 +155,7 @@ def test_create(self): "payment_method": { "id": "master", "type": "credit_card", - "token": card_token_created["response"]["id"], + "token": card_token_id, "installments": 12 } } @@ -51,10 +165,141 @@ def test_create(self): "email": f"test_payer_{random_email_id}@testuser.com" } } - + order_created = self.sdk.order().create(order_object) self.assertEqual(order_created["status"], 201) self.assertEqual(order_created["response"]["status"], "processed") + order_get = self.sdk.order().get(order_created["response"]["id"]) + self.assertEqual(order_get["status"], 200) + + def test_process_order(self): + card_token_id = self.create_test_card() + random_email_id = random.randint(100000, 999999) + order_object = { + "type": "online", + "processing_mode": "manual", + "external_reference": "ext_ref_1234", + "total_amount": "200.00", + "transactions": { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 1 + } + } + ] + }, + "payer": { + "email": f"test_payer_{random_email_id}@testuser.com" + } + } + + order_created = self.sdk.order().create(order_object) + order_id = order_created["response"]["id"] + process_response = self.sdk.order().process(order_id) + if process_response.get("status") != 200 or not process_response.get("response"): + self.fail(f"Failed to create an order: {process_response}") + self.assertEqual(process_response["status"], 200, "Invalid HTTP status when processing the order") + + def test_cancel_order(self): + card_token_id = self.create_test_card() + order_id = self.create_order_canceled_or_captured(card_token_id) + time.sleep(4) + order_canceled = self.sdk.order().cancel(order_id) + self.assertEqual(order_canceled["status"], 200) + self.assertEqual(order_canceled["response"]["status"], "canceled") + + def test_capture_order(self): + card_token_id = self.create_test_card() + order_id = self.create_order_canceled_or_captured(card_token_id) + order_captured = self.sdk.order().capture(order_id) + self.assertEqual(order_captured["status"], 200) + self.assertEqual(order_captured["response"]["status"], "processed") + + def test_create_transaction(self): + card_token_id = self.create_test_card() + order_id = self.create_order_builder_mode(card_token_id) + transaction_object = { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 12 + } + } + ] + } + + transaction_created = self.sdk.order().create_transaction(order_id, transaction_object) + self.assertEqual(transaction_created["status"], 201) + + def test_update_transaction(self): + card_token_id = self.create_test_card() + order_created = self.create_order_builder_mode_complete(card_token_id) + order_id = order_created["id"] + transaction_id = order_created["transactions"]["payments"][0]["id"] + + transaction_update = { + "payment_method": { + "type": "credit_card", + "installments": 5 + } + } + + transaction_updated = self.sdk.order().update_transaction(order_id, transaction_id, transaction_update) + self.assertEqual(transaction_updated["status"], 200) + + def test_partial_refund_transaction(self): + card_token_id = self.create_test_card() + order_created = self.create_order_oneshot_mode_complete(card_token_id) + order_id = order_created["id"] + transaction_id = order_created["transactions"]["payments"][0]["id"] + + transaction_refund = { + "transactions": [ + { + "id": transaction_id, + "amount": "25.00" + } + ] + } + + sleep(3) + + transaction_refunded = self.sdk.order().refund_transaction(order_id, transaction_refund) + print("Refund Transaction Response:", transaction_refunded) + self.assertIn(transaction_refunded["status"], [ 201], + f"Unexpected status code for refund: {transaction_refunded['status']}. Response: {transaction_refunded}") + + def test_refund_transaction(self): + card_token_id = self.create_test_card() + order_created = self.create_order_oneshot_mode_complete(card_token_id) + order_id = order_created["id"] + sleep(3) + transaction_refunded = self.sdk.order().refund_transaction(order_id) + print("Refund Transaction Response:", transaction_refunded) + self.assertIn(transaction_refunded["status"], [ 201], + f"Unexpected status code for refund: {transaction_refunded['status']}. Response: {transaction_refunded}") + + def test_delete_transaction(self): + card_token_id = self.create_test_card() + order_created = self.create_order_builder_mode_complete(card_token_id) + order_id = order_created["id"] + transaction_id = order_created["transactions"]["payments"][0]["id"] + sleep(3) + + transaction_deleted = self.sdk.order().delete_transaction(order_id, transaction_id) + print("Transaction Deleted:", transaction_deleted) + self.assertEqual(transaction_deleted["status"], 204) + + if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file From 36adfff292b0a3121c0d5ea0cdd14b3dfa7bfbe5 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Tue, 18 Mar 2025 15:45:26 -0300 Subject: [PATCH 03/11] Enhancement - Add examples (#6) * examples * create examples * small fixes --- mercadopago/examples/order/cancel_order.py | 67 +++++++++++++++++ mercadopago/examples/order/capture_order.py | 64 ++++++++++++++++ mercadopago/examples/order/create_order.py | 56 ++++++++++++++ .../examples/order/create_transaction.py | 65 ++++++++++++++++ .../examples/order/delete_transaction.py | 66 +++++++++++++++++ mercadopago/examples/order/get_order.py | 62 ++++++++++++++++ mercadopago/examples/order/process_order.py | 64 ++++++++++++++++ mercadopago/examples/order/refund_partial.py | 74 +++++++++++++++++++ mercadopago/examples/order/refund_total.py | 65 ++++++++++++++++ .../examples/order/update_transaction.py | 73 ++++++++++++++++++ 10 files changed, 656 insertions(+) create mode 100644 mercadopago/examples/order/cancel_order.py create mode 100644 mercadopago/examples/order/capture_order.py create mode 100644 mercadopago/examples/order/create_order.py create mode 100644 mercadopago/examples/order/create_transaction.py create mode 100644 mercadopago/examples/order/delete_transaction.py create mode 100644 mercadopago/examples/order/get_order.py create mode 100644 mercadopago/examples/order/process_order.py create mode 100644 mercadopago/examples/order/refund_partial.py create mode 100644 mercadopago/examples/order/refund_total.py create mode 100644 mercadopago/examples/order/update_transaction.py diff --git a/mercadopago/examples/order/cancel_order.py b/mercadopago/examples/order/cancel_order.py new file mode 100644 index 0000000..c848e13 --- /dev/null +++ b/mercadopago/examples/order/cancel_order.py @@ -0,0 +1,67 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "capture_mode": "manual", + "processing_mode": "automatic", + "total_amount": "880.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "880.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully") + + # Get the order ID from the response + order_id = response["response"]["id"] + + time.sleep(5) + # Call the method to CANCEL + order_details = sdk.order().cancel(order_id) + print("Order details:", order_details["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/capture_order.py b/mercadopago/examples/order/capture_order.py new file mode 100644 index 0000000..bbd5d8d --- /dev/null +++ b/mercadopago/examples/order/capture_order.py @@ -0,0 +1,64 @@ +import os +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "capture_mode": "manual", # Mode need to be Manual to use Capture Method. + "processing_mode": "automatic", + "total_amount": "880.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "880.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully") + + # Get the order ID from the response + order_id = response["response"]["id"] + + # Call the method to CAPTURE the order + order_details = sdk.order().capture(order_id) + print("Order details:", order_details["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/create_order.py b/mercadopago/examples/order/create_order.py new file mode 100644 index 0000000..01f55b9 --- /dev/null +++ b/mercadopago/examples/order/create_order.py @@ -0,0 +1,56 @@ +from mercadopago import SDK + + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "total_amount": "880.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "880.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully:", response["response"]) + except Exception as e: + print("Error:", e) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/create_transaction.py b/mercadopago/examples/order/create_transaction.py new file mode 100644 index 0000000..87018e7 --- /dev/null +++ b/mercadopago/examples/order/create_transaction.py @@ -0,0 +1,65 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "manual", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully") + + # Get the order ID from the response + order_id = response["response"]["id"] + + transaction_object = { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 12 + } + } + ] + } + # Call the method to CREATE A TRANSACTION in the order + transaction_created = sdk.order().create_transaction(order_id, transaction_object) + print("Transaction created:", transaction_created["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/delete_transaction.py b/mercadopago/examples/order/delete_transaction.py new file mode 100644 index 0000000..9f31c2f --- /dev/null +++ b/mercadopago/examples/order/delete_transaction.py @@ -0,0 +1,66 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "manual", + "total_amount": "200.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "200.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 12 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully") + + # Get the order ID from the response + order_id = response["response"]["id"] + transaction_id = response["response"]["transactions"]["payments"][0]["id"] + + # Call the method to DELETE the transaction in the order + transaction_deleted = sdk.order().delete_transaction(order_id, transaction_id) + print("Transaction Successful Deleted.", transaction_deleted["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/get_order.py b/mercadopago/examples/order/get_order.py new file mode 100644 index 0000000..2c128ef --- /dev/null +++ b/mercadopago/examples/order/get_order.py @@ -0,0 +1,62 @@ +import os +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "total_amount": "880.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "880.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully!") + + # Get the order ID from the response + order_id = response["response"]["id"] + + # Call the method to get the order details + order_details = sdk.order().get(order_id) + print("Order details:", order_details["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/process_order.py b/mercadopago/examples/order/process_order.py new file mode 100644 index 0000000..a60a023 --- /dev/null +++ b/mercadopago/examples/order/process_order.py @@ -0,0 +1,64 @@ +import os +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "manual", # Mode need to be Manual to use Process Method. + "total_amount": "880.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "880.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully!") + + # Get the order ID from the response + order_id = response["response"]["id"] + print("Order ID:", order_id) + + # Call the method to PROCESS the order created in Manual Mode + order_details = sdk.order().process(order_id) + print("Order details:", order_details["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/refund_partial.py b/mercadopago/examples/order/refund_partial.py new file mode 100644 index 0000000..c260f9a --- /dev/null +++ b/mercadopago/examples/order/refund_partial.py @@ -0,0 +1,74 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "automatic", + "total_amount": "500.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "500.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully.") + + # Get the order ID from the response + order_id = response["response"]["id"] + + refund = { + "transactions": [ + { + "id": response["response"]["transactions"]["payments"][0]["id"], + "amount": "25.00" + } + ] + } + + # Call the method to REFUND + transaction_refund = sdk.order().refund_transaction(order_id, refund) + print("Transaction Partially Refunded:", transaction_refund["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/refund_total.py b/mercadopago/examples/order/refund_total.py new file mode 100644 index 0000000..251b0ca --- /dev/null +++ b/mercadopago/examples/order/refund_total.py @@ -0,0 +1,65 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "automatic", + "total_amount": "500.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "500.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully.") + + # Get the order ID from the response + order_id = response["response"]["id"] + + # Call the method to REFUND TOTALLY the transaction in the order + transaction_refund = sdk.order().refund_transaction(order_id) + print("Transaction Total Refunded:", transaction_refund["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mercadopago/examples/order/update_transaction.py b/mercadopago/examples/order/update_transaction.py new file mode 100644 index 0000000..f552071 --- /dev/null +++ b/mercadopago/examples/order/update_transaction.py @@ -0,0 +1,73 @@ +import os +import time + +from mercadopago import SDK + +def main(): + # Define the authentication token + access_token = "" + + # Define the authentication token + sdk = SDK(access_token) + + # Create a test card token + def create_test_card(): + card_token_object = { + "card_number": "5031433215406351", + "security_code": "123", + "expiration_year": "2030", + "expiration_month": "11", + "cardholder": {"name": "APRO"} + } + card_token_created = sdk.card_token().create(card_token_object) + return card_token_created["response"]["id"] + + # Create an order object + card_token_id = create_test_card() + order_object = { + "type": "online", + "processing_mode": "manual", + "total_amount": "500.00", + "external_reference": "ext_ref_1234", + "transactions": { + "payments": [ + { + "amount": "500.00", + "payment_method": { + "id": "master", + "type": "credit_card", + "token": card_token_id, + "installments": 2 + } + } + ] + }, + "payer": { + "email": "" + } + } + + try: + # Call the method to create the order + response = sdk.order().create(order_object) + print("Order created successfully") + + # Get the order ID from the response + order_id = response["response"]["id"] + transaction_id = response["response"]["transactions"]["payments"][0]["id"] + + transaction_update = { + "payment_method": { + "type": "credit_card", + "installments": 5 + } + } + + # Call the method to UPDATE the transaction in the order + update = sdk.order().update_transaction(order_id, transaction_id, transaction_update) + print("Transaction Updated:", update["response"]) + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() \ No newline at end of file From 1574e67a942e38971807af8d61df57b6ec724fa1 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Fri, 21 Mar 2025 11:46:12 -0300 Subject: [PATCH 04/11] release 2.3.0 --- mercadopago/config/config.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mercadopago/config/config.py b/mercadopago/config/config.py index f457264..dacd786 100644 --- a/mercadopago/config/config.py +++ b/mercadopago/config/config.py @@ -10,7 +10,7 @@ class Config: """ def __init__(self): - self.__version = "2.2.3" + self.__version = "2.3.0" self.__user_agent = "MercadoPago Python SDK v" + self.__version self.__product_id = "bc32bpftrpp001u8nhlg" self.__tracking_id = "platform:" + platform.python_version() diff --git a/pyproject.toml b/pyproject.toml index 350ee6f..7b0252a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "mercadopago" -version = "2.2.3" +version = "2.3.0" authors = [ {name = "Mercado Pago", email = "mp_sdk@mercadopago.com"} ] From f0655b86b35473b29496a18604864c94aba05d28 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Fri, 21 Mar 2025 14:49:40 -0300 Subject: [PATCH 05/11] remove pyhton 3.7 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee2f572..b5e2d1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 From 8489599668c0f9d15bd9a7c5ff23ddfdae850e60 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Fri, 21 Mar 2025 14:54:14 -0300 Subject: [PATCH 06/11] remove pyhton 3.8 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5e2d1f..3d5e6fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 From cd84b0780d478876e08cba723c2a332f0fc0dd22 Mon Sep 17 00:00:00 2001 From: Danielen Cestari Nunes Date: Fri, 21 Mar 2025 15:14:35 -0300 Subject: [PATCH 07/11] fix lint --- mercadopago/http/http_client.py | 1 + mercadopago/resources/order.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mercadopago/http/http_client.py b/mercadopago/http/http_client.py index 6fe628f..bcbfd2b 100644 --- a/mercadopago/http/http_client.py +++ b/mercadopago/http/http_client.py @@ -1,6 +1,7 @@ """ Module: http_client """ +# pylint: disable=too-many-arguments import requests from requests.adapters import HTTPAdapter from urllib3.util import Retry diff --git a/mercadopago/resources/order.py b/mercadopago/resources/order.py index d21c4b4..3386970 100644 --- a/mercadopago/resources/order.py +++ b/mercadopago/resources/order.py @@ -71,7 +71,7 @@ def process(self, order_id, request_options=None): if not isinstance(order_id, str): raise ValueError("Param order_id must be a string") - return self._post(uri="/v1/orders/" + str(order_id) + "/process", request_options=request_options) + return self._post(uri="/v1/orders/" + str(order_id) + "/process", request_options=request_options) # pylint: disable=line-too-long def cancel(self, order_id, request_options=None): """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/cancel-order/post) # pylint: disable=line-too-long @@ -90,7 +90,7 @@ def cancel(self, order_id, request_options=None): if not isinstance(order_id, str): raise ValueError("Param order_id must be a string") - return self._post(uri="/v1/orders/" + str(order_id) + "/cancel", request_options=request_options) + return self._post(uri="/v1/orders/" + str(order_id) + "/cancel", request_options=request_options) # pylint: disable=line-too-long def capture(self, order_id, request_options=None): """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/capture/post) # pylint: disable=line-too-long @@ -108,7 +108,7 @@ def capture(self, order_id, request_options=None): if not isinstance(order_id, str): raise ValueError("Param order_id must be a string") - return self._post(uri="/v1/orders/" + str(order_id) + "/capture", request_options=request_options) + return self._post(uri="/v1/orders/" + str(order_id) + "/capture", request_options=request_options) # pylint: disable=line-too-long def create_transaction(self, order_id, transaction_object, request_options=None): """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/add-transaction/post) # pylint: disable=line-too-long @@ -132,10 +132,10 @@ def create_transaction(self, order_id, transaction_object, request_options=None) response = self._post(uri=f"/v1/orders/{order_id}/transactions", data=transaction_object, request_options=request_options) if response.get("status") != 201: - raise Exception(f"Failed to add transaction: {response}") + raise Exception(f"Failed to add transaction: {response}") # pylint: disable=broad-exception-raised return response - def update_transaction(self, order_id, transaction_id, transaction_object, request_options=None): + def update_transaction(self, order_id, transaction_id, transaction_object, request_options=None): # pylint: disable=line-too-long """[Click here for more info](https://www.mercadopago.com/developers/en/reference/order/online-payments/update-transaction/put) # pylint: disable=line-too-long Args: @@ -155,10 +155,10 @@ def update_transaction(self, order_id, transaction_id, transaction_object, reque if not isinstance(transaction_object, dict): raise ValueError("Param transaction_object must be a Dictionary") - response = self._put(uri=f"/v1/orders/{order_id}/transactions/{transaction_id}", data=transaction_object, - request_options=request_options) + response = self._put(uri=f"/v1/orders/{order_id}/transactions/{transaction_id}", + data=transaction_object, request_options=request_options) if response.get("status") != 200: - raise Exception(f"Failed to update transaction: {response}") + raise Exception(f"Failed to update transaction: {response}") # pylint: disable=broad-exception-raised return response def refund_transaction(self, order_id, transaction_object=None, request_options=None): @@ -180,7 +180,7 @@ def refund_transaction(self, order_id, transaction_object=None, request_options= response = self._post(uri=f"/v1/orders/{order_id}/refund", data=transaction_object, request_options=request_options) if response.get("status") != 201: - raise Exception(f"Failed to refund transaction: {response}") + raise Exception(f"Failed to refund transaction: {response}") # pylint: disable=broad-exception-raised return response def delete_transaction(self, order_id, transaction_id, request_options=None): @@ -203,5 +203,5 @@ def delete_transaction(self, order_id, transaction_id, request_options=None): request_options=request_options) if response.get("status") != 204: - raise Exception(f"Failed to delete transaction: {response}") - return response \ No newline at end of file + raise Exception(f"Failed to delete transaction: {response}") # pylint: disable=broad-exception-raised + return response From a3f39f2152536de202683714e4b88913a3d06869 Mon Sep 17 00:00:00 2001 From: Renan Neri Date: Fri, 21 Mar 2025 16:28:04 -0300 Subject: [PATCH 08/11] lint adjusts --- mercadopago/config/request_options.py | 3 ++- mercadopago/http/http_client.py | 4 ++++ mercadopago/sdk.py | 2 +- tests/test_order.py | 19 +++++++++++-------- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/mercadopago/config/request_options.py b/mercadopago/config/request_options.py index 2cc436c..3516892 100644 --- a/mercadopago/config/request_options.py +++ b/mercadopago/config/request_options.py @@ -21,7 +21,8 @@ class RequestOptions: # pylint: disable=too-many-instance-attributes __integrator_id = None __platform_id = None - def __init__( # pylint: disable=too-many-arguments + def __init__( # pylint: disable=too-many-positional-arguments + # pylint: disable=too-many-arguments self, access_token=None, connection_timeout=60.0, diff --git a/mercadopago/http/http_client.py b/mercadopago/http/http_client.py index bcbfd2b..901f705 100644 --- a/mercadopago/http/http_client.py +++ b/mercadopago/http/http_client.py @@ -37,6 +37,7 @@ def request(self, method, url, maxretries=None, **kwargs): return response def get(self, url, headers, params=None, timeout=None, maxretries=None): # pylint: disable=too-many-arguments + # pylint: disable=too-many-positional-arguments """Makes a GET request to the API""" return self.request( "GET", @@ -48,6 +49,7 @@ def get(self, url, headers, params=None, timeout=None, maxretries=None): # pyli ) def post(self, url, headers, data=None, params=None, timeout=None, maxretries=None): # pylint: disable=too-many-arguments + # pylint: disable=too-many-positional-arguments """Makes a POST request to the API""" return self.request( "POST", @@ -60,6 +62,7 @@ def post(self, url, headers, data=None, params=None, timeout=None, maxretries=No ) def put(self, url, headers, data=None, params=None, timeout=None, maxretries=None): # pylint: disable=too-many-arguments + # pylint: disable=too-many-positional-arguments """Makes a PUT request to the API""" return self.request( "PUT", @@ -72,6 +75,7 @@ def put(self, url, headers, data=None, params=None, timeout=None, maxretries=Non ) def delete(self, url, headers, params=None, timeout=None, maxretries=None): # pylint: disable=too-many-arguments + # pylint: disable=too-many-positional-arguments """Makes a DELETE request to the API""" return self.request( "DELETE", diff --git a/mercadopago/sdk.py b/mercadopago/sdk.py index 13afaeb..6129307 100644 --- a/mercadopago/sdk.py +++ b/mercadopago/sdk.py @@ -122,7 +122,7 @@ def merchant_order(self, request_options=None): """ return MerchantOrder(request_options is not None and request_options or self.request_options, self.http_client) - + def order(self, request_options=None): """ Returns the attribute value of the function diff --git a/tests/test_order.py b/tests/test_order.py index d4bcd6e..3f40b0d 100644 --- a/tests/test_order.py +++ b/tests/test_order.py @@ -1,7 +1,6 @@ """ Module: test_order """ -import json import os import time import unittest @@ -58,7 +57,7 @@ def create_order_canceled_or_captured(self, card_token_id): self.fail(f"Failed to create order: {order_created}") return order_created["response"]["id"] - def create_order_builder_mode(self, card_token_id): + def create_order_builder_mode(self): random_email_id = random.randint(100000, 999999) order_object_cc = { "type": "online", @@ -204,7 +203,8 @@ def test_process_order(self): process_response = self.sdk.order().process(order_id) if process_response.get("status") != 200 or not process_response.get("response"): self.fail(f"Failed to create an order: {process_response}") - self.assertEqual(process_response["status"], 200, "Invalid HTTP status when processing the order") + self.assertEqual(process_response["status"], 200, + "Invalid HTTP status when processing the order") def test_cancel_order(self): card_token_id = self.create_test_card() @@ -223,7 +223,7 @@ def test_capture_order(self): def test_create_transaction(self): card_token_id = self.create_test_card() - order_id = self.create_order_builder_mode(card_token_id) + order_id = self.create_order_builder_mode() transaction_object = { "payments": [ { @@ -254,7 +254,8 @@ def test_update_transaction(self): } } - transaction_updated = self.sdk.order().update_transaction(order_id, transaction_id, transaction_update) + transaction_updated = self.sdk.order().update_transaction(order_id, transaction_id, + transaction_update) self.assertEqual(transaction_updated["status"], 200) def test_partial_refund_transaction(self): @@ -277,7 +278,8 @@ def test_partial_refund_transaction(self): transaction_refunded = self.sdk.order().refund_transaction(order_id, transaction_refund) print("Refund Transaction Response:", transaction_refunded) self.assertIn(transaction_refunded["status"], [ 201], - f"Unexpected status code for refund: {transaction_refunded['status']}. Response: {transaction_refunded}") + f"Unexpected status code for refund: {transaction_refunded['status']}." + " Response: {transaction_refunded}") def test_refund_transaction(self): card_token_id = self.create_test_card() @@ -287,7 +289,8 @@ def test_refund_transaction(self): transaction_refunded = self.sdk.order().refund_transaction(order_id) print("Refund Transaction Response:", transaction_refunded) self.assertIn(transaction_refunded["status"], [ 201], - f"Unexpected status code for refund: {transaction_refunded['status']}. Response: {transaction_refunded}") + f"Unexpected status code for refund: {transaction_refunded['status']}." + " Response: {transaction_refunded}") def test_delete_transaction(self): card_token_id = self.create_test_card() @@ -302,4 +305,4 @@ def test_delete_transaction(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() From 2c771b868c988f01b9436bfbd60e55b7b98d0485 Mon Sep 17 00:00:00 2001 From: Renan Neri Date: Fri, 21 Mar 2025 19:02:01 -0300 Subject: [PATCH 09/11] adjustment tests --- tests/test_merchant_order.py | 3 +-- tests/test_order.py | 3 --- tests/test_plan.py | 4 ++-- tests/test_preference.py | 4 ++-- tests/test_subscription.py | 5 +++-- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/test_merchant_order.py b/tests/test_merchant_order.py index 8142add..67229a3 100644 --- a/tests/test_merchant_order.py +++ b/tests/test_merchant_order.py @@ -25,14 +25,13 @@ def test_all(self): "picture_url": "http://product1.image.png", "quantity": 1, "title": "Item 1", - "currency_id": "R$", + "currency_id": "BRL", "unit_price": 20.5 } ] } preference_saved = self.sdk.preference().create(preference_object) - merchant_order_object = { "preference_id": preference_saved["response"]["id"], "site_id": "MLB", diff --git a/tests/test_order.py b/tests/test_order.py index 3f40b0d..0b4c0d5 100644 --- a/tests/test_order.py +++ b/tests/test_order.py @@ -276,7 +276,6 @@ def test_partial_refund_transaction(self): sleep(3) transaction_refunded = self.sdk.order().refund_transaction(order_id, transaction_refund) - print("Refund Transaction Response:", transaction_refunded) self.assertIn(transaction_refunded["status"], [ 201], f"Unexpected status code for refund: {transaction_refunded['status']}." " Response: {transaction_refunded}") @@ -287,7 +286,6 @@ def test_refund_transaction(self): order_id = order_created["id"] sleep(3) transaction_refunded = self.sdk.order().refund_transaction(order_id) - print("Refund Transaction Response:", transaction_refunded) self.assertIn(transaction_refunded["status"], [ 201], f"Unexpected status code for refund: {transaction_refunded['status']}." " Response: {transaction_refunded}") @@ -300,7 +298,6 @@ def test_delete_transaction(self): sleep(3) transaction_deleted = self.sdk.order().delete_transaction(order_id, transaction_id) - print("Transaction Deleted:", transaction_deleted) self.assertEqual(transaction_deleted["status"], 204) diff --git a/tests/test_plan.py b/tests/test_plan.py index 28d018b..6e3081d 100644 --- a/tests/test_plan.py +++ b/tests/test_plan.py @@ -30,7 +30,7 @@ def test_all(self): "frequency_type": "days" }, "transaction_amount": 60, - "currency_id": "BRL", + "currency_id": "ARS", }, "back_url": "https://www.mercadopago.com.co/subscriptions", "reason": f"Test Plan #{random_reason_number}", @@ -40,7 +40,7 @@ def test_all(self): "frequency": 1, "frequency_type": "months", "transaction_amount": 60, - "currency_id": "BRL", + "currency_id": "ARS", }, "back_url": "https://www.mercadopago.com.co/subscriptions", "reason": f"Test Plan (mandatory) #{random_reason_number}", diff --git a/tests/test_preference.py b/tests/test_preference.py index 862c1fa..c4d1662 100644 --- a/tests/test_preference.py +++ b/tests/test_preference.py @@ -32,7 +32,7 @@ def test_all(self): } preference_saved = self.sdk.preference().create(preference_object) self.assertEqual(preference_saved["status"], 201) - time.sleep(1) + time.sleep(3) preference_object["items"][0]["title"] = "Testando 1 2 3" @@ -40,7 +40,7 @@ def test_all(self): preference_update = self.sdk.preference().update(preference_id, preference_object) self.assertEqual(preference_update["status"], 200) - time.sleep(1) + time.sleep(3) preference_saved = self.sdk.preference().get(preference_id) self.assertEqual(preference_saved["status"], 200) self.assertEqual(preference_saved["response"]["items"][0]["title"], diff --git a/tests/test_subscription.py b/tests/test_subscription.py index c001f29..59f5fc0 100644 --- a/tests/test_subscription.py +++ b/tests/test_subscription.py @@ -6,6 +6,7 @@ import unittest import random import mercadopago +import time class TestSubscription(unittest.TestCase): @@ -96,7 +97,7 @@ def test_create_subscriptions_without_a_plan(self): "frequency": 1, "frequency_type": "months", "transaction_amount": 60, - "currency_id": "BRL", + "currency_id": "ARS", }, "status": "authorized" } @@ -157,7 +158,7 @@ def create_plan(cls): "frequency": 1, "frequency_type": "months", "transaction_amount": 60, - "currency_id": "BRL", + "currency_id": "ARS", }, "back_url": "https://www.mercadopago.com.co/subscriptions", "reason": f"Test Plan #{random.randint(100000, 999999)}", From ad0c7fcba3373122f4749999556e1b3184996085 Mon Sep 17 00:00:00 2001 From: Renan Neri Date: Fri, 21 Mar 2025 19:04:49 -0300 Subject: [PATCH 10/11] remove unused import --- tests/test_subscription.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_subscription.py b/tests/test_subscription.py index 59f5fc0..e1dbe64 100644 --- a/tests/test_subscription.py +++ b/tests/test_subscription.py @@ -6,7 +6,6 @@ import unittest import random import mercadopago -import time class TestSubscription(unittest.TestCase): From bee83fd107227f6d8ff1be5d5e28045a1e1ff083 Mon Sep 17 00:00:00 2001 From: Renan Neri Date: Mon, 24 Mar 2025 17:36:01 -0300 Subject: [PATCH 11/11] Adjustment subscription test --- tests/test_subscription.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_subscription.py b/tests/test_subscription.py index e1dbe64..f72a0fb 100644 --- a/tests/test_subscription.py +++ b/tests/test_subscription.py @@ -44,7 +44,13 @@ def test_all(self): "payer_email": self._customer_email, "preapproval_plan_id": self._plan_id, "card_token_id": card_token_id, - "status": "authorized" + "status": "authorized", + "auto_recurring": { + "frequency": 1, + "frequency_type": "months", + "transaction_amount": 60, + "currency_id": "ARS" + } } subscription_response = self.sdk.subscription().create(subscription_payload)