diff --git a/upload/system/library/PagSeguro/src/Domains/Error.php b/upload/system/library/PagSeguro/src/Domains/Error.php new file mode 100644 index 0000000..55c10be --- /dev/null +++ b/upload/system/library/PagSeguro/src/Domains/Error.php @@ -0,0 +1,31 @@ +code = $code; + $this->msg = $msg; + } + + /** + * @return int + */ + public function getCode(): int + { + return $this->code; + } + + /** + * @return string + */ + public function getMessage(): int + { + return $this->msg; + } +} diff --git a/upload/system/library/PagSeguro/src/Domains/Payment.php b/upload/system/library/PagSeguro/src/Domains/Payment.php index 710f168..bc7d8cc 100644 --- a/upload/system/library/PagSeguro/src/Domains/Payment.php +++ b/upload/system/library/PagSeguro/src/Domains/Payment.php @@ -345,6 +345,12 @@ public static function fromXml(string $value) $instance->shipping = Shipping::fromXml($dom->saveXML($shipping->item(0))); } + $creditCard = $xpath->query('/payment/creditCard'); + + if ($creditCard->count() > 0) { + $instance->creditCard = creditCard::fromXml($dom->saveXML($shipping->item(0))); + } + return $instance; } @@ -392,12 +398,16 @@ public function toXml() if ($this->shipping) { $arr['shipping'] = $this->shipping->toArray(true); } + + if ($this->payment instanceof CreditCard) { + $arr['creditCard'] = $this->payment->toArray(true); + } $parser = new XmlParser(); $result = $parser->parser([ 'payment' => $arr ]); - return $result->saveXML(); + return $result->saveXML(null); } } diff --git a/upload/system/library/PagSeguro/src/Domains/PaymentMethod/CreditCard.php b/upload/system/library/PagSeguro/src/Domains/PaymentMethod/CreditCard.php index 646fadc..9af5d69 100644 --- a/upload/system/library/PagSeguro/src/Domains/PaymentMethod/CreditCard.php +++ b/upload/system/library/PagSeguro/src/Domains/PaymentMethod/CreditCard.php @@ -5,11 +5,12 @@ use DOMDocument; use DOMXPath; use ValdeirPsr\PagSeguro\Interfaces\Serializer\Xml; +use ValdeirPsr\PagSeguro\Interfaces\Serializer\IArray; use ValdeirPsr\PagSeguro\Parser\Xml as XmlParser; use ValdeirPsr\PagSeguro\Domains\User\Holder; use ValdeirPsr\PagSeguro\Domains\Address; -class CreditCard extends AbstractPaymentMethod implements Xml +class CreditCard extends AbstractPaymentMethod implements IArray, Xml { /** @var string */ private $token; @@ -200,18 +201,26 @@ public function toXml(): string { $parser = new XmlParser(); $result = $parser->parser([ - 'creditCard' => [ - 'token' => $this->token, - 'installment' => [ - 'quantity' => $this->installmentQuantity, - 'value' => $this->installmentValue, - 'noInterestInstallmentQuantity' => $this->noInterestInstallmentQuantity - ], - 'holder' => $this->holder->toArray(), - 'billingAddress' => $this->billingAddress->toArray() - ] + 'creditCard' => $this->toArray() ]); return $result->saveXML(); } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return array_filter([ + 'token' => $this->token, + 'installment' => array_filter([ + 'quantity' => $this->installmentQuantity, + 'value' => $this->installmentValue, + 'noInterestInstallmentQuantity' => $this->noInterestInstallmentQuantity + ]), + 'holder' => $this->holder->toArray(), + 'billingAddress' => $this->billingAddress->toArray() + ]); + } } diff --git a/upload/system/library/PagSeguro/src/Exception/PagSeguroRequest.php b/upload/system/library/PagSeguro/src/Exception/PagSeguroRequest.php new file mode 100644 index 0000000..94668fe --- /dev/null +++ b/upload/system/library/PagSeguro/src/Exception/PagSeguroRequest.php @@ -0,0 +1,122 @@ +request = $curl; + $this->requestBody = $requestBody; + + $this->checkErrors(); + } + + /** + * @return Curl + */ + public function getRequest(): Curl + { + return $request; + } + + /** + * @return mixed Retorna a resposta do servidor + */ + public function getResponse() + { + return $this->request->getResponse(); + } + + /** + * @return int Retorna o Status Code da resposta + */ + public function getHttpStatus(): int + { + return $this->request->getHttpstatus(); + } + + /** + * Define o corpo da mensagem enviada + * + * @param mixed $value + * + * @return self + */ + public function setRequestBody($value) + { + $this->requestBody = $value; + + return $this; + } + + /** + * @return mixed + */ + public function getRequestBody() + { + return $this->requestBody; + } + + /** + * @return Error[] + */ + public function getErrors(): array + { + return $this->errors; + } + + /** + * Verifica os erros recebidos pela API + * + * @return void + */ + private function checkErrors() + { + $response = $this->getResponse(); + + if ($response) { + $responseDom = new DOMDocument(); + $status = $responseDom->loadXML($response, LIBXML_NOERROR); + + if ($status) { + $errors = $responseDom->getElementsByTagName('error'); + + foreach ($errors as $error) { + $code = $error->getElementsByTagName('code'); + $msg = $error->getElementsByTagName('message'); + + if ($code->count() > 0) { + $code = intval($code->item(0)->textContent); + } else { + $code = 0; + } + + if ($msg->count() > 0) { + $msg = trim($msg->item(0)->textContent); + } else { + $msg = $response; + } + + $this->errors[] = new Error($msg, $code); + } + } else { + $this->errors[] = new Error($response); + } + } else { + $this->errors[] = new Error('PagSeguroRequest :: Response empty'); + } + } +} diff --git a/upload/system/library/PagSeguro/src/Request/Sale.php b/upload/system/library/PagSeguro/src/Request/Sale.php index 713ce2f..7dc5b99 100644 --- a/upload/system/library/PagSeguro/src/Request/Sale.php +++ b/upload/system/library/PagSeguro/src/Request/Sale.php @@ -6,6 +6,7 @@ use ValdeirPsr\PagSeguro\Domains\Payment; use ValdeirPsr\PagSeguro\Domains\Transaction; use ValdeirPsr\PagSeguro\Exception\Auth as AuthException; +use ValdeirPsr\PagSeguro\Exception\PagSeguroRequest as PagSeguroRequestException; class Sale { @@ -18,20 +19,7 @@ public function __construct(Environment $env) public function create(Payment $payment) { - $url = $this->buildUrl(); - - $request = Factory::request($this->env); - $request->setHeader('Content-Type', 'application/xml; charset=ISO-8859-1'); - $request->post($url, $payment->toXml()); - $request->close(); - - if ($request->isSuccess()) { - return Transaction::fromXml($request->getResponse()); - } elseif ($request->getHttpStatus() === 401) { - throw new AuthException('Check your credentials', 1000); - } else { - throw new PagSeguroRequestException($request); - } + return Transaction::fromXml($this->request($payment)); } /** @@ -44,4 +32,26 @@ protected function buildUrl(): string 'token' => $this->env->getToken() ]); } + + /** + * {@inheritDoc} + */ + protected function request(Payment $payment) + { + $url = $this->buildUrl(); + $data = $payment->toXml(); + + $request = Factory::request($this->env); + $request->setHeader('Content-Type', 'application/xml; charset=ISO-8859-1'); + $request->post($url, $data); + $request->close(); + + if ($request->isSuccess()) { + return $request->getResponse(); + } elseif ($request->getHttpStatus() === 401) { + throw new AuthException('Check your credentials', 1000); + } else { + throw new PagSeguroRequestException($request, $data); + } + } } diff --git a/upload/system/library/PagSeguro/tests/data/sale/invalid-creditcard.xml b/upload/system/library/PagSeguro/tests/data/sale/invalid-creditcard.xml new file mode 100644 index 0000000..d075990 --- /dev/null +++ b/upload/system/library/PagSeguro/tests/data/sale/invalid-creditcard.xml @@ -0,0 +1,71 @@ + + + default + creditcard + + Florbela Espanca + fulano.silva.sandbox.pagseguro.com.br + + 11 + 30380000 + + + + CPF + 72962940005 + + + + BRL + https://sualoja.com.br/notificacao + + + 1 + Antologia poetica de Florbela Espanca + 2780 + 1 + + + 2 + Poesia de Florbela Espanca + 15.600 + 1 + + + R123456 + + 30 + 0.00 + true + + + e79fc9be6fd14b3c8b6164f21ba3c464 + + 3 + 14.46 + + + Nome impresso no cartao + 20/10/2021 + + + CPF + 25136624078 + + + + 11 + 999991111 + + + + Av. Brigadeiro Faria Lima + 1 andar + Jardim Paulistano + Sao Paulo + SP + BRA + 01452002 + + + diff --git a/upload/system/library/PagSeguro/tests/unit/Request/SaleTest.php b/upload/system/library/PagSeguro/tests/unit/Request/SaleTest.php index 6cfbd98..2044c0b 100644 --- a/upload/system/library/PagSeguro/tests/unit/Request/SaleTest.php +++ b/upload/system/library/PagSeguro/tests/unit/Request/SaleTest.php @@ -4,9 +4,15 @@ use ValdeirPsr\PagSeguro\Constants\PaymentMethod\Methods as PaymentMethods; use ValdeirPsr\PagSeguro\Domains\Environment; use ValdeirPsr\PagSeguro\Domains\Payment; +use ValdeirPsr\PagSeguro\Domains\Error; +use \ValdeirPsr\PagSeguro\Domains\Document; +use \ValdeirPsr\PagSeguro\Domains\Address; +use ValdeirPsr\PagSeguro\Domains\PaymentMethod\CreditCard; +use ValdeirPsr\PagSeguro\Domains\User\Holder; use ValdeirPsr\PagSeguro\Request\Factory; use ValdeirPsr\PagSeguro\Request\Sale; use ValdeirPsr\PagSeguro\Exception\Auth as AuthException; +use ValdeirPsr\PagSeguro\Exception\PagSeguroRequest as PagSeguroRequestException; class SaleTest extends TestCase { @@ -87,9 +93,7 @@ public function createSaleWithCreditCardAndValidArguments() { $env = Environment::sandbox('pagseguro@valdeir.dev', '1234567890'); - $xml = file_get_contents('tests/data/sale/valid-creditcard.xml'); - - $payment = Payment::fromXml($xml); + $payment = new Payment(); $stub = $this->getMockBuilder(Sale::class) ->setConstructorArgs([$env]) @@ -113,4 +117,101 @@ public function createSaleWithCreditCardAndValidArguments() $this->assertEquals('1056784170', $newPayment->getGatewaySystem()->getEstablishmentCode()); $this->assertEquals('CIELO', $newPayment->getGatewaySystem()->getAcquirerName()); } + + /** + * @test + */ + public function createSaleWithCreditCardAndInvalidArgumentsShouldGiveError() + { + try { + $env = Environment::sandbox('pagseguro@valdeir.dev', '1234567890'); + + $payment = Payment::fromXml(file_get_contents('tests/data/sale/invalid-creditcard.xml')); + + $creditCard = new CreditCard(); + $creditCard->setToken('e79fc9be6fd14b3c8b6164f21ba3c464'); + $creditCard->setInstallmentQuantity(3); + $creditCard->setInstallmentValue(14.46); + + $holder = new Holder(); + $holder->setName('Nome impresso no cartao'); + $holder->setBirthDate(DateTime::createFromFormat('d/m/Y', '20/10/2021')); + $holder->setDocument(Document::cpf('25136624078')); + $holder->setPhone('11', '999991111'); + $creditCard->setHolder($holder); + + $address = new Address(); + $address->setStreet('Av. Brigadeiro Faria Lima'); + $address->setComplement('1 andar'); + $address->setDistrict('Jardim Paulistano'); + $address->setCity('Sao Paulo'); + $address->setState('SP'); + $address->setPostalCode('01452002'); + $creditCard->setBillingAddress($address); + + $payment->setPayment($creditCard); + + $stub = $this->getMockBuilder(Sale::class) + ->setConstructorArgs([$env]) + ->setMethods(['buildUrl']) + ->getMock(); + + $stub->expects($this->any()) + ->method('buildUrl') + ->willReturn('https://f3528d51-6219-4b80-8bd3-3ab112b8094f.mock.pstmn.io/v2/transactions/creditcard-invalid'); + + $newPayment = $stub->create($payment); + } catch (PagSeguroRequestException $request) { + $errors = $request->getErrors(); + + $this->assertNotEmpty($errors); + $this->assertContainsOnlyInstancesOf(Error::class, $errors); + $this->assertXmlStringEqualsXmlFile('tests/data/sale/invalid-creditcard.xml', $request->getRequestBody()); + } + } + + /** + * @test + */ + public function createSaleWithCreditCardAndValidArgumentsAndInvalidCredentialsShouldGiveError() + { + $this->expectException(AuthException::class); + $env = Environment::sandbox('pagseguro@valdeir.dev', '1234567890'); + + $payment = Payment::fromXml(file_get_contents('tests/data/sale/valid-creditcard.xml')); + + $creditCard = new CreditCard(); + $creditCard->setToken('e79fc9be6fd14b3c8b6164f21ba3c464'); + $creditCard->setInstallmentQuantity(3); + $creditCard->setInstallmentValue(14.46); + + $holder = new Holder(); + $holder->setName('Nome impresso no cartao'); + $holder->setBirthDate(DateTime::createFromFormat('d/m/Y', '20/10/2021')); + $holder->setDocument(Document::cpf('25136624078')); + $holder->setPhone('11', '999991111'); + $creditCard->setHolder($holder); + + $address = new Address(); + $address->setStreet('Av. Brigadeiro Faria Lima'); + $address->setComplement('1 andar'); + $address->setDistrict('Jardim Paulistano'); + $address->setCity('Sao Paulo'); + $address->setState('SP'); + $address->setPostalCode('01452002'); + $creditCard->setBillingAddress($address); + + $payment->setPayment($creditCard); + + $stub = $this->getMockBuilder(Sale::class) + ->setConstructorArgs([$env]) + ->setMethods(['buildUrl']) + ->getMock(); + + $stub->expects($this->any()) + ->method('buildUrl') + ->willReturn('https://f3528d51-6219-4b80-8bd3-3ab112b8094f.mock.pstmn.io/v2/transactions/creditcard-valid-invalid-session'); + + $newPayment = $stub->create($payment); + } }