diff --git a/plugin/css/tbk.css b/plugin/css/tbk.css index 002ae3f4..16b072ac 100644 --- a/plugin/css/tbk.css +++ b/plugin/css/tbk.css @@ -1,3 +1,12 @@ +:root { + --tbk-red: #D5006C; + --tbk-red-2: #C00063; + --tbk-success: #28a745; + --tbk-info: #007bff; + --tbk-warning: #fd7e14; + --tbk-error: #dc3545; + --tbk-default: #6c757d: +} .tbk_table_info { width: 600px; @@ -221,8 +230,6 @@ } .tbk-box { - --tbk-red: #D5006C; - --tbk-red-2: #C00063; background: #fff; border-radius: 10px; padding: 15px; @@ -413,3 +420,95 @@ font-size: 18px; font-weight: 500; } + +.tbk-field { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + font-size: 14px; + line-height: 1.4; +} + +.tbk-field-name { + font-weight: bold; + margin-right: 8px; +} + +.tbk-field-value { + text-align: right; + word-break: break-word; +} + +.tbk-badge { + padding: 2px 6px; + border-radius: 4px; + font-size: 12px; + font-weight: bold; + color: white +} + +.tbk-badge-success { + background-color: var(--tbk-success); +} + +.tbk-badge-info { + background-color: var(--tbk-info); +} + +.tbk-badge-warning { + background-color: var(--tbk-warning); +} + +.tbk-badge-error { + background-color: var(--tbk-error); +} + +.tbk-badge-default { + background-color: var(--tbk-default); +} + +.tbk-status { + display: flex; + flex-direction: row; + align-items: center; +} + +.tbk-status i { + width: 100px; + max-width: 24px; + text-align: center; + font-size: x-large; +} + +.tbk-status p { + padding-left: 10px; + margin: 0px; +} + +.tbk-status.tbk-status-info i { + color: var(--tbk-info); +} + +.tbk-status.tbk-status-error i, .tbk-status.tbk-status-error p { + color: var(--tbk-error); + font-weight: bold; +} + +.tbk-status-button { + display: flex; + justify-content: center; + margin-bottom: 10px; +} + +.tbk-status-button .tbk-button-primary { + width: 100%; + text-align: center; +} + +.tbk-separator { + width: 100%; + height: 1px; + background-color: #ccc; + margin: 10px 0; +} diff --git a/plugin/js/admin.js b/plugin/js/admin.js index 287557d8..fd1a146a 100644 --- a/plugin/js/admin.js +++ b/plugin/js/admin.js @@ -13,7 +13,9 @@ jQuery(function($) { if ($(`.${btnName}`).data('sending') === true) { return false; } - $(`.${btnName}`).data('sending', true).html(msg); + const btn = $(`.${btnName}`); + btn.data('sending', true).html(`${msg} `); + e.preventDefault(); return true; } @@ -72,40 +74,113 @@ jQuery(function($) { }); $('.get-transaction-status').on("click",function(e) { - if (!blockButton(e, 'get-transaction-status', 'Consultando al API REST...')){ + e.preventDefault(); + if (!blockButton(e, 'get-transaction-status', 'Consultando estado')){ return; } + + const container = document.getElementById('transaction_status_admin'); + container.innerHTML = ''; + + const separator = document.createElement('div'); + separator.className = 'tbk-separator'; + separator.style.display = 'none'; + container.appendChild(separator); + post('get_transaction_status', { order_id: $('.get-transaction-status').data('order-id'), buy_order: $('.get-transaction-status').data('buy-order'), token: $('.get-transaction-status').data('token') }, (resp) => { - let $table = $('.transaction-status-response'); - let statusData = resp.status; - if(resp.product == "webpay_plus"){ - $("#tbk_wpp_vci").removeClass("tbk-hide"); - $("#tbk_wpp_session_id").removeClass("tbk-hide"); - }else{ - $("#tbk_wpoc_commerce_code").removeClass("tbk-hide"); + for (const [key, value] of Object.entries(resp)) { + const fieldName = document.createElement('span'); + fieldName.className = 'tbk-field-name'; + fieldName.textContent = getFieldName(key); + + const fieldValue = document.createElement('span'); + fieldValue.className = 'tbk-field-value'; + fieldValue.textContent = value.toString(); + + if(key == 'status') { + fieldValue.classList.add('tbk-badge'); + fieldValue.classList.add(getBadgeColorFromStatus(value.toString())); + } + + if(key == 'cardNumber') { + fieldValue.style.width = '100%'; + } + + const field = document.createElement('div'); + field.className = 'tbk-field'; + field.appendChild(fieldName); + field.appendChild(fieldValue); + + container.appendChild(field); } - const statusDataKeys = Object.keys(statusData); - statusDataKeys.forEach(key => { - let value = statusData[key] ? statusData[key] : '-'; - const tableRow = $table.find('.status-' + key); - tableRow.html(value); - }); - $table.find('.status-product').html(resp.product); - let niceJson = JSON.stringify(resp.raw, null, 2) - $table.find('.status-raw').html(`
${niceJson}
`); - $table.show(); - releaseButton('get-transaction-status','Consultar estado de la transacción'); + separator.style.removeProperty('display'); + + releaseButton('get-transaction-status','Consultar Estado'); }, (error) => { - $('.error-status-raw').html(`

${error.responseJSON.message}

`); - $('.error-transaction-status-response').show(); - releaseButton('get-transaction-status','Consultar estado de la transacción'); + const errorContainer = createErrorContainer(error.responseJSON.message); + container.appendChild(errorContainer); + separator.style.removeProperty('display'); + + releaseButton('get-transaction-status','Consultar Estado'); }); }); + function getBadgeColorFromStatus(status) { + const statusColorsDictionary = { + 'Inicializada': 'tbk-badge-warning', + 'Capturada': 'tbk-badge-success', + 'Autorizada': 'tbk-badge-success', + 'Fallida': 'tbk-badge-error', + 'Anulada': 'tbk-badge-info', + 'Parcialmente anulada': 'tbk-badge-info' + }; + + return statusColorsDictionary[status] ?? 'tbk-badge-default'; + } + + function getFieldName(fieldKey) { + const fieldNameDictionary = { + vci: 'VCI', + status: 'Estado', + responseCode: 'Código de respuesta', + amount: 'Monto', + authorizationCode: 'Código de autorización', + accountingDate: 'Fecha contable', + paymentType: 'Tipo de pago', + installmentType: 'Tipo de cuota', + installmentNumber: 'Número de cuotas', + installmentAmount: 'Monto cuota', + sessionId: 'ID de sesión', + buyOrder: 'Orden de compra', + buyOrderMall: 'Orden de compra mall', + buyOrderStore: 'Orden de compra tienda', + cardNumber: 'Número de tarjeta', + transactionDate: 'Fecha transacción', + transactionTime: 'Hora transacción', + balance: 'Balance' + }; + + return fieldNameDictionary[fieldKey] ?? fieldKey; + } + + function createErrorContainer(errorMessage) + { + const errorContainer = document.createElement('div'); + errorContainer.classList.add('tbk-status', 'tbk-status-error'); + const icon = document.createElement('i'); + icon.classList.add('fa', 'fa-times'); + const paragraph = document.createElement('p'); + paragraph.textContent = errorMessage; + + errorContainer.appendChild(icon); + errorContainer.appendChild(paragraph); + return errorContainer; + } + $('#mainform').on('click', '.notice-dismiss', function() { let noticeId = $(this).closest('.notice').attr('id'); @@ -169,7 +244,4 @@ jQuery(function($) { }); }); - - - }) diff --git a/plugin/src/Controllers/TransactionStatusController.php b/plugin/src/Controllers/TransactionStatusController.php index aa22a824..30646856 100644 --- a/plugin/src/Controllers/TransactionStatusController.php +++ b/plugin/src/Controllers/TransactionStatusController.php @@ -2,6 +2,7 @@ namespace Transbank\WooCommerce\WebpayRest\Controllers; +use Transbank\WooCommerce\WebpayRest\Helpers\ErrorUtil; use Transbank\WooCommerce\WebpayRest\Helpers\TbkFactory; use Transbank\WooCommerce\WebpayRest\Models\Transaction; use Transbank\WooCommerce\WebpayRest\Helpers\TbkResponseUtil; @@ -10,69 +11,63 @@ class TransactionStatusController { const HTTP_OK = 200; const HTTP_UNPROCESSABLE_ENTITY = 422; - public function getStatus() + const NO_TRANSACTION_ERROR_MESSAGE = 'No hay transacciones webpay aprobadas para esta orden'; + const BUY_ORDER_MISMATCH_ERROR_MESSAGE = 'El buy_order enviado y el buy_order de la transacción no coinciden'; + const TOKEN_MISMATCH_ERROR_MESSAGE = 'El token enviado y el token de la transacción no coinciden'; + + /** + * Log instance. + * @var \Transbank\Plugin\Helpers\PluginLogger + */ + private $logger; + + /** + * Controller for status requests. + */ + public function __construct() + { + $this->logger = TbkFactory::createLogger(); + } + + public function getStatus(): void { $response = [ 'body' => [ - 'message' => 'No se pudo obtener el estado de la transacción' - ], - 'code' => self::HTTP_UNPROCESSABLE_ENTITY + 'message' => ErrorUtil::DEFAULT_STATUS_ERROR_MESSAGE + ] ]; + + $this->logger->logInfo('Obteniendo estado de la transacción.'); + // Check for nonce security $nonce = sanitize_text_field($_POST['nonce']); if (!wp_verify_nonce($nonce, 'my-ajax-nonce')) { - wp_send_json($response['body'], $response['code']); + $this->logger->logError($response['body']['message']); + wp_send_json($response['body'], self::HTTP_UNPROCESSABLE_ENTITY); return; } - $orderId = filter_input(INPUT_POST, 'order_id', FILTER_DEFAULT); - $orderId = htmlspecialchars($orderId, ENT_QUOTES, 'UTF-8'); - $buyOrder = filter_input(INPUT_POST, 'buy_order', FILTER_DEFAULT); - $buyOrder = htmlspecialchars($buyOrder, ENT_QUOTES, 'UTF-8'); - $token = filter_input(INPUT_POST, 'token', FILTER_DEFAULT); - $token = htmlspecialchars($token, ENT_QUOTES, 'UTF-8'); + $orderId = $this->getSecureInputValue('order_id'); + $buyOrder = $this->getSecureInputValue('buy_order'); + $token = $this->getSecureInputValue('token'); + + $requestMethod = $_SERVER['REQUEST_METHOD']; + $params = ['orderId' => $orderId, 'buyOrder' => $buyOrder, 'token' => $token]; + + $this->logger->logDebug("Request: method -> $requestMethod"); + $this->logger->logDebug('Request: payload -> ' . json_encode($params)); try { $transaction = Transaction::getApprovedByOrderId($orderId); - if (!$transaction) { - $response = [ - 'body' => [ - 'message' => 'No hay transacciones webpay aprobadas para esta orden' - ], - 'code' => self::HTTP_UNPROCESSABLE_ENTITY - ]; - } - if ($transaction->product == Transaction::PRODUCT_WEBPAY_ONECLICK) { - if ($transaction->buy_order !== $buyOrder) { - $response = [ - 'body' => [ - 'message' => 'El buy_order enviado y el buy_order de la transacción no coinciden' - ], - 'code' => self::HTTP_UNPROCESSABLE_ENTITY - ]; - } - - $response = [ - 'body' => $this->getStatusForOneclickTransaction($orderId, $buyOrder), - 'code' => self::HTTP_OK - ]; + if (!$transaction) { + $response['body'] = self::NO_TRANSACTION_ERROR_MESSAGE; + wp_send_json($response['body'], self::HTTP_UNPROCESSABLE_ENTITY); + return; } - if ($transaction->token !== $token) { - $response = [ - 'body' => [ - 'message' => 'El token enviado y el token de la transacción no coinciden' - ], - 'code' => self::HTTP_UNPROCESSABLE_ENTITY - ]; - } - - $response = [ - 'body' => $this->getStatusForWebpayTransaction($orderId, $token), - 'code' => self::HTTP_OK - ]; + $response = $this->handleGetStatus($transaction, $orderId, $buyOrder, $token); wp_send_json($response['body'], $response['code']); } catch (\Exception $e) { @@ -82,37 +77,74 @@ public function getStatus() } } - private function getStatusForWebpayTransaction(string $orderId, string $token) + private function handleGetStatus(object $transaction, string $orderId, string $buyOrder, string $token): array { - $webpayplusTransbankSdk = TbkFactory::createWebpayplusTransbankSdk(); - $resp = $webpayplusTransbankSdk->status($orderId, $token); - $formattedDate = TbkResponseUtil::transactionDateToLocalDate($resp->getTransactionDate()); - $modifiedResponse = clone $resp; - $modifiedResponse->setTransactionDate($formattedDate); + if ($transaction->product == Transaction::PRODUCT_WEBPAY_ONECLICK) { + return $this->handleOneclickStatus($orderId, $buyOrder, $transaction->buy_order); + } + + return $this->handleWebpayStatus($orderId, $token, $transaction->token); + } + + private function handleOneclickStatus( + string $orderId, + string $requestBuyOrder, + string $transactionBuyOrder + ): array { + if ($transactionBuyOrder !== $requestBuyOrder) { + return [ + 'body' => [ + 'message' => self::BUY_ORDER_MISMATCH_ERROR_MESSAGE + ], + 'code' => self::HTTP_UNPROCESSABLE_ENTITY + ]; + } + + $statusResponse = $this->getStatusForOneclickTransaction($orderId, $transactionBuyOrder); return [ - 'product' => Transaction::PRODUCT_WEBPAY_PLUS, - 'status' => $modifiedResponse, - 'raw' => $resp, + 'body' => TbkResponseUtil::getOneclickStatusFormattedResponse($statusResponse), + 'code' => self::HTTP_OK ]; } - private function getStatusForOneclickTransaction(string $orderId, string $buyOrder) - { - $oneclickTransbankSdk = TbkFactory::createOneclickTransbankSdk(); - $status = $oneclickTransbankSdk->status($orderId, $buyOrder); - $statusArray = json_decode(json_encode($status), true); - $firstDetail = json_decode(json_encode($status->getDetails()[0]), true); + private function handleWebpayStatus( + string $orderId, + string $requestToken, + string $transactionToken + ): array { + if ($transactionToken !== $requestToken) { + return [ + 'body' => [ + 'message' => self::TOKEN_MISMATCH_ERROR_MESSAGE + ], + 'code' => self::HTTP_UNPROCESSABLE_ENTITY + ]; + } - $response = array_merge($statusArray, $firstDetail); - $formattedDate = TbkResponseUtil::transactionDateToLocalDate($status->getTransactionDate()); - $response['transactionDate'] = $formattedDate; - unset($response['details']); + $statusResponse = $this->getStatusForWebpayTransaction($orderId, $transactionToken); return [ - 'product' => Transaction::PRODUCT_WEBPAY_ONECLICK, - 'status' => $response, - 'raw' => $status, + 'body' => TbkResponseUtil::getWebpayStatusFormattedResponse($statusResponse), + 'code' => self::HTTP_OK ]; } + + private function getStatusForWebpayTransaction(string $orderId, string $token) + { + $webpayTransbankSDK = TbkFactory::createWebpayplusTransbankSdk(); + return $webpayTransbankSDK->status($orderId, $token); + } + + private function getStatusForOneclickTransaction(string $orderId, string $buyOrder) + { + $oneclickTransbankSDK = TbkFactory::createOneclickTransbankSdk(); + return $oneclickTransbankSDK->status($orderId, $buyOrder); + } + + private function getSecureInputValue(string $varName): string + { + $tmpValue = filter_input(INPUT_POST, $varName, FILTER_DEFAULT); + return htmlspecialchars($tmpValue, ENT_QUOTES, 'UTF-8'); + } } diff --git a/plugin/src/Helpers/ErrorUtil.php b/plugin/src/Helpers/ErrorUtil.php index 15c4f2d4..12998b79 100644 --- a/plugin/src/Helpers/ErrorUtil.php +++ b/plugin/src/Helpers/ErrorUtil.php @@ -12,6 +12,10 @@ class ErrorUtil { status 422 => "error_message": "Invalid value for parameter: transaction not found" */ + const DEFAULT_STATUS_ERROR_MESSAGE = 'Ocurrió un error al tratar de obtener el estado de la transacción.'; + const EXPIRED_TRANSACTION_ERROR_MESSAGE = 'La transacción supera los 7 días y ya no es posible consultarla por este medio.'; + const API_MISMATCH_ERROR_MESSAGE = 'La versión de API es distinta a la utilizada para crear la transacción.'; + public static function isApiMismatchError(\Throwable $e) { $error = $e->getMessage(); diff --git a/plugin/src/Helpers/TbkResponseUtil.php b/plugin/src/Helpers/TbkResponseUtil.php index 92d558a6..14ce775b 100644 --- a/plugin/src/Helpers/TbkResponseUtil.php +++ b/plugin/src/Helpers/TbkResponseUtil.php @@ -163,4 +163,122 @@ public static function getOneclickFormattedResponse(object $transactionResponse) return array_merge($commonFields, $oneclickFields); } + + /** + * Get the common fields formatted for status response. + * + * @param object $statusResponse The status response. + * @return array The formatted common fields for status response. + */ + private static function getCommonFieldsStatusFormatted(object $statusResponse): array + { + $utcDate = new DateTime($statusResponse->transactionDate, new DateTimeZone('UTC')); + $utcDate->setTimeZone(new DateTimeZone(wc_timezone_string())); + + $buyOrder = $statusResponse->buyOrder; + $cardNumber = "**** **** **** {$statusResponse->cardNumber}"; + $transactionDate = $utcDate->format('d-m-Y'); + $transactionTime = $utcDate->format('H:i:s'); + $accountingDate = self::getAccountingDate($statusResponse->accountingDate); + + return [ + 'buyOrder' => $buyOrder, + 'cardNumber' => $cardNumber, + 'transactionDate' => $transactionDate, + 'transactionTime' => $transactionTime, + 'accountingDate' => $accountingDate + ]; + } + + /** + * Get the formatted response for Webpay status transactions. + * + * @param object $statusResponse The response object for Webpay status transactions. + * @return array The formatted response fields. + */ + public static function getWebpayStatusFormattedResponse(object $statusResponse): array + { + $commonFields = self::getCommonFieldsStatusFormatted($statusResponse); + + $status = self::getStatus($statusResponse->status); + $amount = self::getAmountFormatted($statusResponse->amount); + $paymentType = self::getPaymentType($statusResponse->paymentTypeCode); + $installmentType = self::getInstallmentType($statusResponse->paymentTypeCode); + $installmentNumber = $statusResponse->installmentsNumber; + $installmentAmount = 'N/A'; + $balance = 'N/A'; + + if ($installmentNumber > 0) { + $installmentAmount = self::getAmountFormatted($statusResponse->installmentsAmount ?? 0); + } + + if (!is_null($statusResponse->balance)) { + $balance = self::getAmountFormatted($statusResponse->balance); + } + + return [ + 'vci' => $statusResponse->vci, + 'status' => $status, + 'responseCode' => $statusResponse->responseCode, + 'amount' => $amount, + 'authorizationCode' => $statusResponse->authorizationCode, + 'accountingDate' => $commonFields['accountingDate'], + 'paymentType' => $paymentType, + 'installmentType' => $installmentType, + 'installmentNumber' => $installmentNumber, + 'installmentAmount' => $installmentAmount, + 'sessionId' => $statusResponse->sessionId, + 'buyOrder' => $commonFields['buyOrder'], + 'cardNumber' => $commonFields['cardNumber'], + 'transactionDate' => $commonFields['transactionDate'], + 'transactionTime' => $commonFields['transactionTime'], + 'balance' => $balance + ]; + } + + /** + * Get the formatted response for Oneclick status transactions. + * + * @param object $statusResponse The response object for Oneclick status transactions. + * @return array The formatted response fields. + */ + public static function getOneclickStatusFormattedResponse(object $statusResponse): array + { + $commonFields = self::getCommonFieldsStatusFormatted($statusResponse); + $detail = $statusResponse->details[0]; + + $status = self::getStatus($detail->status); + $amount = self::getAmountFormatted($detail->amount); + $paymentType = self::getPaymentType($detail->paymentTypeCode); + $installmentType = self::getInstallmentType($detail->paymentTypeCode); + $installmentNumber = $detail->installmentsNumber; + $installmentAmount = 'N/A'; + $balance = 'N/A'; + + if ($installmentNumber > 0) { + $installmentAmount = self::getAmountFormatted($detail->installmentsAmount ?? 0); + } + + if (!is_null($detail->balance)) { + $balance = self::getAmountFormatted($detail->balance); + } + + return [ + 'status' => $status, + 'responseCode' => $detail->responseCode, + 'amount' => $amount, + 'authorizationCode' => $detail->authorizationCode, + 'accountingDate' => $commonFields['accountingDate'], + 'paymentType' => $paymentType, + 'installmentType' => $installmentType, + 'installmentNumber' => $installmentNumber, + 'installmentAmount' => $installmentAmount, + 'buyOrderMall' => $commonFields['buyOrder'], + 'buyOrderStore' => $detail->buyOrder, + 'cardNumber' => $commonFields['cardNumber'], + 'transactionDate' => $commonFields['transactionDate'], + 'transactionTime' => $commonFields['transactionTime'], + 'balance' => $balance + ]; + } } diff --git a/plugin/src/OneclickTransbankSdk.php b/plugin/src/OneclickTransbankSdk.php index b9705b6f..2654707a 100644 --- a/plugin/src/OneclickTransbankSdk.php +++ b/plugin/src/OneclickTransbankSdk.php @@ -28,6 +28,7 @@ use Transbank\Plugin\Exceptions\Oneclick\StatusOneclickException; use Transbank\Plugin\Exceptions\Oneclick\StartOneclickException; use Transbank\Plugin\Exceptions\Oneclick\StartInscriptionOneclickException; +use Transbank\WooCommerce\WebpayRest\Helpers\ErrorUtil; /** * Class OneclickTransbankSdk. @@ -121,14 +122,24 @@ public function status($orderId, $buyOrder) $this->afterExecutionTbkApi($orderId, 'status', $params, $response); return $response; } catch (Exception $e) { - $maskedBuyOrder = $this->dataMasker->maskBuyOrder($buyOrder); - $errorMessage = 'Oneclick: Error al obtener el status ( buyOrder: '.$maskedBuyOrder.') '.$e->getMessage(); - $this->errorExecutionTbkApi($orderId, - 'status', - $params, - 'StatusOneclickException', - $e->getMessage(), - $errorMessage); + $errorMessage = ErrorUtil::DEFAULT_STATUS_ERROR_MESSAGE; + + if(ErrorUtil::isMaxTimeError($e)) { + $errorMessage = ErrorUtil::EXPIRED_TRANSACTION_ERROR_MESSAGE; + } + + if (ErrorUtil::isApiMismatchError($e)) { + $errorMessage = ErrorUtil::DEFAULT_STATUS_ERROR_MESSAGE; + } + + $this->errorExecutionTbkApi( + $orderId, + 'status', + $params, + 'StatusOneclickException', + $e->getMessage(), + $errorMessage + ); throw new StatusOneclickException($errorMessage, $buyOrder, $e); } } diff --git a/plugin/src/WebpayplusTransbankSdk.php b/plugin/src/WebpayplusTransbankSdk.php index 8103913d..708f40c6 100644 --- a/plugin/src/WebpayplusTransbankSdk.php +++ b/plugin/src/WebpayplusTransbankSdk.php @@ -98,17 +98,24 @@ public function status($orderId, $token) $this->afterExecutionTbkApi($orderId, 'status', $params, $response); return $response; } catch (Exception $e) { + $errorMessage = ErrorUtil::DEFAULT_STATUS_ERROR_MESSAGE; + + if(ErrorUtil::isMaxTimeError($e)) { + $errorMessage = ErrorUtil::EXPIRED_TRANSACTION_ERROR_MESSAGE; + } + if (ErrorUtil::isApiMismatchError($e)) { - $errorMessage = 'Esta utilizando una version de api distinta a la utilizada para crear la transacción'; - $this->errorExecutionTbkApi($orderId, 'status', $params, 'StatusWebpayException', $e->getMessage(), $errorMessage); - throw new StatusWebpayException($errorMessage, $token, $e); - } elseif (ErrorUtil::isMaxTimeError($e)) { - $errorMessage = 'Ya pasaron mas de 7 dias desde la creacion de la transacción, ya no es posible consultarla por este medio'; - $this->errorExecutionTbkApi($orderId, 'status', $params, 'StatusWebpayException', $e->getMessage(), $errorMessage); - throw new StatusWebpayException($errorMessage, $token, $e); + $errorMessage = ErrorUtil::DEFAULT_STATUS_ERROR_MESSAGE; } - $errorMessage = 'Ocurrió un error al tratar de obtener el status ( token: '.$token.') de la transacción Webpay en Transbank: '.$e->getMessage(); - $this->errorExecutionTbkApi($orderId, 'status', $params, 'StatusWebpayException', $e->getMessage(), $errorMessage); + + $this->errorExecutionTbkApi( + $orderId, + 'status', + $params, + 'StatusWebpayException', + $e->getMessage(), + $errorMessage + ); throw new StatusWebpayException($errorMessage, $token, $e); } } diff --git a/plugin/templates/admin/order/transaction-status.php b/plugin/templates/admin/order/transaction-status.php new file mode 100644 index 00000000..2837d3b0 --- /dev/null +++ b/plugin/templates/admin/order/transaction-status.php @@ -0,0 +1,29 @@ + + +
+ + Consultar Estado + +
+ +
+ +

+
+ +
+
diff --git a/plugin/views/get-status.php b/plugin/views/get-status.php deleted file mode 100644 index 84960f45..00000000 --- a/plugin/views/get-status.php +++ /dev/null @@ -1,86 +0,0 @@ - - -Consultar estado de la transacción - -

Esta es la respuesta del API (solo disponible por 7 días desde la fecha de transacción)

- - - - diff --git a/plugin/webpay-rest.php b/plugin/webpay-rest.php index 0154259d..ddde01ab 100644 --- a/plugin/webpay-rest.php +++ b/plugin/webpay-rest.php @@ -1,4 +1,5 @@ checkIfHposExists(); add_action('plugins_loaded', 'registerPaymentGateways', 0); add_action('wp_loaded', 'woocommerceTransbankInit'); add_action('admin_init', 'on_transbank_rest_webpay_plugins_loaded'); +add_action('add_meta_boxes', function () use ($hposExists) { + addTransbankStatusMetaBox($hposExists); +}); + +add_action('init', function() { + add_action('wp_ajax_check_connection', ConnectionCheck::class . '::check'); + add_action('wp_ajax_check_exist_tables', TableCheck::class . '::check'); + add_action('wp_ajax_check_can_download_file', PluginLogger::class . '::checkCanDownloadLogFile'); + add_action('wp_ajax_get_transaction_status', [new TransactionStatusController(), 'getStatus']); +}); -add_action('wp_ajax_check_connection', ConnectionCheck::class . '::check'); -add_action('wp_ajax_check_exist_tables', TableCheck::class . '::check'); -add_action('wp_ajax_check_can_download_file', PluginLogger::class . '::checkCanDownloadLogFile'); -add_action('wp_ajax_get_transaction_status', [new TransactionStatusController(), 'getStatus']); add_action('woocommerce_before_cart', 'transbank_rest_before_cart'); add_action('woocommerce_before_checkout_form', 'transbank_rest_check_cancelled_checkout'); @@ -60,36 +72,34 @@ ]); }); -add_action('woocommerce_blocks_loaded', function() { - if ( class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ){ +add_action('woocommerce_blocks_loaded', function () { + if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { require_once 'src/Blocks/WC_Gateway_Transbank_Webpay_Blocks.php'; require_once 'src/Blocks/WC_Gateway_Transbank_Oneclick_Blocks.php'; add_action( 'woocommerce_blocks_payment_method_type_registration', - function( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) { - $payment_method_registry->register( new WCGatewayTransbankWebpayBlocks() ); - $payment_method_registry->register( new WCGatewayTransbankOneclickBlocks() ); + function (Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { + $payment_method_registry->register(new WCGatewayTransbankWebpayBlocks()); + $payment_method_registry->register(new WCGatewayTransbankOneclickBlocks()); } ); } }); -add_action( 'before_woocommerce_init', function() { - if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) { - \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true ); +add_action('before_woocommerce_init', function () { + if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true); } -} ); +}); -$hposHelper = new HposHelper(); -$hPosExists = $hposHelper->checkIfHposExists(); -if ($hPosExists) -{ +if ($hposExists) { add_action('before_woocommerce_init', function () { - if (class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class)) { + if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, - true); + true + ); } }); } @@ -104,26 +114,30 @@ function( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_ } }); -function woocommerceTransbankInit() { +function woocommerceTransbankInit() +{ if (!class_exists('WC_Payment_Gateway')) { noticeMissingWoocommerce(); return; } + registerAdminMenu(); registerPluginActionLinks(); NoticeHelper::registerNoticesDismissHook(); NoticeHelper::handleReviewNotice(); } -function registerPaymentGateways() { - add_filter('woocommerce_payment_gateways', function($methods) { +function registerPaymentGateways() +{ + add_filter('woocommerce_payment_gateways', function ($methods) { $methods[] = WC_Gateway_Transbank_Webpay_Plus_REST::class; $methods[] = WC_Gateway_Transbank_Oneclick_Mall_REST::class; return $methods; }); } -function registerAdminMenu() { +function registerAdminMenu() +{ add_action('admin_menu', function () { add_submenu_page('woocommerce', __('Configuración de Webpay Plus', 'transbank_wc_plugin'), 'Webpay Plus', 'administrator', 'transbank_webpay_plus_rest', function () { $tab = filter_input(INPUT_GET, 'tbk_tab', FILTER_DEFAULT); @@ -132,7 +146,7 @@ function registerAdminMenu() { wp_redirect(admin_url('admin.php?page=wc-settings&tab=checkout§ion=transbank_webpay_plus_rest&tbk_tab=options')); } - include_once __DIR__.'/views/admin/options-tabs.php'; + include_once __DIR__ . '/views/admin/options-tabs.php'; }, null); add_submenu_page('woocommerce', __('Configuración de Webpay Plus', 'transbank_wc_plugin'), 'Webpay Oneclick', 'administrator', 'transbank_webpay_oneclick_rest', function () { @@ -141,8 +155,9 @@ function registerAdminMenu() { }); } -function registerPluginActionLinks() { - add_filter('plugin_action_links_'.plugin_basename(__FILE__), function ($actionLinks) { +function registerPluginActionLinks() +{ + add_filter('plugin_action_links_' . plugin_basename(__FILE__), function ($actionLinks) { $webpaySettingsLink = sprintf( '%s', admin_url('admin.php?page=wc-settings&tab=checkout§ion=transbank_webpay_plus_rest'), @@ -162,52 +177,71 @@ function registerPluginActionLinks() { }); } -function on_transbank_rest_webpay_plugins_loaded() -{ - DatabaseTableInstaller::createTableIfNeeded(); -} - -function transbank_rest_remove_database() -{ - DatabaseTableInstaller::deleteTable(); -} - -register_uninstall_hook(__FILE__, 'transbank_rest_remove_database'); - -if ($hPosExists) +function addTransbankStatusMetaBox(bool $hPosExists) { - add_action('add_meta_boxes', function () { + if ($hPosExists) { $screen = wc_get_container() - ->get(Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class) + ->get(CustomOrdersTableController::class) ->custom_orders_table_usage_is_enabled() ? wc_get_page_screen_id('shop-order') : 'shop_order'; + add_meta_box( 'transbank_check_payment_status', __('Verificar estado del pago', 'transbank_wc_plugin'), function ($post_or_order_object) { $order = ($post_or_order_object instanceof WP_Post) - ? wc_get_order($post_or_order_object->ID) - : $post_or_order_object; - $transaction = Transaction::getApprovedByOrderId($order->get_id()); - include_once __DIR__.'/views/get-status.php'; + ? wc_get_order($post_or_order_object->ID) + : $post_or_order_object; + + $orderId = $order->get_id(); + renderTransactionStatusMetaBox($orderId); }, $screen, 'side', - 'core'); - }); -} -else -{ - add_action('add_meta_boxes', function () { + 'core' + ); + } else { add_meta_box('transbank_check_payment_status', __('Verificar estado del pago', 'transbank_wc_plugin'), function ($post) { $order = new WC_Order($post->ID); - $transaction = Transaction::getApprovedByOrderId($order->get_id()); - include_once __DIR__.'/views/get-status.php'; + $orderId = $order->get_id(); + renderTransactionStatusMetaBox($orderId); }, 'shop_order', 'side', 'core'); - }); + } +} + +function renderTransactionStatusMetaBox(int $orderId) +{ + $viewData = []; + $transaction = Transaction::getApprovedByOrderId($orderId); + + if ($transaction) { + $viewData = [ + 'viewData' => [ + 'orderId' => $orderId, + 'token' => $transaction->token, + 'buyOrder' => $transaction->buy_order + ] + ]; + } + + (new Template())->render('admin/order/transaction-status.php', $viewData); +} + +function on_transbank_rest_webpay_plugins_loaded() +{ + DatabaseTableInstaller::createTableIfNeeded(); +} + +function transbank_rest_remove_database() +{ + DatabaseTableInstaller::deleteTable(); } +register_uninstall_hook(__FILE__, 'transbank_rest_remove_database'); + + + function transbank_rest_before_cart() { SessionMessageHelper::printMessage(); @@ -225,7 +259,8 @@ function transbank_rest_check_cancelled_checkout() } } -function noticeMissingWoocommerce() { +function noticeMissingWoocommerce() +{ add_action( 'admin_notices', function () { @@ -253,7 +288,7 @@ function () { $isWooInstalled = !empty($allPlugins['woocommerce/woocommerce.php']); } - if(function_exists('is_plugin_active')) { + if (function_exists('is_plugin_active')) { $isWooActivated = is_plugin_active('woocommerce/woocommerce.php'); } @@ -272,7 +307,7 @@ function () { $noticeDescription = "Woocommerce no se encuentra activado."; } - include_once plugin_dir_path(__FILE__) .'views/admin/components/notice-missing-woocommerce.php'; + include_once plugin_dir_path(__FILE__) . 'views/admin/components/notice-missing-woocommerce.php'; } ); }