From b65dfc957f4b1946b5a9a33bfc07c0b4c45b1d6f Mon Sep 17 00:00:00 2001 From: Edson Nascimento Date: Mon, 2 Jun 2025 14:28:13 -0300 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20Adicionar=20campo=20`httpRespon?= =?UTF-8?q?se`=20para=20salvar=20o=20json=20do=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rede/Http/RedeResponse.php | 20 +++++++++++++++++ src/Rede/ResponseTrait.php | 22 +++++++++++++++++++ .../Service/AbstractTransactionsService.php | 1 + src/Rede/Transaction.php | 5 ++++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/Rede/Http/RedeResponse.php create mode 100644 src/Rede/ResponseTrait.php diff --git a/src/Rede/Http/RedeResponse.php b/src/Rede/Http/RedeResponse.php new file mode 100644 index 0000000..a93e850 --- /dev/null +++ b/src/Rede/Http/RedeResponse.php @@ -0,0 +1,20 @@ +statusCode; + } + + public function getBody(): string + { + return $this->body; + } +} diff --git a/src/Rede/ResponseTrait.php b/src/Rede/ResponseTrait.php new file mode 100644 index 0000000..09b0159 --- /dev/null +++ b/src/Rede/ResponseTrait.php @@ -0,0 +1,22 @@ +httpResponse; + } + + public function setHttpResponse(?RedeResponse $httpResponse): static + { + $this->httpResponse = $httpResponse; + + return $this; + } +} diff --git a/src/Rede/Service/AbstractTransactionsService.php b/src/Rede/Service/AbstractTransactionsService.php index 17c3b26..934fe2f 100644 --- a/src/Rede/Service/AbstractTransactionsService.php +++ b/src/Rede/Service/AbstractTransactionsService.php @@ -78,6 +78,7 @@ protected function parseResponse(string $response, int $statusCode): Transaction } try { + $this->transaction->setHttpResponse(new \Rede\Http\RedeResponse($statusCode, $response)); $this->transaction->jsonUnserialize($response); } catch (\InvalidArgumentException $e) { $previous = $e; diff --git a/src/Rede/Transaction.php b/src/Rede/Transaction.php index 2cff921..cb4df16 100644 --- a/src/Rede/Transaction.php +++ b/src/Rede/Transaction.php @@ -4,6 +4,8 @@ class Transaction implements RedeSerializable, RedeUnserializable { + use ResponseTrait; + public const CREDIT = 'credit'; public const DEBIT = 'debit'; @@ -733,7 +735,8 @@ public function jsonUnserialize(string $serialized): static } foreach (get_object_vars($properties) as $property => $value) { - if ('links' == $property) { + // TODO verify why use urls in request and not use links in response + if ('links' === $property) { continue; } From bfa932b93f08912e5f8787e45687b6a700e24b6f Mon Sep 17 00:00:00 2001 From: Edson Nascimento Date: Mon, 2 Jun 2025 14:48:19 -0300 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8=20Adicionar=20prop=20`brand`=20em?= =?UTF-8?q?=20`Authorization`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rede/Authorization.php | 26 ++++++++++++++++++++++++++ src/Rede/CreateTrait.php | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/src/Rede/Authorization.php b/src/Rede/Authorization.php index 49ca073..4c36565 100644 --- a/src/Rede/Authorization.php +++ b/src/Rede/Authorization.php @@ -40,6 +40,17 @@ class Authorization private ?string $tid = null; + private ?Brand $brand = null; + + /** + * @return array + */ + protected function getObjectMapping(): array + { + return ['brand' => Brand::class]; + } + + // gets and sets public function getAffiliation(): ?string { return $this->affiliation; @@ -294,4 +305,19 @@ public function setTid(?string $tid): static return $this; } + + public function getBrand(): ?Brand + { + return $this->brand; + } + + /** + * @return $this + */ + public function setBrand(Brand $brand): static + { + $this->brand = $brand; + + return $this; + } } diff --git a/src/Rede/CreateTrait.php b/src/Rede/CreateTrait.php index 396cbf6..9c72138 100644 --- a/src/Rede/CreateTrait.php +++ b/src/Rede/CreateTrait.php @@ -11,11 +11,15 @@ public function populate(object $body): static { $bodyKeys = get_object_vars($body); $dateTimeProps = ['requestDateTime', 'dateTime', 'refundDateTime', 'dateTimeExpiration', 'expirationQrCode']; + $objectMapping = method_exists($this, 'getObjectMapping') ? $this->getObjectMapping() : []; foreach ($bodyKeys as $property => $value) { if (property_exists($this, $property) && null !== $value) { if (in_array($property, $dateTimeProps) && is_string($value)) { $value = new \DateTime($value); + } elseif ($objectMapping && isset($objectMapping[$property]) && !empty($value)) { + // @phpstan-ignore-next-line + $value = (new $objectMapping[$property]())?->populate($value); } $this->{$property} = $value; From f88425027b8fe421e3a7e179a62079a3665778ce Mon Sep 17 00:00:00 2001 From: Edson Nascimento Date: Mon, 2 Jun 2025 14:53:06 -0300 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20Adicionar=20novos=20campos=20em?= =?UTF-8?q?=20`Brand`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- composer.json | 10 +- src/Rede/Brand.php | 42 ++++++++ tests/Unit/TransactionUnitTest.php | 152 +++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 tests/Unit/TransactionUnitTest.php diff --git a/README.md b/README.md index 959661e..f9a8e6b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Este SDK possui as seguintes funcionalidades: ## Dependências -- PHP >= 8.1 +- PHP >= 8.2 ## Instalando o SDK @@ -380,3 +380,9 @@ if ($transaction->getReturnCode() == '00') { ); } ``` + +## Observações + +- Ao criar uma transação com `$transaction = (new eRede($store))->create($transaction)` não vai retornar o campo `authorization`, para retornar o campo é preciso fazer uma consulta `$transaction = (new eRede($store))->get('TID123')` +- O campo `$transaction->getAuthorizationCode()` não está retornando nada, use `$transaction->getBrand()?->getAuthorizationCode()` ou `$transaction->getAuthorization()?->getBrand()?->getAuthorizationCode()` +- Caso precise acessar o JSON original do response utilize `$transaction?->getHttpResponse()->getBody()` diff --git a/composer.json b/composer.json index fc1a15b..d180846 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "silbeckdevs/erede-php", - "version": "1.0.0", + "version": "1.0.1", "description": "e.Rede integration SDK", "minimum-stability": "stable", "license": "MIT", @@ -12,11 +12,11 @@ "psr/log": "*" }, "require-dev": { - "phpunit/phpunit": "^11.5.6", - "phpstan/phpstan": "^1.12.16", + "phpunit/phpunit": "^12.1.6", + "phpstan/phpstan": "^1.12.27", "kint-php/kint": "^6.0.1", - "monolog/monolog": "^3.8.1", - "friendsofphp/php-cs-fixer": "^3.68.5", + "monolog/monolog": "^3.9.0", + "friendsofphp/php-cs-fixer": "^3.75.0", "brainmaestro/composer-git-hooks": "^3.0.0" }, "autoload": { diff --git a/src/Rede/Brand.php b/src/Rede/Brand.php index f64dbb2..2488a10 100644 --- a/src/Rede/Brand.php +++ b/src/Rede/Brand.php @@ -12,6 +12,12 @@ class Brand private ?string $returnMessage = null; + private ?string $merchantAdviceCode = null; + + private ?string $authorizationCode = null; + + private ?string $brandTid = null; + public function getName(): ?string { return $this->name; @@ -47,4 +53,40 @@ public function setReturnMessage(?string $returnMessage): Brand return $this; } + + public function getMerchantAdviceCode(): ?string + { + return $this->merchantAdviceCode; + } + + public function setMerchantAdviceCode(?string $merchantAdviceCode): Brand + { + $this->merchantAdviceCode = $merchantAdviceCode; + + return $this; + } + + public function getAuthorizationCode(): ?string + { + return $this->authorizationCode; + } + + public function setAuthorizationCode(?string $authorizationCode): Brand + { + $this->authorizationCode = $authorizationCode; + + return $this; + } + + public function getBrandTid(): ?string + { + return $this->brandTid; + } + + public function setBrandTid(?string $brandTid): Brand + { + $this->brandTid = $brandTid; + + return $this; + } } diff --git a/tests/Unit/TransactionUnitTest.php b/tests/Unit/TransactionUnitTest.php new file mode 100644 index 0000000..64d8924 --- /dev/null +++ b/tests/Unit/TransactionUnitTest.php @@ -0,0 +1,152 @@ +jsonUnserialize($this->getJsonTransactionMock()); + + $this->assertNull($transaction->getAuthorization()); + $this->assertNull($transaction->getCapture()); + + $this->assertSame(20099, $transaction->getAmount()); + $this->assertSame('12345678', $transaction->getTid()); + $this->assertSame('306718396', $transaction->getNsu()); + $this->assertSame('544828', $transaction->getCardBin()); + $this->assertSame('0007', $transaction->getLast4()); + $this->assertSame('00', $transaction->getReturnCode()); + $this->assertSame('2025-06-02T13:15:39-03:00', $transaction->getDateTime()?->format('c')); + + $this->assertIsObject($transaction->getBrand()); + $this->assertSame('Mastercard', $transaction->getBrand()->getName()); + $this->assertSame('00', $transaction->getBrand()->getReturnCode()); + $this->assertSame('Success.', $transaction->getBrand()->getReturnMessage()); + $this->assertSame('MCS1616339888484', $transaction->getBrand()->getBrandTid()); + $this->assertSame('67404', $transaction->getBrand()->getAuthorizationCode()); + } + + public function testShouldPopulateAuthorization(): void + { + $transaction = (new Transaction())->jsonUnserialize($this->getJsonAuthorizationMock()); + + $this->assertNull($transaction->getBrand()); + + $this->assertIsObject($transaction->getAuthorization()); + $this->assertSame('Approved', $transaction->getAuthorization()->getStatus()); + $this->assertSame(20099, $transaction->getAuthorization()->getAmount()); + $this->assertSame('12345678', $transaction->getAuthorization()->getTid()); + $this->assertSame('306718396', $transaction->getAuthorization()->getNsu()); + $this->assertSame('544828', $transaction->getAuthorization()->getCardBin()); + $this->assertSame('0007', $transaction->getAuthorization()->getLast4()); + $this->assertSame('00', $transaction->getAuthorization()->getReturnCode()); + $this->assertSame('Credit', $transaction->getAuthorization()->getKind()); + $this->assertSame('2025-06-02T13:15:39-03:00', $transaction->getAuthorization()->getDateTime()?->format('c')); + $this->assertSame('John Snow', $transaction->getAuthorization()->getCardHolderName()); + $this->assertSame('1', $transaction->getAuthorization()->getOrigin()); + $this->assertEmpty($transaction->getAuthorization()->getSubscription()); + + $this->assertIsObject($transaction->getAuthorization()->getBrand()); + $this->assertSame('Mastercard', $transaction->getAuthorization()->getBrand()->getName()); + $this->assertSame('Success.', $transaction->getAuthorization()->getBrand()->getReturnMessage()); + $this->assertSame('00', $transaction->getAuthorization()->getBrand()->getReturnCode()); + $this->assertSame('MCS1616339888484', $transaction->getAuthorization()->getBrand()->getBrandTid()); + $this->assertSame('67404', $transaction->getAuthorization()->getBrand()->getAuthorizationCode()); + + $this->assertIsObject($transaction->getCapture()); + $this->assertSame('2025-06-02T13:15:39-03:00', $transaction->getCapture()->getDateTime()?->format('c')); + $this->assertSame(20099, $transaction->getCapture()->getAmount()); + $this->assertSame('306718396', $transaction->getCapture()->getNsu()); + } + + private function getJsonTransactionMock(): string + { + return ' + { + "reference": "683dce2f41d8a", + "tid": "12345678", + "nsu": "306718396", + "dateTime": "2025-06-02T13:15:39-03:00", + "amount": 20099, + "cardBin": "544828", + "last4": "0007", + "brand": { + "returnCode": "00", + "brandTid": "MCS1616339888484", + "authorizationCode": "67404", + "name": "Mastercard", + "returnMessage": "Success." + }, + "returnCode": "00", + "returnMessage": "Success.", + "links": [ + { + "method": "GET", + "rel": "transaction", + "href": "https://sandbox-erede.useredecloud.com.br/v1/transactions/12345678" + }, + { + "method": "POST", + "rel": "refund", + "href": "https://sandbox-erede.useredecloud.com.br/v1/transactions/12345678/refunds" + } + ] + } + '; + } + + private function getJsonAuthorizationMock(): string + { + return ' + { + "requestDateTime": "2025-06-02T13:15:40-03:00", + "authorization": { + "dateTime": "2025-06-02T13:15:39-03:00", + "returnCode": "00", + "returnMessage": "Success.", + "affiliation": 38421438, + "status": "Approved", + "reference": "683dce2f41d8a", + "tid": "12345678", + "nsu": "306718396", + "kind": "Credit", + "amount": 20099, + "installments": 0, + "cardHolderName": "John Snow", + "cardBin": "544828", + "last4": "0007", + "origin": 1, + "subscription": false, + "brand": { + "name": "Mastercard", + "returnMessage": "Success.", + "returnCode": "00", + "brandTid": "MCS1616339888484", + "authorizationCode": "67404" + } + }, + "capture": { + "dateTime": "2025-06-02T13:15:39-03:00", + "nsu": "306718396", + "amount": 20099 + }, + "links": [ + { + "method": "GET", + "rel": "refunds", + "href": "https://sandbox-erede.useredecloud.com.br/v1/transactions/12345678/refunds" + }, + { + "method": "POST", + "rel": "refund", + "href": "https://sandbox-erede.useredecloud.com.br/v1/transactions/12345678/refunds" + } + ] + } + '; + } +}