Ir al contenido

stampDraft()

Valida y timbra un borrador con el CSD de la cuenta. En producción emite un CFDI y registra consumo.

Permiso: invoice:stamp

stampDraft(
id: string,
input?: DraftStampInput,
options?: RequestOptions
): Promise<InvoiceRecord>

Referencia HTTP: POST /invoice-drafts/{id}/stamp

  • Antes de llamar: datos fiscales y CSD configurados, acceso al plan, receptor, pago y conceptos completos. Sigue la guía de emisión para preparar esos datos.
  • La respuesta conserva el ID de FactuCat y agrega satUuid. Después, usa getInvoice() para consultar el documento.
  • Ante un timeout no crees otro borrador: consulta el documento original y conserva la clave de la operación. Una respuesta ambigua requiere reconciliar el timbrado.
  • allowPaidStampOverdraft se interpreta como true por defecto en la API pública. Los planes y reglas de consumo siguen aplicando; false no convierte el timbrado en gratuito.
ArgumentoTipoObligatorioUso
idstringSíID de FactuCat del borrador, en formato UUID. No es el UUID fiscal.
inputDraftStampInputNoSe puede omitir; el valor predeterminado es {}.
optionsRequestOptionsNosignal e idempotencyKey; consulta las opciones por solicitud.

Opciones por solicitud: signal e idempotencyKey.

Los campos siguientes corresponden a input en TypeScript. Un campo opcional se puede omitir; null solo se admite cuando aparece en su tipo. Las validaciones de negocio se ejecutan en el servidor.

CampoTipoObligatorioDescripción
issueDatestringNoFecha de emisión: YYYY-MM-DD o datetime ISO (día en la zona horaria del código postal de expedición). La fecha de emisión puede ser hoy o hasta 72 horas antes del timbrado (máximo 3 días de calendario atrás), nunca futura, en la zona horaria del código postal de expedición (regla 2.7.2.9 RMF). INVALID_ISSUE_DATE si no es válida.
skipIssuedEmailSendbooleanNoSuprime el envío de correo de emisión. No desactiva por sí solo WhatsApp.
sendToCustomerContactsbooleanNoAl activarlo, usa los contactos del cliente. Las opciones de cada canal tienen prioridad; false por sí solo no garantiza que se suprima la entrega al receptor.
sendCustomerEmailbooleanNoControla explícitamente el envío de correo al cliente.
sendCustomerWhatsAppbooleanNoControla explícitamente el envío de WhatsApp al cliente.
allowPaidStampOverdraftbooleanNoControla el uso de excedentes donde el plan lo admite; la API pública usa true al omitirlo.
cfdi_relacionadosobjectNoRelación con uno o más CFDI, cuando aplica a la operación.
substitutionobjectNoSolicita la sustitución de un CFDI y la cancelación automática del comprobante original.
Campos de cfdi_relacionados
CampoTipoObligatorioDescripción
tipo_relacionstringSíClave de dos dígitos del tipo de relación.Patrón: ^\d{2}$
cfdi_relacionadoArray<string>SíLista de UUID fiscales de los CFDI relacionados.Mínimo 1 elementos
Campos de substitution
CampoTipoObligatorioDescripción
cancel_originaltrueSíDebe ser true para cancelar automáticamente el CFDI original después del timbrado sustituto.
original_invoice_idstringNoID de FactuCat del CFDI original interno que será sustituido y cancelado.Formato: uuid
external_original_sat_uuidstringNoUUID fiscal del CFDI original externo que será sustituido y cancelado.Formato: uuid
external_original_receiver_rfcstringNoRFC del receptor del CFDI original externo; requerido para solicitar su cancelación.Mínimo 1 carácter
external_original_totalstringNoTotal del CFDI original externo como string; requerido para solicitar su cancelación.Mínimo 1 carácter

Usa el cliente factucat de Instala y conecta. Los IDs y datos fiscales de este ejemplo son ilustrativos: reemplázalos por los registros de tu cuenta y ambiente.

const resultado = await factucat.stampDraft(
"00112233-4455-4677-8899-aabbccddeeff",
{
"sendToCustomerContacts": false,
"sendCustomerEmail": false,
"sendCustomerWhatsApp": false,
"skipIssuedEmailSend": true
},
{
"idempotencyKey": "pedido-1001-timbrar"
},
)
console.log(resultado)

Resuelve una Promise<InvoiceRecord>. El valor recibido es directamente data, sin el envoltorio HTTP ni sus metadatos.

CampoTipoObligatorioDescripción
idstringSíID de FactuCat del recurso. No es el UUID fiscal.Formato: uuid
userIdstringSíID de la cuenta propietaria del recurso.Mínimo 1 carácter
customerIdstringNoID de FactuCat del cliente vinculado. Consulta las notas del método sobre la copia de datos fiscales.Formato: uuid
receiverRfcstringSíRFC del receptor guardado en el documento.
receiverLegalNamestringSíNombre fiscal del receptor guardado en el documento.
receiverPostalCodestringSíCódigo postal fiscal del receptor, como cadena de cinco dígitos.
receiverTaxRegimestringSíClave del régimen fiscal del receptor.
receiverFiscalResidencestringNoClave del país de residencia fiscal del receptor, cuando aplica.
receiverTaxIdstringNoIdentificación tributaria extranjera del receptor, cuando aplica.
receiverEmailstringNoCorreo del receptor guardado en el documento.Formato: email
receiverInvoiceLanguage"es" | "en"SíIdioma del receptor para este documento.
seriestringNoSerie asignada por la cuenta emisora.
foliostringNoFolio del documento.
satUuidstringNoUUID fiscal del CFDI timbrado. Es distinto del ID de FactuCat.
status"draft" | "issued" | "error" | "cancelled"SíEstado del recurso o resultado de la cancelación; consulta las notas del método.
cfdiTypestringSíTipo de comprobante.
cfdiUsestringSíClave del uso de CFDI solicitado por el receptor.
exportacion"01" | "02" | "03" | "04"SíClave del catálogo SAT c_Exportacion.
paymentMethodstringNoClave del método de pago del comprobante.
paymentFormstringNoClave de la forma de pago; conserva los ceros iniciales.
currency"MXN" | "USD" | "EUR"SíMoneda del cliente o del comprobante.
exchangeRatenumberSíTipo de cambio aplicado a la moneda del comprobante.
exchangeRateDatestringNoFecha de referencia del tipo de cambio en formato ISO 8601.Formato: date-time
subtotalnumberSíSubtotal del documento antes de impuestos.
vatRate0 | 0.08 | 0.1 | 0.16SíTasa de IVA como fracción decimal, por ejemplo 0.16; no envíes 16. vatRate: 0 por sí solo significa Tasa 0%.
taxTotalnumberSíTotal de impuestos del documento.
totalnumberSíImporte total del documento. En cancelaciones externas se envía como string.
customerNotesstringNoNotas visibles en el documento.
pdfLanguage"es" | "en"SíIdioma de la representación PDF.
errorMessagestringNoMensaje asociado a un error del documento, cuando está disponible.
issueDatestringNoFecha de emisión seleccionada, en formato ISO 8601.Formato: date-time
issuedAtstringNoFecha y hora de emisión, cuando está disponible.Formato: date-time
cancelledAtstringNoFecha y hora de cancelación, cuando está disponible.Formato: date-time
createdAtstringSíFecha y hora de creación en formato ISO 8601; se devuelve como string.Formato: date-time
updatedAtstringSíFecha y hora de última actualización en formato ISO 8601.Formato: date-time
itemsArray<object>SíConceptos del documento; cada concepto tiene su propio ID.
Campos de items[]
CampoTipoObligatorioDescripción
idstringSíID de FactuCat del recurso. No es el UUID fiscal.Formato: uuid
invoiceIdstringSíID de FactuCat del documento al que pertenece el concepto.Formato: uuid
positionnumber (entero)SíPosición del concepto; comienza en 0.Mínimo: 0. Máximo: 9007199254740991
productCodestringNoClave del producto o servicio del catálogo SAT.
unitCodestringSíClave de unidad del catálogo SAT.
descriptionstringSíDescripción del bien o servicio.
quantitynumberSíCantidad del concepto.
unitPricenumberSíPrecio unitario antes de impuestos.
amountnumberSíImporte del concepto antes de impuestos.
objetoImp"01" | "02" | "03" | "04" | "05" | "06" | "07" | "08"NoObjeto de impuesto del concepto, devuelto en borradores y facturas; 01 indica No objeto de impuesto.
vatKind"none" | "tasa" | "exento"NoTipo de IVA del concepto, devuelto en borradores y facturas: tasa, exento o none (No objeto de impuesto).
vatTreatment"iva_16" | "iva_8" | "tasa_0" | "exento" | "no_objeto"NoTratamiento de IVA opcional: iva_16, iva_8, tasa_0, exento o no_objeto. Omitirlo conserva la inferencia fiscal; un tratamiento explícito se guarda como manual. Si también envías vatRate, deben coincidir; de lo contrario, la API responde HTTP 400 con invalid_input. Se devuelve en los conceptos de borradores y facturas; no representa la tasa histórica de 10%.
vatRate0 | 0.08 | 0.1 | 0.16SíTasa de IVA como fracción decimal, por ejemplo 0.16; no envíes 16. vatRate: 0 por sí solo significa Tasa 0%.
vatSource"manual" | "inferred" | "default"NoOrigen de la tasa de IVA seleccionada.
vatReasonstringNoExplicación de la tasa de IVA, cuando está disponible.
isrWithholdingRate0 | 0.0125 | 0.1SíTasa de retención de ISR como fracción decimal.
isrWithholdingSource"manual" | "inferred" | "default"NoOrigen de la retención de ISR seleccionada.
isrWithholdingReasonstringNoExplicación de la retención de ISR, cuando está disponible.
suggestedProductCodestringNoClave de producto o servicio sugerida.
suggestionConfidencenumberNoConfianza de la sugerencia.
suggestionSource"ai" | "memory" | "manual" | "review"NoOrigen de la sugerencia.

Ejemplo de respuesta

{
"id": "00112233-4455-4677-8899-aabbccddeeff",
"userId": "usuario_ejemplo",
"customerId": "10112233-4455-4677-8899-aabbccddeeff",
"receiverRfc": "AAA010101AAA",
"receiverLegalName": "EMPRESA DE EJEMPLO",
"receiverPostalCode": "06000",
"receiverTaxRegime": "601",
"receiverInvoiceLanguage": "es",
"status": "issued",
"cfdiType": "I",
"cfdiUse": "G03",
"exportacion": "01",
"paymentMethod": "PUE",
"paymentForm": "03",
"currency": "MXN",
"exchangeRate": 1,
"subtotal": 1000,
"vatRate": 0.16,
"taxTotal": 160,
"total": 1160,
"pdfLanguage": "es",
"createdAt": "2026-09-08T12:00:00Z",
"updatedAt": "2026-09-08T12:00:00Z",
"items": [
{
"id": "20112233-4455-4677-8899-aabbccddeeff",
"invoiceId": "00112233-4455-4677-8899-aabbccddeeff",
"position": 0,
"productCode": "81111500",
"unitCode": "E48",
"description": "Desarrollo de aplicaciones",
"quantity": 1,
"unitPrice": 1000,
"amount": 1000,
"vatRate": 0.16,
"isrWithholdingRate": 0
}
],
"satUuid": "30112233-4455-4677-8899-aabbccddeeff",
"issuedAt": "2026-09-08T12:00:00Z"
}

Las fechas se entregan como cadenas ISO 8601. Un campo opcional puede estar ausente. Tipos, paginación y archivos.

La promesa se rechaza si la API devuelve un error, falla la conexión o los datos no cumplen el contrato. Cómo manejar los errores.