From 063314475c50338a75ec98749f4ea3e9edbcd524 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:57:24 -0300 Subject: [PATCH 01/12] feat: implement TransaccionCompletaMallDiferidoController for mall deferred transactions --- ...saccionCompletaMallDiferidoController.java | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 src/main/java/cl/transbank/webpay/example/controllers/TransaccionCompletaMallDiferidoController.java diff --git a/src/main/java/cl/transbank/webpay/example/controllers/TransaccionCompletaMallDiferidoController.java b/src/main/java/cl/transbank/webpay/example/controllers/TransaccionCompletaMallDiferidoController.java new file mode 100644 index 0000000..beae58a --- /dev/null +++ b/src/main/java/cl/transbank/webpay/example/controllers/TransaccionCompletaMallDiferidoController.java @@ -0,0 +1,308 @@ +package cl.transbank.webpay.example.controllers; + +import cl.transbank.common.IntegrationApiKeys; +import cl.transbank.common.IntegrationCommerceCodes; +import cl.transbank.common.IntegrationType; +import cl.transbank.model.MallTransactionCreateDetails; +import cl.transbank.webpay.common.WebpayOptions; +import cl.transbank.webpay.exception.*; +import cl.transbank.webpay.example.models.MallDetailSession; +import cl.transbank.webpay.transaccioncompleta.MallFullTransaction; +import cl.transbank.webpay.transaccioncompleta.model.MallTransactionCommitDetails; +import cl.transbank.webpay.transaccioncompleta.responses.MallFullTransactionInstallmentsDetails; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Log4j2 +@Controller +@RequestMapping("/transaccion-completa-mall-diferido") +public class TransaccionCompletaMallDiferidoController extends BaseController { + private static final String TEMPLATE_FOLDER = "transaccion_completa_mall_diferido"; + private static final String BASE_URL = "/transaccion-completa-mall-diferido"; + private static final String PRODUCT = "Webpay Transacción Completa Mall Diferido"; + + private static final String VIEW_INDEX = TEMPLATE_FOLDER + "/index"; + private static final String VIEW_CREATE = TEMPLATE_FOLDER + "/create"; + private static final String VIEW_INSTALLMENTS = TEMPLATE_FOLDER + "/installments"; + private static final String VIEW_COMMIT = TEMPLATE_FOLDER + "/commit"; + private static final String VIEW_STATUS = TEMPLATE_FOLDER + "/status"; + private static final String VIEW_REFUND = TEMPLATE_FOLDER + "/refund"; + private static final String VIEW_CAPTURE = TEMPLATE_FOLDER + "/capture"; + + private static final String NAV_LABEL_FORM = "Formulario"; + private static final String NAV_LABEL_REQUEST = "Petición"; + private static final String NAV_LABEL_RESPONSE = "Respuesta"; + + private static final String ATTR_NAVIGATION = "navigation"; + private static final String ATTR_PRODUCT = "product"; + private static final String ATTR_BREADCRUMBS = "breadcrumbs"; + private static final String ATTR_RESPONSE_DATA = "response_data"; + private static final String ATTR_RESPONSE_DATA_JSON = "response_data_json"; + private static final String ATTR_REQUEST_TOKEN = "request_token"; + private static final String ATTR_AMOUNT = "amount"; + private static final String ATTR_ERROR = "error"; + private static final String ATTR_ID_QUERY_INSTALLMENTS = "id_query_installments"; + + private static final String SESSION_DETAILS = "transaccion_completa_mall_diferido_details"; + private static final String NAV_KEY_REQUEST = "request"; + private static final String NAV_KEY_RESPONSE = "response"; + private static final String NAV_KEY_FORM = "form"; + + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + + private static final Map NAV_INDEX = createNav(NAV_KEY_FORM); + private static final Map NAV_CREATE = createNav(NAV_KEY_REQUEST, NAV_KEY_RESPONSE, NAV_KEY_FORM); + private static final Map NAV_INSTALLMENTS = createNav(NAV_KEY_REQUEST, NAV_KEY_RESPONSE, NAV_KEY_FORM); + private static final Map NAV_COMMIT = createNav(NAV_KEY_REQUEST, NAV_KEY_RESPONSE, NAV_KEY_FORM); + private static final Map NAV_STATUS = createNav(NAV_KEY_REQUEST, NAV_KEY_RESPONSE); + private static final Map NAV_CAPTURE = NAV_STATUS; + private static final Map NAV_REFUND = NAV_STATUS; + private final MallFullTransaction tx; + + private static Map createNav(String... keys) { + Map nav = new LinkedHashMap<>(); + for (String key : keys) { + String label = switch (key) { + case NAV_KEY_REQUEST -> NAV_LABEL_REQUEST; + case NAV_KEY_RESPONSE -> NAV_LABEL_RESPONSE; + case NAV_KEY_FORM -> NAV_LABEL_FORM; + default -> null; + }; + if (label != null) { + nav.put(key, label); + } + } + return nav; + } + + + public TransaccionCompletaMallDiferidoController() { + this.tx = new MallFullTransaction( + new WebpayOptions( + IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED, + IntegrationApiKeys.WEBPAY, + IntegrationType.TEST + ) + ); + } + + private void addProductAndBreadcrumbs(Model model, String label, String url) { + var breadcrumbs = new LinkedHashMap(); + breadcrumbs.put("Inicio", "/"); + breadcrumbs.put(PRODUCT, BASE_URL); + if (label != null) { + breadcrumbs.put(label, url); + } + model.addAttribute(ATTR_PRODUCT, PRODUCT); + model.addAttribute(ATTR_BREADCRUMBS, breadcrumbs); + } + + @GetMapping("") + public String index(Model model) { + model.addAttribute(ATTR_NAVIGATION, NAV_INDEX); + addProductAndBreadcrumbs(model, null, null); + return VIEW_INDEX; + } + + @PostMapping("/create") + public String create( + HttpServletRequest req, + @RequestParam("number") String number, + @RequestParam("expiry") String expiry, + @RequestParam("cvc") String cvc, + Model model + ) throws TransactionCreateException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_CREATE); + addProductAndBreadcrumbs(model, "Crear transacción", BASE_URL + "/create"); + + String cardNumber = number.replaceAll("\\s+", ""); + String[] expiryParts = expiry.split("/"); + String month = expiryParts.length > 0 ? expiryParts[0] : ""; + String year = expiryParts.length > 1 ? expiryParts[1] : ""; + String cardExpiry = year + "/" + month; + + String buyOrder = "O-" + getRandomNumber(); + String sessionId = "S-" + getRandomNumber(); + + var sessionDetails = buildSessionDetails( + IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED_CHILD1, + IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED_CHILD2 + ); + + var details = MallTransactionCreateDetails.build() + .add(sessionDetails.get(0).getAmount(), sessionDetails.get(0).getCommerceCode(), sessionDetails.get(0).getBuyOrder()) + .add(sessionDetails.get(1).getAmount(), sessionDetails.get(1).getCommerceCode(), sessionDetails.get(1).getBuyOrder()); + + var resp = tx.create(buyOrder, sessionId, cardNumber, cardExpiry, details, Short.parseShort(cvc)); + req.getSession().setAttribute(SESSION_DETAILS, sessionDetails); + + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + + return VIEW_CREATE; + } + + @PostMapping("/installments") + public String installments( + HttpServletRequest req, + @RequestParam("token") String token, + @RequestParam("installments_number") byte installmentsNumber, + Model model + ) throws TransactionInstallmentException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_INSTALLMENTS); + addProductAndBreadcrumbs(model, "Consulta de cuotas", BASE_URL + "/installments"); + + List sessionDetails = getSessionDetails(req); + if (sessionDetails.isEmpty()) { + model.addAttribute(ATTR_ERROR, "Debes crear la transacción antes de consultar cuotas."); + return VIEW_ERROR; + } + + var details = MallFullTransactionInstallmentsDetails.build() + .add(sessionDetails.get(0).getCommerceCode(), sessionDetails.get(0).getBuyOrder(), installmentsNumber) + .add(sessionDetails.get(1).getCommerceCode(), sessionDetails.get(1).getBuyOrder(), installmentsNumber); + + var resp = tx.installments(token, details); + Long idQueryInstallments = null; + if (resp != null && resp.getResponseList() != null && !resp.getResponseList().isEmpty()) { + idQueryInstallments = resp.getResponseList().get(0).getIdQueryInstallments(); + } + + model.addAttribute(ATTR_REQUEST_TOKEN, token); + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + model.addAttribute(ATTR_ID_QUERY_INSTALLMENTS, idQueryInstallments); + + return VIEW_INSTALLMENTS; + } + + @GetMapping("/commit") + public String commit( + HttpServletRequest req, + @RequestParam("token") String token, + @RequestParam(value = "idQueryInstallments", required = false) Long idQueryInstallments, + @RequestParam(value = "deferredPeriodIndex", required = false) Byte deferredPeriodIndex, + @RequestParam(value = "gracePeriod", required = false) Boolean gracePeriod, + Model model + ) throws TransactionCommitException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_COMMIT); + addProductAndBreadcrumbs(model, "Confirmar transacción", BASE_URL + "/commit"); + + List sessionDetails = getSessionDetails(req); + if (sessionDetails.isEmpty()) { + model.addAttribute(ATTR_ERROR, "Debes crear la transacción antes de confirmar."); + return VIEW_ERROR; + } + + boolean safeGracePeriod = gracePeriod != null ? gracePeriod : Boolean.FALSE; + + var details = MallTransactionCommitDetails.build() + .add(sessionDetails.get(0).getCommerceCode(), sessionDetails.get(0).getBuyOrder(), idQueryInstallments, deferredPeriodIndex, safeGracePeriod) + .add(sessionDetails.get(1).getCommerceCode(), sessionDetails.get(1).getBuyOrder(), idQueryInstallments, deferredPeriodIndex, safeGracePeriod); + + var resp = tx.commit(token, details); + + model.addAttribute(ATTR_REQUEST_TOKEN, token); + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + + return VIEW_COMMIT; + } + + @GetMapping("/capture") + public String capture( + @RequestParam("token") String token, + @RequestParam("child_commerce_code") String commerceCode, + @RequestParam("child_buy_order") String buyOrder, + @RequestParam("authorization_code") String authorizationCode, + @RequestParam("amount") double amount, + Model model + ) throws TransactionCaptureException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_CAPTURE); + addProductAndBreadcrumbs(model, "Capturar", BASE_URL + "/capture"); + + var resp = tx.capture(token, commerceCode, buyOrder, authorizationCode, amount); + model.addAttribute(ATTR_AMOUNT, amount); + model.addAttribute(ATTR_REQUEST_TOKEN, token); + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + model.addAttribute("child_buy_order", buyOrder); + model.addAttribute("child_commerce_code", commerceCode); + + return VIEW_CAPTURE; + } + + @GetMapping("/status") + public String status( + @RequestParam("token") String token, + Model model + ) throws TransactionStatusException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_STATUS); + addProductAndBreadcrumbs(model, "Estado de transacción", BASE_URL + "/status"); + + var resp = tx.status(token); + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + + return VIEW_STATUS; + } + + @GetMapping("/refund") + public String refund( + @RequestParam("token") String token, + @RequestParam("buy_order") String buyOrder, + @RequestParam("commerce_code") String commerceCode, + @RequestParam("amount") double amount, + Model model + ) throws TransactionRefundException, IOException { + model.addAttribute(ATTR_NAVIGATION, NAV_REFUND); + addProductAndBreadcrumbs(model, "Reembolsar", BASE_URL + "/refund"); + + var resp = tx.refund(token, buyOrder, commerceCode, amount); + model.addAttribute(ATTR_REQUEST_TOKEN, token); + model.addAttribute(ATTR_RESPONSE_DATA, resp); + model.addAttribute(ATTR_RESPONSE_DATA_JSON, toJson(resp)); + + return VIEW_REFUND; + } + + private List buildSessionDetails(String commerceCode1, String commerceCode2) { + List details = new ArrayList<>(); + details.add(new MallDetailSession( + 1000.0 + SECURE_RANDOM.nextInt(1001), + commerceCode1, + "O-" + getRandomNumber() + )); + details.add(new MallDetailSession( + 1000.0 + SECURE_RANDOM.nextInt(1001), + commerceCode2, + "O-" + getRandomNumber() + )); + return details; + } + + @SuppressWarnings("unchecked") + private List getSessionDetails(HttpServletRequest req) { + Object value = req.getSession().getAttribute(SESSION_DETAILS); + if (value instanceof List) { + return (List) value; + } + return new ArrayList<>(); + } + + @ExceptionHandler(Exception.class) + public String handleException(Exception e, Model model) { + model.addAttribute(ATTR_ERROR, e.getMessage()); + return VIEW_ERROR; + } +} From ae8a3674b8031025d60727d11af2aefadb0260f1 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:57:45 -0300 Subject: [PATCH 02/12] feat: add transaction form for Mall Completa Diferido with card details input --- .../index.html | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/index.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/index.html b/src/main/resources/templates/transaccion_completa_mall_diferido/index.html new file mode 100644 index 0000000..081db69 --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/index.html @@ -0,0 +1,128 @@ +
+
+

Transacción Completa Mall Diferido - Formulario

+

+ En esta primera etapa necesitas obtener los datos esenciales de la tarjeta + de crédito, débito o prepago del titular. Utiliza el formulario para + recolectar esta información de manera segura. +

+ +
+
+ +
+
+
+
+ + +
+ +
+
+ + +
+
+ + + +
+
+
+ + +
+
+
+ + +
+
From 3a4128e33a74403e4d6a19580ba999435a046abd Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:57:52 -0300 Subject: [PATCH 03/12] feat: add create transaction form for Mall Completa Diferido with options for installments and confirmation --- .../create.html | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/create.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/create.html b/src/main/resources/templates/transaccion_completa_mall_diferido/create.html new file mode 100644 index 0000000..3b6f606 --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/create.html @@ -0,0 +1,71 @@ +
+
+

Transacción Completa Mall Diferido - Crear transacción

+

+ En este paso sucede la creación de la transacción con el objetivo de obtener un identificador único para la misma. +

+ +

Paso 1: Petición

+

+ Comienza importando la librería TransaccionCompleta Mall, y a continuación, crea la transacción necesaria. +

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.model.MallTransactionCreateDetails;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+var details = MallTransactionCreateDetails.build()
+  .add(1000, IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED_CHILD1, "O-123")
+  .add(1000, IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED_CHILD2, "O-456");
+
+var resp = tx.create(buyOrder, sessionId, cardNumber, cardExpiry, details, cvv);
+    
+ +

Paso 2: Respuesta

+

Una vez creada la transacción, recibirás los siguientes datos de respuesta:

+ +
+ +

¡Transacción creada!

+

Ahora que hemos creado la transacción, se abren dos opciones para continuar:

+
    +
  • + Consultar Cuotas (opcional): Alternativamente puedes realizar consultas de cuotas + para ofrecer opciones de pago a plazos. +
  • +
  • + Confirmar Transacción: Debes confirmar directamente la transacción para + finalizar con el proceso de pago. +
  • +
+ +
+ +
+ Formulario de redirección + +
+ + + +
+ +
+
+
+
From d8e771462c397e54f1115e912ca99d2f13d13604 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:58:09 -0300 Subject: [PATCH 04/12] feat: add installments consultation form for Mall Completa Diferido with optional fields and confirmation link --- .../installments.html | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/installments.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html new file mode 100644 index 0000000..85ed2bc --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html @@ -0,0 +1,100 @@ +
+
+

Transacción Completa Mall Diferido - Consulta de cuotas

+

+ En esta etapa, realizaremos una consulta de cuotas para conocer sus condiciones. Es importante + destacar que este paso es opcional y se utiliza únicamente si deseas ofrecer opciones de pago a plazos. +

+ +

Paso 1: Petición

+

Para llevar a cabo la consulta de cuotas, debemos enviar los siguientes datos relevantes.

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+import cl.transbank.webpay.transaccioncompleta.responses.MallFullTransactionInstallmentsDetails;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+var details = MallFullTransactionInstallmentsDetails.build()
+  .add("597055555577", "O-123", (byte) 3)
+  .add("597055555578", "O-456", (byte) 3);
+
+var resp = tx.installments(token, details);
+    
+ +

Paso 2: Respuesta

+

Una vez realizada la consulta de cuotas, recibirás los siguientes datos de respuesta:

+ +
+ +

Confirmar Transacción

+

+ Si decides utilizar cuotas y estás satisfecho con las condiciones obtenidas en la consulta, el + siguiente paso sería confirmar la transacción. +

+ +
+ + +
+ + +
+ +
+ + +
+
+ + +
+ + +
+ + +
+
From 36aee464b1c6ba49da5c75f9b90a291f4b93db43 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:58:19 -0300 Subject: [PATCH 05/12] feat: add refund process template for Mall Completa Diferido transactions --- .../refund.html | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/refund.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html b/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html new file mode 100644 index 0000000..141dda2 --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html @@ -0,0 +1,44 @@ +
+
+

Transacción Completa Mall Diferido - Reembolsar

+

+ En esta etapa, tendrás la posibilidad de solicitar el reembolso del dinero al tarjeta habiente. El + tipo de reembolso (Reversa, Anulación o Anulación parcial) dependerá del monto y el tiempo transcurrido desde la + transacción. +

+ +

Paso 1: Petición

+

+ Para efectuar la solicitud de reembolso, necesitarás el token de la transacción, el buy order del detalle, + el commerce code hijo y el monto que deseas reversar. +

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+var resp = tx.refund(token, buyOrder, childCommerceCode, amount);
+    
+ +

Paso 2: Respuesta

+

+ Transbank responderá con el resultado de la reversa o anulación. Evalúa cuidadosamente esta respuesta para + confirmar que el reembolso se haya procesado de manera efectiva. +

+ +
+ + CONSULTAR ESTADO +
+
From bee83e74b2de47466fa1905f60815246487769d3 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:58:27 -0300 Subject: [PATCH 06/12] feat: add capture transaction template for Mall Completa Diferido with refund and status consultation options --- .../capture.html | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/capture.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/capture.html b/src/main/resources/templates/transaccion_completa_mall_diferido/capture.html new file mode 100644 index 0000000..4ac779f --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/capture.html @@ -0,0 +1,68 @@ +
+
+

Transacción Completa Mall Diferido - Capturar transacción

+

+ En este paso debemos capturar la transacción para realmente capturar el dinero que habia sido previamente reservado al hacer la transacción. +

+ +

Paso 1: Petición

+

+ Para capturar una transacción, necesitaremos el Token, la Orden de compra, el Código de autorización y el monto a capturar. +

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+var resp = tx.capture(token, childCommerceCode, childBuyOrder, authorizationCode, amount);
+    
+ +

Paso 2: Respuesta

+

Una vez capturada la transacción, recibirás los siguientes datos de respuesta:

+ +
+ +

Otras utilidades

+

+ Con la transacción capturada, puedes mostrar al usuario una página de éxito de la transacción, proporcionándole la confirmación de que el proceso se ha completado con éxito. +

+ +

Después de capturar la transacción, podrás realizar otras operaciones útiles:

+
    +
  • Reembolsar: Puedes reversar o anular el pago según ciertas condiciones comerciales.
  • +
  • Consultar Estado: Hasta 7 días después de realizada la transacción, podrás consultar el estado de la transacción.
  • +
+ +
+
+
+ + + + + +
+ + +
+
+ + CONSULTAR ESTADO +
+
From 580b5b68fe3798ec91fcb2094e89327a56957e0d Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 10:58:36 -0300 Subject: [PATCH 07/12] feat: add confirmation template for Mall Completa Diferido transaction with capture form --- .../commit.html | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/commit.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/commit.html b/src/main/resources/templates/transaccion_completa_mall_diferido/commit.html new file mode 100644 index 0000000..e5c5b1d --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/commit.html @@ -0,0 +1,81 @@ +
+
+

Transacción Completa Mall Diferido - Confirmar transacción

+

+ En este paso crucial, procederemos a confirmar la transacción con el objetivo de notificar a + Transbank que hemos recibido la transacción de manera exitosa. Es fundamental destacar que si no se confirma la + transacción, esta será caducada. +

+ +

Paso 1: Petición

+

+ Para confirmar la transacción, debes enviar el token correspondiente. En el caso de pagos a + plazos, también debes incluir el ID de la consulta de cuotas. En algunos casos, será necesario proporcionar el + índice del periodo diferido y un valor boolean indicando si se tomará el periodo de gracia. +

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+import cl.transbank.webpay.transaccioncompleta.model.MallTransactionCommitDetails;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+// idQueryInstallments, deferredPeriodIndex y gracePeriod son opcionales
+var details = MallTransactionCommitDetails.build()
+  .add("597055555577", "O-123", idQueryInstallments, deferredPeriodIndex, gracePeriod)
+  .add("597055555578", "O-456", idQueryInstallments, deferredPeriodIndex, gracePeriod);
+
+var resp = tx.commit(token, details);
+    
+ +

Paso 2: Respuesta

+

+ Una vez que la transacción ha sido confirmada Transbank proporcionará la siguiente información. Es fundamental + conservar esta respuesta y verificar que el campo "response_code" tenga un valor de cero y que el campo "status" + sea "AUTHORIZED". +

+ +
+ +

¡Listo!

+

Ahora que se ha confirmado la transacción, puedes capturar el monto previamente autorizado.

+ +
+
+
+ Capturar +
+ + + + + + + + + +
+ + +
+
+
+ + CONSULTAR ESTADO +
+
From b4225aaa92a31a83d3515feb55b6f561a832efb4 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 11:02:32 -0300 Subject: [PATCH 08/12] feat: add status template for Mall Completa Diferido transactions --- .../status.html | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/resources/templates/transaccion_completa_mall_diferido/status.html diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/status.html b/src/main/resources/templates/transaccion_completa_mall_diferido/status.html new file mode 100644 index 0000000..b26e491 --- /dev/null +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/status.html @@ -0,0 +1,44 @@ +
+
+

Transacción Completa Mall Diferido - Estado de transacción

+

+ En esta fase, tendrás la capacidad de solicitar el estado actual de una transacción hasta 7 días + después de su realización. Es importante destacar que no hay límite en la cantidad de solicitudes de este tipo + durante este período. Sin embargo, una vez transcurridos los 7 días, ya no podrás revisar el estado de la + transacción. +

+ +

Paso 1: Petición

+

+ Para llevar a cabo la solicitud de estado, necesitarás el token correspondiente a la transacción + de la cual deseas obtener información. Utiliza este token para realizar una llamada a + MallFullTransaction.status(). +

+ +

+import cl.transbank.common.IntegrationApiKeys;
+import cl.transbank.common.IntegrationCommerceCodes;
+import cl.transbank.common.IntegrationType;
+import cl.transbank.webpay.common.WebpayOptions;
+import cl.transbank.webpay.transaccioncompleta.MallFullTransaction;
+
+MallFullTransaction tx = new MallFullTransaction(
+  new WebpayOptions(
+    IntegrationCommerceCodes.TRANSACCION_COMPLETA_MALL_DEFERRED,
+    IntegrationApiKeys.WEBPAY,
+    IntegrationType.TEST
+  )
+);
+
+var resp = tx.status(token);
+    
+ +

Paso 2: Respuesta

+

+ Transbank responderá con la siguiente información. Asegúrate de guardar estos detalles; lo único que necesitas + validar es que el campo "response_code" sea igual a cero. +

+ +
+
+
From 18877b1cf7e3a0f2f4ca9e2efe57ed6507cba68d Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Tue, 31 Mar 2026 11:08:37 -0300 Subject: [PATCH 09/12] feat: improve formatting and readability of installments consultation template for Mall Completa Diferido --- .../installments.html | 112 ++++++++++++------ 1 file changed, 78 insertions(+), 34 deletions(-) diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html index 85ed2bc..5ecbeb2 100644 --- a/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html @@ -2,12 +2,16 @@

Transacción Completa Mall Diferido - Consulta de cuotas

- En esta etapa, realizaremos una consulta de cuotas para conocer sus condiciones. Es importante - destacar que este paso es opcional y se utiliza únicamente si deseas ofrecer opciones de pago a plazos. + En esta etapa, realizaremos una consulta de cuotas para conocer sus + condiciones. Es importante destacar que este paso es opcional y se utiliza + únicamente si deseas ofrecer opciones de pago a plazos.

Paso 1: Petición

-

Para llevar a cabo la consulta de cuotas, debemos enviar los siguientes datos relevantes.

+

+ Para llevar a cabo la consulta de cuotas, debemos enviar los siguientes + datos relevantes. +


 import cl.transbank.common.IntegrationApiKeys;
@@ -33,45 +37,83 @@ 

Paso 1: Petición

Paso 2: Respuesta

-

Una vez realizada la consulta de cuotas, recibirás los siguientes datos de respuesta:

+

+ Una vez realizada la consulta de cuotas, recibirás los siguientes datos de + respuesta: +

-
+

Confirmar Transacción

- Si decides utilizar cuotas y estás satisfecho con las condiciones obtenidas en la consulta, el - siguiente paso sería confirmar la transacción. + Si decides utilizar cuotas y estás satisfecho con las condiciones + obtenidas en la consulta, el siguiente paso sería confirmar la + transacción.

- - -
- - + + +
+ +
-
- - +
+ +
-
- - +
+ +
From d6684b8e67fbe95805ca173485674ee12deac46e Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Wed, 1 Apr 2026 13:47:45 -0300 Subject: [PATCH 10/12] fix: correct wording in transaction form description for Mall Completa Diferido --- .../templates/transaccion_completa_mall_diferido/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/index.html b/src/main/resources/templates/transaccion_completa_mall_diferido/index.html index 081db69..5c7ad81 100644 --- a/src/main/resources/templates/transaccion_completa_mall_diferido/index.html +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/index.html @@ -3,8 +3,8 @@

Transacción Completa Mall Diferido - Formulario

En esta primera etapa necesitas obtener los datos esenciales de la tarjeta - de crédito, débito o prepago del titular. Utiliza el formulario para - recolectar esta información de manera segura. + de crédito del titular. Utiliza el formulario para recolectar esta + información de manera segura.

From 7ce0bc07d593e5d6c113b044e3ab0cec437ff7c6 Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Wed, 1 Apr 2026 13:50:39 -0300 Subject: [PATCH 11/12] feat: enhance readability and formatting of refund template for Mall Completa Diferido --- .../refund.html | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html b/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html index 141dda2..61a611d 100644 --- a/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/refund.html @@ -2,15 +2,17 @@

Transacción Completa Mall Diferido - Reembolsar

- En esta etapa, tendrás la posibilidad de solicitar el reembolso del dinero al tarjeta habiente. El - tipo de reembolso (Reversa, Anulación o Anulación parcial) dependerá del monto y el tiempo transcurrido desde la + En esta etapa, tendrás la posibilidad de solicitar el reembolso del dinero + al tarjeta habiente. El tipo de reembolso (Reversa, Anulación o Anulación + parcial) dependerá del monto y el tiempo transcurrido desde la transacción.

Paso 1: Petición

- Para efectuar la solicitud de reembolso, necesitarás el token de la transacción, el buy order del detalle, - el commerce code hijo y el monto que deseas reversar. + Para efectuar la solicitud de reembolso, necesitarás el token de la + transacción, el buy order del detalle, el commerce code (tienda) y el + monto que deseas reversar.


@@ -33,12 +35,20 @@ 

Paso 1: Petición

Paso 2: Respuesta

- Transbank responderá con el resultado de la reversa o anulación. Evalúa cuidadosamente esta respuesta para - confirmar que el reembolso se haya procesado de manera efectiva. + Transbank responderá con el resultado de la reversa o anulación. Evalúa + cuidadosamente esta respuesta para confirmar que el reembolso se haya + procesado de manera efectiva.

-
+
+      
+    
- CONSULTAR ESTADO + + CONSULTAR ESTADO +
From 43518b32077db28e3f53e2e05f8f0ce4d184e93f Mon Sep 17 00:00:00 2001 From: victor mendoza Date: Wed, 1 Apr 2026 13:58:41 -0300 Subject: [PATCH 12/12] feat: improve formatting and readability of installments template for Mall Completa Diferido --- .../installments.html | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html index 5ecbeb2..74e5cb2 100644 --- a/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html +++ b/src/main/resources/templates/transaccion_completa_mall_diferido/installments.html @@ -42,9 +42,9 @@

Paso 2: Respuesta

respuesta:

-
+
+      
+    

Confirmar Transacción

@@ -62,9 +62,9 @@

Confirmar Transacción

/>
- + Confirmar Transacción
- + Confirmar Transacción />
- + Confirmar Transacción