# Changelog

## = v1.0.6 2026-06-29 =

**3DS — migración de dominios Cardinal (Visa)**
- Fix: La validación del `event.origin` del Device Data Collection (DDC) 3DS ya no compara contra un dominio fijo. Ahora el origin se DERIVA del `deviceDataCollectionUrl` que devuelve `/3ds/setup`, por lo que el match es a prueba de la migración de dominios Visa `*.cardinalcommerce.com` → `*.cardinaltrusted.com` (pruebas ya migrado; producción ~julio 2026) sin tocar el código. Se eliminó la constante `cardinal_commerce_url`.
- Fix: Se agregó un timeout de respaldo (10s) en `createIframe3DSDeviceDataCollection` que oculta el loader y re-habilita el botón de pago si Cardinal no confirma el DDC, evitando que el flujo quede bloqueado. La lógica de desbloqueo se centralizó en `unblockAfterDDC()`.
- Nota: El listener del challenge 3DS (`addEventListenerOrchestrator`) no cambia: valida contra el dominio del orquestador GreenPay (`checkoutv2.greenpay*.me`), no afectado por la migración.

## = v1.0.5 2026-04-27 =

**Compatibilidad checkout clásico**
- Fix: Los IDs de los inputs de tarjeta en el checkout clásico ahora coinciden con los que esperan el JS y el componente Blocks (`#greenpayService-card-number/-expiry/-cvc`, `#wc-greenpayService-cc-form`). Resuelve `TypeError: Cannot read properties of undefined (reading 'substring')` al cargar la página.
- Fix: El botón "Place order" ahora dispara correctamente el flujo de pago en checkout clásico (la detección del método ya no depende de un ID que no existía).
- Fix: `payloadCreateOrder` ahora lee los campos billing del `<form>` padre (estaban fuera del fieldset CC), evitando que el flujo se aborte y se borren los datos de tarjeta al cambiar al CVC.
- Fix: `inputMasks()` evita aplicar `jquery.mask` sobre el expiry/number/cvc cuando WooCommerce ya formatea esos campos vía `wc-credit-card-form.js`. Antes el conflicto bloqueaba el expiry a 2 dígitos en clásico.
- Fix: `errorNoticeBlocks` detecta el contexto y escribe en `#greenpayService-error-notice` (Blocks), `.payment_box.payment_method_greenpay-payment-service` (clásico) o como fallback en el form de checkout. Antes en clásico el mensaje de error nunca se mostraba.
- Fix: Selector de `errorNotice` corregido a `.payment_method_greenpay-payment-service` (la clase real que WooCommerce genera).

**Manejo de errores 3DS y de pago**
- Fix: El overlay del modal 3DS (`.div-iframe`) ahora se elimina correctamente al cerrar el challenge y en cualquier rama de error de validate. Antes quedaba bloqueando la pantalla con el mensaje de error oculto detrás.
- Enhancement: Helper `extractAjaxErrorMessage(jqXHR)` extrae el mensaje real del API GreenPay (`responseJSON.gp_error.message/description`, `responseJSON.message`). Aplicado en todos los AJAX al API (`createOrder`, `3DSSetup`, `3DSEnrollment`, `3DSValidate`, `checkoutV1`, `checkoutV2`, `setOrderPaid`).
- Enhancement: Helper `isApiErrorResponse(response)` detecta respuestas de error que llegan con HTTP 200 (`status: "fail"`, `gp_error`) y aborta el flujo mostrando el mensaje. Aplicado en cada paso del flujo 3DS y de pago directo.
- Fix: `setOrderPaid` rama `result === "failure"` ahora lee `result.error.message` (formato real del backend) en lugar de `result.messages` (que no existía).
- Fix: Backend `greenpayProcessPaymentWithThreeds` lee `$response['error']['message']` para construir el `wc_add_notice` (antes leía `$response['message']` que nunca existía).
- Enhancement: Nueva clave i18n `i18n_3ds_validate_error` como fallback legible cuando el API no devuelve mensaje específico.

**Validación de tarjeta**
- Fix: Validación de CVC ahora respeta el tipo de tarjeta. AMEX requiere 4 dígitos; Visa/Mastercard/Credix requieren 3. Antes `$.payment.validateCardCVC` se llamaba sin tipo y dejaba pasar AMEX con 3 dígitos al submit.
- Enhancement: Guard defensivo en `validateForm` que retorna temprano si los inputs de tarjeta no están en DOM (cubre escenarios donde el form se renderiza con retraso).

**Compatibilidad con flujos personalizados**
- Fix: "Please complete the required fields first." ya no aparece cuando el cliente captura los datos de billing/shipping en otra pantalla (My Account → Address, popup, flujo custom). Se inyecta `customer_data` desde `WC()->customer` (sesión) en `gpservice_params` y se usa como fallback en `validateForm`, `payloadCreateOrder` y `setOrderPaid` cuando los inputs HTML del checkout form están vacíos.
- Fix: Soporte para la página **"Pay for Order"** (`/checkout/order-pay/...`). Antes el plugin enviaba `amount = 0` y `customer_data` vacío porque leía del cart (vacío en order-pay) y de `WC()->customer`. Ahora detecta `is_checkout_pay_page()` y lee `amount`, `currency`, `products` y billing/shipping desde la orden. Aplica defaults razonables (`'N/A'`, `'00000'`, `'00000000'`) a los campos billing vacíos para no bloquear el cobro cuando plugins de terceros (ej. Tourmaster) crean órdenes con billing parcial; el AVS del banco hace la validación final.
- Fix: En "Pay for Order", el backend (`submitedAjaxOrderData`) ahora **procesa el pago contra la orden existente** (preserva total, items, notas y meta originales). Antes creaba una orden duplicada con total = 0 porque usaba `WC()->cart` (vacío). Cuando el JS detecta order-pay, envía `order_pay_id` y el PHP toma esa orden, le aplica `payment_complete()` y mantiene la transacción atada a la orden original.
- Fix: En "Pay for Order", si la orden externa fue creada sin `payment_method` (Tourmaster, Tigo Play, API admin), el plugin ahora la asocia al gateway antes de procesar el cobro. Antes la metabox de admin omitía la línea "Payment via Credit card (Greenpay) (XXXXXX)" porque WC core la oculta cuando `$order->get_payment_method()` está vacío; solo quedaba visible "Paid on …. Customer IP: …". Solo se setea cuando el campo está vacío, sin pisar órdenes que ya tenían otro gateway asociado.

## = v1.0.4 2026-02-24 =

- Enhancement: Added AMEX support for V2 terminals via new "Enable AMEX" checkbox in V2 settings section
- Fix: V2 terminals using UUIDs can now accept AMEX cards (previously only BAC-named terminals could enable AMEX)
- Fixed WordPress.org compliance: Renamed helper functions from wcga()/wcgpt() to gpservice_api()/gpservice_payment_tokens()
- Fixed class name bug in gpservice_payment_tokens() function
- All function names now use proper greenpay_ or gpservice_ prefix to avoid conflicts with WooCommerce core

## = v1.0.3 2025-01-12 =

- Security enhancements: Fixed webhook signature verification
- Added CSRF protection with nonce verification
- Implemented REST API authorization checks
- Added automatic sanitization of sensitive data in logs (PCI-DSS compliance)
- Performance improvements: Added database indexes
- Changed PHP requirement from 8.2 to 7.4 for better compatibility
- Fixed PHPCS compliance issues

## = v1.0.2 2025-01-13 =

- Fixed: Shipping address and order notes now correctly saved in WooCommerce orders during 3DS checkout
- Fixed: Place Order button now works correctly when other payment methods are selected (no longer blocked by GreenPay validation)
- Fixed: Added payment method change listener to properly enable/disable Place Order button when switching between payment methods
- Fixed: Order notes field detection improved for both classic and block checkout compatibility
- Fixed: Build script now properly cleans minified JS files before regenerating (prevents .min.min.js duplicates)
- Tested with WordPress 6.9 and WooCommerce 10.4.3

## = v1.0.0 2025-10-14 =

- Initial release of GreenPay Payment Service
- Renamed from GreenPay Payment Gateway to GreenPay Payment Service
- Updated all class names, function names, and text domains
- Complete refactoring of plugin structure and naming conventions
