← Volver al portfolio

Nonino Caffe

Tienda de café de especialidad

Tienda online en WooCommerce con tema propio y plugin a medida. Me encargué del diseño, el desarrollo y las integraciones de pago y envío.

El código se reparte en dos piezas: un tema propio y un único plugin propio, donde vive la lógica de la tienda (checkout, envíos, pagos, emails, newsletter y medición). Los plugins de terceros, como los de los transportistas, se adaptan con filtros y hooks de WordPress.

Herramientas desarrolladas

Hechas para Nonino Caffe, ordenadas de la más compleja a la más simple.

  1. Checkout a medida

    • PHP
    • JavaScript
    • jQuery
    • WooCommerce

    Qué hace

    Reemplaza el formulario de compra clásico de WooCommerce. El plugin propio redefine los campos: un solo campo de nombre completo que se separa en nombre y apellido, código postal de cuatro números, calle, altura y localidad. Valida todo en el servidor con mensajes en español, y un script del tema repite las validaciones en el navegador, junto a cada campo.

    Para los envíos a sucursal, el comprador elige entre las sucursales de Correo Argentino y de Andreani en selectores con el mismo aspecto. La lista de Correo se limita a la provincia del checkout y se ordena por cercanía de código postal. El retiro local no pide calle ni altura.

    Qué complejidad tiene

    El checkout de WooCommerce se actualiza por AJAX cada vez que cambia la dirección, y dos plugins de transportistas de terceros agregan sus propios selectores y recargas sobre la misma página. La dificultad fue hacerlos convivir sin editar sus archivos: se registra la acción AJAX de sucursales de Correo antes que la del plugin para filtrar la lista, los mensajes de los dos transportistas se unifican reemplazando solo el texto con el filtro gettext, y el script reconstruye ambos selectores con la misma configuración cada vez que los plugins vuelven a cargar su lista.

    La tabla que cruza código postal y provincia es deliberadamente permisiva: marca error solo cuando el código está fuera de la provincia con certeza, para no bloquear una compra válida. Si hay una incompatibilidad, no se piden cotizaciones a los transportistas. El script también controla el desplazamiento de la página cuando hay errores de validación, porque WooCommerce lo mueve por su cuenta.

  2. Tema propio de WooCommerce

    • PHP
    • JavaScript
    • CSS
    • WooCommerce

    Qué hace

    Un tema clásico de WordPress hecho a medida, que reemplaza las plantillas de WooCommerce del catálogo, la ficha de producto, el carrito, el detalle del pedido y la página de pedido recibido. Incluye las secciones de la portada, una página del club y una de preguntas frecuentes.

    El catálogo tiene filtros por origen y peso, rango de precio y un orden por puntaje. El carrito también se abre en un panel lateral desde el encabezado, y la página del carrito tiene un selector de cantidad que actualiza el pedido solo.

    Qué complejidad tiene

    Los filtros usan los parámetros nativos de WooCommerce (atributos en la URL, rango de precio y orden), así que una búsqueda filtrada funciona como un formulario común sin JavaScript. El script solo agrega el envío automático al cambiar un filtro y, en celulares, convierte el panel en un cajón lateral con trampa de foco, cierre con Escape y bloqueo del scroll de la página, más una vista previa de cuántos cafés da la selección.

    La página de pedido recibido cambia según el estado del pedido (fallido, pagado, en espera, pendiente o recibido) y distingue los pagos por transferencia. Al sobrescribir plantillas de WooCommerce, el tema tiene que seguir funcionando con las actualizaciones de WooCommerce y de los plugins de pago y envío.

  3. Cotización de envío en la ficha de producto

    • PHP
    • JavaScript
    • AJAX
    • WooCommerce

    Qué hace

    En la ficha de un producto, el visitante ingresa provincia y código postal y ve las opciones de envío y su costo antes de agregar nada al carrito. Una acción AJAX del plugin propio valida la consulta (nonce, código postal de cuatro números y provincia) y responde con las tarifas disponibles o con un mensaje específico si algo falla.

    Qué complejidad tiene

    WooCommerce calcula el envío a partir del carrito, no de un producto suelto. Para cotizar desde la ficha se arma un paquete de envío simulado, con una unidad del producto y el destino ingresado, sin tocar el carrito del comprador. Cada método de envío se calcula por separado: si un transportista falla, las tarifas de los demás se muestran igual, y solo se informa un error cuando ninguno responde.

    Sobre ese resultado se vuelven a aplicar los mismos filtros de tarifas que usa el checkout, para que el retiro local y el envío gratis que ve el visitante coincidan con lo que va a ver al comprar.

  4. Newsletter con doble confirmación y cupón de bienvenida

    • PHP
    • JavaScript
    • MySQL
    • WooCommerce

    Qué hace

    El visitante se suscribe desde una ventana de bienvenida, recibe un mail con un enlace para confirmar y, al confirmar, se le emite un cupón de WooCommerce con vencimiento. Cada mail incluye un enlace de baja. En el panel hay un listado de suscriptores con filtro por estado, búsqueda, exportación a CSV y borrado.

    Los suscriptores se guardan en una tabla propia de MySQL, con el texto de consentimiento y su versión, la fecha y un hash de la IP en lugar de la IP. El cupón se valida en el carrito y en el checkout: solo sirve para la primera compra y para el email que lo recibió.

    Qué complejidad tiene

    Se usa una tabla propia en lugar de un tipo de contenido de WordPress porque son datos personales: necesitan una clave única sobre el email normalizado para no duplicar suscriptores de forma atómica (por ejemplo, variantes de Gmail con puntos o con +etiqueta), y no deben quedar expuestos a la API REST ni a la búsqueda de WordPress. El enlace de confirmación guarda solo el hash del token y vence a los dos días.

    El cupón combina varias reglas: el control de primera compra compara con los datos de pedidos anteriores, que se guardan normalizados al comprar, y el descuento por transferencia puede reducirse cuando el pedido usa este cupón.

  5. Reglas de envío local y envío gratis

    • PHP
    • WooCommerce

    Qué hace

    El retiro y la entrega local son métodos nativos de WooCommerce que el plugin muestra solo para los códigos postales de Alta Gracia y Anisacate, en Córdoba. La entrega a domicilio pasa a costo cero cuando el carrito llega al mismo monto de envío gratis que se anuncia para el resto del país, y el retiro agrega una nota para coordinar la dirección por WhatsApp. Los pedidos de retiro reciben las mismas instrucciones en los mails.

    Para el resto del país, un adaptador pone en cero las tarifas de Correo Argentino y Andreani cuando el pedido alcanza el monto, y muestra el costo original tachado junto a la etiqueta de envío gratis.

    Qué complejidad tiene

    Los transportistas calculan cada tarifa por API y no conocen el envío gratis. El adaptador no inventa precios: toma la tarifa que devuelve el transportista, la pone en cero y conserva el costo original para mostrarlo tachado. Actúa solo sobre una lista cerrada de métodos de envío verificados, así que el retiro y otras tarifas nunca quedan gratis por error.

    El monto se lee de la configuración nativa de envío gratis, por lo que la barra de progreso del carrito, la entrega local y los transportistas coinciden. Para el retiro, el servidor deja de exigir calle y altura, pero WooCommerce sigue rechazando una tarifa de retiro que no corresponda al destino.

  6. Medición de e-commerce con GA4 y Meta Pixel

    • PHP
    • JavaScript
    • Google Analytics 4
    • Meta Pixel

    Qué hace

    El plugin prepara en PHP los datos de cada producto, el carrito y la compra, y un script los convierte en eventos de Google Analytics 4: lista y vista de producto, agregar y quitar del carrito, ver carrito, inicio de checkout, método de pago y compra. Si el Meta Pixel está cargado, refleja los eventos estándar equivalentes. Una página de ajustes permite cargar los IDs, y mientras no haya ninguno no se carga ni se envía nada a terceros.

    Qué complejidad tiene

    El evento de compra se dispara una sola vez por pedido: el plugin marca el pedido apenas entrega los datos a la página, así que recargar o abrir otra pestaña no lo vuelve a informar, y tampoco se informa para pedidos fallidos, cancelados o con más de un día. Cada evento lleva un identificador compartido con el del Meta Pixel, de modo que se pueda deduplicar si más adelante se suma el envío desde el servidor.

    También cubre los agregados al carrito que ocurren con un envío de formulario normal, sin AJAX, guardándolos en la sesión para informarlos en la página siguiente, y ofrece un modo para Google Tag Manager y un ajuste de consentimiento por defecto.

  7. Descuento por transferencia y cancelación automática

    • PHP
    • WP-Cron
    • WooCommerce

    Qué hace

    Al elegir transferencia bancaria, el carrito suma un descuento (porcentual o fijo, configurable en el panel) y la descripción del medio de pago lo explica. Los pedidos por transferencia quedan en espera y una tarea horaria cancela los que superan el plazo, 24 horas por defecto, si no tienen fecha de pago. El cliente recibe un mail de cancelación con la marca, y la página de gracias y los mails del pedido le informan el plazo.

    Qué complejidad tiene

    El descuento depende del medio de pago elegido, que cambia después de calcular el carrito, así que el checkout recalcula los totales cada vez que se cambia de método. WooCommerce solo cancela por su cuenta los pedidos pendientes y los de transferencia quedan en espera, por lo que hizo falta una tarea programada propia.

    La cancelación pasa por el cambio de estado de WooCommerce para que se devuelva el stock, procesa hasta 50 pedidos por corrida y descarta los que tienen fecha de pago.

  8. Emails transaccionales con la identidad de la marca

    • PHP
    • SMTP
    • WooCommerce

    Qué hace

    El plugin envía los mails por un servicio SMTP externo, activo solo cuando sus credenciales están definidas en la configuración del sitio: no viven en el repositorio y el entorno local usa un servicio de captura de mails. Los mails de WooCommerce llevan el encabezado, los colores y el pie de la marca, y se agregan bloques propios: instrucciones de retiro local, plazo de la transferencia y un mail de pedido cancelado.

    Qué complejidad tiene

    La dirección de envío no recibe respuestas, así que los mails al cliente salen con Reply-To a la casilla del negocio, mientras que los de administración mantienen la dirección del cliente. El texto con la dirección de la tienda se reemplaza para que apunte a una casilla que sí responde, y los demás mails del sitio, como la confirmación de suscripción, reciben el mismo Reply-To.

    Cada bloque agregado debe resolverse en HTML y en texto plano, y aparecer solo para el cliente y en el estado de pedido que corresponde.

  9. Contenido editable desde el panel

    • PHP
    • JavaScript
    • Gutenberg

    Qué hace

    El plugin registra tipos de contenido propios para avisos con fecha de inicio y fin, banners de portada con imagen de escritorio y de celular, banners de tienda, colecciones, imágenes de estilo de vida y orígenes de café, además de una ficha del café en cada producto. Agrega un bloque de Gutenberg, el carrusel de productos, donde se eligen los productos y el título. El carrusel de orígenes está escrito sin librerías.

    Qué complejidad tiene

    El bloque del carrusel se arma en PHP en cada visita, por lo que un producto que se oculta o se despublica desaparece del carrusel sin editar la página. El carrusel de orígenes implementa a mano el arrastre con umbral, la proyección de la velocidad al soltar, el teclado y el avance automático. Sin JavaScript, cada origen se muestra como una tarjeta apilada con su ficha.

¿Querés algo así para tu tienda?

Escribime por WhatsApp, me contás qué necesitás y vemos cómo ayudarte.

Hablemos por WhatsApp