PrestaShop te da documentos de pedido y un botón Imprimir en el navegador. Lo que no te da es un ticket que aparece en la trastienda en el momento en que el cliente paga: eso exige conectar el ciclo de vida del pedido a una impresora accesible por internet.
Respuesta corta: engancha actionOrderStatusPostUpdate, comprueba que el nuevo estado significa "pagado", construye el ticket y haz un POST. Un módulo ya hecho resuelve esto con ajustes en lugar de código; un módulo propio pequeño lo hace exactamente a tu manera. Ninguno de los dos necesita un ordenador encendido en la tienda.
Dos vías
| Módulo | Hook a medida | |
|---|---|---|
| Puesta en marcha | Instalar y configurar | Unas 20 líneas de PHP |
| Control de la maquetación | Ajustes de plantilla | Total |
| Multitienda | Resuelto | A tu cargo |
| Mejor para | La mayoría de tiendas | Enrutado o lógica específicos |
El conector de PrestaShop cubre la primera vía; la documentación del módulo recorre la instalación y los ajustes del ticket.
La vía del hook
PrestaShop dispara actionOrderStatusPostUpdate después de que el estado del pedido haya cambiado y se haya persistido. Ese es el momento correcto: el anterior actionOrderStatusUpdate se dispara antes de que el cambio esté confirmado.
public function hookActionOrderStatusPostUpdate($params)
{
/** @var OrderState $newStatus */
$newStatus = $params['newOrderStatus'];
$order = new Order((int) $params['id_order']);
// Imprimir solo cuando el pago está aceptado; `paid` cubre los estados estándar.
if (!$newStatus->paid) {
return;
}
$lineas = [
'PEDIDO ' . $order->reference,
date('d/m/Y H:i'),
'',
];
foreach ($order->getProducts() as $product) {
$lineas[] = (int) $product['product_quantity'] . 'x ' . $product['product_name'];
}
$lineas[] = '';
$lineas[] = 'TOTAL: ' . number_format($order->total_paid, 2) . ' ' . $this->context->currency->iso_code;
$ch = curl_init('https://www.expedy.fr/api/v2/printers/' . Configuration::get('MYMOD_PRINTER_UID') . '/print');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: ' . Configuration::get('MYMOD_API_SID') . ':' . Configuration::get('MYMOD_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'printer_msg' => implode("\n", $lineas),
'origin' => 'ps-' . $order->id,
]),
]);
curl_exec($ch);
curl_close($ch);
}
Trampas propias de PrestaShop
Los cambios de estado no son únicos. Un módulo de pago puede fijar el mismo estado pagado dos veces, y un comerciante puede volver a aplicarlo a mano desde el back office. Guarda una marca (una fila de metadatos del pedido o una tabla dedicada), y sal pronto si el pedido ya se imprimió. Sin eso, cada nuevo guardado es otro ticket.
newOrderStatus->paid es la prueba fiable. Escribir a fuego los ids de estado se rompe el día en que alguien añade un estado personalizado o despliegas en una tienda configurada de otra forma. La marca paid es lo que los módulos de pago fijan de verdad.
Multitienda necesita una impresora por tienda. En una instalación multitienda, lee el id de impresora del contexto de tienda en lugar de un único valor global de configuración, o todas las tiendas imprimirán en la misma máquina.
Los timeouts bloquean al cliente. El hook corre dentro de la petición que confirma el pedido. Un CURLOPT_TIMEOUT de cinco segundos es un techo de lo que un comprador podría esperar si la API no responde: mantenlo bajo, y trata los fallos de entrega de forma asíncrona en vez de hacer que el checkout dependa de una impresora.
Los nombres de producto llevan de todo. Los caracteres acentuados van bien; los emoji y los símbolos raros no. Translitera antes de construir el ticket: es la causa más común de una impresora que "se para sin motivo".
Maquetación del ticket
Cabeceras en negrita, un logo, un código QR al pedido, un código de barras, corte automático: todo eso son etiquetas dentro de printer_msg. Consulta la referencia de maquetación y, para un ticket de tipo factura europea, los códigos de barras EAN-13.
Empieza por un ticket de prueba
Antes de tocar PrestaShop, crea una cuenta gratuita e imprime un ticket con un simple curl. Verificar la cadena de impresión por separado significa que, cuando algo falle después, ya sabrás si mirar en PrestaShop o en la impresora.
También: Shopify y WooCommerce siguen el mismo patrón con hooks distintos.
FAQ
¿Qué hook de PrestaShop debo usar para imprimir un pedido?
actionOrderStatusPostUpdate, que se dispara después de que el cambio de estado se haya persistido. Comprueba newOrderStatus->paid en lugar de escribir a fuego los ids de estado, para que los estados personalizados y las tiendas configuradas de otra forma sigan funcionando.
¿Por qué el mismo pedido se imprime dos veces?
Los módulos de pago pueden aplicar el mismo estado pagado más de una vez, y los comerciantes pueden reaplicarlo a mano. Guarda una marca de impreso en el pedido y sal pronto cuando ya esté puesta.
¿Funciona con una instalación multitienda?
Sí, pero lee el id de impresora del contexto de tienda en vez de un único valor global de configuración, o todas las tiendas imprimirán en la misma máquina.
¿Necesito un ordenador en la tienda?
No. Una impresora en la nube se conecta sola por 4G, Wi-Fi o Ethernet, y una impresora USB existente se alcanza con un adaptador Raspberry Pi.