# Registrar un ticket

`POST https://api.fiscalisto.com/v1/tickets`

Una venta que su comprador factura él mismo: con el código (code) y el total en el portal del emisor (url, que puede incrustar en su página con fiscalisto.js), da sus datos fiscales y la factura se timbra al momento con los timbres de su cuenta. Lo que nadie factura entra solo en la factura global del periodo. Registrar otra vez el mismo folio con el mismo total contesta el ticket que ya existe (los reintentos son seguros); con otro total, 409.

## Parámetros

| Nombre | Dónde | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `Idempotency-Key` | encabezado |  | Opcional (los SDK la mandan solos). Si la respuesta se pierde, repita la solicitud con el mismo valor durante 24 horas: contesta lo mismo, con idempotent-replayed: true, y no lo hace dos veces (ni crea, ni manda correos, ni cobra). |

## Cuerpo

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `issuer` | string |  | El emisor (iss_…) que vendió. Por omisión, su único emisor. |
| `folio` | string | sí | El folio de la venta en su sistema, único por emisor: letras, números, - _ / y punto. Registrar el mismo folio con el mismo total responde el ticket que ya existe. (hasta 40 caracteres) |
| `total` | number | sí | Lo que se cobró, impuestos incluidos y sin propina. (de -∞ a 10000000) |
| `tip` | number |  | Propina: no va en la factura. El cliente puede escribir el total con ella o sin ella. (de 0 a 10000000) |
| `payment_form` | string | sí | c_FormaPago de la venta: 01 efectivo, 04 tarjeta de crédito… |
| `sold_at` | string |  | Cuándo se vendió: ISO 8601 (2026-10-02T13:45:00-06:00) o la hora de la Ciudad de México sin zona. Por omisión, ahora. (hasta 40 caracteres) |
| `product` | string |  | Un producto (prd_…) de su catálogo: el concepto de la factura. |
| `description` | string |  | El concepto. Con `product`, reemplaza su descripción; sin él, va con `product_key`. (hasta 1000 caracteres) |
| `product_key` | string |  | c_ClaveProdServ (8 dígitos), si no usa `product`. |
| `unit_key` | string |  | c_ClaveUnidad. Por omisión, la de la clave del producto. |
| `iva` | `0`, `0.16`, `0.08`, `exento` |  | Tasa de IVA incluida en el total. Por omisión 0.16. |

Ejemplo:

```json
{
  "folio": "A1042",
  "total": 580,
  "payment_form": "04",
  "product_key": "90101501",
  "description": "Consumo de alimentos",
  "sold_at": "2026-10-24T14:32:00-06:00"
}
```

## Con el SDK de TypeScript

```ts
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const ticket = await fiscalisto.tickets.create({
  folio: "A1042",
  total: 580,
  payment_form: "04",
  product_key: "90101501",
  description: "Consumo de alimentos",
  sold_at: "2026-10-24T14:32:00-06:00",
}, { idempotencyKey: "pedido-A-1042" });
```

## Con el SDK de Python

```python
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

ticket = fiscalisto.tickets.create({
    "folio": "A1042",
    "total": 580,
    "payment_form": "04",
    "product_key": "90101501",
    "description": "Consumo de alimentos",
    "sold_at": "2026-10-24T14:32:00-06:00",
}, idempotency_key="pedido-A-1042")
```

## Con el SDK de PHP

```php
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$ticket = $fiscalisto->tickets->create([
    'folio' => 'A1042',
    'total' => 580,
    'payment_form' => '04',
    'product_key' => '90101501',
    'description' => 'Consumo de alimentos',
    'sold_at' => '2026-10-24T14:32:00-06:00',
], ['idempotency_key' => 'pedido-A-1042']);
```

## Con el SDK de .NET

```csharp
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var ticket = await fiscalisto.Tickets.CreateAsync(new CreateTicketParams
{
    Folio = "A1042",
    Total = 580,
    PaymentForm = "04",
    ProductKey = "90101501",
    Description = "Consumo de alimentos",
    SoldAt = "2026-10-24T14:32:00-06:00",
}, new RequestOptions { IdempotencyKey = "pedido-A-1042" });
```

## Con el SDK de Go

```go
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	ticket, err := client.Tickets.Create(ctx, &fiscalisto.CreateTicketParams{
		Folio:       "A1042",
		Total:       580,
		PaymentForm: "04",
		ProductKey:  fiscalisto.String("90101501"),
		Description: fiscalisto.String("Consumo de alimentos"),
		SoldAt:      fiscalisto.String("2026-10-24T14:32:00-06:00"),
	}, fiscalisto.WithIdempotencyKey("pedido-A-1042"))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(ticket.ID)
}
```

## Con el SDK de Java

```java
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.RequestOptions;
import com.fiscalisto.model.CreateTicketParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var ticket = fiscalisto.tickets().create(new CreateTicketParams()
        .setFolio("A1042")
        .setTotal(580)
        .setPaymentForm("04")
        .setProductKey("90101501")
        .setDescription("Consumo de alimentos")
        .setSoldAt("2026-10-24T14:32:00-06:00"), RequestOptions.idempotencyKey("pedido-A-1042"));
System.out.println(ticket.getId());
```

## Respuesta 201

Correcto.

Un objeto `Ticket`:

| Campo | Tipo | Siempre viene | Descripción |
| --- | --- | --- | --- |
| `id` | string | sí | Identificador del objeto, con su prefijo (iss_, inv_, ret_, cus_, prd_, emp_, bat_, brn_, whs_, stm_, adj_, evt_, whe_). |
| `livemode` | boolean | sí | true en producción (llaves fk_live_), false en pruebas (fk_test_). Lo de pruebas no vale ante el SAT. |
| `object` | `"ticket"` | sí | Qué tipo de objeto es («invoice», «customer»…). |
| `issuer` | string | sí | El emisor que vendió. |
| `folio` | string | sí | El folio de la venta en su sistema. |
| `code` | string | sí | Lo que su comprador escribe en el portal junto con el total: el folio y 4 caracteres al azar (A123-K7QX). Imprímalo en el ticket o mándelo con la compra. |
| `status` | `pending`, `invoiced`, `global`, `cancelled` | sí | pending (se puede facturar), invoiced (su comprador lo facturó: la factura en invoice), global (entró en la factura global del periodo) o cancelled. |
| `url` | string o null | sí | La página del portal con el código ya escrito: el comprador pone el total y sus datos. Puede incrustarla con fiscalisto.js. null si ya no está pendiente. |
| `total` | number | sí | Lo que se cobró, impuestos incluidos y sin propina. |
| `tip` | number | sí | La propina (no va en la factura). |
| `payment_form` | string | sí | c_FormaPago de la venta. |
| `description` | string | sí | El concepto de la factura. |
| `product_key` | string | sí | c_ClaveProdServ del concepto. |
| `sold_at` | string (date-time) | sí | Cuándo se vendió. |
| `invoiceable_until` | string | sí | El último día (AAAA-MM-DD) en que el comprador puede facturarlo; después entra en la factura global. |
| `invoice` | string o null | sí | La factura (inv_…) que hizo su comprador, o null. |
| `global_invoice` | string o null | sí | La factura global (inv_…) en que entró, o null. |
| `customer` | objeto o null | sí | A quién se facturó, o null. |
| `customer.tax_id` | string | sí | RFC (Rfc), 12 caracteres una persona moral y 13 una física. |
| `customer.legal_name` | string o null | sí | Nombre o razón social tal como está en la constancia de situación fiscal, sin el régimen de capital (sin «S.A. de C.V.»). |
| `created_at` | string (date-time) o null | sí | Cuándo se registró. |

```json
{
  "id": "tkt_OufpKqnrvx9p6hW1yQbT3mZr8sKdLx0VeN",
  "object": "ticket",
  "livemode": false,
  "issuer": "iss_OufpKqnrvx9p",
  "folio": "A1042",
  "code": "A1042-K7QX",
  "status": "pending",
  "url": "https://fiscalisto.com/autofactura/Tx8mQ2vLp9WnR4c?c=A1042-K7QX",
  "total": 580,
  "tip": 0,
  "payment_form": "04",
  "description": "Consumo de alimentos",
  "product_key": "90101501",
  "sold_at": "2026-10-24T14:32:00-06:00",
  "invoiceable_until": "2026-10-31",
  "invoice": null,
  "global_invoice": null,
  "customer": null,
  "created_at": "2026-10-24T14:32:05-06:00"
}
```

## Errores

Puede responder 400, 401, 403, 404, 429, 500 con el cuerpo de error de siempre; cada código está en https://fiscalisto.com/docs/api/errores.md.
