From 287423f33c892e78ccbb68ca31edd2b2cce6df6d Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:26 -0500 Subject: [PATCH 1/8] auto-gen: 9faed4b2-5a27-412d-9a5b-72d9ae5f2b17 mercadopago/resources/address.py --- mercadopago/resources/address.py | 99 ++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 mercadopago/resources/address.py diff --git a/mercadopago/resources/address.py b/mercadopago/resources/address.py new file mode 100644 index 0000000..a8bcc58 --- /dev/null +++ b/mercadopago/resources/address.py @@ -0,0 +1,99 @@ +""" +Address resource for MercadoPago SDK. + +This module contains the Address model with properties for representing +physical addresses. +""" + +from mercadopago.resources.base import ResourceBase + + +class Address(ResourceBase): + """ + Address resource model. + + Represents a physical address with properties for city, country, state, + street name, street number, and zip code. + """ + + _schema = { + "city": str, + "country": str, + "state": str, + "street_name": str, + "street_number": str, + "zip_code": str, + } + + def __init__(self, data=None): + """ + Initialize an Address instance. + + Args: + data (dict, optional): Dictionary containing address data. + """ + super(Address, self).__init__(data) + + self.city = None + self.country = None + self.state = None + self.street_name = None + self.street_number = None + self.zip_code = None + + if data: + self._load_from_dict(data) + + def _load_from_dict(self, data): + """ + Load address properties from a dictionary. + + Args: + data (dict): Dictionary containing address data. + """ + if not isinstance(data, dict): + return + + self.city = data.get("city") + self.country = data.get("country") + self.state = data.get("state") + self.street_name = data.get("street_name") + self.street_number = data.get("street_number") + self.zip_code = data.get("zip_code") + + def to_dict(self): + """ + Convert the Address instance to a dictionary. + + Returns: + dict: Dictionary representation of the address. + """ + result = {} + + if self.city is not None: + result["city"] = self.city + if self.country is not None: + result["country"] = self.country + if self.state is not None: + result["state"] = self.state + if self.street_name is not None: + result["street_name"] = self.street_name + if self.street_number is not None: + result["street_number"] = self.street_number + if self.zip_code is not None: + result["zip_code"] = self.zip_code + + return result + + def __repr__(self): + """ + Return a string representation of the Address instance. + + Returns: + str: String representation of the address. + """ + return ( + f"Address(city={self.city!r}, country={self.country!r}, " + f"state={self.state!r}, street_name={self.street_name!r}, " + f"street_number={self.street_number!r}, zip_code={self.zip_code!r})" + ) \ No newline at end of file From a2300a52107b2edc313697742c61f28f8e939cb8 Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:27 -0500 Subject: [PATCH 2/8] auto-gen: 99b5d72d-e210-42b1-8e32-d440a2626d39 mercadopago/resources/payment_additional_info.py --- .../resources/payment_additional_info.py | 255 ++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 mercadopago/resources/payment_additional_info.py diff --git a/mercadopago/resources/payment_additional_info.py b/mercadopago/resources/payment_additional_info.py new file mode 100644 index 0000000..8647c6f --- /dev/null +++ b/mercadopago/resources/payment_additional_info.py @@ -0,0 +1,255 @@ +"""Payment Additional Info resource for Mercado Pago SDK.""" + +from mercadopago.sdk import MPBase + + +class PaymentAdditionalInfo(MPBase): + """ + Payment Additional Info resource. + + Used for providing additional information for fraud scoring and payment processing. + Includes items, payer information, and shipment details. + """ + + def __init__(self, client): + """ + Initialize PaymentAdditionalInfo resource. + + Args: + client: Mercado Pago client instance + """ + super().__init__(client) + self._resource_name = "payment_additional_info" + + @staticmethod + def create_item(id=None, title=None, description=None, picture_url=None, + category_id=None, quantity=None, unit_price=None): + """ + Create a payment item dictionary. + + Args: + id (str, optional): Item identifier + title (str, optional): Item title + description (str, optional): Item description + picture_url (str, optional): Item picture URL + category_id (str, optional): Item category identifier + quantity (int, optional): Item quantity + unit_price (float, optional): Unit price of the item + + Returns: + dict: Payment item data + """ + item = {} + + if id is not None: + item["id"] = id + if title is not None: + item["title"] = title + if description is not None: + item["description"] = description + if picture_url is not None: + item["picture_url"] = picture_url + if category_id is not None: + item["category_id"] = category_id + if quantity is not None: + item["quantity"] = quantity + if unit_price is not None: + item["unit_price"] = unit_price + + return item + + @staticmethod + def create_payer_info(first_name=None, last_name=None, phone=None, + address=None): + """ + Create payer information dictionary. + + Args: + first_name (str, optional): Payer's first name + last_name (str, optional): Payer's last name + phone (dict, optional): Phone information (area_code, number) + address (dict, optional): Address information (zip_code, street_name, + street_number) + + Returns: + dict: Payer information data + """ + payer = {} + + if first_name is not None: + payer["first_name"] = first_name + if last_name is not None: + payer["last_name"] = last_name + if phone is not None: + payer["phone"] = phone + if address is not None: + payer["address"] = address + + return payer + + @staticmethod + def create_phone(area_code=None, number=None): + """ + Create phone information dictionary. + + Args: + area_code (str, optional): Phone area code + number (str, optional): Phone number + + Returns: + dict: Phone information data + """ + phone = {} + + if area_code is not None: + phone["area_code"] = area_code + if number is not None: + phone["number"] = number + + return phone + + @staticmethod + def create_address(zip_code=None, street_name=None, street_number=None): + """ + Create address information dictionary. + + Args: + zip_code (str, optional): Address zip code + street_name (str, optional): Street name + street_number (str, optional): Street number + + Returns: + dict: Address information data + """ + address = {} + + if zip_code is not None: + address["zip_code"] = zip_code + if street_name is not None: + address["street_name"] = street_name + if street_number is not None: + address["street_number"] = street_number + + return address + + @staticmethod + def create_shipments(receiver_address=None): + """ + Create shipments information dictionary. + + Args: + receiver_address (dict, optional): Receiver address information + (zip_code, street_name, street_number, + floor, apartment) + + Returns: + dict: Shipments information data + """ + shipments = {} + + if receiver_address is not None: + shipments["receiver_address"] = receiver_address + + return shipments + + @staticmethod + def create_receiver_address(zip_code=None, street_name=None, + street_number=None, floor=None, apartment=None): + """ + Create receiver address information dictionary. + + Args: + zip_code (str, optional): Address zip code + street_name (str, optional): Street name + street_number (str, optional): Street number + floor (str, optional): Floor number + apartment (str, optional): Apartment number + + Returns: + dict: Receiver address information data + """ + address = {} + + if zip_code is not None: + address["zip_code"] = zip_code + if street_name is not None: + address["street_name"] = street_name + if street_number is not None: + address["street_number"] = street_number + if floor is not None: + address["floor"] = floor + if apartment is not None: + address["apartment"] = apartment + + return address + + @staticmethod + def create_additional_info(items=None, payer=None, shipments=None): + """ + Create complete additional info dictionary for payment. + + Args: + items (list, optional): List of payment items + payer (dict, optional): Payer information + shipments (dict, optional): Shipments information + + Returns: + dict: Complete additional info data structure + """ + additional_info = {} + + if items is not None: + additional_info["items"] = items + if payer is not None: + additional_info["payer"] = payer + if shipments is not None: + additional_info["shipments"] = shipments + + return additional_info + + def validate_additional_info(self, additional_info): + """ + Validate additional info structure. + + Args: + additional_info (dict): Additional info to validate + + Returns: + tuple: (is_valid, errors) where is_valid is bool and errors is list of str + """ + errors = [] + + if not isinstance(additional_info, dict): + errors.append("additional_info must be a dictionary") + return False, errors + + # Validate items + if "items" in additional_info: + if not isinstance(additional_info["items"], list): + errors.append("items must be a list") + else: + for idx, item in enumerate(additional_info["items"]): + if not isinstance(item, dict): + errors.append(f"item at index {idx} must be a dictionary") + + # Validate payer + if "payer" in additional_info: + if not isinstance(additional_info["payer"], dict): + errors.append("payer must be a dictionary") + else: + payer = additional_info["payer"] + if "phone" in payer and not isinstance(payer["phone"], dict): + errors.append("payer.phone must be a dictionary") + if "address" in payer and not isinstance(payer["address"], dict): + errors.append("payer.address must be a dictionary") + + # Validate shipments + if "shipments" in additional_info: + if not isinstance(additional_info["shipments"], dict): + errors.append("shipments must be a dictionary") + else: + shipments = additional_info["shipments"] + if "receiver_address" in shipments and not isinstance(shipments["receiver_address"], dict): + errors.append("shipments.receiver_address must be a dictionary") + + return len(errors) == 0, errors \ No newline at end of file From 288b00f4a22184ee836dcdb4551ad9134bcfab5f Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:28 -0500 Subject: [PATCH 3/8] auto-gen: 15fa89fd-97be-47e6-8774-e6827389fa30 mercadopago/resources/payment_item.py --- mercadopago/resources/payment_item.py | 127 ++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 mercadopago/resources/payment_item.py diff --git a/mercadopago/resources/payment_item.py b/mercadopago/resources/payment_item.py new file mode 100644 index 0000000..04a013d --- /dev/null +++ b/mercadopago/resources/payment_item.py @@ -0,0 +1,127 @@ +"""Payment Item resource for MercadoPago SDK.""" + +from mercadopago.resources.base import ResourceBase + + +class PaymentItem(ResourceBase): + """ + PaymentItem resource class. + + Represents an item in a payment transaction with details about + the product or service being purchased. + """ + + _schema = { + "id": str, + "title": str, + "description": str, + "category_id": str, + "quantity": int, + "unit_price": float + } + + def __init__(self, client=None): + """ + Initialize PaymentItem resource. + + Args: + client: MercadoPago client instance + """ + super().__init__(client) + self.id = None + self.title = None + self.description = None + self.category_id = None + self.quantity = None + self.unit_price = None + + def validate(self): + """ + Validate PaymentItem data. + + Returns: + bool: True if valid + + Raises: + ValueError: If required fields are missing or invalid + """ + if not self.title: + raise ValueError("title is required") + + if self.quantity is not None and self.quantity < 1: + raise ValueError("quantity must be greater than 0") + + if self.unit_price is not None and self.unit_price < 0: + raise ValueError("unit_price must be non-negative") + + return True + + def to_dict(self): + """ + Convert PaymentItem to dictionary. + + Returns: + dict: Dictionary representation of the payment item + """ + data = {} + + if self.id is not None: + data["id"] = self.id + + if self.title is not None: + data["title"] = self.title + + if self.description is not None: + data["description"] = self.description + + if self.category_id is not None: + data["category_id"] = self.category_id + + if self.quantity is not None: + data["quantity"] = self.quantity + + if self.unit_price is not None: + data["unit_price"] = self.unit_price + + return data + + def from_dict(self, data): + """ + Populate PaymentItem from dictionary. + + Args: + data (dict): Dictionary with payment item data + + Returns: + PaymentItem: Self instance + """ + if not isinstance(data, dict): + return self + + self.id = data.get("id") + self.title = data.get("title") + self.description = data.get("description") + self.category_id = data.get("category_id") + self.quantity = data.get("quantity") + self.unit_price = data.get("unit_price") + + return self + + @property + def total_amount(self): + """ + Calculate total amount for this item. + + Returns: + float: Total amount (quantity * unit_price) or None + """ + if self.quantity is not None and self.unit_price is not None: + return self.quantity * self.unit_price + return None + + def __repr__(self): + """String representation of PaymentItem.""" + return ( + f"PaymentItem(id={self.id!r}, title={self.title!r}, " + f"quantity={self.quantity}, unit_price={self.unit_price})" + ) \ No newline at end of file From d288a9735324977f584bf6c0b9cf3b3d8789559f Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:30 -0500 Subject: [PATCH 4/8] auto-gen: 7c98252a-956c-439f-a396-cc927bf7b3a9 mercadopago/resources/payment_payer.py --- mercadopago/resources/payment_payer.py | 111 +++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 mercadopago/resources/payment_payer.py diff --git a/mercadopago/resources/payment_payer.py b/mercadopago/resources/payment_payer.py new file mode 100644 index 0000000..faf75be --- /dev/null +++ b/mercadopago/resources/payment_payer.py @@ -0,0 +1,111 @@ +"""Payment payer resource for MercadoPago SDK.""" + +from typing import Optional +from mercadopago.resources.base import Resource + + +class PaymentPayer(Resource): + """ + Payment payer model. + + Represents the payer information for a payment transaction. + + Attributes: + email (str): Required. Email address of the payer. + id (str): Optional. Unique identifier of the payer. + identification (dict): Optional. Identification information with 'type' and 'number'. + type (str): Optional. Type of payer. Enum: 'customer', 'registered', 'guest'. + """ + + PAYER_TYPES = ['customer', 'registered', 'guest'] + + def __init__(self, email: str, id: Optional[str] = None, + identification: Optional[dict] = None, + type: Optional[str] = None): + """ + Initialize a PaymentPayer instance. + + Args: + email (str): Email address of the payer (required). + id (str, optional): Unique identifier of the payer. + identification (dict, optional): Identification information containing: + - type (str): Type of identification document. + - number (str): Identification document number. + type (str, optional): Type of payer ('customer', 'registered', or 'guest'). + + Raises: + ValueError: If email is not provided or if type is not in allowed values. + """ + if not email: + raise ValueError("Email is required for PaymentPayer") + + if type and type not in self.PAYER_TYPES: + raise ValueError(f"Type must be one of {self.PAYER_TYPES}") + + if identification: + if not isinstance(identification, dict): + raise ValueError("Identification must be a dictionary") + if 'type' not in identification or 'number' not in identification: + raise ValueError("Identification must contain 'type' and 'number' keys") + + self.email = email + self.id = id + self.identification = identification + self.type = type + + def to_dict(self) -> dict: + """ + Convert the PaymentPayer instance to a dictionary. + + Returns: + dict: Dictionary representation of the payer, excluding None values. + """ + data = { + 'email': self.email + } + + if self.id is not None: + data['id'] = self.id + + if self.identification is not None: + data['identification'] = self.identification + + if self.type is not None: + data['type'] = self.type + + return data + + @classmethod + def from_dict(cls, data: dict) -> 'PaymentPayer': + """ + Create a PaymentPayer instance from a dictionary. + + Args: + data (dict): Dictionary containing payer information. + + Returns: + PaymentPayer: New PaymentPayer instance. + + Raises: + ValueError: If required fields are missing. + """ + if 'email' not in data: + raise ValueError("Email is required in data dictionary") + + return cls( + email=data['email'], + id=data.get('id'), + identification=data.get('identification'), + type=data.get('type') + ) + + def __repr__(self) -> str: + """String representation of PaymentPayer.""" + return (f"PaymentPayer(email='{self.email}', id='{self.id}', " + f"type='{self.type}')") + + def __eq__(self, other) -> bool: + """Check equality based on email and id.""" + if not isinstance(other, PaymentPayer): + return False + return self.email == other.email and self.id == other.id \ No newline at end of file From bb384a4652bc5578ac12ce7d3025a350c020739d Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:31 -0500 Subject: [PATCH 5/8] auto-gen: 27eec3b5-577c-49ac-8fdb-96f22346cde9 mercadopago/resources/phone.py --- mercadopago/resources/phone.py | 79 ++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 mercadopago/resources/phone.py diff --git a/mercadopago/resources/phone.py b/mercadopago/resources/phone.py new file mode 100644 index 0000000..113fc33 --- /dev/null +++ b/mercadopago/resources/phone.py @@ -0,0 +1,79 @@ +""" +Phone resource model for MercadoPago SDK. + +This module defines the Phone schema with area code and number fields. +""" + + +class Phone: + """ + Phone model representing a phone number with area code. + + Attributes: + area_code (str): The area code of the phone number. + number (str): The phone number without area code. + """ + + def __init__(self, area_code=None, number=None): + """ + Initialize a Phone instance. + + Args: + area_code (str, optional): The area code of the phone number. + number (str, optional): The phone number without area code. + """ + self.area_code = area_code + self.number = number + + def to_dict(self): + """ + Convert the Phone instance to a dictionary. + + Returns: + dict: Dictionary representation of the phone object. + """ + return { + "area_code": self.area_code, + "number": self.number + } + + @classmethod + def from_dict(cls, data): + """ + Create a Phone instance from a dictionary. + + Args: + data (dict): Dictionary containing phone data. + + Returns: + Phone: A new Phone instance. + """ + if data is None: + return None + + return cls( + area_code=data.get("area_code"), + number=data.get("number") + ) + + def __repr__(self): + """ + Return a string representation of the Phone instance. + + Returns: + str: String representation of the phone object. + """ + return f"Phone(area_code='{self.area_code}', number='{self.number}')" + + def __str__(self): + """ + Return a human-readable string of the phone number. + + Returns: + str: Formatted phone number string. + """ + if self.area_code and self.number: + return f"({self.area_code}) {self.number}" + elif self.number: + return self.number + return "" \ No newline at end of file From eb8c5e2c6e06931334c7097952790ef77a6ea614 Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:32 -0500 Subject: [PATCH 6/8] auto-gen: d5e2d46b-b1fa-4abf-8df5-7751b6bcade9 mercadopago/resources/payment.py --- mercadopago/resources/payment.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/mercadopago/resources/payment.py b/mercadopago/resources/payment.py index 7104828..c1c0c0a 100644 --- a/mercadopago/resources/payment.py +++ b/mercadopago/resources/payment.py @@ -52,8 +52,24 @@ def create(self, payment_object, request_options=None): """Creates a new payment. Args: - payment_object: Dict describing the payment (amount, payer, - payment_method_id, token, etc.). + payment_object: Dict describing the payment with the following fields: + - transaction_amount (float, required): Payment amount. + - payer (dict, required): Payer information (PaymentPayer). + - token (string, optional): Card token for card payments. + - payment_method_id (string, optional): Payment method identifier. + - installments (integer, optional): Number of installments. + - issuer_id (string, optional): Card issuer identifier. + - capture (boolean, optional): Whether to capture immediately (default: true). + - binary_mode (boolean, optional): Binary payment mode (default: false). + - external_reference (string, optional): External reference ID. + - statement_descriptor (string, optional): Statement descriptor (max 22 chars). + - date_of_expiration (datetime, optional): Payment expiration date. + - additional_info (dict, optional): Additional payment information (PaymentAdditionalInfo). + - application_fee (float, optional): Application fee amount. + - notification_url (uri, optional, deprecated): IPN notification URL. + - callback_url (uri, optional): Callback URL. + - coupon_code (string, optional): Coupon code. + - coupon_amount (float, optional): Coupon discount amount. request_options: Per-call configuration overrides. Raises: @@ -92,4 +108,4 @@ def update(self, payment_id, payment_object, request_options=None): raise ValueError("Param payment_object must be a Dictionary") return self._put(uri="/v1/payments/" + str(payment_id), data=payment_object, - request_options=request_options) + request_options=request_options) \ No newline at end of file From d9359b52b72890f32473eb585c19992ae27e1b7a Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:33 -0500 Subject: [PATCH 7/8] auto-gen: 02297e53-7ade-4180-84f3-46c7eebab656 mercadopago/resources/pagination.py --- mercadopago/resources/pagination.py | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 mercadopago/resources/pagination.py diff --git a/mercadopago/resources/pagination.py b/mercadopago/resources/pagination.py new file mode 100644 index 0000000..042e339 --- /dev/null +++ b/mercadopago/resources/pagination.py @@ -0,0 +1,52 @@ +"""Pagination resource for MercadoPago SDK.""" + + +class Pagination: + """Represents pagination information for list responses.""" + + def __init__(self, total: int = 0, limit: int = 0, offset: int = 0): + """ + Initialize Pagination. + + Args: + total: Total number of items available + limit: Maximum number of items per page + offset: Number of items to skip + """ + self.total = total + self.limit = limit + self.offset = offset + + def to_dict(self): + """ + Convert pagination to dictionary. + + Returns: + dict: Dictionary representation of pagination + """ + return { + "total": self.total, + "limit": self.limit, + "offset": self.offset, + } + + @classmethod + def from_dict(cls, data: dict): + """ + Create Pagination instance from dictionary. + + Args: + data: Dictionary containing pagination data + + Returns: + Pagination: New Pagination instance + """ + return cls( + total=data.get("total", 0), + limit=data.get("limit", 0), + offset=data.get("offset", 0), + ) + + def __repr__(self): + """String representation of Pagination.""" + return f"Pagination(total={self.total}, limit={self.limit}, offset={self.offset})" \ No newline at end of file From aea99a24dad3c3abf4ac742f97638e761bcb51dd Mon Sep 17 00:00:00 2001 From: Diego Barajas Date: Fri, 26 Jun 2026 10:00:34 -0500 Subject: [PATCH 8/8] auto-gen: 41d3e24c-2d90-4f6b-b8d3-99d8ddc03dfd mercadopago/resources/refund.py --- mercadopago/resources/refund.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mercadopago/resources/refund.py b/mercadopago/resources/refund.py index 3f8f3a4..5f38010 100644 --- a/mercadopago/resources/refund.py +++ b/mercadopago/resources/refund.py @@ -38,11 +38,12 @@ def create(self, payment_id, refund_object=None, request_options=None): """Creates a refund for a payment. Omit *refund_object* for a full refund, or pass - ``{"amount": }`` for a partial refund. + ``{"amount": }`` for a partial refund. The amount field + is optional; omit it for a full refund. Args: payment_id: Identifier of the payment to refund. - refund_object: Optional dict with partial refund details. + refund_object: Optional dict with amount only (float, optional). request_options: Per-call configuration overrides. Raises: @@ -57,4 +58,4 @@ def create(self, payment_id, refund_object=None, request_options=None): raise ValueError("Param refund_object must be a Dictionary") return self._post(uri="/v1/payments/" + str(payment_id) + "/refunds", - data=refund_object, request_options=request_options) + data=refund_object, request_options=request_options) \ No newline at end of file