En el ambiente de pruebas no se factura de verdad: no hay OCR, no se contacta a los comercios y no se emiten CFDI. En su lugar, un simulador mueve cada ticket por un recorrido de estatus que tú eliges con los últimos 4 dígitos de la tarjeta (CardLastFour) al subirlo. Así puedes probar tu integración (consultas, reportes y webhooks) con algunos de los finales posibles y en tiempos predecibles.
El simulador solo existe en el ambiente de pruebas. En producción los tickets siguen el flujo real descrito en Flujo del ticket y CardLastFour solo se usa para facturar.
Ambiente de pruebas
| Producción | Pruebas | |
|---|---|---|
| URL base | https://api.fotofacturas.ai/B2B/ | https://api-staging.fotofacturas.ai/B2B/ |
| Token | Token de producción. Se consulta en la web app business, sección API y plan › Token de API. | Token de pruebas. Se consulta en la web app business de pruebas, sección API y plan › Token de API. |
| Procesamiento de tickets | OCR, facturación automática, correo con el comercio y agentes | Simulador (este documento) |
| Webhooks | Se envían | Se envían |
- Los datos de cada ambiente están separados: asociaciones, usuarios, RFC, webhooks y tickets de pruebas no existen en producción, y viceversa.
- Las APIs, los permisos, las validaciones y los límites del plan son los mismos que en producción. Un ticket de pruebas sí cuenta para el límite mensual del plan de pruebas.
Cómo funciona
El simulador revisa los tickets cada minuto. En cada revisión avanza cada ticket un solo paso de su recorrido, siempre que haya pasado el tiempo de espera desde su último cambio de estatus.
Los últimos 4 dígitos de la tarjeta definen el escenario:
| Posición | Ejemplo 0 0 3 7 | Significado |
|---|---|---|
| 1.° dígito | 0 | Se ignora. |
| 2.° dígito | 0 | Se ignora. |
| 3.° dígito | 3 | Minutos de espera entre cada cambio de estatus (0 a 9). |
| 4.° dígito | 7 | Escenario (0 a 9): recorrido de estatus y resultado final. |
Con 0037 el ticket sigue el escenario 7 y cambia de estatus cada 3 minutos.
CardLastFour es obligatorio solo con tarjeta de crédito (04) o débito (28), pero la API lo acepta con cualquier método de pago. En pruebas mándalo siempre, aunque el método sea efectivo (01), para elegir el escenario.
Escenarios
Todos los tickets empiezan en 1 CREATED. Los números son el ticketStatusId (ver Catálogos).
No facturables (terminan en 10 UNSIGNABLE)
| 4.° dígito | Recorrido | ticketCodeId final |
|---|---|---|
0 | 1 → 3 → 10 | 4 · No es un ticket de compra |
1 | 1 → 3 → 5 → 10 | 5 · Ticket vencido |
2 | 1 → 3 → 6 → 10 | 8 · Ticket ilegible |
3 | 1 → 3 → 6 → 5 → 10 | 19 · No se pudo contactar al comercio |
4 | 1 → 3 → 6 → 8 → 10 | 15 · No identificado |
Facturados (terminan en 11 SIGNED)
| 4.° dígito | Recorrido | ticketCodeId final |
|---|---|---|
5 | 1 → 3 → 11 | 2 · Facturado |
6 | 1 → 3 → 5 → 11 | 2 · Facturado |
7 | 1 → 3 → 6 → 11 | 2 · Facturado |
8 | 1 → 3 → 6 → 5 → 11 | 2 · Facturado |
9 | 1 → 3 → 6 → 8 → 11 | 2 · Facturado |
Al llegar al estatus final, el ticket queda con invoiceMethod: 2 (automática) y el ticketCodeId de la tabla.
Casos especiales
| Situación | Resultado |
|---|---|
No se mandó CardLastFour o no son 4 dígitos | En la primera revisión pasa a 3 → 10 con código 15 (No identificado), sin esperar. |
| El ticket llega a un estatus que no es de su recorrido (por ejemplo, lo movió un agente) | Pasa a 3 → 10 con código 15, sin esperar. |
| El ticket se archivó | El simulador lo ignora. |
Tiempos
Cada paso ocurre en la primera revisión (cada minuto) después de que pasaron los minutos de espera desde el último cambio. Tiempo aproximado hasta el estatus final:
pasos del recorrido × máx(3.° dígito, 1) minutos, con hasta 1 minuto extra por paso.
| Tarjeta | Pasos | Tiempo aproximado |
|---|---|---|
0005 | 2 (1 → 3 → 11) | 2 a 4 min |
0009 | 4 (1 → 3 → 6 → 8 → 11) | 4 a 8 min |
0050 | 2 (1 → 3 → 10) | 10 a 12 min |
0099 | 4 | 36 a 40 min |
Usa 0 o 1 en el tercer dígito para pruebas rápidas y un valor alto para tener tiempo de revisar cada estatus intermedio con GetTicketById y cada webhook que recibes.
Qué recibes en cada escenario
Webhooks
Se generan los mismos eventos que en producción (ver Webhooks):
ticket.status_changedal crear el ticket (1) y en cada cambio de estatus del recorrido.ticket.invoicedal llegar a11.ticket.failedal llegar a10.
Ejemplo con 0006 (escenario 6) y los tres eventos configurados:
| Cambio | Eventos |
|---|---|
null → 1 | ticket.status_changed |
1 → 3 | ticket.status_changed |
3 → 5 | ticket.status_changed |
5 → 11 | ticket.status_changed + ticket.invoiced |
Datos del ticket (GetTicketById)
| Campo | En pruebas |
|---|---|
ticketStatusId / ticketCodeId / invoiceMethod | Según el escenario. |
ticketUrl | La imagen que subiste. |
pdfUrl, xmlUrl, xmlData | En los escenarios facturados (5 a 9), el simulador adjunta una factura genérica real, siempre la misma. En los no facturables vienen vacíos. |
ticketDate, ticketAmount | En los escenarios facturados, la fecha y el total de esa factura genérica. |
Los reportes (GetPeriodStats, GetTicketStatuses, GetTicketsByMonth…) cuentan los tickets de pruebas igual que en producción.
Guía para tu desarrollo
-
Obtén tu token de pruebas en la web app business de pruebas, sección API y plan.
-
Prepara datos: crea una asociación (
CreateAssociation), un usuario (CreateUser) y registra un RFC con su CSF (AddUserTaxInfooSaveAssociationCSF). -
Configura tus webhooks (
SaveWebhook), guarda el secreto y valida la firma conTestWebhook. -
Sube un ticket por escenario con
CreateUserTicketoCreateAssociationTicket, variandoCardLastFour.La imagen puede ser cualquier archivo válido (JPG, JPEG, HEIC, WEBP, PNG, PDF, máx. 10 MB): el simulador no la lee.
-
Verifica que tu sistema reciba y procese cada evento, y que el estatus final coincida con
GetTicketById.
Set mínimo recomendado:
| Tarjeta | Para probar |
|---|---|
0015 | Facturado directo. |
0019 | Facturado con varios estatus intermedios. |
0010 | No facturable directo. |
0013 | No facturable con varios estatus intermedios. |
sin CardLastFour | Caso especial: termina en 10 con código 15. |
Para probar reintentos de webhooks, haz que tu servidor responda un error (por ejemplo, 500) en algún evento y revisa los intentos con GetWebhookEventById o bien en la web app business; luego reenvíalo con Reenviar evento en la pantalla Webhooks.