diff --git a/app/src/Service/MediosPago/AbstractEndPoint.php b/app/src/Service/MediosPago/AbstractEndPoint.php index 6049832..882b931 100644 --- a/app/src/Service/MediosPago/AbstractEndPoint.php +++ b/app/src/Service/MediosPago/AbstractEndPoint.php @@ -9,6 +9,7 @@ use Psr\Http\Message\ResponseInterface; use Incoviba\Common\Define\Repository; use Incoviba\Common\Implement\Exception\{EmptyResponse, EmptyResult}; use Incoviba\Common\Ideal\LoggerEnabled; +use Incoviba\Exception\InvalidResult; abstract class AbstractEndPoint extends LoggerEnabled implements EndPoint { @@ -147,7 +148,7 @@ abstract class AbstractEndPoint extends LoggerEnabled implements EndPoint * @param string $id * @param string $message * @return array - * @throws EmptyResponse + * @throws InvalidResult */ protected function doGetById(callable $callable, string $id, string $message): array { @@ -155,7 +156,7 @@ abstract class AbstractEndPoint extends LoggerEnabled implements EndPoint $model = $callable($id); return json_decode(json_encode($model), true); } catch (EmptyResult $exception) { - throw new EmptyResponse($message, $exception); + throw new InvalidResult($message, 404, $exception); } } diff --git a/app/src/Service/MediosPago/EndPoint.php b/app/src/Service/MediosPago/EndPoint.php index bf4c2ea..3aaf17a 100644 --- a/app/src/Service/MediosPago/EndPoint.php +++ b/app/src/Service/MediosPago/EndPoint.php @@ -2,15 +2,23 @@ namespace Incoviba\Service\MediosPago; use Incoviba\Common\Implement\Exception\EmptyResponse; +use Incoviba\Exception\InvalidResult; interface EndPoint { /** * @param string $id * @return array - * @throws EmptyResponse + * @throws InvalidResult */ public function getById(string $id): array; + + /** + * @param string $id + * @return array + * @throws InvalidResult + */ + public function getByExternalId(string $id): array; /** * @param string $id * @return array diff --git a/app/src/Service/MediosPago/Toku.php b/app/src/Service/MediosPago/Toku.php index 4def84a..b8347c0 100644 --- a/app/src/Service/MediosPago/Toku.php +++ b/app/src/Service/MediosPago/Toku.php @@ -2,10 +2,12 @@ namespace Incoviba\Service\MediosPago; use InvalidArgumentException; -use Psr\Http\Client\ClientInterface; use Psr\Log\LoggerInterface; use Incoviba\Common\Ideal; use Incoviba\Common\Implement\Exception\EmptyResponse; +use Incoviba\Exception\InvalidResult; +use Incoviba\Model\Persona; +use Incoviba\Model\Venta\Propietario; use Incoviba\Model; class Toku extends Ideal\Service @@ -32,16 +34,16 @@ class Toku extends Ideal\Service } /** - * @param Model\Persona $persona + * @param Persona|Propietario $persona * @return array - * @throws EmptyResponse + * @throws InvalidResult */ public function sendPersona(Model\Persona|Model\Venta\Propietario $persona): array { $rut = implode('', [$persona->rut, strtoupper($persona->dv)]); try { return $this->customer->getById($rut); - } catch (EmptyResponse $exception) { + } catch (InvalidResult $exception) { $datos = $persona->datos; $customerData = [ 'rut' => $rut, @@ -49,30 +51,38 @@ class Toku extends Ideal\Service 'email' => $datos?->email ?? '', 'telefono' => $datos?->telefono ?? '' ]; - if (!$this->customer->add($customerData)) { - throw new EmptyResponse("Could not save Customer for Persona {$rut}", $exception); + try { + if (!$this->customer->add($customerData)) { + throw new InvalidResult("Could not save Customer for Persona {$rut}", 409, $exception); + } + } catch (EmptyResponse $exception) { + throw new InvalidResult("Could not save Customer for Persona {$rut}", 409, $exception); } return $this->customer->getById($rut); } } /** * @param Model\Venta $venta - * @return bool - * @throws EmptyResponse + * @return array + * @throws InvalidResult */ public function sendVenta(Model\Venta $venta): array { $customer = $this->sendPersona($venta->propietario()); try { return $this->subscription->getById($venta->id); - } catch (EmptyResponse $exception) { + } catch (InvalidResult $exception) { $subscriptionData = [ 'customer' => $customer['toku_id'], 'product_id' => $venta->id, 'venta' => $venta ]; - if (!$this->subscription->add($subscriptionData)) { - throw new EmptyResponse("Could not save Subscription for Venta {$venta->id}", $exception); + try { + if (!$this->subscription->add($subscriptionData)) { + throw new InvalidResult("Could not save Subscription for Venta {$venta->id}", 409, $exception); + } + } catch (EmptyResponse $exception) { + throw new InvalidResult("Could not save Subscription for Venta {$venta->id}", 409, $exception); } return $this->subscription->getById($venta->id); } @@ -80,10 +90,11 @@ class Toku extends Ideal\Service /** * @param Model\Venta $venta + * @param array $cuotas_ids * @return array - * @throws EmptyResponse + * @throws InvalidResult */ - public function sendCuotas(Model\Venta $venta): array + public function sendCuotas(Model\Venta $venta, array $cuotas_ids = []): array { $customer = $this->sendPersona($venta->propietario()); $subscription = $this->sendVenta($venta); @@ -91,9 +102,12 @@ class Toku extends Ideal\Service $invoices = []; $errors = []; foreach ($venta->formaPago()->pie->cuotas() as $cuota) { + if (count($cuotas_ids) > 0 and !in_array($cuota->id, $cuotas_ids)) { + continue; + } try { $invoices []= $this->invoice->getById($cuota->id); - } catch (EmptyResponse $exception) { + } catch (InvalidResult $exception) { try { $invoiceData = [ 'customer' => $customer['toku_id'], @@ -116,4 +130,18 @@ class Toku extends Ideal\Service } return $invoices; } + + /** + * @param array $request + * @return bool + * @throws InvalidResult + */ + public function updatePago(array $request): bool + { + # If $customer is not found, it will throw an exception and stop + $customer = $this->customer->getByExternalId($request['customer']); + $invoice = $this->invoice->getByExternalId($request['invoice']); + + return $this->invoice->update($invoice['id'], $request); + } } diff --git a/app/src/Service/MediosPago/Toku/Customer.php b/app/src/Service/MediosPago/Toku/Customer.php index eb40a7b..519b2de 100644 --- a/app/src/Service/MediosPago/Toku/Customer.php +++ b/app/src/Service/MediosPago/Toku/Customer.php @@ -17,6 +17,10 @@ class Customer extends AbstractEndPoint { return $this->doGetById([$this->customerRepository, 'fetchByRut'], $id, "No existe toku_id para Persona {$id}"); } + public function getByExternalId(string $id): array + { + return $this->doGetById([$this->customerRepository, 'fetchByTokuId'], $id, "No existe Customer para toku_id {$id}"); + } public function get(string $id): array { $request_uri = "/customers/{$id}"; diff --git a/app/src/Service/MediosPago/Toku/Invoice.php b/app/src/Service/MediosPago/Toku/Invoice.php index 0d8237d..a818198 100644 --- a/app/src/Service/MediosPago/Toku/Invoice.php +++ b/app/src/Service/MediosPago/Toku/Invoice.php @@ -1,14 +1,22 @@ doGetById([$this->invoiceRepository, 'fetchByCuota'], $id, "No existe toku_id para Cuota {$id}"); } + public function getByExternalId(string $id): array + { + return $this->doGetById([$this->invoiceRepository, 'fetchByTokuId'], $id, "No existe Invoice para toku_id {$id}"); + } public function get(string $id): array { $request_uri = "/invoices/{$id}"; @@ -38,6 +50,38 @@ class Invoice extends AbstractEndPoint $this->sendDelete($request_uri, [204], [404, 409]); } + /** + * @param string $invoice_toku_id + * @param array $data + * @return bool + * @throws InvalidResult + */ + public function update(string $invoice_toku_id, array $data): bool + { + try { + $invoice = $this->invoiceRepository->fetchByTokuId($invoice_toku_id); + } catch (EmptyResult $exception) { + throw new InvalidResult("No existe Invoice para toku_id {$invoice_toku_id}", 404, $exception); + } + if ($data['status'] !== 'AUTHORIZED') { + throw new InvalidResult("Pago no autorizado", 422); + } + try { + $date = new DateTimeImmutable($data['transaction_date']); + } catch (DateMalformedStringException $exception) { + throw new InvalidResult("Fecha no válida: {$data['transaction_date']}", 422, $exception); + } + $uf = $this->ufService->get($date); + if ($uf === 0.0) { + throw new InvalidResult("No hay UF para la fecha: {$data['transaction_date']}", 422); + } + $valor = $data['amount'] / $uf; + if (abs($valor - $invoice->cuota->pago->valor()) >= 0.0001) { + throw new InvalidResult("Valor en UF no coincide: {$data['amount']}", 422); + } + return $this->pagoService->depositar($invoice->cuota->pago, $date); + } + protected function save(array $data): bool { return $this->doSave($this->invoiceRepository, $data); @@ -71,7 +115,7 @@ class Invoice extends AbstractEndPoint continue; } if ($ref === 'valor') { - $params[$key] = $data['cuota']->pago->valor; + $params[$key] = $data['cuota']->pago->valor(); continue; } if ($ref === 'datosCuota') { @@ -104,7 +148,7 @@ class Invoice extends AbstractEndPoint return $mappedData; } - protected function datosCuota(Cuota $cuota): string + protected function datosCuota(Model\Venta\Cuota $cuota): string { return json_encode([ 'Numero' => $cuota->numero, diff --git a/app/src/Service/MediosPago/Toku/Subscription.php b/app/src/Service/MediosPago/Toku/Subscription.php index b365a55..c31b773 100644 --- a/app/src/Service/MediosPago/Toku/Subscription.php +++ b/app/src/Service/MediosPago/Toku/Subscription.php @@ -17,6 +17,11 @@ class Subscription extends AbstractEndPoint { return $this->doGetById([$this->subscriptionRepsitory, 'fetchByVenta'], $id, "No existe toku_id para Venta {$id}"); } + public function getByExternalId(string $id): array + { + return $this->doGetById([$this->subscriptionRepsitory, 'fetchByTokuId'], $id, "No existe Subscription para toku_id {$id}"); + } + public function get(string $id): array { $request_uri = "/subscriptions/{$id}";