Pre-launch · ERPlora is in active development. You're viewing a product preview.
Back to apps Sales, payments and tax

Cart & Checkout

An internal notebook of shopping carts and the orders made from them, with a payment status you mark.

Free
Start free
Turn it on from your Hub

Apps are turned on from the Apps page of your Hub. Create your free account to get one.

This documentation is only available in Spanish.

Para qué sirve y para quién

Carrito y pago es una libreta interna de carritos y pedidos. Guarda carritos — de una persona (su email y su nombre) o de una visita anónima, que se distingue por un código de sesión — con sus líneas (producto, cantidad y precio), y los convierte en pedidos con número, direcciones, método de envío y de pago y un estado: Iniciado, Pagado o Fallido, y Completado.

Lo más importante: no es el TPV y nada de lo que hace es fiscal. Un pedido pagado y completado aquí no genera venta, ni factura, ni registro VeriFactu, ni movimiento de caja, ni movimiento de stock, y nada de lo cobrado aquí llega a la AEAT. «Pagado» es un estado que una persona marca después de cobrar por otra vía: la app no cobra, no habla con ninguna pasarela y no pide importe ni justificante. Para cobrar en el mostrador está Ventas.

No tiene tienda ni página pública: solo la usa personal con sesión en el Hub.

Quién la usa:

  • El empleado: solo mira los carritos y los pedidos.
  • El responsable, el administrador y el propietario: además crean, abandonan y borran carritos, y marcan los pedidos como pagados, completados o fallidos.
  • El asistente: hace lo mismo que la persona que le habla y, además, lo que la pantalla no ofrece: añadir y cambiar líneas, vaciar un carrito, iniciar un pedido y caducar los carritos vencidos.

Referencia adoptada

El modelo de carrito y pedido de una tienda en línea (Shopify Checkout, WooCommerce, Odoo eCommerce): carrito con código de sesión, pedido con número correlativo y estados iniciado → pagado o fallido → completado. Se adopta solo el modelo de estados: la tienda pública, la pasarela de pago, los impuestos, el envío y el stock de esas referencias no existen aquí. Sin investigación nueva: es el mismo alcance que el producto actual.

Antes de empezar

  1. Carrito y pago no viene encendida con ningún tipo de negocio: se enciende desde la tienda de apps. No enciende ninguna otra app ni la necesita: se puede encender y apagar sola.
  2. No tiene ajustes. La moneda de un carrito nuevo es la del negocio (euros mientras el Hub no guarde otra), salvo que quien lo crea por el asistente o la API diga otra.
  3. Un carrito puede llevar fecha de caducidad; sin ella no caduca nunca.

Pantallas

Carrito y pago se abre desde el menú y tiene dos pestañas: Carritos y Pedidos. Lo que una persona no puede hacer no aparece, y la app lo rechaza aunque lo intente por la API o por el asistente.

Carritos

Una tabla con las columnas Sesión, Email, Estado (Activo, Abandonado, Convertido, Expirado), Ítems y Total. Buscador «Buscar sesión o email…» (busca en el código de sesión, el email y el nombre), filtros por columna — sesión y email por un trozo del texto, el estado por lista, los ítems y el total «desde / hasta» —, orden por columna, vista de lista o de tarjetas y 50 filas por página. Va ordenada por fecha de alta, el más reciente arriba. El total sale en la moneda del carrito; el filtro de Total se escribe en la moneda del negocio (en euros: «12» son 12,00 €) y compara el importe tal cual, sin convertir monedas.

El botón Nuevo carrito abre el formulario «Nuevo carrito»: Sesión (obligatoria; «Guardar» no se activa sin ella), Email y Nombre. Cada fila ofrece Abandonar (solo un carrito activo) y Borrar (pide confirmación). No hay pantalla de las líneas de un carrito ni para añadirlas: eso lo hace el asistente o la API.

Pedidos

Una tabla con Pedido (su número), Email, Estado (Iniciado, Pagado, Fallido, Completado), Pago (el método de pago, texto) y Total, en la moneda del pedido. Buscador «Buscar pedido o email…», filtros por columna, orden por columna, vista de lista o de tarjetas y 50 filas por página, el más reciente arriba. Un pedido fallido enseña su motivo debajo del estado.

Cada fila ofrece la acción que le toca: Marcar pagado (Iniciado), Completar (Pagado) y Fallar (Iniciado o Pagado), que abre un formulario que pide el motivo. Mientras una acción de fila trabaja, su botón gira y un segundo toque no hace nada. No hay botón para crear un pedido: nacen del flujo CART_CHECKOUT-F08.

Estados de cada pantalla

Estado Qué ve la persona
Cargando «Cargando…» mientras llega el primer resultado.
Vacío «Sin carritos.» o «Sin pedidos.»; con búsqueda o filtro, «Sin resultados».
Error El aviso de la tabla con «Reintentar». Un rechazo de un formulario sale dentro del formulario, cada motivo debajo de su campo, sin perder lo tecleado; el de una acción de fila, encima de la tabla.
Reconectando Lo pintado se queda; una franja avisa «Reconectando…».
App inactiva «Esta app no está activa en este negocio».
Sin permiso No aparece lo que no puede hacer; si llega por otra puerta, «No tienes permiso».

Importes con el formato del idioma de quien mira y en la moneda de cada fila; cantidades sin ceros de adorno («2», «0,5»).

Flujos

ID Flujo Estado
CART_CHECKOUT-F01 Crear un carrito hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F02 Añadir una línea a un carrito hecho (pytest y Vitest); e2e pendiente (asistente o API; sin pantalla, como hoy)
CART_CHECKOUT-F03 Cambiar la cantidad de una línea o quitarla hecho (pytest y Vitest); e2e pendiente (asistente o API)
CART_CHECKOUT-F04 Vaciar un carrito hecho (pytest y Vitest); e2e pendiente (asistente o API)
CART_CHECKOUT-F05 Abandonar un carrito hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F06 Borrar un carrito hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F07 Caducar los carritos vencidos hecho (pytest y Vitest); e2e pendiente (orden y lectura); la tarea sola, con el worker de la fase 2
CART_CHECKOUT-F08 Iniciar el pedido desde un carrito hecho (pytest y Vitest); e2e pendiente (asistente o API)
CART_CHECKOUT-F09 Marcar un pedido como pagado hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F10 Registrar que el pago falló hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F11 Completar un pedido hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F12 Consultar carritos, líneas y pedidos hecho (pytest y Vitest); e2e pendiente
CART_CHECKOUT-F13 Avisar a otras apps de lo que ocurre hecho (pytest y Vitest); e2e pendiente; el aviso sale al outbox y nadie lo escucha
CART_CHECKOUT-F14 Borrar los datos personales de un cliente hecho (pytest y Vitest); e2e pendiente (asistente, API o admin)

CART_CHECKOUT-F01 Crear un carrito

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Carritos Pasos: 1. En Carritos pulsa Nuevo carrito. 2. Escribe la Sesión (el código que distingue la visita, obligatorio) y, si quieres, Email y Nombre. 3. Pulsa Guardar: el formulario se cierra y el carrito sale en la lista como Activo, sin líneas y con total cero. Entra: código de sesión (hasta 128 caracteres), email y nombre, de la persona; el asistente o la API pueden dar además la moneda (código ISO 4217) y la fecha de caducidad. Sale: un carrito activo en la moneda dicha o, si no se dice, la del negocio (cart_checkout.cart.created). Si falla: dentro del formulario, debajo de su campo: una sesión vacía; una sesión que ya usa otro carrito no borrado («Ya hay un carrito con esa sesión.»); un email que no es un email; una moneda que no existe; una caducidad que ya pasó. Lo tecleado se conserva. Sin permiso, se rechaza.

CART_CHECKOUT-F02 Añadir una línea a un carrito

Estado: hecho (pytest y Vitest); e2e pendiente (asistente o API; sin pantalla, como hoy) Actor: responsable, administrador, propietario, asistente Pantalla: asistente Pasos: 1. Pide al asistente añadir un producto a un carrito, diciendo el carrito (su sesión, o el email o el nombre del cliente), la referencia y el nombre del producto, la cantidad y el precio por unidad. 2. Confirma la tarjeta del asistente. 3. La línea queda guardada y los totales del carrito (ítems e importe) se recalculan. Entra: el carrito; referencia y nombre del producto (texto libre: no se comprueban contra el catálogo), SKU y atributos de variante (talla, color…) opcionales, cantidad mayor que cero y como mucho 1 000 000 (hasta tres decimales: «0,5») y precio por unidad en céntimos, que dice quien llama. Sale: la línea con su total (cantidad × precio, redondeado al céntimo, la mitad hacia arriba), los totales del carrito y su última actividad (cart_checkout.item.added). Si falla: carrito que no existe («Ese carrito no existe en este negocio.»); varios carritos para lo dicho (los nombra y pide cuál); carrito que no está activo, también uno vencido («Este carrito ya no admite cambios: está Abandonado.»); referencia o nombre vacíos, cantidad cero, negativa o de más de 1 000 000, precio negativo: cada uno en su campo; un total de la línea, o del carrito con ella, por encima de lo que cabe en un carrito (99 999 999 999,99 €), debajo de la cantidad. No se guarda nada.

CART_CHECKOUT-F03 Cambiar la cantidad de una línea o quitarla

Estado: hecho (pytest y Vitest); e2e pendiente (asistente o API) Actor: responsable, administrador, propietario, asistente Pantalla: asistente Pasos: 1. Pide al asistente cambiar la cantidad de una línea, o quitarla. 2. Confirma la tarjeta. 3. Con cantidad mayor que cero la línea cambia y su total se recalcula con el precio guardado en la línea; con cantidad cero la línea se quita. También existe la orden «quitar línea», que solo quita. 4. Los totales del carrito se recalculan en la misma operación. Entra: la línea (su id) y la cantidad; el precio lo lee el Hub de la línea, nunca de quien llama. Sale: la línea cambiada o quitada, los totales del carrito y su última actividad (cart_checkout.item.updated, con removed: true cuando la cantidad es cero; cart_checkout.item.removed sale de «quitar línea»). Si falla: línea que no existe; carrito que ya no está activo; cantidad negativa o de más de 1 000 000; un total por encima de lo que cabe en un carrito, debajo de la cantidad. No cambia nada.

CART_CHECKOUT-F04 Vaciar un carrito

Estado: hecho (pytest y Vitest); e2e pendiente (asistente o API) Actor: responsable, administrador, propietario, asistente Pantalla: asistente Pasos: 1. Pide al asistente vaciar un carrito. 2. Confirma la tarjeta. 3. Se quitan todas sus líneas y los totales vuelven a cero; el carrito sigue Activo. Entra: el carrito. Sale: el carrito sin líneas, totales a cero (cart_checkout.cart.cleared). Vaciar uno que ya estaba vacío no cambia nada ni avisa. Si falla: carrito que no existe o que no está activo. No cambia nada.

CART_CHECKOUT-F05 Abandonar un carrito

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Carritos Pasos: 1. En Carritos, en la fila de un carrito activo, pulsa Abandonar. 2. El carrito pasa a Abandonado y conserva sus líneas. El asistente puede dar un motivo, que queda en el carrito. Entra: el carrito y un motivo opcional (hasta 500 caracteres). Sale: estado Abandonado (cart_checkout.cart.abandoned). Si falla: solo se abandona un carrito activo; en otro estado se rechaza diciendo en cuál está, encima de la tabla, y no cambia nada.

CART_CHECKOUT-F06 Borrar un carrito

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Carritos Pasos: 1. En Carritos, en la fila, pulsa Borrar. 2. Confirma «¿Borrar el carrito …?» con Borrar; Cancelar lo deja como estaba. 3. El carrito desaparece de la lista. El asistente pide confirmación reforzada (acción peligrosa). Entra: el carrito. Sale: el carrito borrado en cualquier estado, también Convertido (cart_checkout.cart.deleted). Sus pedidos siguen existiendo y su sesión queda libre para otro carrito. Si falla: un carrito que no existe (o ya borrado) se rechaza; no cambia nada.

CART_CHECKOUT-F07 Caducar los carritos vencidos

Estado: hecho (pytest y Vitest); e2e pendiente (orden y lectura); la tarea sola, con el worker de la fase 2 Actor: sistema (tarea programada), administrador, asistente Pantalla: Carritos (el estado) Pasos: 1. Un carrito activo cuya fecha de caducidad ya pasó se lee como Expirado en la lista, en su detalle y en el filtro por estado, y ya no admite cambios ni pedidos. 2. Cada quince minutos, la tarea de la app lo deja guardado como Expirado. También se puede pedir al asistente o a la API «caducar los carritos vencidos». Entra: nada; la hora la pone el Hub. Sale: los carritos vencidos pasan a Expirado y la orden dice cuántos (cart_checkout.cart.expired, con el número; sin ninguno no avisa). Si falla: sin carritos vencidos contesta «0» y no avisa. Un carrito sin caducidad no caduca nunca. Con la lista ya abierta, un carrito que vence en ese momento sigue pintado «Activo» hasta que la lista se vuelve a leer: con el siguiente cambio, al volver a abrirla o con la relectura de seguridad del Hub (cada 5 minutos); hasta la tarea de la fase 2 no hay aviso que la refresque en el instante.

CART_CHECKOUT-F08 Iniciar el pedido desde un carrito

Estado: hecho (pytest y Vitest); e2e pendiente (asistente o API) Actor: responsable, administrador, propietario, asistente Pantalla: asistente Pasos: 1. Pide al asistente iniciar el pedido de un carrito y, si quieres, el email del cliente, las direcciones de envío y de facturación, el método de envío, el método de pago y unas notas. 2. Confirma la tarjeta. 3. Aparece en Pedidos un pedido Iniciado con número OS-AAAAMMDD-NNNN (correlativo por día del negocio, sin huecos) y el total del carrito copiado en ese momento, en su moneda. Entra: el carrito; el email del cliente (sin él, el del carrito); direcciones (si falta la de facturación se copia la de envío); métodos de envío y de pago (texto) y notas. Sale: un pedido Iniciado con el total del carrito en ese instante (cart_checkout.checkout.initiated). El carrito sigue activo: se pueden cambiar sus líneas e iniciar otro pedido; el total del pedido ya no cambia. Si falla: carrito que no existe, que no está activo (también vencido) o sin líneas; email que falta o que no es un email. No se crea pedido, no se gasta número y no avisa.

CART_CHECKOUT-F09 Marcar un pedido como pagado

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Pedidos Pasos: 1. Cobra al cliente fuera de esta app. 2. En Pedidos, en la fila de un pedido Iniciado, pulsa Marcar pagado. 3. El pedido pasa a Pagado con la hora del pago. Entra: el pedido (por su número o su id). Sale: estado Pagado y hora del pago (cart_checkout.order.paid). No se cobra ni se pide importe, medio ni justificante, y no se crea venta, factura, registro fiscal, movimiento de caja ni de stock. El asistente pide confirmación reforzada. Si falla: solo se marca un pedido Iniciado; en otro estado se rechaza diciendo en cuál está. El empleado no puede.

CART_CHECKOUT-F10 Registrar que el pago falló

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Pedidos Pasos: 1. En Pedidos, en la fila de un pedido Iniciado o Pagado, pulsa Fallar. 2. Escribe el motivo (obligatorio; «Fallar pedido» no se activa sin él) y pulsa Fallar pedido; Mantener lo deja como estaba. 3. El pedido pasa a Fallido y enseña su motivo. Entra: el pedido y el motivo (hasta 500 caracteres). Sale: estado Fallido, el motivo y la hora (cart_checkout.order.failed). Un pedido ya Pagado también puede fallar, como hoy: no deja rastro de devolución (no hay devoluciones en esta app). El carrito sigue como estaba. El asistente pide confirmación reforzada. Si falla: un pedido Completado o ya Fallido se rechaza; un motivo vacío, debajo de su campo, sin perder lo escrito.

CART_CHECKOUT-F11 Completar un pedido

Estado: hecho (pytest y Vitest); e2e pendiente Actor: responsable, administrador, propietario, asistente Pantalla: Pedidos Pasos: 1. En Pedidos, en la fila de un pedido Pagado, pulsa Completar. 2. El pedido pasa a Completado y su carrito, a Convertido, en la misma operación. Entra: el pedido. Sale: pedido Completado con su hora y carrito Convertido (cart_checkout.order.completed). Nada fiscal ni de stock. Si el carrito ya estaba borrado, el pedido se completa igual. Si falla: solo se completa un pedido Pagado; en otro estado se rechaza diciendo en cuál está.

CART_CHECKOUT-F12 Consultar carritos, líneas y pedidos

Estado: hecho (pytest y Vitest); e2e pendiente Actor: empleado, responsable, administrador, propietario, asistente Pantalla: Carritos, Pedidos Pasos: 1. Abre Carritos o Pedidos. 2. Busca por sesión, email o nombre (carritos) o por número de pedido o email (pedidos), filtra por columna y ordena. 3. Las líneas de un carrito y el detalle de un pedido (direcciones, métodos, fechas, notas) se leen con el asistente o la API: un carrito por su sesión o por el email o el nombre de su cliente, un pedido por su número. Entra: permiso «ver carritos» (el empleado lo tiene). Sale: listas de 50 filas (hasta 100 por petición). Cantidades con sus decimales, importes en céntimos con la moneda de la fila. Si falla: error de carga con «Reintentar»; sin permiso, «No tienes permiso».

CART_CHECKOUT-F13 Avisar a otras apps de lo que ocurre

Estado: hecho (pytest y Vitest); e2e pendiente; el aviso sale al outbox y nadie lo escucha Actor: sistema Pantalla: ninguna Pasos: 1. Cada cambio de los flujos anteriores deja un aviso en el outbox del Hub en su misma transacción. 2. Las dos pantallas se actualizan solas con lo que cambió. Entra: el cambio que lo provoca. Sale: trece avisos: los doce del producto actual (cart.created, cart.abandoned, cart.deleted, cart.cleared, cart.expired, item.added, item.updated, item.removed, checkout.initiated, order.paid, order.failed, order.completed) y customer.erased, con el prefijo cart_checkout.. Ninguna app del Hub los escucha. Si falla: un cambio rechazado no deja ni el cambio ni el aviso.

CART_CHECKOUT-F14 Borrar los datos personales de un cliente

Estado: hecho (pytest y Vitest); e2e pendiente (asistente, API o admin) Actor: responsable, administrador, propietario, asistente; el personal de la plataforma desde el admin Pantalla: asistente; admin del Hub (acción «Borrar los datos personales de sus clientes») Pasos: 1. Un cliente pide que se borren sus datos (derecho de supresión, RGPD). 2. Pide al asistente borrar los datos del cliente con su email exacto, o el personal de la plataforma marca sus carritos o pedidos en el admin y lanza la acción. 3. Confirma la tarjeta (acción peligrosa: no se deshace). Entra: el email exacto del cliente (sin distinguir mayúsculas). Sale: todos los carritos con ese email, también los borrados, se quedan sin email, nombre, notas ni motivo de abandono; todos los pedidos con ese email o de esos carritos, sin email, direcciones, notas ni motivo de fallo. Número, importes, estados y fechas se quedan. Dice cuántos carritos y pedidos cambió (cart_checkout.customer.erased, con los dos números y nunca el email; si no había nada, no avisa). Si falla: un email vacío o que no es un email, en su campo. Sin permiso «gestionar carritos», se rechaza. En el admin, sin hub elegido no hace nada y lo dice.

Carrito y pago: lo que entra y lo que sale

Lo que ofrece: consultas (leen, no cambian nada)

Operación Qué da
cart_checkout.cart.list Carritos, con búsqueda, filtros, orden y páginas de hasta 100.
cart_checkout.cart.get Un carrito con sus líneas, por id, sesión o cliente (email o nombre).
cart_checkout.item.list Las líneas de un carrito, con búsqueda, filtros y páginas.
cart_checkout.item.get Una línea por su id.
cart_checkout.order.list Pedidos, con búsqueda, filtros, orden y páginas de hasta 100.
cart_checkout.order.get Un pedido con todo (direcciones, métodos, fechas, notas), por id o número.

Lo que ofrece: acciones (cambian datos)

Operación Qué hace Permiso
cart_checkout.cart.create Crea un carrito gestionar carritos
cart_checkout.cart.mark_abandoned Abandona un carrito activo gestionar carritos
cart_checkout.cart.delete Borra un carrito (peligrosa) gestionar carritos
cart_checkout.cart.clear Vacía un carrito activo gestionar carritos
cart_checkout.cart.cleanup_expired Caduca los carritos vencidos (también la tarea) gestionar carritos
cart_checkout.item.add Añade una línea gestionar carritos
cart_checkout.item.update Cambia la cantidad (0 la quita) gestionar carritos
cart_checkout.item.remove Quita una línea gestionar carritos
cart_checkout.checkout.initiate Inicia un pedido desde un carrito cobrar
cart_checkout.order.mark_paid Marca un pedido pagado (peligrosa) cobrar
cart_checkout.order.fail Marca un pedido fallido con su motivo (peligrosa) cobrar
cart_checkout.order.complete Completa un pedido pagado y convierte su carrito cobrar
cart_checkout.customer.erase Borra los datos personales de un cliente por su email (peligrosa) gestionar carritos

Lo que avisa

Los trece avisos de CART_CHECKOUT-F13. Solo salen cuando el cambio ocurrió.

A qué reacciona y lo que necesita de otras apps

Nada. No lee ni escribe en otras apps: producto, referencia, SKU y precio son texto y números libres, sin vínculo con Inventario, y el cliente es un email y un nombre sin vínculo con Clientes.

Quién puede qué

Permiso Qué deja hacer Quién lo tiene
cart_checkout.view_cart Ver carritos, líneas y pedidos todos, también el empleado
cart_checkout.manage_cart Crear, abandonar, borrar, vaciar y caducar carritos; añadir, cambiar y quitar líneas; borrar los datos personales de un cliente responsable, administrador, propietario
cart_checkout.checkout Iniciar pedidos y marcarlos pagados, fallidos o completados responsable, administrador, propietario