Skip to main content

CURSOR PROMPT — Integración Restaurant Controller POS con Restaurantero Pro

Este prompt va en el repo de Restaurant Controller POS (express_pos / restaurant_pos), NO en el repo de Restaurantero Pro. Lee este documento completo antes de escribir cualquier línea de código.

CONTEXT

You are working on Restaurant Controller POS — specifically the express_pos codebase (Laravel 12, PHP 8.2). The same integration applies to the Full Dining version (restaurant_pos). What you are building: A service that automatically sends data to the Restaurantero Pro API every time a Corte Z (cash register closing) is completed. The operator does nothing extra — it happens automatically in the background. Restaurantero Pro API base URL: https://my.restauranteropro.com/api/v1 Authentication: Header X-API-Key: rpro_live_xxx (configured per branch in .env) The integration point: The CashRegisterOpeningObserver already exists and fires on every status change. We hook into it when status = completed AND type contains zout. What the service sends (in this exact order):
  1. POST /api/v1/ingest/orders — productos vendidos (from OrderTicketLine)
  2. POST /api/v1/ingest/discounts — descuentos aplicados
  3. POST /api/v1/ingest/cancellations — cancelaciones y voids
  4. POST /api/v1/ingest/payments — pagos por método
  5. POST /api/v1/ingest/sales — resumen de ventas
  6. POST /api/v1/ingest/cash-register — el Corte Z (este dispara el procesamiento en RP)

CRITICAL RULES

  1. This runs in the background — use dispatch()->onQueue('default') for the main job. The POS cannot wait for HTTP requests to Restaurantero Pro.
  2. Idempotency is mandatory — use CashRegisterOpening->identifier as the base key.
  3. Never block the POS — all failures must be caught and logged, never thrown to the user.
  4. Feature flag — only run if RESTAURANTERO_ENABLED=true in .env. Default: false.
  5. Money conversion — RC stores amounts with mutators that divide by 100. When reading $payment->amount or $line->unit_price, the value is already in pesos. Multiply by 100 to get centavos for Restaurantero Pro.
  6. Quantity conversion$line->quantity also uses a mutator (divides by 100). A qty of 1 unit is stored as 100, returned as 1.0. Send as integer: (int) round($line->quantity).
  7. Laravel 12 — register everything in bootstrap/app.php, not Kernel.php.
  8. Do NOT modify any existing working code — only ADD new files.
  9. No BOM in PHP files.

WHAT TO BUILD — Step by step

STEP 1 — Environment configuration

Add these variables to .env.example (do NOT add values — just the keys):
Create config file config/restaurantero.php:

STEP 2 — Main service: RestauranteroProService


STEP 3 — Job: SendZOutToRestauranteroProJob


STEP 4 — Hook into the existing Observer

IMPORTANT: Do NOT rewrite CashRegisterOpeningObserver.php. Only ADD the dispatch call inside the existing handleStatusChange method, after the existing logic. Find the existing file app/Observers/CashRegisterOpeningObserver.php. In the handleStatusChange method, add this block at the END of the method, after the existing if statements:
The final handleStatusChange method should look like this:

STEP 5 — Artisan command to test the connection


STEP 6 — .env configuration for Pitic (first client)

Add these lines to the .env of the RC installation at Pitic:
Note for Carlos: Use rpro_test_ key for testing. Switch to rpro_live_ key when going to production. The branch_identifier above is for Pitic (Hermosillo).

VERIFICATION CHECKLIST

After completing all steps:
  • config/restaurantero.php exists with all keys
  • app/Services/RestauranteroProService.php exists
  • app/Jobs/SendZOutToRestauranteroProJob.php exists
  • app/Observers/CashRegisterOpeningObserver.php has the new block at the end of handleStatusChange
  • app/Console/Commands/TestRestauranteroProCommand.php exists
  • Run: php artisan restaurantero:test → should show “Conexión exitosa”
  • With RESTAURANTERO_ENABLED=falsephp artisan restaurantero:test shows the setup instructions
  • Complete a test Corte Z in the POS → check Laravel logs for “RestauranteroPro: Corte Z enviado”
  • Verify in Restaurantero Pro dashboard that data arrived

NOTES FOR CARLOS

Full Dining vs Express: The integration is identical for both versions. The models (CashRegisterOpening, OrderTicketLine, Payment, Discount, Cancellation) exist in both codebases with the same structure. Apply this same integration to both repos. Queue: The job runs on the default queue. Make sure the queue worker is running:
Logs: All activity is logged with the prefix RestauranteroPro: — easy to grep:
Testing without a real Corte Z: You can trigger the job manually:
Colección de Postman: para probar los 8 endpoints de ingesta directo, sin escribir código, descarga la colección con ejemplos reales (mismo orden de Corte Z documentado en la sección 3 de api-v1.mdx): 📥 Descargar Restaurantero_Pro_API.postman_collection.json Importa el archivo en Postman (Import → File), configura las variables base_url, api_key, y branch_identifier en la pestaña “Variables” de la colección, y el header X-Idempotency-Key ya viene listo para generar un UUID nuevo automáticamente en cada request.
Restaurant Controller POS — Restaurantero Pro Integration — Fase 4 de 4 Laravel 12 · PHP 8.2 Mayo 2026