Integration

Ticket simulation

In the test environment nothing is really invoiced: there’s no OCR, merchants aren’t contacted and no CFDI is issued. Instead, a simulator moves each ticket through a status path that you choose with the last 4 digits of the card (CardLastFour) when you upload it. That way you can test your integration (queries, reports and webhooks) against several possible outcomes, with predictable timing.

The simulator only exists in the test environment. In production, tickets follow the real flow described in Ticket flow and CardLastFour is only used for invoicing.


Test environment

ProductionTest
Base URLhttps://api.fotofacturas.ai/B2B/https://api-staging.fotofacturas.ai/B2B/
TokenProduction token. Find it in the business web app, under API y plan › Token de API.Test token. Find it in the test business web app, under API y plan › Token de API.
Ticket processingOCR, automatic invoicing, email with the merchant and agentsSimulator (this document)
WebhooksSentSent
  • Each environment’s data is separate: test associations, users, RFCs, webhooks and tickets don’t exist in production, and vice versa.
  • APIs, permissions, validations and plan limits are the same as in production. A test ticket does count toward the test plan’s monthly limit.

How it works

The simulator checks tickets every minute. On each check it moves every ticket one single step along its path, as long as the wait time since its last status change has passed.

The last 4 digits of the card define the scenario:

PositionExample 0 0 3 7Meaning
1st digit0Ignored.
2nd digit0Ignored.
3rd digit3Minutes to wait between each status change (0 to 9).
4th digit7Scenario (0 to 9): status path and final result.

With 0037 the ticket follows scenario 7 and changes status every 3 minutes.

CardLastFour is only required with a credit (04) or debit (28) card, but the API accepts it with any payment method. In test, always send it, even if the method is cash (01), to choose the scenario.


Scenarios

Every ticket starts at 1 CREATED. The numbers are the ticketStatusId (see Catalogs).

Not invoiceable (end at 10 UNSIGNABLE)

4th digitPathFinal ticketCodeId
01 → 3 → 104 · Not a purchase ticket
11 → 3 → 5 → 105 · Expired ticket
21 → 3 → 6 → 108 · Illegible ticket
31 → 3 → 6 → 5 → 1019 · Couldn’t reach the merchant
41 → 3 → 6 → 8 → 1015 · Not identified

Invoiced (end at 11 SIGNED)

4th digitPathFinal ticketCodeId
51 → 3 → 112 · Invoiced
61 → 3 → 5 → 112 · Invoiced
71 → 3 → 6 → 112 · Invoiced
81 → 3 → 6 → 5 → 112 · Invoiced
91 → 3 → 6 → 8 → 112 · Invoiced

On reaching the final status, the ticket ends with invoiceMethod: 2 (automatic) and the ticketCodeId from the table.

Special cases

SituationResult
CardLastFour wasn’t sent or isn’t 4 digitsOn the first check it moves to 3 → 10 with code 15 (Not identified), without waiting.
The ticket reaches a status that isn’t on its path (for example, an agent moved it)It moves to 3 → 10 with code 15, without waiting.
The ticket was archivedThe simulator ignores it.

Timing

Each step happens on the first check (every minute) after the wait time since the last change has passed. Approximate time to the final status:

steps in the path × max(3rd digit, 1) minutes, with up to 1 extra minute per step.

CardStepsApproximate time
00052 (1 → 3 → 11)2 to 4 min
00094 (1 → 3 → 6 → 8 → 11)4 to 8 min
00502 (1 → 3 → 10)10 to 12 min
0099436 to 40 min

Use 0 or 1 as the third digit for quick tests, and a higher value when you want time to check each intermediate status with GetTicketById and each webhook you receive.


What you get in each scenario

Webhooks

The same events as in production are generated (see Webhooks):

  • ticket.status_changed when the ticket is created (1) and on every status change along the path.
  • ticket.invoiced on reaching 11.
  • ticket.failed on reaching 10.

Example with 0006 (scenario 6) and all three events configured:

ChangeEvents
null → 1ticket.status_changed
1 → 3ticket.status_changed
3 → 5ticket.status_changed
5 → 11ticket.status_changed + ticket.invoiced

Ticket data (GetTicketById)

FieldIn test
ticketStatusId / ticketCodeId / invoiceMethodPer the scenario.
ticketUrlThe image you uploaded.
pdfUrl, xmlUrl, xmlDataIn the invoiced scenarios (5 to 9), the simulator attaches a real generic invoice, always the same one. In the not-invoiceable ones they’re empty.
ticketDate, ticketAmountIn the invoiced scenarios, the date and total of that generic invoice.

Reports (GetPeriodStats, GetTicketStatuses, GetTicketsByMonth…) count test tickets the same way as in production.


Guide for your development

  1. Get your test token in the test business web app, under API y plan.

  2. Set up data: create an association (CreateAssociation), a user (CreateUser) and register an RFC with its CSF (AddUserTaxInfo or SaveAssociationCSF).

  3. Configure your webhooks (SaveWebhook), store the secret and validate the signature with TestWebhook.

  4. Upload one ticket per scenario with CreateUserTicket or CreateAssociationTicket, varying CardLastFour.

    The image can be any valid file (JPG, JPEG, HEIC, WEBP, PNG, PDF, max. 10 MB): the simulator doesn’t read it.

  5. Check that your system receives and processes every event, and that the final status matches GetTicketById.

Recommended minimum set:

CardTo test
0015Invoiced directly.
0019Invoiced with several intermediate statuses.
0010Not invoiceable directly.
0013Not invoiceable with several intermediate statuses.
no CardLastFourSpecial case: ends at 10 with code 15.

To test webhook retries, have your server respond with an error (for example, 500) to some event and review the attempts with GetWebhookEventById or in the business web app; then resend it with Reenviar evento on the Webhooks screen.