Skip to content

Withdrawal from contract - Pro features

La versión Pro amplía el módulo gratuito de desistimiento con una gestión de reembolsos operada por el operador, PDF de declaraciones, un registro de auditoría, informes e integraciones con suscripciones / paquetes de productos. Presupone que tiene activa la versión gratuita de Polski for WooCommerce y que conoce el módulo básico de desistimiento.

Reembolso automático (con confirmación del operador)

Section titled “Reembolso automático (con confirmación del operador)”

Nunca automático, un reembolso requiere una acción explícita del operador en la pantalla del pedido. En Edit order › Polski - withdrawal refund (metabox a la derecha) el operador ve:

  • El importe de reembolso calculado a partir de las líneas de declaración seleccionadas
  • Un botón Process refund now (con un confirm() de JS para una doble confirmación)
  • Tras el procesamiento: el número de reembolso de WooCommerce, el importe y la fecha

Lógica:

  1. Obtiene las líneas de polski_withdrawal_items para la declaración indicada
  2. Las mapea al formato de wc_create_refund() (qty, refund_total, refund_tax)
  3. Añade el coste de envío solo si el desistimiento cubre todas las líneas del pedido
  4. Llama al reembolso de la pasarela (refund_payment => true) y a la reposición de existencias (restock_items => true)
  5. Guarda refund_id y refund_amount en polski_withdrawals
  6. Dispara polski_pro/withdrawal/refund_processed y WithdrawalService::complete()

El filtro polski_pro/withdrawal/refund_payload le permite modificar el payload antes de wc_create_refund() (por ejemplo, para añadir el envío en casos específicos o cambiar los impuestos).

Polski\Pro\Service\WithdrawalPdfGenerator utiliza TCPDF para generar un PDF A4 con:

  • Un número de declaración POL-WD-NNNNNN y la fecha de presentación
  • El destinatario (datos de la tienda de polski_general o woocommerce_store_*)
  • El consumidor (nombre/apellidos de facturación, dirección, correo electrónico)
  • El texto de la declaración con una referencia al art. 27 de la Ley de derechos del consumidor
  • Una tabla de líneas (nombre + atributos de variación, cantidad, valor)
  • El valor del pedido
  • La fecha del pedido
  • El motivo (si el cliente lo indicó)
  • Un espacio para una firma (solo versión en papel)
  • Una nota sobre el soporte duradero

Se guarda en wp-content/uploads/polski-withdrawals/YYYY/MM/POL-WD-NNNNNN.pdf (protegido con .htaccess deny from all).

Se genera automáticamente en cada evento requested/guest_requested/manual_registered, se adjunta al correo del consumidor mediante el filtro woocommerce_email_attachments. La ruta se almacena en la meta del pedido _polski_withdrawal_pdf, las llamadas posteriores a ensurePdf() son idempotentes (solo se regenera si el archivo ha desaparecido).

Verificación del número de descargas (relajación del art. 16(m))

Section titled “Verificación del número de descargas (relajación del art. 16(m))”

Para pedidos 100 % digitales, incluso cuando ha recogido el consentimiento del art. 16(m), el consumidor conserva el derecho de desistimiento si no ha descargado ningún archivo. El servicio DigitalDownloadVerifier:

  1. Se engancha en el filtro polski/withdrawal/eligible con prioridad 30 (después de DigitalConsentService=20)
  2. Itera las líneas del pedido, para cada elemento descargable/virtual suma las descargas de wc_get_customer_download_log por permiso
  3. Si ningún elemento tiene count > 0, restaura la elegibilidad (devuelve true en lugar de false)
  4. Si al menos uno se ha descargado, deja false

Se activa mediante polski_withdrawal['digital_download_verification'] = '1' en los ajustes (desactivado por defecto, opt-in según la política de la tienda).

Por defecto, las suscripciones no se excluyen de los desistimientos (a menos que el storefront establezca el filtro polski_pro/subscriptions/treat_as_exempt => true para el comportamiento heredado). Lógica:

  • Cuando una declaración se completa (polski/withdrawal/completed), el servicio itera las suscripciones vinculadas al pedido a través de wcs_get_subscriptions_for_order y establece el estado en cancelled (con una nota)
  • El payload de reembolso es proporcional a la parte no utilizada del periodo de facturación actual de acuerdo con el art. 9(2)(b)(iii) de la directiva
  • Fórmula: ratio = 1 - (elapsed / total_period_length), aplicada por línea a refund_total y refund_tax
  • Toma el ratio mínimo de todas las suscripciones vinculadas al pedido

Tres estrategias de reembolso (bundle_refund_mode en los ajustes o el filtro polski_pro/withdrawal/bundle_refund_mode):

ModoComportamiento
whole_bundle (por defecto)El reembolso cubre todo el paquete + todos los componentes (amplía el payload con el parent y los siblings)
proportionalReembolso solo por el componente seleccionado (una parte del precio del paquete proporcional al número de elementos)
remove_discountReembolso por el componente al precio individual (sin el descuento del paquete)

Detección del paquete mediante la meta de línea de pedido _bundled_by o el tipo de producto bundle.

AnnexMultiLanguageService amplía el filtro polski/annex/form_html con traducciones para los locales: pl, de, de_AT, fr, nl, it, es + eu genérico (fallback en inglés). Cada traducción contiene la redacción correcta de la versión oficial de la directiva + una referencia legal nacional (BGB §355 DE, KSchG §11 AT, Code de la consommation art. L221-18 FR, Burgerlijk Wetboek 6:230o NL, Codice del Consumo art. 52 IT, TRLGDCU art. 102 ES, Consumer Rights Act art. 27 PL).

Selección de idioma:

  • El ajuste polski_withdrawal['annex_locale'] (anulación global)
  • Detección automática desde get_locale() si el ajuste está vacío
  • Atributo de shortcode: [polski_withdrawal_form_template_pro lang="de"]
  • El filtro polski/annex/locale

Polski Pro › Withdrawal reports - scorecards + desglose con un filtro de rango de fechas:

  • Filed - número total de declaraciones presentadas
  • Completed - finalizadas
  • In progress - requested + confirmed
  • Rejected - rechazadas
  • Average processing time - requested_at → completed_at (segundos, formateado mediante human_time_diff)
  • Refunded - recuento × importe
  • Top reasons - los 10 motivos únicos principales (agrupados por motivo)
  • Channel breakdown - online / guest / phone / email / letter / in_store

Almacenado en caché durante 5 minutos por tupla de filtro (transient).

Endpoints REST (paridad para WP más antiguos):

  • GET /polski-pro/v1/withdrawals/reports/scorecards?from=...&to=...
  • GET /polski-pro/v1/withdrawals/reports/reasons?limit=10
  • GET /polski-pro/v1/withdrawals/reports/channels

Todos protegidos por manage_woocommerce.

Registro de auditoría con exportación a CSV

Section titled “Registro de auditoría con exportación a CSV”

polski_pro_withdrawal_audit (Migration 2.5.0) registra cada evento del ciclo de vida de la declaración:

CampoContenido
withdrawal_idID de la declaración
order_idID del pedido
actionrequested / confirmed / completed / rejected / guest_requested / manual_registered / refunded
actor_user_idID de usuario de WP (o NULL para un invitado)
actor_roleEl primer rol de WP del usuario
actor_loginuser_login
ip_addressDe HTTP_CF_CONNECTING_IPX_FORWARDED_FORREMOTE_ADDR
user_agentTruncado a 1000 caracteres
payload_jsonInstantánea del evento (channel, reason, refund_amount, email, etc.)
created_atdatetime UTC

Admin Polski Pro › Withdrawal audit - una tabla con filtros (action, rango de fechas, withdrawal_id, order_id) + un botón Export to CSV (transmitido a través de admin-post.php con un nonce).

REST:

  • GET /polski-pro/v1/withdrawals/audit - lista paginada
  • GET /polski-pro/v1/withdrawals/audit/export - CSV transmitido

4 abilities adicionales en la categoría polski-pro/withdrawal:

IDQué hace
polski-pro/withdrawal-process-refundConstruye y ejecuta el reembolso de una declaración
polski-pro/withdrawal-generate-pdfGenera (o devuelve un PDF en caché de) la declaración
polski-pro/withdrawal-audit-listEnumera las entradas del registro de auditoría con filtros
polski-pro/withdrawal-report-scorecardsPanel de KPI

Todos protegidos por manage_woocommerce, descritos con JSON Schema (entrada/salida).

do_action('polski_pro/withdrawal/refund_processed', int $withdrawalId, WC_Order_Refund $refund);
do_action('polski/pro/withdrawal/pdf_generated', int $withdrawalId, string $filepath);
apply_filters('polski_pro/withdrawal/refund_payload', array $payload, WC_Order, int $withdrawalId);
apply_filters('polski_pro/withdrawal/download_verification_enabled', bool $enabled);
apply_filters('polski_pro/withdrawal/bundle_refund_mode', string $mode);
apply_filters('polski_pro/subscriptions/treat_as_exempt', bool $exempt, WC_Order $order);