From 656a7b0b0efdc9bf23ce8a4a93c4eca1b3ddf354 Mon Sep 17 00:00:00 2001 From: luismeli10 Date: Sun, 12 Apr 2026 23:13:06 -0500 Subject: [PATCH 1/2] Enhancement: Add missing Orders API fields and Search operation - Add shipment field to root Request object - Add currency, taxes, discounts, type_response to Order - Add chargebacks to Transactions - Add refunded_amount, provider, discounts to Payment - Add e2e_id, redirect_url to PaymentMethod - Add id to TransactionSecurity - Add e2e_id to Refund - Add default_type, installments_cost, installments, min_installments to PaymentMethodConfig - Add entity_type to Payer - Add unit_measure, external_categories to Items - New classes: TypeResponse, Taxes, Discounts, PaymentMethodDiscount, PaymentDiscount, Installments, InstallmentsInterestFree, InstallmentsAvailable, Chargeback, ExternalCategory - Add search() method to OrderClient (GET /v1/orders) - Add OrderSearch resource with data and paging fields - Add total_pages to Paging; change field types to string --- src/MercadoPago/Client/Order/OrderClient.php | 21 ++++++++++++ src/MercadoPago/Resources/Common/Paging.php | 9 ++++-- src/MercadoPago/Resources/Order.php | 4 +++ .../Resources/Order/Chargeback.php | 22 +++++++++++++ .../Resources/Order/Installments.php | 31 ++++++++++++++++++ .../Resources/Order/InstallmentsAvailable.php | 10 ++++++ .../Order/InstallmentsInterestFree.php | 13 ++++++++ src/MercadoPago/Resources/Order/Payment.php | 10 ++++++ .../Resources/Order/PaymentDiscount.php | 10 ++++++ .../Resources/Order/PaymentMethod.php | 6 ++++ .../Resources/Order/PaymentMethodConfig.php | 29 +++++++++++++++++ src/MercadoPago/Resources/Order/Refund.php | 3 ++ .../Resources/Order/TransactionSecurity.php | 4 ++- .../Resources/Order/Transactions.php | 4 +++ .../Resources/Order/TypeResponse.php | 10 ++++++ src/MercadoPago/Resources/OrderSearch.php | 32 +++++++++++++++++++ src/MercadoPago/Resources/Payment.php | 2 +- .../Resources/Payment/Expanded.php | 2 +- .../Payment/NetworkTransactionData.php | 2 +- src/MercadoPago/Resources/Payment/Order.php | 1 - 20 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 src/MercadoPago/Resources/Order/Chargeback.php create mode 100644 src/MercadoPago/Resources/Order/Installments.php create mode 100644 src/MercadoPago/Resources/Order/InstallmentsAvailable.php create mode 100644 src/MercadoPago/Resources/Order/InstallmentsInterestFree.php create mode 100644 src/MercadoPago/Resources/Order/PaymentDiscount.php create mode 100644 src/MercadoPago/Resources/Order/TypeResponse.php create mode 100644 src/MercadoPago/Resources/OrderSearch.php diff --git a/src/MercadoPago/Client/Order/OrderClient.php b/src/MercadoPago/Client/Order/OrderClient.php index 65428148..b1c62eb1 100644 --- a/src/MercadoPago/Client/Order/OrderClient.php +++ b/src/MercadoPago/Client/Order/OrderClient.php @@ -5,9 +5,11 @@ use MercadoPago\Client\Common\RequestOptions; use MercadoPago\Client\MercadoPagoClient; use MercadoPago\Resources\Order; +use MercadoPago\Resources\OrderSearch; use MercadoPago\MercadoPagoConfig; use MercadoPago\Net\HttpMethod; use MercadoPago\Net\MPHttpClient; +use MercadoPago\Net\MPSearchRequest; use MercadoPago\Serialization\Serializer; /** Client responsible for performing Order actions. */ @@ -15,6 +17,7 @@ final class OrderClient extends MercadoPagoClient { private const URL = "/v1/orders"; private const URL_WITH_ID = "/v1/orders/%s"; + private const URL_SEARCH = "/v1/orders"; private const URL_CAPTURE = self::URL_WITH_ID . '/capture'; private const URL_CANCEL = self::URL_WITH_ID . '/cancel'; private const URL_PROCESS = self::URL_WITH_ID . '/process'; @@ -129,4 +132,22 @@ public function refund(string $order_id, ?array $request = null, ?RequestOptions $result->setResponse($response); return $result; } + + /** + * Method responsible for searching Orders. + * + * @param \MercadoPago\Net\MPSearchRequest $request search request. + * @param \MercadoPago\Client\Common\RequestOptions request options to be sent. + * @return \MercadoPago\Resources\OrderSearch search results. + * @throws \MercadoPago\Exceptions\MPApiException if the request fails. + * @throws \Exception if the request fails. + */ + public function search(MPSearchRequest $request, ?RequestOptions $request_options = null): OrderSearch + { + $query_params = isset($request) ? $request->getParameters() : null; + $response = parent::send(self::URL_SEARCH, HttpMethod::GET, null, $query_params, $request_options); + $result = Serializer::deserializeFromJson(OrderSearch::class, $response->getContent()); + $result->setResponse($response); + return $result; + } } diff --git a/src/MercadoPago/Resources/Common/Paging.php b/src/MercadoPago/Resources/Common/Paging.php index a7ce047e..a4843fe7 100644 --- a/src/MercadoPago/Resources/Common/Paging.php +++ b/src/MercadoPago/Resources/Common/Paging.php @@ -6,11 +6,14 @@ class Paging { /** Total. */ - public ?int $total; + public ?string $total; + + /** Total pages. */ + public ?string $total_pages; /** Limit. */ - public ?int $limit; + public ?string $limit; /** Offset. */ - public ?int $offset; + public ?string $offset; } diff --git a/src/MercadoPago/Resources/Order.php b/src/MercadoPago/Resources/Order.php index bfcf2c39..7b8f574b 100644 --- a/src/MercadoPago/Resources/Order.php +++ b/src/MercadoPago/Resources/Order.php @@ -99,6 +99,9 @@ class Order extends MPResource /** Taxes. */ public ?array $taxes; + /** Type response. */ + public array|object|null $type_response; + private $map = [ "transactions" => "MercadoPago\Resources\Order\Transactions", "items" => "MercadoPago\Resources\Order\Items", @@ -108,6 +111,7 @@ class Order extends MPResource "shipment" => "MercadoPago\Resources\Order\Shipment", "discounts" => "MercadoPago\Resources\Order\Discounts", "taxes" => "MercadoPago\Resources\Order\Taxes", + "type_response" => "MercadoPago\Resources\Order\TypeResponse", ]; /** diff --git a/src/MercadoPago/Resources/Order/Chargeback.php b/src/MercadoPago/Resources/Order/Chargeback.php new file mode 100644 index 00000000..fa33eb66 --- /dev/null +++ b/src/MercadoPago/Resources/Order/Chargeback.php @@ -0,0 +1,22 @@ + "MercadoPago\Resources\Order\InstallmentsInterestFree", + "available" => "MercadoPago\Resources\Order\InstallmentsAvailable", + ]; + + /** + * Method responsible for getting map of entities. + */ + public function getMap(): array + { + return $this->map; + } +} diff --git a/src/MercadoPago/Resources/Order/InstallmentsAvailable.php b/src/MercadoPago/Resources/Order/InstallmentsAvailable.php new file mode 100644 index 00000000..1633b935 --- /dev/null +++ b/src/MercadoPago/Resources/Order/InstallmentsAvailable.php @@ -0,0 +1,10 @@ + "MercadoPago\Resources\Order\PaymentMethod", "attempts" => "MercadoPago\Resources\Order\Attempt", "automatic_payments" => "MercadoPago\Resources\Order\AutomaticPayments", "stored_credential" => "MercadoPago\Resources\Order\StoredCredential", "subscription_data" => "MercadoPago\Resources\Order\SubscriptionData", + "discounts" => "MercadoPago\Resources\Order\PaymentDiscount", ]; /** diff --git a/src/MercadoPago/Resources/Order/PaymentDiscount.php b/src/MercadoPago/Resources/Order/PaymentDiscount.php new file mode 100644 index 00000000..cef8ec78 --- /dev/null +++ b/src/MercadoPago/Resources/Order/PaymentDiscount.php @@ -0,0 +1,10 @@ + "MercadoPago\Resources\Order\Installments", + ]; + + /** + * Method responsible for getting map of entities. + */ + public function getMap(): array + { + return $this->map; + } } diff --git a/src/MercadoPago/Resources/Order/Refund.php b/src/MercadoPago/Resources/Order/Refund.php index 78733e87..358e7845 100644 --- a/src/MercadoPago/Resources/Order/Refund.php +++ b/src/MercadoPago/Resources/Order/Refund.php @@ -27,6 +27,9 @@ class Refund /** Status. */ public ?string $status; + /** E2E ID. */ + public ?string $e2e_id; + /** Items. */ public ?array $items; diff --git a/src/MercadoPago/Resources/Order/TransactionSecurity.php b/src/MercadoPago/Resources/Order/TransactionSecurity.php index 066d2b71..2ff0b36c 100644 --- a/src/MercadoPago/Resources/Order/TransactionSecurity.php +++ b/src/MercadoPago/Resources/Order/TransactionSecurity.php @@ -12,6 +12,9 @@ class TransactionSecurity /** Class mapper. */ use Mapper; + /** Transaction security ID. */ + public ?string $id; + /** Validation. */ public ?string $validation; @@ -29,4 +32,3 @@ public function getMap(): array return []; } } - diff --git a/src/MercadoPago/Resources/Order/Transactions.php b/src/MercadoPago/Resources/Order/Transactions.php index e7e5e349..243f7694 100644 --- a/src/MercadoPago/Resources/Order/Transactions.php +++ b/src/MercadoPago/Resources/Order/Transactions.php @@ -19,9 +19,13 @@ class Transactions extends MPResource /** Refunds. */ public ?array $refunds; + /** Chargebacks. */ + public ?array $chargebacks; + private $map = [ "payments" => "MercadoPago\Resources\Order\Payment", "refunds" => "MercadoPago\Resources\Order\Refund", + "chargebacks" => "MercadoPago\Resources\Order\Chargeback", ]; /** diff --git a/src/MercadoPago/Resources/Order/TypeResponse.php b/src/MercadoPago/Resources/Order/TypeResponse.php new file mode 100644 index 00000000..5806d0fa --- /dev/null +++ b/src/MercadoPago/Resources/Order/TypeResponse.php @@ -0,0 +1,10 @@ + "MercadoPago\Resources\Common\Paging", + "data" => "MercadoPago\Resources\Order", + ]; + + /** + * Method responsible for getting map of entities. + */ + public function getMap(): array + { + return $this->map; + } +} diff --git a/src/MercadoPago/Resources/Payment.php b/src/MercadoPago/Resources/Payment.php index 7dcf6ce8..7b6ee053 100644 --- a/src/MercadoPago/Resources/Payment.php +++ b/src/MercadoPago/Resources/Payment.php @@ -238,7 +238,7 @@ class Payment extends MPResource "payment_method" => "MercadoPago\Resources\Payment\PaymentMethod", "metadata" => "MercadoPago\Resources\Payment\Metadata", "three_ds_info" => "MercadoPago\Resources\Payment\ThreeDSInfo", - "order"=> "MercadoPago\Resources\Payment\Order", + "order" => "MercadoPago\Resources\Payment\Order", "expanded" => "MercadoPago\Resources\Payment\Expanded" ]; diff --git a/src/MercadoPago/Resources/Payment/Expanded.php b/src/MercadoPago/Resources/Payment/Expanded.php index 8e0b9d73..8db18ef5 100644 --- a/src/MercadoPago/Resources/Payment/Expanded.php +++ b/src/MercadoPago/Resources/Payment/Expanded.php @@ -53,4 +53,4 @@ class ExpandedGatewayReference { /** Network transaction ID. */ public ?string $network_transaction_id; -} \ No newline at end of file +} diff --git a/src/MercadoPago/Resources/Payment/NetworkTransactionData.php b/src/MercadoPago/Resources/Payment/NetworkTransactionData.php index e59e9730..8ef7d553 100644 --- a/src/MercadoPago/Resources/Payment/NetworkTransactionData.php +++ b/src/MercadoPago/Resources/Payment/NetworkTransactionData.php @@ -7,4 +7,4 @@ class NetworkTransactionData { /** Network transaction ID. */ public ?string $network_transaction_id; -} \ No newline at end of file +} diff --git a/src/MercadoPago/Resources/Payment/Order.php b/src/MercadoPago/Resources/Payment/Order.php index 1252c063..86143d0f 100644 --- a/src/MercadoPago/Resources/Payment/Order.php +++ b/src/MercadoPago/Resources/Payment/Order.php @@ -5,7 +5,6 @@ /** Order class. */ class Order { - /** Order ID. */ public ?int $id; From b07e2b7daf45fd520d2dbeb7a0e95d0f5b86d23e Mon Sep 17 00:00:00 2001 From: luismeli10 Date: Thu, 16 Apr 2026 19:46:32 -0500 Subject: [PATCH 2/2] Fix: Restore int types in Paging and add Order search test Revert Paging fields from ?string back to ?int to match the actual API response types and align with existing patterns (Payment, Customer). Add total_pages as ?int for the Orders search response. Include order_search.json fixture and testSearchSuccess unit test for OrderClient::search. --- src/MercadoPago/Resources/Common/Paging.php | 8 ++--- .../Client/Unit/Order/OrderClientUnitTest.php | 30 ++++++++++++++++--- .../Mocks/Response/Order/order_search.json | 29 ++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 tests/MercadoPago/Resources/Mocks/Response/Order/order_search.json diff --git a/src/MercadoPago/Resources/Common/Paging.php b/src/MercadoPago/Resources/Common/Paging.php index a4843fe7..d8649d09 100644 --- a/src/MercadoPago/Resources/Common/Paging.php +++ b/src/MercadoPago/Resources/Common/Paging.php @@ -6,14 +6,14 @@ class Paging { /** Total. */ - public ?string $total; + public ?int $total; /** Total pages. */ - public ?string $total_pages; + public ?int $total_pages; /** Limit. */ - public ?string $limit; + public ?int $limit; /** Offset. */ - public ?string $offset; + public ?int $offset; } diff --git a/tests/MercadoPago/Client/Unit/Order/OrderClientUnitTest.php b/tests/MercadoPago/Client/Unit/Order/OrderClientUnitTest.php index 80913947..51c44939 100644 --- a/tests/MercadoPago/Client/Unit/Order/OrderClientUnitTest.php +++ b/tests/MercadoPago/Client/Unit/Order/OrderClientUnitTest.php @@ -257,7 +257,7 @@ public function testRequestContainsCaptureMode(): void $mockHttpRequest->method('execute')->willReturn(json_encode($mockResponse)); $mockHttpRequest->method('getInfo')->willReturnCallback( - fn($option) => $option === CURLINFO_HTTP_CODE ? 201 : null + fn ($option) => $option === CURLINFO_HTTP_CODE ? 201 : null ); MercadoPagoConfig::setHttpClient(new MPDefaultHttpClient($mockHttpRequest)); @@ -319,7 +319,7 @@ public function testBoletoFieldReplacesBolbradescoInRequestAndResponse(): void $mockHttpRequest->method('execute')->willReturn(json_encode($mockResponse)); $mockHttpRequest->method('getInfo')->willReturnCallback( - fn($option) => $option === CURLINFO_HTTP_CODE ? 201 : null + fn ($option) => $option === CURLINFO_HTTP_CODE ? 201 : null ); MercadoPagoConfig::setHttpClient(new MPDefaultHttpClient($mockHttpRequest)); @@ -350,8 +350,30 @@ public function testBoletoFieldReplacesBolbradescoInRequestAndResponse(): void $this->assertEquals('order_boleto_test', $order->id); $this->assertEquals('pending', $order->status); - $this->assertEquals('boleto', $order->transactions->payments[0]->payment_method->id, + $this->assertEquals( + 'boleto', + $order->transactions->payments[0]->payment_method->id, 'O campo payment_method.id da resposta deve ser "boleto".' ); } -} \ No newline at end of file + + public function testSearchSuccess(): void + { + $filepath = '../../../../Resources/Mocks/Response/Order/order_search.json'; + $mock_http_request = $this->mockHttpRequest($filepath, 200); + + $http_client = new MPDefaultHttpClient($mock_http_request); + MercadoPagoConfig::setHttpClient($http_client); + + $client = new OrderClient(); + $search_request = new \MercadoPago\Net\MPSearchRequest(5, 0, []); + $search_result = $client->search($search_request); + $this->assertSame(200, $search_result->getResponse()->getStatusCode()); + $this->assertSame(10, $search_result->paging->total); + $this->assertSame(2, $search_result->paging->total_pages); + $this->assertSame(5, $search_result->paging->limit); + $this->assertSame(0, $search_result->paging->offset); + $this->assertSame(1, count($search_result->data)); + $this->assertSame("01JD2P9GGXAPBDGG6YT90N77M3", $search_result->data[0]->id); + } +} diff --git a/tests/MercadoPago/Resources/Mocks/Response/Order/order_search.json b/tests/MercadoPago/Resources/Mocks/Response/Order/order_search.json new file mode 100644 index 00000000..45f781f1 --- /dev/null +++ b/tests/MercadoPago/Resources/Mocks/Response/Order/order_search.json @@ -0,0 +1,29 @@ +{ + "paging": { + "total": 10, + "total_pages": 2, + "limit": 5, + "offset": 0 + }, + "data": [ + { + "id": "01JD2P9GGXAPBDGG6YT90N77M3", + "type": "online", + "processing_mode": "automatic", + "capture_mode": "automatic_async", + "external_reference": "ext_ref_1234", + "total_amount": "200.00", + "site_id": "MLB", + "status": "processed", + "status_detail": "accredited", + "created_date": "2024-11-19T17:07:31.486Z", + "last_updated_date": "2024-11-19T17:07:33.068Z", + "payer": { + "email": "test_1731354550@testuser.com" + }, + "transactions": { + "payments": [] + } + } + ] +}