Pedidos y pagos de Balobrador
El sistema de pedidos y pagos con tarjeta que hay detrás de balobrador.es, una tienda de tartas de queso cerca de Madrid: catálogo, carrito, programación de recogidas y Stripe Checkout. Lo construí yo solo, procesa pagos reales desde octubre de 2025 y sigo a cargo de él.
Visitar balobrador.es- Stripe
- Astro
- React
- TypeScript
- Netlify Functions
- Node.js
- Zustand
- Tailwind
Qué hace
Balobrador vende tartas de queso en tres tamaños, y también galletas, para recoger en su tienda de Rivas-Vaciamadrid. El sitio gestiona el pedido completo: un catálogo, un carrito que se conserva aunque se cierre la pestaña, un calendario de recogida que solo ofrece fechas que la cocina puede atender, una página de pago con tarjeta alojada en Stripe y emails de confirmación al cliente y a la tienda una vez completado el pago. Las páginas son Astro estático, con React solo donde algo tiene que responder; la parte de servidor es un puñado de Netlify Functions. No hay base de datos: los archivos de producto del repositorio son la fuente de verdad, y cada cambio de precio, sabor nuevo o cierre se publica como un commit que se despliega al hacer push.
El servidor decide cuánto cuesta cada cosa
El proceso de pago no se fía de la cesta que envía el navegador. Un paso de build convierte los archivos de producto en un catálogo de precios indexado por producto y tamaño, y la función de pago reconstruye a partir de él cada línea de pedido de Stripe: precio, nombre y categoría vienen del servidor, las cantidades son enteros acotados, el pedido mínimo se comprueba con los precios del catálogo y una fecha de recogida que cae dentro de un cierre se rechaza antes de que exista ninguna sesión de pago. Los precios incluyen el IVA del 10 % y se convierten exactamente en los céntimos enteros que cobra Stripe. El webhook verifica la firma de Stripe y construye los emails del pedido solo a partir de la sesión que ha verificado.
Reglas de recogida como código
La cocina prepara los pedidos del fin de semana en una sola tanda a partir del viernes, así que las recogidas del sábado, el domingo y el lunes comparten una única hora límite: el jueves a las 18:30, hora de Madrid. Las recogidas de martes a viernes requieren dos días de antelación, con la misma hora límite de las 18:30. Escribí la regla en días de antelación y no con nombres de días de la semana, para que siga funcionando al pasar de una semana a otra. Un cierre es una única entrada con fecha en un archivo de datos: deshabilita esas fechas en el calendario, pone un aviso en todas las páginas y en el email de confirmación, hace que la función de pago rechace esas fechas y publica un horario de apertura especial en los datos estructurados. Un rango mal formado hace fallar el build.
Mantenerlo en marcha
Lo he mantenido en marcha desde el lanzamiento, con una subida de precios, sabores de temporada y un cierre de dos semanas en verano, y dos lecciones forman ya parte del proceso. Los carritos se guardan en el navegador con una instantánea de los precios, así que una subida de precios también sube la versión del esquema, lo que vacía las cestas guardadas, en lugar de mostrar un precio y cobrar otro. Y después de que tres despliegues fallaran en silencio, con Netlify sirviendo todavía el build anterior, porque mis paquetes instalados se habían adelantado al lockfile y había usado un tipo que la versión fijada no tiene, los cambios que afectan a los tipos empiezan ahora desde una instalación limpia. La comprobación del build tiene que terminar con cero errores, avisos y sugerencias.