Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ on:
jobs:
upload:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -24,12 +27,27 @@ jobs:
python3 -m pip install setuptools build twine
python3 -m pip install .

# Build and upload to PyPI
- name: "Builds and uploads to PyPI"
- name: Build distribution
run: |
python3 -m build
python3 -m twine check dist/*
python3 -m twine upload dist/*

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
PYPI_OIDC_AUDIENCE: pypi
run: |
set -euo pipefail

oidc_response=$(curl --fail-with-body --silent --show-error \
-H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${PYPI_OIDC_AUDIENCE}")
oidc_token=$(jq --raw-output '.value' <<< "${oidc_response}")

token_response=$(curl --fail-with-body --silent --show-error \
-X POST https://pypi.org/_/oidc/mint-token \
-H 'Content-Type: application/json' \
--data "$(jq --null-input --arg token "${oidc_token}" '{token: $token}')")
api_token=$(jq --raw-output '.token' <<< "${token_response}")

echo "::add-mask::${api_token}"
TWINE_USERNAME=__token__ TWINE_PASSWORD="${api_token}" python3 -m twine upload dist/*
1 change: 1 addition & 0 deletions mercadopago/resources/order_automatic_payments.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ class OrderAutomaticPayments:
retries: Optional[int] = None
schedule_date: Optional[str] = None
due_date: Optional[str] = None
subscription: Optional[dict] = None
22 changes: 22 additions & 0 deletions tests/test_order.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Unit tests for the Order resource using a mock HTTP client."""
from dataclasses import asdict
import unittest

from mercadopago.resources.order_automatic_payments import OrderAutomaticPayments

from tests.base_client_test import BaseClientTest


Expand Down Expand Up @@ -146,6 +149,25 @@ def test_create_raises_for_non_dict(self):
with self.assertRaises(ValueError):
self.sdk.order().create("not-a-dict")

def test_automatic_payments_subscription_payload(self):
automatic_payments = OrderAutomaticPayments(
subscription={
"id": "subscription-1",
"sequence": {"number": 1, "total": 12},
"invoice": {
"id": "invoice-1",
"billing_date": "2026-08-26",
"period": {"interval": 1, "type": "month"},
},
}
)

payload = asdict(automatic_payments)

self.assertEqual("subscription-1", payload["subscription"]["id"])
self.assertEqual(12, payload["subscription"]["sequence"]["total"])
self.assertEqual("month", payload["subscription"]["invoice"]["period"]["type"])


if __name__ == "__main__":
unittest.main()
22 changes: 22 additions & 0 deletions tests/test_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ def test_get(self):
self.assertEqual("6351", resp["card"]["last_four_digits"])
self.mock_http.get.assert_called_once()

def test_get_preserves_expanded_gateway_network_data(self):
self.mock_get(
{
"expanded": {
"gateway": {
"reference": {
"network_data": {
"transaction_id": "ABC123",
"transaction_link_id": "550e8400",
}
}
}
}
}
)

result = self.sdk.payment().get(17014025134)

network_data = result["response"]["expanded"]["gateway"]["reference"]["network_data"]
self.assertEqual("ABC123", network_data["transaction_id"])
self.assertEqual("550e8400", network_data["transaction_link_id"])

def test_search(self):
fixture = self.load_fixture("payment_search.json")
self.mock_get(fixture)
Expand Down