Documentación
Información general
Esta documentación explica como consultar, timbrar y cancelar facturas desde el API de Factura.com, así como el proceso para su descarga y envío por correo electrónico.
La documentación de la API de Factura.com ofrece una descripción detallada de los métodos y endpoints (URLs o direcciones) disponibles con ejemplos de las posibles respuestas a obtener o enviar. Además podrás consultar información general que facilitará su uso.
Con el Api de Factura.com podrás:
- Crear todo tipo de CFDI
- Listar CFDIs
- Crear complemento de pagos
- Acceder a los catálogos de la plataforma
- Crear, editar, consultar y listar clientes
- Listar productos
- Entre otras cosas
Entornos
El API de Factura.com cuenta con dos entornos disponibles:
Sandbox
Host: https://sandbox.factura.com/
Es un entorno de pruebas que simula el funcionamiento de nuestra API en producción, generando CFDIs sin validez fiscal.
Producción
Host: https://api.factura.com/
Es el host para realizar el timbrado real, te recomendamos hacer pruebas en la versión sandbox primero, ya que los CFDIs generados en este entorno si tienen validez fiscal.
Composición de la URL
Independientemente del entorno en el que estes trabajando, la estructura de la URL se compone de la siguiente forma:
- Host = sandbox https://sandbox.factura.com/ o producción https://api.factura.com/
- Version = Versión de la API = api/v1, api/v3 ó api/v4
- End_point = Describe el método al que se está haciendo la petición.
Por ejemplo, para traer listado de facturas en el entorno de producción la url es la siguiente:
https://api.factura.com/v1/invoices
Primeros pasos
Para hacer uso del API de Factura.com es necesario hacer uso del formato JSON . Todas las respuestas, exitosas o de error, están en formato JSON. Es necesario incluir en las cabeceras el token de acceso llamado API KEY y SECRET KEY
Obtener API KEY y SECRET KEY
Para obtener tus llaves de acceso deber seguir los siguientes pasos:
- Iniciar sesión (Si es en producción en https://api.factura.com/, si es en sandbox en https://sandbox.factura.com/ ).
- En el menú lateral dirígete a Configuraciones - API - Datos de acceso .
- Haz clic en el botón que se encuentra junto a cada token de acceso para copiarlo.
Agregar a la cabecera
Ejemplo de cabeceras.json:
"Content-Type: application/json",
"F-PLUGIN": . "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed",
"F-Api-Key": . "JDJ5JDEwJGRuT1Y3cUM3WnJEMUNaaXRwVW5UUmVMS3RLUHhHMjlYZndaeWxyRXVpUjBLVmwxOHBPWFXX",
"F-Secret-Key": . "JDJ5JDEwJDZaTjRhWDVVRXh3ejZIRmxEU1pjeE9GMVRHakh4OGY0MG5lRS5DclhISGFoeUFmaThxaUXX"
Dentro de las cabeceras de la petición es necesario agregar las llaves para poder acceder al API.
CFDI 4.0
Listar CFDIs 4.0
A continuación se explica como listar los CFDI's , con un ejemplo y la muestra de posibles respuestas obtenidas.
Podemos consultar los CFDI's filtrando por los siguientes parámetros:
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
month | number | Opcional | Induca el número de mes que deseas consultar. Éste debe estar escrito en 2 dígitos. Ejemplo: Enero = 01, Diciembre = 12, etc. |
year | number | Opcional | Indica el año que deseas consultar. Éste debe estar escrito en 4 dígitos. Ejemplo: 2017. |
rfc | string | Opcional | Indica un RFC para traer todos los CFDI's timbrados al mismo. Ejemplo: XAXX010101000. |
type_dpcument | string | Opcionl | Indica un tipo de CFDI para listar solo los CFDI's de ese tipo. Para ello enviar la clave indicada en el catálogo de Tipos de CFDI. Ejemplo: factura Consulta el catálogo de tipos de CFDIs. |
page | int | Opcional | Indica número de página a consultar, por default posiciona en la página 1. |
per_page | int | Opcional | Indica el limite de resultados para mostrar, por default retorna 100 registros. |
Construcción de la URL para listar CFDIs 4.0
Ejemplo.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/list',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/list',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/list"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/list")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/list
Ejemplo: https://api.factura.com/v4/cfdi40/list
Respuestas de listar CFDIs 4.0
Ejemplo de respuesta exitosa.
{
"status": "success",
"response": "success",
"total": 20,
"per_page": 100,
"current_page": 1,
"last_page": 1,
"from": 1,
"to": 100,
"data": [
{
"RazonSocialReceptor": "PRUEBAS",
"Folio": "F 100",
"UID": "61d4c2d768a14",
"UUID": "ed20099a-3c7d-4277-be8a-377715fbcbb2",
"Subtotal": "229.900000",
"Descuento": null,
"Total": "259.780000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAXX010101000",
"FechaTimbrado": "2022-01-04",
"Status": "enviada",
"TipoDocumento": "F",
"Version": "4.0"
},
{
"RazonSocialReceptor": "PRUEBAS",
"Folio": "F 99",
"UID": "61d4c0326907f",
"UUID": "357a0cf5-be19-4c1a-8f18-7fdb453193f2",
"Subtotal": "229.900000",
"Descuento": null,
"Total": "259.780000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAXX010101000",
"FechaTimbrado": "2022-01-04",
"Status": "cancelada",
"TipoDocumento": "F",
"Version": "4.0"
},
{
"RazonSocialReceptor": "PRUEBAS",
"Folio": "F 98",
"UID": "61d4c0197fbfd",
"UUID": "42ffe80d-3c8f-46f6-af64-513656615bb4",
"Subtotal": "229.900000",
"Descuento": null,
"Total": "259.780000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAXX010101000",
"FechaTimbrado": "2022-01-04",
"Status": "cancelada",
"TipoDocumento": "F",
"Version": "4.0"
}
]
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Buscar CFDI por UID
A continuación se explica como buscar un CFDI por UID, con un ejemplo y la muestra de posibles respuestas obtenidas.
Podemos buscar un CFDI utilizando el UID como parámetro y obtener la información relacionada con este, a continuación se muestran las características de este valor.
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Es el identificador interno para la plataforma de factura.com asignado al CFDI cuando lo creamos |
Construcción de la URL para buscar un CFDI con el parametro UID
Ejemplo.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi/uid/63389a6a27f88',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi/uid/63389a6a27f88',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi/uid/63389a6a27f88"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi/uid/63389a6a27f88")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = https.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi/uid/{UID de tu CFDI}
Ejemplo: https://api.factura.com/v4/cfdi/uid/63389a6a27f88
Respuestas al buscar un CFDI por UID
Ejemplo de respuesta exitosa.
{
"status": "success",
"message": "CFDI obtenido exitosamente",
"data": {
"RazonSocialReceptor": "ALBA XKARAJAM MENDEZ",
"Folio": "F 693",
"UID": "63389a6a27f88",
"UUID": "1a7cf8f9-3406-4024-9028-84266cab1f13",
"Subtotal": "400.000000",
"Descuento": null,
"Total": "745.480000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAMA620210DQ5",
"FechaTimbrado": "2022-10-01",
"Status": "enviada",
"Version": "4.0",
"TipoDocumento": "F",
"XML": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...................
}
}
Ejemplo de respuesta erronea al introducir un UID que no existe
{
"status": "error",
"message": "No se encontró CFDI: 63389a627f88"
}
Ejemplo de respuesta erronea de autenticación
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe"
}
Buscar CFDI por UUID
A continuación se explica como buscar un CFDI por UUID, con un ejemplo y la muestra de posibles respuestas obtenidas.
Podemos buscar un CFDI utilizando el UUID como parámetro y obtener la información relacionada con este, a continuación se muestran las características de este valor.
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
UUID | String | Requerido | Es el identificador unico que asigna el SAT a nuestro CFDI cuando lo timbramos, otra forma en la que lo podemos encontrar es como "Folio fiscal" |
Construcción de la URL para buscar un CFDI con el parametro UUID
Ejemplo.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi/uuid/1a7cf8f9-3406-4024-9028-84266cab1f13',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi/uuid/1a7cf8f9-3406-4024-9028-84266cab1f13',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi/uuid/1a7cf8f9-3406-4024-9028-84266cab1f13"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi/uuid/1a7cf8f9-3406-4024-9028-84266cab1f13")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = https.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi/uuid/{UUID de tu CFDI}
Ejemplo: https://api.factura.com/v4/cfdi/uuid/1a7cf8f9-3406-4024-9028-84266cab1f13
Respuestas al buscar un CFDI por UUID
Ejemplo de respuesta exitosa.
{
"status": "success",
"message": "CFDI obtenido exitosamente",
"data": {
"RazonSocialReceptor": "ALBA XKARAJAM MENDEZ",
"Folio": "F 693",
"UID": "63389a6a27f88",
"UUID": "1a7cf8f9-3406-4024-9028-84266cab1f13",
"Subtotal": "400.000000",
"Descuento": null,
"Total": "745.480000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAMA620210DQ5",
"FechaTimbrado": "2022-10-01",
"Status": "enviada",
"Version": "4.0",
"TipoDocumento": "F",
"XML": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...................
}
}
Ejemplo de respuesta erronea al introducir un UUID que no existe
{
"status": "error",
"message": "No se encontró CFDI: 1a7cf8f9-3406-4024-9028-84266ab1f13"
}
Ejemplo de respuesta erronea de autenticación
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe"
}
Buscar CFDI por Folio
A continuación se explica como buscar un CFDI por Folio, con un ejemplo y la muestra de posibles respuestas obtenidas.
Podemos buscar un CFDI utilizando el Folio como parámetro y obtener la información relacionada con este, a continuación se muestran las características de este valor.
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
Folio | String | Requerido | Este valor se asigna al crear un nuevo CFDI dependiendo de la serie que utilicemos para el control de nuestros consecutivos y consta de la letra de esta serie + el consecutivo, por ejemplo: "F693" o "f693" (Es importante introducir sin espacios el folio que buscamos y puede ser en mayúsculas o minúsculas) |
Construcción de la URL para buscar un CFDI con el parametro Folio
Ejemplo.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi/folio/F693',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi/folio/F693',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi/folio/F693"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi/folio/F693")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = https.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi/folio/{Folio de tu CFDI}
Ejemplo: https://api.factura.com/v4/cfdi/folio/F693
Respuestas al buscar un CFDI por Folio
Ejemplo de respuesta exitosa.
{
"status": "success",
"message": "CFDI obtenido exitosamente",
"data": {
"RazonSocialReceptor": "ALBA XKARAJAM MENDEZ",
"Folio": "F 693",
"UID": "63389a6a27f88",
"UUID": "1a7cf8f9-3406-4024-9028-84266cab1f13",
"Subtotal": "400.000000",
"Descuento": null,
"Total": "745.480000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAMA620210DQ5",
"FechaTimbrado": "2022-10-01",
"Status": "enviada",
"Version": "4.0",
"TipoDocumento": "F",
"XML": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...................
}
}
Ejemplo de respuesta erronea al introducir un Folio que no existe
{
"status": "error",
"message": "No se encontró CFDI: F6934"
}
Ejemplo de respuesta erronea de autenticación
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe"
}
Crear CFDI 4.0
A continuación se explica como crear un CFDI, con un ejemplo y muestra de posibles respuestas obtenidas.
Podemos crear un CFDI haciendo uso de los siguientes parametros:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Receptor | array | Requerido | Indica el UID del receptor/cliente previamente creado en factura.com Ver listado de atributos posibles para este nodo. Ejemplo:
|
TipoDocumento | string | Requerido | Indica la clave del tipo de documento que deseas timbrar. Ver listado de tipos de documentos. Ejemplo:
|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Conceptos | array | Requerido | Es un arreglo de objetos, en el que cada objeto corresponde a un concepto con sus atibutos para agregar al CFDI. Ver listado de atributos posibles para este nodo. Ejemplo:
|
UsoCFDI | string | Requerido | Indica la clave del Uso de CFDI, ésta debe ser válida para el SAT. Ver catálogo de claves de uso de cfdi. Ejemplo:
|
Serie | number | Requerido | Indica id de la serie con la que deseas timbrar el documento. Ésta debe estar dada de alta en tu panel de Factura.com y coincidir con el tipo de CFDI que deseas timbrar. Para obtenerlo Inicia sesión y dirígete al Menú lateral - Configuraciones - Series y folios Ejemplo:
|
FormaPago | string | Requerido | Indica la clave de la forma de pago. Ésta puedes consultarla en el Catálogo de formas de pago. Ejemplo:
|
MetodoPago | string | Requerido | Indica la clave del método de pago
Ésta puedes consultarla en el Catálogo de métodos de pago. Ejemplo:
|
CondicionesDePago | string | Opcional | Indica las condiciones de pago del CFDI, éstas deben tener una longitud minima de 1 y máxima de 1000 caracteres.
Ejemplo:
|
CfdiRelacionados | array | Opcional | En caso que tu CFDI vaya relacionado con otro(s), envía un arreglo con el/los UUID's con los que está relacionado.
Ver listado de atributos posibles para este nodo. Ejemplo:
|
Moneda | string | Requerido | Indica la clave de la moneda del CFDI.
Ésta puedes consultarla en el Catálogo de monedas Ejemplo:
|
TipoCambio | string | Opcional / Requerido en caso que el atributo Moneda sea diferente de MXN | Indicar el tipo de cambio vigente al momento de crear el CFDI. Ejemplo:
|
NumOrder | string | Opcional | Indica el número de orden o pedido. Este dato es solo para control interno. Ejemplo:
|
Fecha | string | Opcional | Indica una fecha con formato (Y-m-d\TH: m :s). Es posible enviar hasta 72 horas de atraso a la fecha actual, sin embargo no están permitidas las fechas futuras. Ejemplo:
|
Comentarios | string | Opcional | Indica si deseas que aparezcan comentarios en el PDF de tu CFDI.
Ejemplo:
|
Cuenta | string | Opcional | En caso de desearlo, indica los últimos 4 dígitos de la tarjeta o cuenta bancaria del cliente.
Ejemplo:
|
EnviarCorreo | bolean | Opcional | Indica si deseas que el CFDI se envíe a tu cliente por correo electrónico. Por default esta opción es true. Ejemplo:
|
LugarExpedicion | string | Opcional | Indica el Código postal del lugar de expedición del CFDI. Éste debe tener 5 caracteres. Ejemplo:
|
Construcción de la URL para crear CFDI 4.0:
Ejemplo para crear CFDI.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor" : {
"UID": "6169fc02637e1"
},
"TipoDocumento":"factura",
"Conceptos": [{
"ClaveProdServ": "81112101",
"Cantidad":1,
"ClaveUnidad":"E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.90,
"Descripcion": "Desarrollo a la medida",
"Impuestos":{
"Traslados":[
{
"Base": 229.90,
"Impuesto":"002",
"TipoFactor":"Tasa",
"TasaOCuota":"0.16",
"Importe":36.784
}
],
"Locales":[
{
"Base": 229.90,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": False
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/create
Ejemplo: https://api.factura.com/v4/cfdi40/create
Ejemplo para crear cfdi exento.
<?php
for ($x = 1; $x <= 1; $x++) {
$Conceptos[] = [
'ClaveProdServ' => '81112107',
'Cantidad' => '1',
'ClaveUnidad' => 'E48',
'Unidad' => 'Unidad de servicio',
'ValorUnitario' => '100',
'Descripcion' => 'Desarrollo a la medida',
'Descuento' => '0',
'Impuestos' => [
'Traslados' => [
['Base' => '100', 'Impuesto' => '002', 'TipoFactor' => 'Exento', 'TasaOCuota' => '0.00', 'Importe' => '00'],
]
],
];
}
$ch = curl_init();
$fields = [
"Receptor" => ["UID" => "55c0fdc675XXX"],
"TipoDocumento" => "factura",
"UsoCFDI" => "P01",
"Redondeo" => 2,
"Conceptos" => $Conceptos,
"FormaPago" => "01",
"MetodoPago" => 'PUE',
"Moneda" => "MXN",
"CondicionesDePago" => "Pago en una sola exhibición",
"Serie" => 1,
"EnviarCorreo" => 'true',
"InvoiceComments" => ""
];
$jsonfield = json_encode($fields);
curl_setopt($ch, CURLOPT_URL, "https://sandbox.factura.com/api/v4/cfdi40/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonfield);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-API-KEY: ". 'Ingresa API KEY',
"F-SECRET-KEY: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
return die($response);
curl_close($ch);
?>
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": False
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
response = http.request(request)
puts response.read_body
Ejemplo de respuesta exitosa
{
"response": "success",
"message": "Factura creada y enviada satisfactoriamente",
"UUID": "8ff503a2-c6b7-4a25-XXX-a25610e6b488",
"uid": "5c06fa8b3bbe6",
"SAT": {
"UUID": "8ff503a2-c6b7-XXX-92c7-a25610e6b488",
"FechaTimbrado": "2018-12-04T16:07:08",
"NoCertificadoSAT": "20001000000300022323",
"Version": "1.1",
"SelloSAT": "lzlv2bEVsjx8XkiJHJvlfCjr7xJ/laxZnvSmGSKF3C/HI9WFDYFFk4NfGyILBj8ll7m1VoCqlkSLvu9dRex4jSSGfPJOPGDrx7w/4AOj/scHPU23uIPhztnaHIYHKg9UxP4L9rgX814msJ8V86IXZ1nY7akr77Cpf2c2yAnHaO1fm81oQIe32obIs2GrOey6JG9oxQNrcUawSXXXXXXXX",
"SelloCFD": "NJQH6WT8eLxAeti7pUWhB7F6C6xrdSqkFfORf3+SeGkhu+5E0cZZUQjgaSZLpPcgk01aQUf0Jayw2GewYou5MjD4OLzZnZuizPwy3cSfQXzgX6sJTtAsI00VyhQewxLYDSMqFUrPpniNQG8Nl/eEg1kx72kkmqih2KX2Z+URkhx14W7CMG2aMJnhDyZuyliF+cy3utjXwzxQMl+28A/mgnlfUXzZd/3IunTtxM/p4bpqbYinK+7Bd/n+90Z6axsFBs6N7wxUX6aK9YL58owhgVGXXXXXXXX"
},
"INV": {
"Serie": "F",
"Folio": 1433
},
"invoice_uid": "5c06fa8b3bXXX"
}
Ejemplo de respuesta de error
{
"response": "error",
"message": {
"message": "CFDI33161 - El valor del campo Importe o que corresponde a Traslado no se encuentra entre el limite inferior y superior permitido.",
"messageDetail": "Comprobante:Concepto:Impuestos:Traslado:Importe: El Importe es mayor o menor al limite superior/inferior calculado. LimiteSuperiorCalculado: 17 LimiteInferiorCalculado: 15 Comprobante:Concepto:Impuestos:Traslado:Importe: 19",
"data": null,
"status": "error"
},
"xmlerror": "\n</cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos></cfdi:Traslados></cfdi:Impuestos></cfdi:Comprobante>\n"
}
Error al crear CFDI 4.0 con numero de orden existente
Ejemplo de error al crear CFDI numero de orden repetido
{
"response": "error",
"message": "Ya existe un CFDI con folio y serie [F-1]",
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd\" Version=\"3.3\" Serie=\"F\" Folio=\"1\" Fecha=\"2021-04-18T10:26:27\" FormaPago=\"02\" NoCertificado=\"30001000000400002330\" SubTotal=\"1635.48\" Moneda=\"MXN\" Total=\"2502.28\" TipoDeComprobante=\"I\" MetodoPago=\"PUE\" LugarExpedicion=\"45562\" Sello=\"TPFAOe/vqOpiyVRMKzO4yd5ZEG4g3RwBTTd/FfbLNvPYtmFh8Stra9gFDgXRcI43NSh6ABgz5+Tum+5KYYeoTwRF3LY7O5iww3lzSe8pJZJuBrUyONeFIzWkmdW9SIfZJdYjT6M5G2zNOxTodtk7/8kEFF0mSQZoeXZ1Z5X+jBHmxSy2sqWheuJJP92TVhstRRqwOgNGxqGoQUNebNPlWn2cAxsesc5hJkajj1D/RAkHl0eHLsdFQTf7f8yRUu5vnn3RtdVYn7zsx4uXdQE9kgGFVYv+FNrsj/chtF0GAL6D0liIFlA2fdDVgh7ulxr0eexVC5kNjV4xzKTay3IRGw==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"CRISTIAN\" RegimenFiscal=\"612\"/><cfdi:Receptor Rfc=\"XAXX010101000\" Nombre=\"General\" UsoCFDI=\"G01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"50202200\" Unidad=\"Pieza\" Cantidad=\"1.000000\" ClaveUnidad=\"H87\" Descripcion=\"producto 1\" ValorUnitario=\"1635.480000\" Importe=\"1635.480000\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"1635.480000\" Impuesto=\"003\" TipoFactor=\"Tasa\" TasaOCuota=\"0.530000\" Importe=\"866.804400\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"866.80\"><cfdi:Traslados><cfdi:Traslado Impuesto=\"003\" TipoFactor=\"Tasa\" TasaOCuota=\"0.530000\" Importe=\"866.80\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento><tfd:TimbreFiscalDigital xmlns:tfd=\"http://www.sat.gob.mx/TimbreFiscalDigital\" xsi:schemaLocation=\"http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd\" Version=\"1.1\" UUID=\"1250466f-4424-4e8a-a236-c5a714224f56\" FechaTimbrado=\"2021-04-19T11:18:15\" RfcProvCertif=\"SPR190613I52\" SelloCFD=\"TPFAOe/vqOpiyVRMKzO4yd5ZEG4g3RwBTTd/FfbLNvPYtmFh8Stra9gFDgXRcI43NSh6ABgz5+Tum+5KYYeoTwRF3LY7O5iww3lzSe8pJZJuBrUyONeFIzWkmdW9SIfZJdYjT6M5G2zNOxTodtk7/8kEFF0mSQZoeXZ1Z5X+jBHmxSy2sqWheuJJP92TVhstRRqwOgNGxqGoQUNebNPlWn2cAxsesc5hJkajj1D/RAkHl0eHLsdFQTf7f8yRUu5vnn3RtdVYn7zsx4uXdQE9kgGFVYv+FNrsj/chtF0GAL6D0liIFlA2fdDVgh7ulxr0eexVC5kNjV4xzKTay3IRGw==\" NoCertificadoSAT=\"30001000000400002495\" SelloSAT=\"VnVdqPsb7KANYN9GBDBy3F765+MAZGRuRmhXAGXBnfJ6HOcOIBZZO4wnKbruPyFXy4n+//lkcG7C6GRrTlfGV01ZJnJV3++X0E41H/ayy+j2gfCyVAxD6NX7YTBT7I9ccvSK63BRuLyhf5e3AtC4Dp+rjBrX/wldgvrXsoBGvz04pwMZZXPwJTj9TvwZn+ITtrushJFWg5ywSbhZsezd0F21TZ3ZOA00EZ3G67Iu/VSyIF91t3FRP05lbkMnsfjXP+PQe/rhghiHcRxnynLZIbdehxCVXE5WKmKWPcESScEyUA1F228IZP/u/AoYXdjowR8S4DGHR5r4c/1mPIizbw==\"/></cfdi:Complemento></cfdi:Comprobante>\n",
"uid": "607dad4789745",
"uuid": "1250466f-4424-4e8a-a236-c5a714224f56"
}
A continuación se explica un caso de error que puede ocurrir al crear un CFDI cuando utilizamos un numero de orden repetido, en nuestra plataforma existe una validación que evita que el numero o folio de orden que asignemos a nuestro CFDI sea repetido esto es para evitar crear CFDIs con los mismos identificadores que podria causar confusión, a continuacion se lista la variable de la cual depende este error.
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
NumOrder | string | Opcional | Indica el número de orden o pedido. Este dato es solo para control interno. Ejemplo:
|
Cuando este error aparece en la respuesta obtendremos el mensaje de error que indica que ya existe un CFDI con el folio o numero de orden que intentamos crear y se adjunta el XML del CFDI a el que esta asignado este numero para que podamos consultar a que CFDI asignamos previamente el numero de orden que intentamos utilizar en esta ocasión
Receptor
Ejemplo de receptor .json
"Receptor": {
"ResidenciaFIscal": "",
"UID": "55c0fdc67593d"
},
A continuación se describen los atributos que deben incluirse en el nodo Receptor
El receptor debe incluir los siguientes atributos:
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | string | Requerido | Indica el UID del receptor del CFDI. Ejemplo: "UID": "55c0fdc67593d" |
ResidenciaFiscal | string | Opcional | Indicar el número de residencia fiscal cuando el receptor del comprobante sea un residente en el extranjero. Ejemplo: "ResidenciaFiscal": "5256452" |
Conceptos
Ejemplo de conceptos .json
"Conceptos": [
{
"ClaveProdServ": "43232408",
"NoIdentificacion": "WEBDEV10",
"Cantidad": "1.000000",
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"Descripcion": "Desarrollo web a la medida",
"ValorUnitario": "15000.000000",
"Importe": "15000.000000",
"Descuento": "0",
"honorarioInverso": "",
"montoHonorario": "0",
"Impuestos": {
"Traslados": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [],
"Locales": []
},
"NumeroPedimento": "",
"Predial": "",
"Partes": "0",
"Complemento": "0"
}
],
A continuación se describen los atributos que deben incluirse en el nodo Conceptos
Para cada concepto es necesario incluir los siguientes atributos:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
ClaveProdServ | string | Requerido | Indica la clave del producto o servicio correspondiente a tu concepto. Es importante que ésta la tomes del catálogo indicado por el SAT para que sea válida. Ejemplo: "ClaveProdServ": "43232408" |
NoIdentificacion | string | Opcional | Indica el número de identificación o SKU en caso de tenerlo. Ejemplo: "NoIdentificacion": "WEBDEV10" |
Cantidad | number | Requerido | Indica la cantidad. Ejemplo: 'Cantidad' : '1' |
ClaveUnidad | string | Requerido | Indica la clave de la unidad de medida correspondiente a tu concepto. Consulta el listado de claves válidas para el SAT. Ejemplo: "ClaveUnidad": "E48" |
Unidad | string | Requerido | Indica la unidad de medida. Ésta debe coincidir con la clave de la unidad ingresada en el parámetro anterior. Consulta el listado de claves válidas para el SAT. Ejemplo: "Unidad": "Unidad de servicio" |
ValorUnitario | string | Requerido | Indica el precio unitario sin incluir impuestos. Ejemplo: "ValorUnitario": "15000.00" |
Descripcion | string | Requerido | Indica la descripción del concepto. Ejemplo: "Descripcion": "Desarrollo web a la medida" |
Descuento | string | Opcional | Indica el importe del descuento, en caso de desear agregarlo. Ejemplo: "Descuento": "10.00" |
Impuestos | array | Opcional | Indicar los impuestos (traslados, locales y retenidos) que tendrá el concepto. Consulta los parámetros que debe contener. Ejemplo: "Impuestos": { "Traslados": [ { "Base": "15000.000000", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.000000" } ], "Retenidos": [], "Locales": [] } |
NumeroPedimento | string | Opcional | Indica el número del pedimento correspondiente a la importación del bien. Ejemplo: "NumeroPedimento" : "15 48 3009 0001234" |
Predial | string | Opcional | necesario. Ejemplo: "Predial": "56485422", |
Partes | array | Opcional | Indica las partes o componentes que integran la totalidad del concepto. Ver los atributos que puede contener. |
Impuestos
Ejemplo de impuestos.json
"Impuestos": {
"Traslados": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Locales": [
{
"Impuesto": "CEDULAR",
"TasaOCuota": "0.05",
}
]
},
A continuación se describen los atributos que deben incluirse en el nodo de impuestos
El nodo de impuestos se conforma de los siguientes atributos:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Traslados | array |
Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Traslado. |
Indica los impuestos trasladados que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Traslados": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.00" } ], Ejemplo Excento: "Traslados": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor":"Exento", "TasaOCuota": "0.00", "Importe": "0.00" } ], |
Retenidos | array | Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Retenciones. |
Indica los impuestos retenidos que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Retenidos": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.00" } ], |
Locales | array | Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Locales |
Indica los impuestos locales que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Locales": [ { "Impuesto": "ISH", "TasaOCuota": "0.05", } ], |
Atributos de los nodos Traslados y Retenidos
A continuación se describen los nodos que componen cada impuesto que desees agregar a tu concepto.
Un concepto puede tener más de un traslado y más de una retención. Cada impuesto debe incluirse dentro de un objeto, que a su vez es contenido por en el arreglo del tipo de impuesto correspondiente.
Los impuestos que pueden incluirse dentro de traslados son:
- IVA
- IEPS
Los impuestos que pueden incluirse dentro de retenciones son:
- IVA
- ISR
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Base | float | Requerido | Indica el valor sobre el cual se calculará el impuesto. Ejemplo: "Base": "15000.00", |
Impuesto | string | Requerido | Indica la clave correspondiente al impuesto que deseas agregar. Consultar el catálogo de claves de Impuestos. Ejemplo: "Impuesto": "002" |
TipoFactor | string | Requerido | Indica tipo de factor correspondiente al impuesto que deseas agregar. Consultar el catálogo de Tipo factor. Ejemplo: "TipoFactor": "Tasa" |
TasaOCuota | float | Requerido | Indica la tasa o cuota correspondiente al impuesto que deseas agregar. Consultar el catálogo de Tasa o cuota. Ejemplo: "TasaOCuota": "0.16" |
Importe | float | Requerido | Indica el importe del impuesto trasladado que aplica a cada concepto. No se permiten valores negativos. Ejemplo: "Importe": "2400.00" |
Atributos del nodo Locales
A continuación se describen los nodos que componen los impuestos locales:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Impuesto | string | Requerido | Indica el impuesto que deseas agregar, éste puede ser CEDULAR o ISH Ejemplo: "Impuesto": "CEDULAR" |
TasaOCuota | float | Requerido | Indica el valor de la tasa o cuota del impuesto que deseas agregar. Ejemplo: "TasaOCuota": "0.05" |
Partes
Ejemplo de partes.json
"Partes":[
{
"ClaveProdServ": "43232408",
"NoIdentificacion":"WEBDEV10",
"Cantidad":"1",
"Unidad": "Unidad de servicio",
"ValorUnitario": "15000.00",
"Descripcion": "Desarrollo web a la medida"
}
]
Este nodo es opcional y se utiliza para especificar los componentes de un concepto.
Ejemplo:
Si tu concepto es un kit de herramientas, en el nodo partes puedes especificar los elementos que conforman ese kit como: martillo, desarmador, pienzas,etc.
A continuación se describen los atributos que conforman el nodo Partes:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
ClaveProdServ | string | Requerido | Indica la clave del producto o servicio correspondiente a tu concepto. Es importante que ésta la tomes del catálogo proveído por el SAT para que sea válida. Ejemplo: "ClaveProdServ": "43232408" |
NoIdentificacion | string | Opcional | Indica el número de identificación o SKU en caso de tenerlo. Ejemplo: "NoIdentificacion": "WEBDEV10" |
Cantidad | number | Requerido | Indica la cantidad. Ejemplo: 'Cantidad' : '1' |
Unidad | string | Requerido | Indica la unidad de medida. Ésta debe coincidir con la clave de la unidad ingresada en el parámetro anterior. Consulta el listado de claves válidas para el SAT. Ejemplo: "Unidad": "Unidad de servicio" |
ValorUnitario | float |
Requerido |
Indica el precio unitario sin incluir impuestos. Ejemplo: "ValorUnitario": "15000.00" |
Descripcion | string | Requerido | Indica la descripción del concepto. Ejemplo: "Descripcion": "Desarrollo web a la medida" |
CFDIs relacionados
Ejemplo de cfdi_relacionados.json
"CfdiRelacionados": {
"TipoRelacion": "01",
"UUID": [
"29c98cb2-f72a-4cbe-a297-606da335e187",
"a96f6b9a-70aa-4f2d-bc5e-d54fb7371236"
]
},
Este nodo es opcional y se utiliza para especificar los CFDIs con los que se encuentra relacionado el CFDI que se está timbrando.
Ejemplo
Si tu CFDI está sustituyendo a un CFDI timbrado y cancelado anteriormente al mismo receptor, entonces deberás indicar en este el UID y el tipo de relación que existe entre ambos.
A continuación se describen los atributos que conforman el nodo CfdiRelacionados:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
TipoRelacion | string | Requerido | Indicar la clave del tipo de relación correspondiente. Revisar el listado de claves proporcionado por el SAT. Ejemplo: "TipoRelacion": "01" |
UUID | array | Requerido | Indicar el o los UID de los CFDIS con los que se relaciona el actual. Ejemplo: "UUID": [ "29c98cb2-f72a-4cbe-a297-606da335e187", "a96f6b9a-70aa-4f2d-bc5e-d54fb7371236" ] |
Borradores
Ejemplo de borradores .json
"BorradorSiFalla": "1",
"Draft": "0"
Este nodo es opcional y se utiliza para especificar si deseamos crear un borrador de CFDI, existen 2 situaciones distintas donde podremos generar un borrador.
La primera es utilizando la bandera BorradorSiFalla con la cual trataremos de timbrar nuestro CFDI y en caso de que contenga algun error en la información enviada o configuraciones de nuestro cliente o algun problema en la configuración de nuestra empresa la información que enviamos generara un borrador el cual podremos recuperar y modificar para timbrar de nuevo nuestro comprobante despues de las correcciones necesarias
La segunda situación es con la bandera Draft la cual al estar activa utilizaremos el método para crear un CFDI pero este no intentara ser timbrado este directamente se almacena como borrador
Ejemplo de repuesta de borrador generado por error en el timbrado
{
"response": "error",
"message": {
"message": "CFDI40111 - El TipoDeComprobante no es I,E o N, y un concepto incluye el campo descuento.",
"messageDetail": "El atributo Comprobante:Descuento no es igual a la suma de los atributos Descuento registrados en los conceptos Valor Esperado: 81.47 Valor Reportado: 81.46",
"data": null,
"status": "error"
},
"xmlerror": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd\" Version=\"4.0\" Serie=\"F\" Folio=\"401\" Fecha=\"2022-04-06T10:47:27\" TipoDeComprobante=\"I\" NoCertificado=\"30001000000400002330\" Descuento=\"81.46\" FormaPago=\"01\" Exportacion=\"01\" SubTotal=\"543.10\" Moneda=\"MXN\" Total=\"73584.50\" MetodoPago=\"PUE\" LugarExpedicion=\"11111\" Sello=\"NmtzfcCp1rLhUZYFh/GmBYYtgloTo8p9cjwl4oMsmxlR7pf91CZsJq4Owb7NgTY80/UHx+xkY+AAHw4qlZVnc4qf3E/Cbc25xjr9ArEwZ5DPdT94mfnipLQ9tmNADVh9Hm5S1lRWIFX5AoQZ+whr82rZ3ukcFyOiwIRW0mthJHuK/PfSZyUFSOrj/t3G3qV/iW5FwmakK1ir8Ww+8xdkGAqBm7uPFpow/AVOJf3tvhI+z5HCIOA56pSUbWRk4L1zI9ZdpeOtpkwzLWZHrJYZ73LTOQC5/0E3wZvPHEgJDcaqfSyeZkb56JUzPYbLMBZ3YcnAUW9SV7kp1fiFj3OrVg==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" RegimenFiscal=\"621\"/><cfdi:Receptor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" DomicilioFiscalReceptor=\"88965\" RegimenFiscalReceptor=\"616\" UsoCFDI=\"P01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"30161503\" NoIdentificacion=\"AT01\" Unidad=\"Pieza\" Cantidad=\"5\" ClaveUnidad=\"H87\" Descripcion=\"PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM\" ValorUnitario=\"108.62\" Importe=\"543.100000\" Descuento=\"81.465\" ObjetoImp=\"02\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"461.635\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.8616\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"73122.86\"><cfdi:Traslados><cfdi:Traslado Base=\"543.10\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.86\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento/></cfdi:Comprobante>\n",
"draft": {
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db6101b8e7",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": null,
"NoCertificadoSAT": null,
"Version": null,
"SelloSAT": null,
"SelloCFD": null
},
"INV": {
"Serie": "F",
"Folio": 401
},
"invoice_uid": "624db6101b8e7"
}
}
Ejemplo
Si tu CFDI utiliza la bandera BorradorSiFalla y el CFDI contiene algun error lo primero que veremos en la respuesta es el error por el cual no puede ser timbrado y a continuación la confirmación del borrador generado
Ejemplo de borrador generado directamente
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db7b10b1bd",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 402
},
"invoice_uid": "624db7b10b1bd"
}
Ejemplo
Si tu CFDI utiliza la bandera Draft directamente recibiremos la respuesta del estado del borrador con la informacion correspondiente
A continuación se muestran los valores que necesitaremos si queremos generar un borrador de algun CFDIParámetro | Tipo | Requerido | Detalles |
---|---|---|---|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Crear CFDI Global 4.0
A continuación se explica la forma de crear un CFDI global 4.0, es importante tomar en cuenta que la creación de este CFDI es similar a un CFDI normal a el cual se añadiran datos como la Periodicidad y los elementos que la componen para definir el lapso de tiempo que cubre este CFDI global.
Los elementos necesarios para la creación de un CFDI global son los siguientes:
Ejemplo de bloque para CFDI global .json
"InformacionGlobal": {
"Periodicidad" : "05",
"Meses" : "14",
"Año" : "2021"
},
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
InformacionGlobal | Arreglo | Requerido | Contiene los elementos para la conformación de un CFDI global 4.0 |
Periodicidad | String | Requerido |
Se utiliza para definir el tipo de periodo que abarca el CFDI global puede contener alguno de los siguientes valores: "01", "02", "03", "04" o "05" Más delante se detalla la información de estos valores |
Meses | String | Requerido |
Indica el mes o lapso de meses el cual abarca el CFDI global y puede contener alguno de los siguientes valores: "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17" o "18" Más delante se detalla la información de estos valores |
Año | String | Requerido | Indica el año al que corresponde el CFDI global ejemplo: "2022" |
Ejemplo de creación de CFDI global
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor" : {
"UID": "6169fc02637e1"
},
"TipoDocumento":"factura",
"InformacionGlobal": {
"Periodicidad" : "05",
"Meses" : "14",
"Año" : "2021"
},
"Conceptos": [{
"ClaveProdServ": "81112101",
"Cantidad":1,
"ClaveUnidad":"E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.90,
"Descripcion": "Desarrollo a la medida",
"Impuestos":{
"Traslados":[
{
"Base": 229.90,
"Impuesto":"002",
"TipoFactor":"Tasa",
"TasaOCuota":"0.16",
"Importe":36.784
}
],
"Locales":[
{
"Base": 229.90,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: {{API-key}}',
'F-Secret-Key: {{Secret-key}}'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': '{{API-key}}',
'F-Secret-Key': '{{Secret-key}}'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"InformacionGlobal": {
"Periodicidad": "05",
"Meses": "14",
"Año": "2021"
},
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"InformacionGlobal": {
"Periodicidad": "05",
"Meses": "14",
"Año": "2021"
},
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": False
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': '{{API-key}}',
'F-Secret-Key': '{{Secret-key}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "{{API-key}}"
request["F-Secret-Key"] = "{{Secret-key}}"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"InformacionGlobal": {
"Periodicidad": "05",
"Meses": "14",
"Año": "2021"
},
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
],
"Locales": [
{
"Base": 229.9,
"Impuesto": "ISH",
"TipoFactor": "Tasa",
"TasaOCuota": "0.03",
"Importe": 6.897
}
]
}
}
],
"UsoCFDI": "P01",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
response = http.request(request)
puts response.read_body
Valor | Descripción |
---|---|
InformacionGlobal | Se utiliza como el identificador para definir un CFDI global y es el arreglo que contendrá los valores de "Periodicidad", "Meses", "Año" al utilizarlo es necesario enviar información en todos los campos que lo componen. |
Periodicidad |
Define el periodo de tiempo que abarca el CFDI global y los valores corresponden a los tipos de periodicidad: "01" - Diario "02" - Semanal "03" - Quincenal "04" - Mensual "05" - Bimestral |
Meses |
Corresponde al mes en el cual se va a generar el CFDI global y los valores corresponden a los meses como se muestra aquí: "01" - Enero "02" - Febrero "03" - Marzo "04" - Abril "05" - Mayo "06" - Junio "07" - Julio "08" - Agosto "09" - Septiembre "10" - Octubre "11" - Noviembre "12" - Diciembre Al utilizar la periodicidad "05"(Bimestral) se deben utilizar los siguientes valores con los bimestres correspondientes como se muestra a continuación: "13" - Enero - Febrero "14" - Marzo - Abril "15" - Mayo - Junio "16" - Julio - Agosto "17" - Septiembre - Octubre "18" - Noviembre - Diciembre |
Año | En este campo se ingresa el año a el cual corresponde el CFDI global en este campo se debe ingresar únicamente el año a cuatro dígitos ejemplo: "2022" |
Construcción de la URL para crear CFDI Global 4.0:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/create
Ejemplo: https://sandbox.factura.com/api/v4/cfdi40/create
Ejemplo de respuesta exitosa
{
"response": "success",
"message": "Factura creada y enviada satisfactoriamente",
"UUID": "8ff503a2-c6b7-4a25-XXX-a25610e6b488",
"uid": "5c06fa8b3bbe6",
"SAT": {
"UUID": "8ff503a2-c6b7-XXX-92c7-a25610e6b488",
"FechaTimbrado": "2018-12-04T16:07:08",
"NoCertificadoSAT": "20001000000300022323",
"Version": "1.1",
"SelloSAT": "lzlv2bEVsjx8XkiJHJvlfCjr7xJ/laxZnvSmGSKF3C/HI9WFDYFFk4NfGyILBj8ll7m1VoCqlkSLvu9dRex4jSSGfPJOPGDrx7w/4AOj/scHPU23uIPhztnaHIYHKg9UxP4L9rgX814msJ8V86IXZ1nY7akr77Cpf2c2yAnHaO1fm81oQIe32obIs2GrOey6JG9oxQNrcUawSXXXXXXXX",
"SelloCFD": "NJQH6WT8eLxAeti7pUWhB7F6C6xrdSqkFfORf3+SeGkhu+5E0cZZUQjgaSZLpPcgk01aQUf0Jayw2GewYou5MjD4OLzZnZuizPwy3cSfQXzgX6sJTtAsI00VyhQewxLYDSMqFUrPpniNQG8Nl/eEg1kx72kkmqih2KX2Z+URkhx14W7CMG2aMJnhDyZuyliF+cy3utjXwzxQMl+28A/mgnlfUXzZd/3IunTtxM/p4bpqbYinK+7Bd/n+90Z6axsFBs6N7wxUX6aK9YL58owhgVGXXXXXXXX"
},
"INV": {
"Serie": "F",
"Folio": 1433
},
"invoice_uid": "5c06fa8b3bXXX"
}
Ejemplo de respuesta de error
{
"response": "error",
"message": {
"message": "CFDI33161 - El valor del campo Importe o que corresponde a Traslado no se encuentra entre el limite inferior y superior permitido.",
"messageDetail": "Comprobante:Concepto:Impuestos:Traslado:Importe: El Importe es mayor o menor al limite superior/inferior calculado. LimiteSuperiorCalculado: 17 LimiteInferiorCalculado: 15 Comprobante:Concepto:Impuestos:Traslado:Importe: 19",
"data": null,
"status": "error"
},
"xmlerror": "\n</cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos></cfdi:Traslados></cfdi:Impuestos></cfdi:Comprobante>\n"
}
Crear borrador de CFDI 4.0
Ejemplo para crear borrador de CFDI 4.0 con bandera "borradorSiFalla"
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create"
payload = json.dumps({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
Este nodo es opcional y se utiliza para especificar si deseamos crear un borrador de CFDI, existen 2 situaciones distintas donde podremos generar un borrador.
La primera es utilizando la bandera BorradorSiFalla con la cual trataremos de timbrar nuestro CFDI y en caso de que contenga algun error en la información enviada o configuraciones de nuestro cliente o algun problema en la configuración de nuestra empresa la información que enviamos generara un borrador el cual podremos recuperar y modificar para timbrar de nuevo nuestro comprobante despues de las correcciones necesarias
Ejemplo para crear borrador de CFDI 4.0 con bandera "draft"
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create"
payload = json.dumps({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
La segunda situación es con la bandera Draft la cual al estar activa utilizaremos el método para crear un CFDI pero este no intentara ser timbrado este directamente se almacena como borrador
Ejemplo de repuesta de borrador generado por error en el timbrado
{
"response": "error",
"message": {
"message": "CFDI40111 - El TipoDeComprobante no es I,E o N, y un concepto incluye el campo descuento.",
"messageDetail": "El atributo Comprobante:Descuento no es igual a la suma de los atributos Descuento registrados en los conceptos Valor Esperado: 81.47 Valor Reportado: 81.46",
"data": null,
"status": "error"
},
"xmlerror": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd\" Version=\"4.0\" Serie=\"F\" Folio=\"401\" Fecha=\"2022-04-06T10:47:27\" TipoDeComprobante=\"I\" NoCertificado=\"30001000000400002330\" Descuento=\"81.46\" FormaPago=\"01\" Exportacion=\"01\" SubTotal=\"543.10\" Moneda=\"MXN\" Total=\"73584.50\" MetodoPago=\"PUE\" LugarExpedicion=\"11111\" Sello=\"NmtzfcCp1rLhUZYFh/GmBYYtgloTo8p9cjwl4oMsmxlR7pf91CZsJq4Owb7NgTY80/UHx+xkY+AAHw4qlZVnc4qf3E/Cbc25xjr9ArEwZ5DPdT94mfnipLQ9tmNADVh9Hm5S1lRWIFX5AoQZ+whr82rZ3ukcFyOiwIRW0mthJHuK/PfSZyUFSOrj/t3G3qV/iW5FwmakK1ir8Ww+8xdkGAqBm7uPFpow/AVOJf3tvhI+z5HCIOA56pSUbWRk4L1zI9ZdpeOtpkwzLWZHrJYZ73LTOQC5/0E3wZvPHEgJDcaqfSyeZkb56JUzPYbLMBZ3YcnAUW9SV7kp1fiFj3OrVg==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" RegimenFiscal=\"621\"/><cfdi:Receptor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" DomicilioFiscalReceptor=\"88965\" RegimenFiscalReceptor=\"616\" UsoCFDI=\"P01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"30161503\" NoIdentificacion=\"AT01\" Unidad=\"Pieza\" Cantidad=\"5\" ClaveUnidad=\"H87\" Descripcion=\"PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM\" ValorUnitario=\"108.62\" Importe=\"543.100000\" Descuento=\"81.465\" ObjetoImp=\"02\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"461.635\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.8616\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"73122.86\"><cfdi:Traslados><cfdi:Traslado Base=\"543.10\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.86\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento/></cfdi:Comprobante>\n",
"draft": {
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db6101b8e7",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": null,
"NoCertificadoSAT": null,
"Version": null,
"SelloSAT": null,
"SelloCFD": null
},
"INV": {
"Serie": "F",
"Folio": 401
},
"invoice_uid": "624db6101b8e7"
}
}
Ejemplo
Si tu CFDI utiliza la bandera BorradorSiFalla y el CFDI contiene algun error lo primero que veremos en la respuesta es el error por el cual no puede ser timbrado y a continuación la confirmación del borrador generado
Ejemplo de borrador generado directamente
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db7b10b1bd",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 402
},
"invoice_uid": "624db7b10b1bd"
}
Ejemplo
Si tu CFDI utiliza la bandera Draft directamente recibiremos la respuesta del estado del borrador con la informacion correspondiente
A continuación se muestran las banderas utilizadas en los borradoresParámetro | Tipo | Requerido | Detalles |
---|---|---|---|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Construcción de la URL para crear un borrador de CFDI 4.0:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/create
Ejemplo: https://sandbox.factura.com/api/v4/cfdi40/create
Recuperar borradores de CFDI
Ejemplo para recuperar borradores de CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POSTFIELDS =>'{
"perPage": 25,
"page": 1
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/drafts',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"perPage": 25,
"page": 1
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts"
payload = json.dumps({
"perPage": 25,
"page": 1
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"perPage": 25,
"page": 1
})
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras recuperar los borradores de CFDI este método no hace distinción entre versiones de CFDI por lo que todos seran listados
Para recuperar los borradores se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
perPage | Numerico | Requerido | Indica el numero de borradores que queremos recupear por pagina |
page | Numerico | Requerido | Se utiliza para indicar la pagina en la que queremos localizar los borradores |
Construcción de la URL para recuperar los borradores de mi cuenta:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts
Ejemplo: https://sandbox.factura.com/api/v4/drafts
Respuesta recuperar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"total": 32,
"perPage": 2,
"currentPage": 1,
"lastPage": 16,
"data": [
{
"UUID": "62478ea8b9b9e",
"Serie": "F",
"Folio": 392,
"Version": "4.0",
"draft": {
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "17317",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73122.8616"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba"
}
},
{
"UUID": "6247841ce68ed",
"Serie": "F",
"Folio": 389,
"Version": "3.3",
"draft": {
"TipoCfdi": "factura",
"Comentarios": "Prueba",
"EnviarCorreo": "1",
"Abonado": "",
"Draft": "1",
"DocumentoAbonado": {
"Cuenta": "",
"PagarTotal": "1",
"Monto": "536",
"Fecha": "",
"Estado": "",
"Referencia": "",
"Nota": ""
},
"AppOrigin": "cb958479f1f201e367aed1aa76a2022e30dde66430099d7557001bd29dddd2f0",
"Version": "4.0",
"Serie": "17317",
"Folio": "",
"Fecha": "2022/04/01",
"Sello": "",
"FormaPago": "01",
"NoCertificado": "",
"Certificado": "",
"SubTotal": "543",
"Descuento": "81.47",
"Moneda": "MXN",
"Total": "536",
"TipoDeComprobante": "",
"MetodoPago": "PUE",
"LugarExpedicion": "11111",
"LugarExpedicionId": "",
"Confirmacion": "",
"UsoCFDI": "P01",
"CfdiRelacionados": {
"UUID": []
},
"Emisor": {
"Rfc": "",
"Nombre": "",
"RegimenFiscal": ""
},
"Receptor": {
"ResidenciaFiscal": "",
"UID": "6169fc02637e1"
},
"Conceptos": [
{
"ClaveProdServ": "30161503",
"NoIdentificacion": "AT01",
"Cantidad": "5",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"ValorUnitario": "108.62",
"Importe": "543.100000",
"Descuento": "81.47",
"tipoDesc": "cantidad",
"Impuestos": {
"Traslados": [
{
"Base": "461.630000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8616"
}
],
"Retenidos": [],
"Locales": []
},
"Partes": "0",
"Complemento": "0"
}
]
}
}
]
}
Recuperar borrador de CFDI por UID
Ejemplo para recuperar borradores de CFDI por UID
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts/6245d596c1be2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/drafts/6245d596c1be2',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts/6245d596c1be2"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts/6245d596c1be2")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras recuperar los borradores de CFDI este método no hace distinción entre versiones de CFDI por lo que todos seran listados
Para recuperar un borrador por UID se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para recuperar un borrador por identificador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts/UID
Ejemplo: https://sandbox.factura.com/api/v4/drafts/UID
Respuesta recuperar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"data": {
"UUID": "6245d596c1be2",
"Serie": "F",
"Folio": 384,
"Version": "4.0",
"draft": {
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "17317",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73122.8616"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba"
}
}
}
Modificar borrador de CFDI
Ejemplo para modificar borradores de CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/create/6245d596c1be2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/create/6245d596c1be2',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/create/6245d596c1be2"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/create/6245d596c1be2")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras modificar los borradores de CFDI
La forma en la que se modifican los borradores es por medio del UID correspondiente a nuestro borrador y enviaremos el campo bandera "Draft": "1" en este caso utilizaremos el mismo folio asignado donde se encuentra nuestro borrador original y enviaremos el json con toda la información del CFDI.
Para modificar un borrador se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para modificar un borrador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/create/UID
Ejemplo: https://sandbox.factura.com/api/v4/cfdi40/create/UID
Respuesta modificar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "6245d596c1be2",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 384
},
"invoice_uid": "6245d596c1be2"
}
Timbrar borrador de CFDI
Ejemplo para timbrar borradores de CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/62683c478e319/timbrarborrador',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/62683c478e319/timbrarborrador',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/62683c478e319/timbrarborrador"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/62683c478e319/timbrarborrador")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras timbrar los borradores de CFDI, al timbrar un borrador este utiliza el mismo folio o UID que el borrador
Para timbrar un borrador se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para modificar un borrador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/UID/timbrarborrador
Ejemplo: https://sandbox.factura.com/api/v4/cfdi40/UID/timbrarborrador
Respuesta timbrar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"message": "Factura creada y enviada satisfactoriamente",
"UUID": "d72667bd-c189-4734-bfff-5b3eed9448dc",
"uid": "62683c478e319",
"SAT": {
"UUID": "d72667bd-c189-4734-bfff-5b3eed9448dc",
"FechaTimbrado": "2022-04-26T17:04:06",
"NoCertificadoSAT": "30001000000400002495",
"Version": "1.1",
"SelloSAT": "pG/AMq9sip4G70TPpflXGOdLJB5DKHz6Do0ATQemBjxLQ73YZu0vuRziyW7QeuTerXyHhscl/tPwgcDPIrjXbhqnCdUHdDqvKnRyjqWXGj38Eg37L/bNKudytKRNs6TnfOr6WlZDrojD6vVHLUvVSuvjS74S4mObdAT67XorWIe6CJVlIsP+cllKngXZ+wGxgzz/ywjtHlCinIFScbH3lS1oIXDrvNGeMFerq3I/ScmttClp+EpNoeR9G2QcDAoDeMKZtiwkxaNGsQPNDcRvn/0f81ezFlWawIncYRDsfegMj/oo1RZEMNh2Zwbh+0+IpRUWrobNrcvxh4E3wOLL0Q==",
"SelloCFD": "a0FjZ6MRPkzZh1WLffQsJMqZpbiOWB69p09Rojy1+IVhimJkKOc2XEfSKRytAuu2di77kgwaLJKpXT0Zq/VSV2pzmTr0SHDnHoHjjYLja62G5f/EXKHepjYPbHdrgPLHzjIJZvsluXZcI5PCt7u1sWl40/RsrHS+4VmWB/uD42ExXzFkG44gTbbEO3uv0Yf43ohWkGCcayIUC46U8X8hlBgrm38gB12BfygS5g32gKSAjTOZQ692jDwo2Pkl3X3mzpDyLlGS6vHKP2w3tIGrbCZheqoqAhSMVym2rnyW8nhHG+PhGldht6Wy7fcqCROHs7MiI60pACrLgYopLBqhXw=="
},
"INV": {
"Serie": "F",
"Folio": 425
},
"invoice_uid": "62683c478e319"
}
Eliminar borradores de CFDI 4.0
Ejemplo para eliminar un borrador de CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
formData: {
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop"
payload={}
files={}
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
form_data = []
request.set_form form_data, 'multipart/form-data'
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras eliminar los borradores de CFDI almacenados en tu cuenta, este método no hace distinción entre versiones de CFDI por lo que se pueden eliminar borradores para CFDI 3.3 y 4.0
Para Eliminar los borradores se utilizaran los siguientes parametros en nuestro método:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Es el identificador unico que hace referencia a el borrador el cual deseamos eliminar, se utiliza en el endpoint para la solicitud |
Construcción de la URL para eliminar un borrador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts/UID/drop
Ejemplo: https://sandbox.factura.com/api/v4/drafts/621810e1974b1/drop
Respuesta eliminar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"message": "Borrador eliminado",
"0": "extra",
"1": {
"inv_id": 53873,
"inv_uid": "62506108ebad9",
"inv_version": "4.0",
"inv_user_id": 1765,
"inv_account_id": 1832,
"inv_status": "eliminada",
"inv_folio_letra": "F-62506108ebad9",
"inv_folio_numero": 406
}
}
Descargar CFDI 4.0
Ejemplo para descargar CFDI en formato PDF
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/pdf',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Ingresa API KEY',
'F-Secret-Key: Ingresa SECRET KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/pdf',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/pdf"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/pdf")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Ingresa API KEY"
request["F-Secret-Key"] = "Ingresa SECRET KEY"
response = http.request(request)
puts response.read_body
A continuación se explica como descargar un CFDI 4.0
Cada CFDI puede ser descargado a través de nuestra API en dos tipos de archivo distintos:
- XML
Para obtener uno u otro solo es necesario cambiar el endpoint al que estamos apuntando:
- /xml
Tambien para descargar un CFDI es necesario el uso del siguiente parámetro el cual se utiliza en la construcción del enpoint para identificar el CFDI que deseamos descargar:
Ejemplo para descargar CFDI en formato XML
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/xml',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Ingresa API KEY',
'F-Secret-Key: Ingresa SECRET KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/xml',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/xml"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/xml")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Ingresa API KEY"
request["F-Secret-Key"] = "Ingresa SECRET KEY"
response = http.request(request)
puts response.read_body
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas descargar. Ejemplo: 55c0fdc67593d |
Contrucción de la URL para descargar CFDI 4.0
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
- Endpoint PDF: /api/v4/cfdi40/{cfdi_uid}/pdf
- Endpoint XML: /api/v4/cfdi40/{cfdi_uid}/xml
Ejemplo: https://api.factura.com/v4/cfdi40/55c0fdc67593d/pdf
Además de reemplazar cfdi_uid por el UID del CFDI que deseas descargar.
Cancelar CFDI 4.0
Ejemplo para cancelar CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/{cfdi_uid}/cancel',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"motivo": "01",
"folioSustituto": "3336cbb9-ebd4-45e8-b60b-e7bfa6f6b5e0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Ingresa API KEY',
'F-Secret-Key: Ingresa SECRET KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/61ba335bd48fa/cancel',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
},
body: JSON.stringify({
"motivo": "01",
"folioSustituto": "3336cbb9-ebd4-45e8-b60b-e7bfa6f6b5e0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/61ba335bd48fa/cancel"
payload = json.dumps({
"motivo": "01",
"folioSustituto": "3336cbb9-ebd4-45e8-b60b-e7bfa6f6b5e0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Ingresa API KEY',
'F-Secret-Key': 'Ingresa SECRET KEY'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/61ba335bd48fa/cancel")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Ingresa API KEY"
request["F-Secret-Key"] = "Ingresa SECRET KEY"
request.body = JSON.dump({
"motivo": "01",
"folioSustituto": "3336cbb9-ebd4-45e8-b60b-e7bfa6f6b5e0"
})
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras realizar cancelaciones de tus comprobantes con la versión de CFDI 4.0.
Para las cancelaciones en la versión 4.0 se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas cancelar. Ejemplo: 55c0fdc67593d |
motivo | string | Requerido |
Indica motivo por el cual es solicitada la cancelación del CFDI. |
folioSustituto | string | Requerido |
Indica el UID o UUID del CFDI que reemplazara el CFDI cancelado. Ejemplo: |
Clave | Motivo | Descripción | Acción |
01 | Comprobante emitido con errores con relación | Aplica cuando la factura generada contiene un error en la clave del producto, valor unitario, descuento o cualquier otro dato, por lo que se debe reexpedir. | Primero se sustituye la factura y cuando se solicita la cancelación, se incorpora el folio de la factura que sustituye a la cancelada. |
02 | Comprobante emitido con errores sin relación | Aplica cuando la factura generada contiene un error en la clave del producto, valor unitario, descuento o cualquier otro dato y no se requiera relacionar con otra factura generada. | No hay acción adicional requerida. |
03 | No se llevó a cabo la operación | Aplica cuando se facturó una operación que no se concreta. | No hay acción adicional requerida. |
04 | Operación nominativa relacionada en la factura global | Aplica cuando se incluye una venta en la factura global de operaciones con el público en general y, posterior a ello, el cliente solicita su factura nominativa; es decir, a su nombre y RFC. | Se cancela la factura global, se reexpide sin incluir la operación por la que se solicita factura. Se expide la factura nominativa. |
Construcción de la URL para cancelar CFDI 4.0:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/cfdi_uid/cancel
Ejemplo: https://api.factura.com/v4/cfdi40/55c0fdc67593d/cancel
Respuesta de cancelación para CFDI 4.0
Respuesta exitosa
{
"response": "success",
"message": "Estimado cliente tu CFDI F66(a80387be-bb02-45c4-ac33-c85ed48a49ab) se canceló exitosamente",
"respuestaapi": {
"response": "success",
"acuse": "<?xml version=\"1.0\" encoding=\"utf-8\"?><Acuse xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Fecha=\"2021-12-28T14:30:48.3934087\" RfcEmisor=\"XOJI740919U48\"><Folios xmlns=\"http://cancelacfd.sat.gob.mx\"><UUID>A80387BE-BB02-45C4-AC33-C85ED48A49AB</UUID><EstatusUUID>201</EstatusUUID></Folios><Signature Id=\"SelloSAT\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#hmac-sha512\" /><Reference URI=\"\"><Transforms><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"><XPath>not(ancestor-or-self::*[local-name()='Signature'])</XPath></Transform></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha512\" /><DigestValue>pyf1Z8DeV/R934tgx7duakRCDSK0rlY+1Ql3pfc6OMXLMJnthgDyfNY20jXzxncIsJR1JGRKjj08AcGuLM4r1Q==</DigestValue></Reference></SignedInfo><SignatureValue>vagn0h0kJ9UJf0g5+fX6s7uSUnor7+by0Uj/CdYiEba8KM6a5HO2/DxUZqw8XovbxKrVyducZpqBamLXDTrG5w==</SignatureValue><KeyInfo><KeyName>BF66E582888CC845</KeyName><KeyValue><RSAKeyValue><Modulus>n5YsGT0w5Z70ONPbqszhExfJU+KY3Bscftc2jxUn4wxpSjEUhnCuTd88OK5QbDW3Mupoc61jr83lRhUCjchFAmCigpC10rEntTfEU+7qtX8ud/jJJDB1a9lTIB6bhBN//X8IQDjhmHrfKvfen3p7RxLrFoxzWgpwKriuGI5wUlU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></Acuse>"
}
}
Te sugerimos leer cuidadosamente el mensaje del error ya que en el mismo se indica donde es necesario corregir la información.
Descargar acuse CFDI 4.0
Ejemplo para descargar acuse de cancelación CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/cfdi_uid/acuse',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/cfdi_uid/acuse',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/cfdi_uid/acuse"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/cfdi_uid/acuse")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras descargar el acuse de cancelación de tus comprobantes con la versión de CFDI 4.0.
Para descargar el acuse de cancelación en la versión 4.0 se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas cancelar. Ejemplo: 620d79fd116d9 |
Construcción de la URL para descargar el acuse de CFDI 4.0:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/cfdi_uid/acuse
Ejemplo: https://api.factura.com/v4/cfdi40/620d79fd116d9/acuse
Respuesta al descargar acuse de cancelación de CFDI 4.0
Respuesta exitosa
<?xml version="1.0" encoding="utf-8"?>
<Acuse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Fecha="2022-02-18T18:12:14.2906078" RfcEmisor="XAXX010101000">
<Folios xmlns="http://cancelacfd.sat.gob.mx">
<UUID>7C665342-65F1-46A8-ABB2-58F5909FB14A</UUID>
<EstatusUUID>201</EstatusUUID>
</Folios>
<Signature Id="SelloSAT" xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<XPath>not(ancestor-or-self::*[local-name()='Signature'])</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
<DigestValue>UdAXttKXwWcmQwY7RVvMxBs37qLT4O0ysHH+hLao+Ah96ldD+RKUZ70UR9CaksZFzfxMHMgjbgMxvaMFkcgg4A==</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>dSU5q9IXiK7xTFFOrcDC8UJUFvOXY46dsBFaoDnnD47CotH/c6IHRTnPD6bGUxA8URutCCmBg0lcxVxBAl4GCQ==</SignatureValue>
<KeyInfo>
<KeyName>BF66E582888CC845</KeyName>
<KeyValue>
<RSAKeyValue>
<Modulus>n5YsGT0w5Z70ONPbqszhExfJU+KY3Bscftc2jxUn4wxpSjEUhnCuTd88OK5QbDW3Mupoc61jr83lRhUCjchFAmCigpC10rEntTfEU+7qtX8ud/jJJDB1a9lTIB6bhBN//X8IQDjhmHrfKvfen3p7RxLrFoxzWgpwKriuGI5wUlU=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</Acuse>
Enviar CFDI 4.0
Ejemplo de enviar CFDI 4.0
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/email',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/email',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/email"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/61d4c3fe77dd8/email")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como enviar un CFDI.
Podemos enviar un CFDI haciendo uso del siguiente parámetro:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas enviar. Ejemplo: 55c0fdc67593d |
Construcción de la URL para enviar CFDI 4.0:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/cfdi_uid/email
Ejemplo: https://api.factura.com/v4/cfdi40/55c0fdc67593d/email
Respuesta de enviar CFDI 4.0
Ejemplo de envio exitoso de CFDI 4.0
{
"response": "success",
"uid": "6169fc02637e1",
"message": "Hemos enviado tu Factura con exito al e-mail's [email protected]"
}
Consultar estatus de cancelación de un CFDI 4.0
A continuación se explica como consultar el estatus de la cancelación de un CFDI con un ejemplo de como hacerlo.
Podemos consultar el estatus CFDI haciendo uso del siguiente parámetro:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UUID | string | Requerido | Indica el UID o UUID del CFDI que deseas consultar. Ejemplo: 55c0fdc67593d |
Construcción de la URL para consultar estatus de CFDI 4.0:
Ejemplo de estatus de CFDI
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.factura.com/v4/cfdi40/uid/cancel_status");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ". 'Ingresa API KEY',
"F-Secret-Key: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi40/616d946410050/cancel_status',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi40/616d946410050/cancel_status"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi40/616d946410050/cancel_status")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi40/uid/cancel_status
Ejemplo: https://api.factura.com/v4/cfdi40/c55df8b4-37b3-47cf-9e35-efdb4c3261b4/cancel_status
Ejemplo: https://api.factura.com/v4/cfdi40/c55df8b4/cancel_status
Respuesta de estatus de CFDI 4.0
Estatus vigente cancelable
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Vigente",
"EsCancelable": "Cancelable sin aceptación",
"EstatusCancelacion": []
}
}
Estatus cancelado
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Cancelado",
"EsCancelable": "Cancelable sin aceptación",
"EstatusCancelacion": "Cancelado sin aceptación"
}
}
Estatus vigente no cancelable
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Vigente",
"EsCancelable": "No Cancelable",
"EstatusCancelacion": []
}
}
CFDI 3.3
Listar CFDIs 3.3
A continuación se explica como listar los CFDI's , con un ejemplo y muestra de posibles respuestas obtenidas.
Podemos consultar los CFDI's filtrando por los siguientes parámetros:
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
month | number | Opcional | Induca el número de mes que deseas consultar. Éste debe estar escrito en 2 dígitos. Ejemplo: Enero = 01, Diciembre = 12, etc. |
year | number | Opcional | Indica el año que deseas consultar. Éste debe estar escrito en 4 dígitos. Ejemplo: 2017. |
rfc | string | Opcional | Indica un RFC para traer todos los CFDI's timbrados al mismo. Ejemplo: XAXX010101000. |
type_dpcument | string | Opcionl | Indica un tipo de CFDI para listar solo los CFDI's de ese tipo. Para ello enviar la clave indicada en el catálogo de Tipos de CFDI. Ejemplo: factura Consulta el catálogo de tipos de CFDIs. |
page | int | Opcional | Indica número de página a consultar, por default posiciona en la página 1. |
per_page | int | Opcional | Indica el limite de resultados para mostrar, por default retorna 100 registros. |
Construcción de la URL para listar CFDI 3.3
Ejemplo.
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://sandbox.factura.com/api/v3/cfdi33/list");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ".'Ingresa API KEY',
"F-Secret-Key: " .'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
return die($response);
curl_close($ch);
?>
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/list',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/list"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/list")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v3/cfdi33/list
Ejemplo: https://api.factura.com/v3/cfdi33/list
Respuestas de listar CFDIs 3.3
Ejemplo de respuesta exitosa.
{
"status": "success",
"response": "success",
"total": 2479,
"per_page": 100,
"current_page": 1,
"last_page": 25,
"from": 1,
"to": 100,
"data": [
{
"RazonSocialReceptor": "Venta Al Público en General",
"Folio": "F 01",
"UID": "5c04c662exxxx",
"UUID": "1750d757-577d-xxxx-xxxx-518b87b24a87",
"Subtotal": "5.000000",
"Descuento": null,
"Total": "5.800000",
"ReferenceClient": 0,
"NumOrder": null,
"Receptor": "XAXX010101000",
"FechaTimbrado": "2018-12-03",
"Status": "enviada",
"Version": "3.3"
},
{
"RazonSocialReceptor": "Cliente ejemplo",
"Folio": "F 160",
"UID": "5c033ca2e4xxx",
"UUID": "c25c6c99-xxx-xxx-810e-e5ae7e12eb15",
"Subtotal": "10000.000000",
"Descuento": null,
"Total": "11600.000000",
"ReferenceClient": 15,
"NumOrder": null,
"Receptor": "XAXX010101000",
"FechaTimbrado": "2018-12-01",
"Status": "enviada",
"Version": "3.3"
}
]
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$dnOV7qC7ZrD1CZitpUnTReLKtKPxG29XfwZylrEuiR0KVl18pOXXX",
"Secret": "$2y$10$6ZN4aX5UExwz6HFlDSZcxOF1TGjHx8f40neE.CrXHHahyAfi8qiXXX"
}
Buscar CFDI 3.3 por UID
Buscar CFDI 3.3 por UUID
Buscar CFDI 3.3 por Folio
Crear CFDI 3.3
A continuación se explica como crear un CFDI, con un ejemplo y muestra de posibles respuestas obtenidas.
Podemos crear un CFDI haciendo uso de los siguientes parametros:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Receptor | array | Requerido | Indica el UID del receptor/cliente previamente creado en factura.com Ver listado de atributos posibles para este nodo. Ejemplo:
|
TipoDocumento | string | Requerido | Indica la clave del tipo de documento que deseas timbrar. Ver listado de tipos de documentos. Ejemplo:
|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Conceptos | array | Requerido | Es un arreglo de objetos, en el que cada objeto corresponde a un concepto con sus atibutos para agregar al CFDI. Ver listado de atributos posibles para este nodo. Ejemplo:
|
UsoCFDI | string | Requerido | Indica la clave del Uso de CFDI, ésta debe ser válida para el SAT. Ver catálogo de claves de uso de cfdi. Ejemplo:
|
Serie | number | Requerido | Indica id de la serie con la que deseas timbrar el documento. Ésta debe estar dada de alta en tu panel de Factura.com y coincidir con el tipo de CFDI que deseas timbrar. Para obtenerlo Inicia sesión y dirígete al Menú lateral - Configuraciones - Series y folios Ejemplo:
|
FormaPago | string | Requerido | Indica la clave de la forma de pago. Ésta puedes consultarla en el Catálogo de formas de pago. Ejemplo:
|
MetodoPago | string | Requerido | Indica la clave del método de pago
Ésta puedes consultarla en el Catálogo de métodos de pago. Ejemplo:
|
CondicionesDePago | string | Opcional | Indica las condiciones de pago del CFDI, éstas deben tener una longitud minima de 1 y máxima de 1000 caracteres.
Ejemplo:
|
CfdiRelacionados | array | Opcional | En caso que tu CFDI vaya relacionado con otro(s), envía un arreglo con el/los UUID's con los que está relacionado.
Ver listado de atributos posibles para este nodo. Ejemplo:
|
Moneda | string | Requerido | Indica la clave de la moneda del CFDI.
Ésta puedes consultarla en el Catálogo de monedas Ejemplo:
|
TipoCambio | string | Opcional / Requerido en caso que el atributo Moneda sea diferente de MXN | Indicar el tipo de cambio vigente al momento de crear el CFDI. Ejemplo:
|
NumOrder | string | Opcional | Indica el número de orden o pedido. Este dato es solo para control interno. Ejemplo:
|
Fecha | string | Opcional | Indica una fecha con formato (Y-m-d\TH: m :s). Es posible enviar hasta 72 horas de atraso a la fecha actual, sin embargo no están permitidas las fechas futuras. Ejemplo:
|
Comentarios | string | Opcional | Indica si deseas que aparezcan comentarios en el PDF de tu CFDI.
Ejemplo:
|
Cuenta | string | Opcional | En caso de desearlo, indica los últimos 4 dígitos de la tarjeta o cuenta bancaria del cliente.
Ejemplo:
|
EnviarCorreo | bolean | Opcional | Indica si deseas que el CFDI se envíe a tu cliente por correo electrónico. Por default esta opción es true. Ejemplo:
|
LugarExpedicion | string | Opcional | Indica el Código postal del lugar de expedición del CFDI. Éste debe tener 5 caracteres. Ejemplo:
|
Construcción de la URL para crear CFDI 3.3
Ejemplo para crear CFDI.
<?php
for ($x = 1; $x <= 1; $x++) {
$Conceptos[] = [
'ClaveProdServ' => '81112107',
'Cantidad' => '1',
'ClaveUnidad' => 'E48',
'Unidad' => 'Unidad de servicio',
'ValorUnitario' => '100',
'Descripcion' => 'Desarrollo a la medida',
'Descuento' => '0',
'Impuestos' => [
'Traslados' => [
['Base' => '100', 'Impuesto' => '002', 'TipoFactor' => 'Tasa', 'TasaOCuota' => '0.160000', 'Importe' => '16'],
]
],
];
}
$ch = curl_init();
$fields = [
"Receptor" => ["UID" => "55c0fdc675XXX"],
"TipoDocumento" => "factura",
"UsoCFDI" => "P01",
"Redondeo" => 2,
"Conceptos" => $Conceptos,
"FormaPago" => "01",
"MetodoPago" => 'PUE',
"Moneda" => "MXN",
"CondicionesDePago" => "Pago en una sola exhibición",
"Serie" => 1,
"EnviarCorreo" => 'true',
"InvoiceComments" => ""
];
$jsonfield = json_encode($fields);
curl_setopt($ch, CURLOPT_URL, "https://sandbox.factura.com/api/v3/cfdi33/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonfield);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-API-KEY: ". 'Ingresa API KEY',
"F-SECRET-KEY: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
return die($response);
curl_close($ch);
?>
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/create"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": False
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": 36.784
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v3/cfdi33/create
Ejemplo: https://api.factura.com/v3/cfdi33/create
Ejemplo para crear cfdi exento.
<?php
for ($x = 1; $x <= 1; $x++) {
$Conceptos[] = [
'ClaveProdServ' => '81112107',
'Cantidad' => '1',
'ClaveUnidad' => 'E48',
'Unidad' => 'Unidad de servicio',
'ValorUnitario' => '100',
'Descripcion' => 'Desarrollo a la medida',
'Descuento' => '0',
'Impuestos' => [
'Traslados' => [
['Base' => '100', 'Impuesto' => '002', 'TipoFactor' => 'Exento', 'TasaOCuota' => '0.00', 'Importe' => '00'],
]
],
];
}
$ch = curl_init();
$fields = [
"Receptor" => ["UID" => "55c0fdc675XXX"],
"TipoDocumento" => "factura",
"UsoCFDI" => "P01",
"Redondeo" => 2,
"Conceptos" => $Conceptos,
"FormaPago" => "01",
"MetodoPago" => 'PUE',
"Moneda" => "MXN",
"CondicionesDePago" => "Pago en una sola exhibición",
"Serie" => 1,
"EnviarCorreo" => 'true',
"InvoiceComments" => ""
];
$jsonfield = json_encode($fields);
curl_setopt($ch, CURLOPT_URL, "https://sandbox.factura.com/api/v3/cfdi33/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonfield);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-API-KEY: ". 'Ingresa API KEY',
"F-SECRET-KEY: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
return die($response);
curl_close($ch);
?>
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/create"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": False
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"Conceptos": [
{
"ClaveProdServ": "81112101",
"Cantidad": 1,
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"ValorUnitario": 229.9,
"Descripcion": "Desarrollo a la medida",
"Impuestos": {
"Traslados": [
{
"Base": 229.9,
"Impuesto": "002",
"TipoFactor": "Exento",
"TasaOCuota": "0.00",
"Importe": 0
}
]
}
}
],
"UsoCFDI": "G03",
"Serie": 17317,
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"EnviarCorreo": false
})
response = http.request(request)
puts response.read_body
Ejemplo de respuesta exitosa
{
"response": "success",
"message": "Factura creada y enviada satisfactoriamente",
"UUID": "8ff503a2-c6b7-4a25-XXX-a25610e6b488",
"uid": "5c06fa8b3bbe6",
"SAT": {
"UUID": "8ff503a2-c6b7-XXX-92c7-a25610e6b488",
"FechaTimbrado": "2018-12-04T16:07:08",
"NoCertificadoSAT": "20001000000300022323",
"Version": "1.1",
"SelloSAT": "lzlv2bEVsjx8XkiJHJvlfCjr7xJ/laxZnvSmGSKF3C/HI9WFDYFFk4NfGyILBj8ll7m1VoCqlkSLvu9dRex4jSSGfPJOPGDrx7w/4AOj/scHPU23uIPhztnaHIYHKg9UxP4L9rgX814msJ8V86IXZ1nY7akr77Cpf2c2yAnHaO1fm81oQIe32obIs2GrOey6JG9oxQNrcUawSXXXXXXXX",
"SelloCFD": "NJQH6WT8eLxAeti7pUWhB7F6C6xrdSqkFfORf3+SeGkhu+5E0cZZUQjgaSZLpPcgk01aQUf0Jayw2GewYou5MjD4OLzZnZuizPwy3cSfQXzgX6sJTtAsI00VyhQewxLYDSMqFUrPpniNQG8Nl/eEg1kx72kkmqih2KX2Z+URkhx14W7CMG2aMJnhDyZuyliF+cy3utjXwzxQMl+28A/mgnlfUXzZd/3IunTtxM/p4bpqbYinK+7Bd/n+90Z6axsFBs6N7wxUX6aK9YL58owhgVGXXXXXXXX"
},
"INV": {
"Serie": "F",
"Folio": 1433
},
"invoice_uid": "5c06fa8b3bXXX"
}
Ejemplo de respuesta de error
{
"response": "error",
"message": {
"message": "CFDI33161 - El valor del campo Importe o que corresponde a Traslado no se encuentra entre el limite inferior y superior permitido.",
"messageDetail": "Comprobante:Concepto:Impuestos:Traslado:Importe: El Importe es mayor o menor al limite superior/inferior calculado. LimiteSuperiorCalculado: 17 LimiteInferiorCalculado: 15 Comprobante:Concepto:Impuestos:Traslado:Importe: 19",
"data": null,
"status": "error"
},
"xmlerror": "\n</cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos></cfdi:Traslados></cfdi:Impuestos></cfdi:Comprobante>\n"
}
Error al crear CFDI 3.3 con numero de orden existente
Ejemplo de error al crear CFDI numero de orden repetido
{
"response": "error",
"message": "Ya existe un CFDI con folio y serie [F-1]",
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd\" Version=\"3.3\" Serie=\"F\" Folio=\"1\" Fecha=\"2021-04-18T10:26:27\" FormaPago=\"02\" NoCertificado=\"30001000000400002330\" SubTotal=\"1635.48\" Moneda=\"MXN\" Total=\"2502.28\" TipoDeComprobante=\"I\" MetodoPago=\"PUE\" LugarExpedicion=\"45562\" Sello=\"TPFAOe/vqOpiyVRMKzO4yd5ZEG4g3RwBTTd/FfbLNvPYtmFh8Stra9gFDgXRcI43NSh6ABgz5+Tum+5KYYeoTwRF3LY7O5iww3lzSe8pJZJuBrUyONeFIzWkmdW9SIfZJdYjT6M5G2zNOxTodtk7/8kEFF0mSQZoeXZ1Z5X+jBHmxSy2sqWheuJJP92TVhstRRqwOgNGxqGoQUNebNPlWn2cAxsesc5hJkajj1D/RAkHl0eHLsdFQTf7f8yRUu5vnn3RtdVYn7zsx4uXdQE9kgGFVYv+FNrsj/chtF0GAL6D0liIFlA2fdDVgh7ulxr0eexVC5kNjV4xzKTay3IRGw==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"CRISTIAN\" RegimenFiscal=\"612\"/><cfdi:Receptor Rfc=\"XAXX010101000\" Nombre=\"General\" UsoCFDI=\"G01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"50202200\" Unidad=\"Pieza\" Cantidad=\"1.000000\" ClaveUnidad=\"H87\" Descripcion=\"producto 1\" ValorUnitario=\"1635.480000\" Importe=\"1635.480000\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"1635.480000\" Impuesto=\"003\" TipoFactor=\"Tasa\" TasaOCuota=\"0.530000\" Importe=\"866.804400\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"866.80\"><cfdi:Traslados><cfdi:Traslado Impuesto=\"003\" TipoFactor=\"Tasa\" TasaOCuota=\"0.530000\" Importe=\"866.80\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento><tfd:TimbreFiscalDigital xmlns:tfd=\"http://www.sat.gob.mx/TimbreFiscalDigital\" xsi:schemaLocation=\"http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd\" Version=\"1.1\" UUID=\"1250466f-4424-4e8a-a236-c5a714224f56\" FechaTimbrado=\"2021-04-19T11:18:15\" RfcProvCertif=\"SPR190613I52\" SelloCFD=\"TPFAOe/vqOpiyVRMKzO4yd5ZEG4g3RwBTTd/FfbLNvPYtmFh8Stra9gFDgXRcI43NSh6ABgz5+Tum+5KYYeoTwRF3LY7O5iww3lzSe8pJZJuBrUyONeFIzWkmdW9SIfZJdYjT6M5G2zNOxTodtk7/8kEFF0mSQZoeXZ1Z5X+jBHmxSy2sqWheuJJP92TVhstRRqwOgNGxqGoQUNebNPlWn2cAxsesc5hJkajj1D/RAkHl0eHLsdFQTf7f8yRUu5vnn3RtdVYn7zsx4uXdQE9kgGFVYv+FNrsj/chtF0GAL6D0liIFlA2fdDVgh7ulxr0eexVC5kNjV4xzKTay3IRGw==\" NoCertificadoSAT=\"30001000000400002495\" SelloSAT=\"VnVdqPsb7KANYN9GBDBy3F765+MAZGRuRmhXAGXBnfJ6HOcOIBZZO4wnKbruPyFXy4n+//lkcG7C6GRrTlfGV01ZJnJV3++X0E41H/ayy+j2gfCyVAxD6NX7YTBT7I9ccvSK63BRuLyhf5e3AtC4Dp+rjBrX/wldgvrXsoBGvz04pwMZZXPwJTj9TvwZn+ITtrushJFWg5ywSbhZsezd0F21TZ3ZOA00EZ3G67Iu/VSyIF91t3FRP05lbkMnsfjXP+PQe/rhghiHcRxnynLZIbdehxCVXE5WKmKWPcESScEyUA1F228IZP/u/AoYXdjowR8S4DGHR5r4c/1mPIizbw==\"/></cfdi:Complemento></cfdi:Comprobante>\n",
"uid": "607dad4789745",
"uuid": "1250466f-4424-4e8a-a236-c5a714224f56"
}
A continuación se explica un caso de error que puede ocurrir al crear un CFDI cuando utilizamos un numero de orden repetido, en nuestra plataforma existe una validación que evita que el numero o folio de orden que asignemos a nuestro CFDI sea repetido esto es para evitar crear CFDIs con los mismos identificadores que podria causar confusión, a continuacion se lista la variable de la cual depende este error.
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
NumOrder | string | Opcional | Indica el número de orden o pedido. Este dato es solo para control interno. Ejemplo:
|
Cuando este error aparece en la respuesta obtendremos el mensaje de error que indica que ya existe un CFDI con el folio o numero de orden que intentamos crear y se adjunta el XML del CFDI a el que esta asignado este numero para que podamos consultar a que CFDI asignamos previamente el numero de orden que intentamos utilizar en esta ocasión
Receptor CFDI 3.3
Ejemplo de receptor .json
"Receptor": {
"ResidenciaFIscal": "",
"UID": "55c0fdc67593d"
},
A continuación se describen los atributos que deben incluirse en el nodo Receptor
El receptor debe incluir los siguientes atributos:
Parametro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | string | Requerido | Indica el UID del receptor del CFDI. Ejemplo: "UID": "55c0fdc67593d" |
ResidenciaFiscal | string | Opcional | Indicar el número de residencia fiscal cuando el receptor del comprobante sea un residente en el extranjero. Ejemplo: "ResidenciaFiscal": "5256452" |
Conceptos CFDI 3.3
Ejemplo de conceptos .json
"Conceptos": [
{
"ClaveProdServ": "43232408",
"NoIdentificacion": "WEBDEV10",
"Cantidad": "1.000000",
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"Descripcion": "Desarrollo web a la medida",
"ValorUnitario": "15000.000000",
"Importe": "15000.000000",
"Descuento": "0",
"honorarioInverso": "",
"montoHonorario": "0",
"Impuestos": {
"Traslados": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [],
"Locales": []
},
"NumeroPedimento": "",
"Predial": "",
"Partes": "0",
"Complemento": "0"
}
],
A continuación se describen los atributos que deben incluirse en el nodo Conceptos
Para cada concepto es necesario incluir los siguientes atributos:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
ClaveProdServ | string | Requerido | Indica la clave del producto o servicio correspondiente a tu concepto. Es importante que ésta la tomes del catálogo indicado por el SAT para que sea válida. Ejemplo: "ClaveProdServ": "43232408" |
NoIdentificacion | string | Opcional | Indica el número de identificación o SKU en caso de tenerlo. Ejemplo: "NoIdentificacion": "WEBDEV10" |
Cantidad | number | Requerido | Indica la cantidad. Ejemplo: 'Cantidad' : '1' |
ClaveUnidad | string | Requerido | Indica la clave de la unidad de medida correspondiente a tu concepto. Consulta el listado de claves válidas para el SAT. Ejemplo: "ClaveUnidad": "E48" |
Unidad | string | Requerido | Indica la unidad de medida. Ésta debe coincidir con la clave de la unidad ingresada en el parámetro anterior. Consulta el listado de claves válidas para el SAT. Ejemplo: "Unidad": "Unidad de servicio" |
ValorUnitario | string | Requerido | Indica el precio unitario sin incluir impuestos. Ejemplo: "ValorUnitario": "15000.00" |
Descripcion | string | Requerido | Indica la descripción del concepto. Ejemplo: "Descripcion": "Desarrollo web a la medida" |
Descuento | string | Opcional | Indica el importe del descuento, en caso de desear agregarlo. Ejemplo: "Descuento": "10.00" |
Impuestos | array | Opcional | Indicar los impuestos (traslados, locales y retenidos) que tendrá el concepto. Consulta los parámetros que debe contener. Ejemplo: "Impuestos": { "Traslados": [ { "Base": "15000.000000", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.000000" } ], "Retenidos": [], "Locales": [] } |
NumeroPedimento | string | Opcional | Indica el número del pedimento correspondiente a la importación del bien. Ejemplo: "NumeroPedimento" : "15 48 3009 0001234" |
Predial | string | Opcional | necesario. Ejemplo: "Predial": "56485422", |
Partes | array | Opcional | Indica las partes o componentes que integran la totalidad del concepto. Ver los atributos que puede contener. |
Impuestos CFDI 3.3
Ejemplo de impuestos.json
"Impuestos": {
"Traslados": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [
{
"Base": "15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Locales": [
{
"Impuesto": "CEDULAR",
"TasaOCuota": "0.05",
}
]
},
A continuación se describen los atributos que deben incluirse en el nodo de impuestos
El nodo de impuestos se conforma de los siguientes atributos:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Traslados | array |
Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Traslado. |
Indica los impuestos trasladados que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Traslados": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.00" } ], Ejemplo Excento: "Traslados": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor":"Exento", "TasaOCuota": "0.00", "Importe": "0.00" } ], |
Retenidos | array | Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Retenciones. |
Indica los impuestos retenidos que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Retenidos": [ { "Base": "15000.00", "Impuesto": "002", "TipoFactor": "Tasa", "TasaOCuota": "0.16", "Importe": "2400.00" } ], |
Locales | array | Requerido* * Es requerido siempre y cuando la factura lleve el tipo de impuesto Locales |
Indica los impuestos locales que se aplican a tu concepto. Ver listado de atributos posibles para este nodo. Ejemplo: "Locales": [ { "Impuesto": "ISH", "TasaOCuota": "0.05", } ], |
Atributos de los nodos Traslados y Retenidos CFDI 3.3
A continuación se describen los nodos que componen cada impuesto que desees agregar a tu concepto.
Un concepto puede tener más de un traslado y más de una retención. Cada impuesto debe incluirse dentro de un objeto, que a su vez es contenido por en el arreglo del tipo de impuesto correspondiente.
Los impuestos que pueden incluirse dentro de traslados son:
- IVA
- IEPS
Los impuestos que pueden incluirse dentro de retenciones son:
- IVA
- ISR
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Base | float | Requerido | Indica el valor sobre el cual se calculará el impuesto. Ejemplo: "Base": "15000.00", |
Impuesto | string | Requerido | Indica la clave correspondiente al impuesto que deseas agregar. Consultar el catálogo de claves de Impuestos. Ejemplo: "Impuesto": "002" |
TipoFactor | string | Requerido | Indica tipo de factor correspondiente al impuesto que deseas agregar. Consultar el catálogo de Tipo factor. Ejemplo: "TipoFactor": "Tasa" |
TasaOCuota | float | Requerido | Indica la tasa o cuota correspondiente al impuesto que deseas agregar. Consultar el catálogo de Tasa o cuota. Ejemplo: "TasaOCuota": "0.16" |
Importe | float | Requerido | Indica el importe del impuesto trasladado que aplica a cada concepto. No se permiten valores negativos. Ejemplo: "Importe": "2400.00" |
Atributos del nodo Locales CFDI 3.3
A continuación se describen los nodos que componen los impuestos locales:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
Impuesto | string | Requerido | Indica el impuesto que deseas agregar, éste puede ser CEDULAR o ISH Ejemplo: "Impuesto": "CEDULAR" |
TasaOCuota | float | Requerido | Indica el valor de la tasa o cuota del impuesto que deseas agregar. Ejemplo: "TasaOCuota": "0.05" |
Partes CFDI 3.3
Ejemplo de partes.json
"Partes":[
{
"ClaveProdServ": "43232408",
"NoIdentificacion":"WEBDEV10",
"Cantidad":"1",
"Unidad": "Unidad de servicio",
"ValorUnitario": "15000.00",
"Descripcion": "Desarrollo web a la medida"
}
]
Este nodo es opcional y se utiliza para especificar los componentes de un concepto.
Ejemplo:
Si tu concepto es un kit de herramientas, en el nodo partes puedes especificar los elementos que conforman ese kit como: martillo, desarmador, pienzas,etc.
A continuación se describen los atributos que conforman el nodo Partes:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
ClaveProdServ | string | Requerido | Indica la clave del producto o servicio correspondiente a tu concepto. Es importante que ésta la tomes del catálogo proveído por el SAT para que sea válida. Ejemplo: "ClaveProdServ": "43232408" |
NoIdentificacion | string | Opcional | Indica el número de identificación o SKU en caso de tenerlo. Ejemplo: "NoIdentificacion": "WEBDEV10" |
Cantidad | number | Requerido | Indica la cantidad. Ejemplo: 'Cantidad' : '1' |
Unidad | string | Requerido | Indica la unidad de medida. Ésta debe coincidir con la clave de la unidad ingresada en el parámetro anterior. Consulta el listado de claves válidas para el SAT. Ejemplo: "Unidad": "Unidad de servicio" |
ValorUnitario | float |
Requerido |
Indica el precio unitario sin incluir impuestos. Ejemplo: "ValorUnitario": "15000.00" |
Descripcion | string | Requerido | Indica la descripción del concepto. Ejemplo: "Descripcion": "Desarrollo web a la medida" |
CFDIs relacionados CFDI 3.3
Ejemplo de cfdi_relacionados.json
"CfdiRelacionados": {
"TipoRelacion": "01",
"UUID": [
"29c98cb2-f72a-4cbe-a297-606da335e187",
"a96f6b9a-70aa-4f2d-bc5e-d54fb7371236"
]
},
Este nodo es opcional y se utiliza para especificar los CFDIs con los que se encuentra relacionado el CFDI que se está timbrando.
Ejemplo
Si tu CFDI está sustituyendo a un CFDI timbrado y cancelado anteriormente al mismo receptor, entonces deberás indicar en este el UID y el tipo de relación que existe entre ambos.
A continuación se describen los atributos que conforman el nodo CfdiRelacionados:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
TipoRelacion | string | Requerido | Indicar la clave del tipo de relación correspondiente. Revisar el listado de claves proporcionado por el SAT. Ejemplo: "TipoRelacion": "01" |
UUID | array | Requerido | Indicar el o los UID de los CFDIS con los que se relaciona el actual. Ejemplo: "UUID": [ "29c98cb2-f72a-4cbe-a297-606da335e187", "a96f6b9a-70aa-4f2d-bc5e-d54fb7371236" ] |
Borradores CFDI 3.3
Ejemplo de borradores .json
"BorradorSiFalla": "1",
"Draft": "0"
Este nodo es opcional y se utiliza para especificar si deseamos crear un borrador de CFDI, existen 2 situaciones distintas donde podremos generar un borrador.
La primera es utilizando la bandera BorradorSiFalla con la cual trataremos de timbrar nuestro CFDI y en caso de que contenga algun error en la información enviada o configuraciones de nuestro cliente o algun problema en la configuración de nuestra empresa la información que enviamos generara un borrador el cual podremos recuperar y modificar para timbrar de nuevo nuestro comprobante despues de las correcciones necesarias
La segunda situación es con la bandera Draft la cual al estar activa utilizaremos el método para crear un CFDI pero este no intentara ser timbrado este directamente se almacena como borrador
Ejemplo de repuesta de borrador generado por error en el timbrado
{
"response": "error",
"message": {
"message": "CFDI40111 - El TipoDeComprobante no es I,E o N, y un concepto incluye el campo descuento.",
"messageDetail": "El atributo Comprobante:Descuento no es igual a la suma de los atributos Descuento registrados en los conceptos Valor Esperado: 81.47 Valor Reportado: 81.46",
"data": null,
"status": "error"
},
"xmlerror": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd\" Version=\"4.0\" Serie=\"F\" Folio=\"401\" Fecha=\"2022-04-06T10:47:27\" TipoDeComprobante=\"I\" NoCertificado=\"30001000000400002330\" Descuento=\"81.46\" FormaPago=\"01\" Exportacion=\"01\" SubTotal=\"543.10\" Moneda=\"MXN\" Total=\"73584.50\" MetodoPago=\"PUE\" LugarExpedicion=\"11111\" Sello=\"NmtzfcCp1rLhUZYFh/GmBYYtgloTo8p9cjwl4oMsmxlR7pf91CZsJq4Owb7NgTY80/UHx+xkY+AAHw4qlZVnc4qf3E/Cbc25xjr9ArEwZ5DPdT94mfnipLQ9tmNADVh9Hm5S1lRWIFX5AoQZ+whr82rZ3ukcFyOiwIRW0mthJHuK/PfSZyUFSOrj/t3G3qV/iW5FwmakK1ir8Ww+8xdkGAqBm7uPFpow/AVOJf3tvhI+z5HCIOA56pSUbWRk4L1zI9ZdpeOtpkwzLWZHrJYZ73LTOQC5/0E3wZvPHEgJDcaqfSyeZkb56JUzPYbLMBZ3YcnAUW9SV7kp1fiFj3OrVg==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" RegimenFiscal=\"621\"/><cfdi:Receptor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" DomicilioFiscalReceptor=\"88965\" RegimenFiscalReceptor=\"616\" UsoCFDI=\"P01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"30161503\" NoIdentificacion=\"AT01\" Unidad=\"Pieza\" Cantidad=\"5\" ClaveUnidad=\"H87\" Descripcion=\"PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM\" ValorUnitario=\"108.62\" Importe=\"543.100000\" Descuento=\"81.465\" ObjetoImp=\"02\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"461.635\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.8616\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"73122.86\"><cfdi:Traslados><cfdi:Traslado Base=\"543.10\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.86\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento/></cfdi:Comprobante>\n",
"draft": {
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db6101b8e7",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": null,
"NoCertificadoSAT": null,
"Version": null,
"SelloSAT": null,
"SelloCFD": null
},
"INV": {
"Serie": "F",
"Folio": 401
},
"invoice_uid": "624db6101b8e7"
}
}
Ejemplo
Si tu CFDI utiliza la bandera BorradorSiFalla y el CFDI contiene algun error lo primero que veremos en la respuesta es el error por el cual no puede ser timbrado y a continuación la confirmación del borrador generado
Ejemplo de borrador generado directamente
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db7b10b1bd",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 402
},
"invoice_uid": "624db7b10b1bd"
}
Ejemplo
Si tu CFDI utiliza la bandera Draft directamente recibiremos la respuesta del estado del borrador con la informacion correspondiente
A continuación se muestran los valores que necesitaremos si queremos generar un borrador de algun CFDIParámetro | Tipo | Requerido | Detalles |
---|---|---|---|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Crear borrador de CFDI 3.3
Ejemplo para crear borrador de CFDI 3.3 con bandera "borradorSiFalla"
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi33/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/create"
payload = json.dumps({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
Este nodo es opcional y se utiliza para especificar si deseamos crear un borrador de CFDI, existen 2 situaciones distintas donde podremos generar un borrador.
La primera es utilizando la bandera BorradorSiFalla con la cual trataremos de timbrar nuestro CFDI y en caso de que contenga algun error en la información enviada o configuraciones de nuestro cliente o algun problema en la configuración de nuestra empresa la información que enviamos generara un borrador el cual podremos recuperar y modificar para timbrar de nuevo nuestro comprobante despues de las correcciones necesarias
Ejemplo para crear borrador de CFDI 3.3 con bandera "draft"
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi33/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/create"
payload = json.dumps({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "623396a68457b"
},
"TipoDocumento": "factura",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": "22",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.47",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "7254461.63",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8716"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
La segunda situación es con la bandera Draft la cual al estar activa utilizaremos el método para crear un CFDI pero este no intentara ser timbrado este directamente se almacena como borrador
Ejemplo de repuesta de borrador generado por error en el timbrado
{
"response": "error",
"message": {
"message": "CFDI40111 - El TipoDeComprobante no es I,E o N, y un concepto incluye el campo descuento.",
"messageDetail": "El atributo Comprobante:Descuento no es igual a la suma de los atributos Descuento registrados en los conceptos Valor Esperado: 81.47 Valor Reportado: 81.46",
"data": null,
"status": "error"
},
"xmlerror": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd\" Version=\"4.0\" Serie=\"F\" Folio=\"401\" Fecha=\"2022-04-06T10:47:27\" TipoDeComprobante=\"I\" NoCertificado=\"30001000000400002330\" Descuento=\"81.46\" FormaPago=\"01\" Exportacion=\"01\" SubTotal=\"543.10\" Moneda=\"MXN\" Total=\"73584.50\" MetodoPago=\"PUE\" LugarExpedicion=\"11111\" Sello=\"NmtzfcCp1rLhUZYFh/GmBYYtgloTo8p9cjwl4oMsmxlR7pf91CZsJq4Owb7NgTY80/UHx+xkY+AAHw4qlZVnc4qf3E/Cbc25xjr9ArEwZ5DPdT94mfnipLQ9tmNADVh9Hm5S1lRWIFX5AoQZ+whr82rZ3ukcFyOiwIRW0mthJHuK/PfSZyUFSOrj/t3G3qV/iW5FwmakK1ir8Ww+8xdkGAqBm7uPFpow/AVOJf3tvhI+z5HCIOA56pSUbWRk4L1zI9ZdpeOtpkwzLWZHrJYZ73LTOQC5/0E3wZvPHEgJDcaqfSyeZkb56JUzPYbLMBZ3YcnAUW9SV7kp1fiFj3OrVg==\" Certificado=\"MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMzAwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgzNzQyWhcNMjMwNTI5MTgzNzQyWjCBsTEdMBsGA1UEAxMUSU5HUklEIFhPREFSIEpJTUVORVoxHTAbBgNVBCkTFElOR1JJRCBYT0RBUiBKSU1FTkVaMR0wGwYDVQQKExRJTkdSSUQgWE9EQVIgSklNRU5FWjEWMBQGA1UELRMNWE9KSTc0MDkxOVU0ODEbMBkGA1UEBRMSWE9KSTc0MDkxOU1RVERNTjAyMR0wGwYDVQQLExRJTkRSSUQgWE9EQVIgSklNRU5FWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIo8voRABIB6aqN9pU3lJWSPo0mMx/rC5lUuN+qwTuwDfq156to9eJ5tQIy+O5YYDo8bcZFsNNm20c/xN9W5jcTCOEQw8C9Vt3YBxvW5Mn5h+v4AwveeN2UTGP/hTKx7Kh1RueULx7LzJgY80CJHONRPymjfNj+E+t77ZhiyO2JHSU/YtoKzmy69/UzAobRJ3uCI2OR5ulgIvTAYlCo1JWcWzRvzLRLnFS9jqMgzMc3z8LESddrWJH8C/CZlSkUuVvZX0QwaNoCr0BkBC1niSbtrMLUfnqmUFz5DlTIlk9xdHkWY8fJhrDF6IHRMsmSrFBDGhegMv6Uw/E7jnzK7JXMCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBADPFRl/VS//6r/+BLfhbJYAcnh448QiOnuvEXGNnhlas14+dVn0CUSSTfJBZmKH6vOteq9cEjVvGqPBM/Jxia72xQ0njFAavYaGiuVUA7DVdzljLgoVcKgY+0hdvFtV2kkY82WcYLuzbdgs5wpAjytVYWe16bqNrLH0XAV7Hh9203v6FV92/OFG4/t8iaG+WnM/0cjzYJaFL6f+ukqLxmCwE10f6/5lKp7kEYl7gTD5wJw8hHvelqgL+oZdBklG84Gk7a9vUI/Ms+VDODAs4UmAK/KybY8Q3wZ6ElF5BQ+mVqxtowCkrLvLe7NECIPwypqiiXVqn8j9nWzutGOQSvryS9cV4I6c68pHkr0ilO7QRbL9cOBEo2c8QkYLLo7ve66AG1nNxorjm2l7SG4tzkC5GpsraiF654XM/tsdit09Saj4pkG152FUAe/5+dBZFXGSC6P5JboUIF+lIDfdcbOIQ2gQIJvm2XSz811z9x7PxbWKa9bmWgth0yY8UsQKoTG/tyuAZt66trRbXcHwZbMXv7B7NGRHDrpZK6foxrLfBUrlC40syN/j4I23cRDA+nwkzdiM6D+LuxwNSsWEZ/JZ+B98iYH6cckJEACVwIQgOnDxdzaw0FdVJ7GrPhWnbuI+tUIcippIJ4lKzSAwCuA/SqyUU1S1C1Psoc2+3XmVL\"><cfdi:Emisor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" RegimenFiscal=\"621\"/><cfdi:Receptor Rfc=\"XOJI740919U48\" Nombre=\"INGRID XODAR JIMENEZ\" DomicilioFiscalReceptor=\"88965\" RegimenFiscalReceptor=\"616\" UsoCFDI=\"P01\"/><cfdi:Conceptos><cfdi:Concepto ClaveProdServ=\"30161503\" NoIdentificacion=\"AT01\" Unidad=\"Pieza\" Cantidad=\"5\" ClaveUnidad=\"H87\" Descripcion=\"PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM\" ValorUnitario=\"108.62\" Importe=\"543.100000\" Descuento=\"81.465\" ObjetoImp=\"02\"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base=\"461.635\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.8616\"/></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados=\"73122.86\"><cfdi:Traslados><cfdi:Traslado Base=\"543.10\" Impuesto=\"002\" TipoFactor=\"Tasa\" TasaOCuota=\"0.160000\" Importe=\"73122.86\"/></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento/></cfdi:Comprobante>\n",
"draft": {
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db6101b8e7",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": null,
"NoCertificadoSAT": null,
"Version": null,
"SelloSAT": null,
"SelloCFD": null
},
"INV": {
"Serie": "F",
"Folio": 401
},
"invoice_uid": "624db6101b8e7"
}
}
Ejemplo
Si tu CFDI utiliza la bandera BorradorSiFalla y el CFDI contiene algun error lo primero que veremos en la respuesta es el error por el cual no puede ser timbrado y a continuación la confirmación del borrador generado
Ejemplo de borrador generado directamente
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "624db7b10b1bd",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 402
},
"invoice_uid": "624db7b10b1bd"
}
Ejemplo
Si tu CFDI utiliza la bandera Draft directamente recibiremos la respuesta del estado del borrador con la informacion correspondiente
A continuación se muestran las banderas utilizadas en los borradoresParámetro | Tipo | Requerido | Detalles |
---|---|---|---|
BorradorSiFalla | string | Opcional | Esta bandera funciona para crear un borrador al intentar timbrar un CFDI que contenga algun error en su construcción, al estar activa crearemos un CFDI y en caso de que presente algun error que no permita el timbrado el formato con la informacion enviada generara un borrador el cual podremos recuperar para corregirlo Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpeta como falso Ejemplo: "BorradorSiFalla": "1" |
Draft | string | Opcional | Esta bandera se utiliza para generar un borrador de CFDI, al utilizarla los datos enviados seran directamente guardados en un borrador estos datos deben cumplir con las caractreisticas minimas de timbrado de CFDI para generar un borrador por lo que no s puede almacenar cualquier información Los valores admitidos son "0" para falso y "1" para verdadero, por defecto si no se envia se interpreta como falso Ejemplo: "Draft": "1" |
Construcción de la URL para crear un borrador de CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi33/create
Ejemplo: https://sandbox.factura.com/api/v4/cfdi33/create
Recuperar borradores de CFDI 3.3
Ejemplo para recuperar borradores de CFDI 3.3
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POSTFIELDS =>'{
"perPage": 25,
"page": 1
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/drafts',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"perPage": 25,
"page": 1
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts"
payload = json.dumps({
"perPage": 25,
"page": 1
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"perPage": 25,
"page": 1
})
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras recuperar los borradores de CFDI este método no hace distinción entre versiones de CFDI por lo que todos seran listados
Para las recuperar los borradores se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
perPage | Numerico | Requerido | Indica el numero de borradores que queremos recupear por pagina |
page | Numerico | Requerido | Se utiliza para indicar la pagina en la que queremos localizar los borradores |
Construcción de la URL para recuperar los borradores de mi cuenta CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts
Ejemplo: https://sandbox.factura.com/api/v4/drafts
Respuesta recuperar los borradores de CFDI 3.3
Respuesta exitosa
{
"response": "success",
"total": 32,
"perPage": 2,
"currentPage": 1,
"lastPage": 16,
"data": [
{
"UUID": "62478ea8b9b9e",
"Serie": "F",
"Folio": 392,
"Version": "4.0",
"draft": {
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "17317",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73122.8616"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba"
}
},
{
"UUID": "6247841ce68ed",
"Serie": "F",
"Folio": 389,
"Version": "3.3",
"draft": {
"TipoCfdi": "factura",
"Comentarios": "Prueba",
"EnviarCorreo": "1",
"Abonado": "",
"Draft": "1",
"DocumentoAbonado": {
"Cuenta": "",
"PagarTotal": "1",
"Monto": "536",
"Fecha": "",
"Estado": "",
"Referencia": "",
"Nota": ""
},
"AppOrigin": "cb958479f1f201e367aed1aa76a2022e30dde66430099d7557001bd29dddd2f0",
"Version": "4.0",
"Serie": "17317",
"Folio": "",
"Fecha": "2022/04/01",
"Sello": "",
"FormaPago": "01",
"NoCertificado": "",
"Certificado": "",
"SubTotal": "543",
"Descuento": "81.47",
"Moneda": "MXN",
"Total": "536",
"TipoDeComprobante": "",
"MetodoPago": "PUE",
"LugarExpedicion": "11111",
"LugarExpedicionId": "",
"Confirmacion": "",
"UsoCFDI": "P01",
"CfdiRelacionados": {
"UUID": []
},
"Emisor": {
"Rfc": "",
"Nombre": "",
"RegimenFiscal": ""
},
"Receptor": {
"ResidenciaFiscal": "",
"UID": "6169fc02637e1"
},
"Conceptos": [
{
"ClaveProdServ": "30161503",
"NoIdentificacion": "AT01",
"Cantidad": "5",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"ValorUnitario": "108.62",
"Importe": "543.100000",
"Descuento": "81.47",
"tipoDesc": "cantidad",
"Impuestos": {
"Traslados": [
{
"Base": "461.630000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73.8616"
}
],
"Retenidos": [],
"Locales": []
},
"Partes": "0",
"Complemento": "0"
}
]
}
}
]
}
Recuperar borrador de CFDI por UID CFDI 3.3
Ejemplo para recuperar borradores de CFDI por UID
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts/6245d596c1be2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/drafts/6245d596c1be2',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts/6245d596c1be2"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts/6245d596c1be2")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras recuperar los borradores de CFDI este método no hace distinción entre versiones de CFDI por lo que todos seran listados
Para las recuperar un borrador por UID se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para recuperar un borrador por identificador CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts/UID
Ejemplo: https://sandbox.factura.com/api/v4/drafts/UID
Respuesta recuperar los borradores de CFDI 3.3
Respuesta exitosa
{
"response": "success",
"data": {
"UUID": "6245d596c1be2",
"Serie": "F",
"Folio": 384,
"Version": "3.3",
"draft": {
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"BorradorSiFalla": "1",
"Serie": "17317",
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "73122.8616"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba"
}
}
}
Modificar borrador de CFDI 3.3
Ejemplo para modificar borradores de CFDI 3.3
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi33/create/6245d596c1be2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/create/6245d596c1be2',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/create/6245d596c1be2"
payload = json.dumps({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/create/6245d596c1be2")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"Receptor": {
"UID": "6169fc02637e1"
},
"TipoDocumento": "factura",
"EnviarCorreo": "1",
"Draft": "1",
"BorradorSiFalla": "1",
"Serie": 17317,
"Conceptos": [
{
"ClaveProdServ": "30161503",
"Cantidad": "5",
"Descripcion": "PANEL DE YESO LIGTH REY DE 1.22 X 2.44 12.7 MM",
"Descuento": "81.465",
"NoIdentificacion": "AT01",
"ClaveUnidad": "H87",
"Unidad": "Pieza",
"ValorUnitario": "108.62",
"Impuestos": {
"Traslados": [
{
"Base": "543.1",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "86.89"
}
]
}
}
],
"UsoCFDI": "P01",
"FormaPago": "01",
"MetodoPago": "PUE",
"Moneda": "MXN",
"Comentarios": "Prueba V3.0"
})
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras modificar los borradores de CFDI
La forma en la que se modifican los borradores es por medio del UID correspondiente a nuestro borrador y enviaremos el campo bandera "Draft": "1" en este caso utilizaremos el mismo folio asignado donde se encuentra nuestro borrador original y enviaremos el json con toda la información del CFDI.
Para modificar un borrador se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para modificar un borrador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi33/create/UID
Ejemplo: https://sandbox.factura.com/api/v4/cfdi33/create/UID
Respuesta modificar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"message": "Borrador creado satisfactoriamente",
"UUID": "sin_uuid",
"uid": "6245d596c1be2",
"SAT": {
"UUID": "sin_uuid",
"FechaTimbrado": "sin_FechaTimbrado",
"NoCertificadoSAT": "NoCertificadoSAT",
"Version": "sin_Version",
"SelloSAT": "SelloSAT",
"SelloCFD": "sin_SelloCFD"
},
"INV": {
"Serie": "F",
"Folio": 384
},
"invoice_uid": "6245d596c1be2"
}
Timbrar borrador de CFDI 3.3
Ejemplo para timbrar borradores de CFDI 3.3
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi33/62683c478e319/timbrarborrador',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/62683c478e319/timbrarborrador',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/62683c478e319/timbrarborrador"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/62683c478e319/timbrarborrador")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras timbrar los borradores de CFDI, al timbrar un borrador este utiliza el mismo folio o UID que el borrador
Para timbrar un borrador se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Indica el UID del borrador que deseamos recuperar |
Construcción de la URL para modificar un borrador:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi33/UID/timbrarborrador
Ejemplo: https://sandbox.factura.com/api/v4/cfdi33/UID/timbrarborrador
Respuesta timbrar los borradores de CFDI
Respuesta exitosa
{
"response": "success",
"message": "Factura creada y enviada satisfactoriamente",
"UUID": "d72667bd-c189-4734-bfff-5b3eed9448dc",
"uid": "62683c478e319",
"SAT": {
"UUID": "d72667bd-c189-4734-bfff-5b3eed9448dc",
"FechaTimbrado": "2022-04-26T17:04:06",
"NoCertificadoSAT": "30001000000400002495",
"Version": "1.1",
"SelloSAT": "pG/AMq9sip4G70TPpflXGOdLJB5DKHz6Do0ATQemBjxLQ73YZu0vuRziyW7QeuTerXyHhscl/tPwgcDPIrjXbhqnCdUHdDqvKnRyjqWXGj38Eg37L/bNKudytKRNs6TnfOr6WlZDrojD6vVHLUvVSuvjS74S4mObdAT67XorWIe6CJVlIsP+cllKngXZ+wGxgzz/ywjtHlCinIFScbH3lS1oIXDrvNGeMFerq3I/ScmttClp+EpNoeR9G2QcDAoDeMKZtiwkxaNGsQPNDcRvn/0f81ezFlWawIncYRDsfegMj/oo1RZEMNh2Zwbh+0+IpRUWrobNrcvxh4E3wOLL0Q==",
"SelloCFD": "a0FjZ6MRPkzZh1WLffQsJMqZpbiOWB69p09Rojy1+IVhimJkKOc2XEfSKRytAuu2di77kgwaLJKpXT0Zq/VSV2pzmTr0SHDnHoHjjYLja62G5f/EXKHepjYPbHdrgPLHzjIJZvsluXZcI5PCt7u1sWl40/RsrHS+4VmWB/uD42ExXzFkG44gTbbEO3uv0Yf43ohWkGCcayIUC46U8X8hlBgrm38gB12BfygS5g32gKSAjTOZQ692jDwo2Pkl3X3mzpDyLlGS6vHKP2w3tIGrbCZheqoqAhSMVym2rnyW8nhHG+PhGldht6Wy7fcqCROHs7MiI60pACrLgYopLBqhXw=="
},
"INV": {
"Serie": "F",
"Folio": 425
},
"invoice_uid": "62683c478e319"
}
Eliminar borradores de CFDI 3.3
Ejemplo para eliminar un borrador de CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
formData: {
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop"
payload={}
files={}
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/drafts/62506108ebad9/drop")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
form_data = []
request.set_form form_data, 'multipart/form-data'
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras eliminar los borradores de CFDI almacenados en tu cuenta, este método no hace distinción entre versiones de CFDI por lo que se pueden eliminar borradores para CFDI 3.3 y 4.0
Para las Eliminar los borradores se utilizaran los siguientes parametros en nuestro método:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido | Es el identificador unico que hace referencia a el borrador el cual deseamos eliminar |
Las variables previas se utilizan para generar un paginado en la respuesta de los borradores esto facilita la navegacion en estos borradores, si no se envia informacion para el paginado el método por default regresa los 3 ultimos borradores creados en nuestra cuenta
Construcción de la URL para eliminar un borrador CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/drafts/UID/drop
Ejemplo: https://sandbox.factura.com/api/v4/drafts/621810e1974b1/drop
Respuesta eliminar los borradores de CFDI 3.3
Respuesta exitosa
{
"response": "success",
"message": "Borrador eliminado",
"0": "extra",
"1": {
"inv_id": 53873,
"inv_uid": "62506108ebad9",
"inv_version": "4.0",
"inv_user_id": 1765,
"inv_account_id": 1832,
"inv_status": "eliminada",
"inv_folio_letra": "F-62506108ebad9",
"inv_folio_numero": 406
}
}
Descargar CFDI 3.3
A continuación se explica como descargar un CFDI.
Cada CFDI puede ser descargado a través de nuestra API en dos tipos de archivo distintos:
- XML
Para obtener uno u otro solo es necesario cambiar el endpoint al que estamos apuntando:
- /xml
Podemos descargar un CFDI haciendo uso del siguiente parámetro:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas descargar. Ejemplo: 55c0fdc67593d |
Contrucción de la URL para descargar CFDI 3.3:
Ejemplo para descargar CFDI en formato PDF
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.factura.com/v3/cfdi33/cfdi_uid/pdf");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ". 'Ingresa API KEY',
"F-Secret-Key: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
curl_close($ch);
$filename = 'F450';
header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header('Content-disposition: attachment; filename="' . $filename . '.pdf"');
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/pdf',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/pdf"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
open('/Users/user/descarga.pdf', 'wb').write(response.content)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/pdf")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint PDF: /api/v3/cfdi33/cfdi_uid/pdf
Endpoint XML: /api/v3/cfdi33/cfdi_uid/xml
Ejemplo: https://api.factura.com/v3/cfdi33/55c0fdc67593d/pdf
Ejemplo para descargar CFDI en formato XML
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.factura.com/v3/cfdi33/cfdi_uid/xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ".'Ingresa API KEY',
"F-Secret-Key: " .'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
curl_close($ch);
$filename = 'F450';
header('Content-disposition: attachment; filename="' . $filename . '.xml"');
header('Content-type: "text/xml"; charset="utf8"');
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/xml',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/xml"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
open('/Users/user/descarga.pdf', 'wb').write(response.content)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/616d991b0e1ca/xml")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
Descargar Carta Porte CFDI 3.3 sin costos
Podemos descargar la Carta Porte en su version PDF con los costos ocultos.
Esta opcion esta pensada en la seguridad de nuestros clientes para poder proporcionar un documento a los transportistas sin incluir el dato del costo de los productos.
Para descargar nuestra Carta Porte con los costos ocultos es necesario añadir el siguiente parametro al final de nuestro endpoint:
- ?hidePrices=1
Ejemplo: https://api.factura.com/v3/cfdi33/55c0fdc67593d/pdf?hidePrices=1
Cancelar CFDI 3.3
Ejemplo para cancelar CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v4/cfdi33/61cce9cf49e2e/cancel',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"motivo": "01",
"folioSustituto": "8a5c291c-9540-4c20-984c-814de68c3dca"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/61cce9cf49e2e/cancel',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"motivo": "01",
"folioSustituto": "8a5c291c-9540-4c20-984c-814de68c3dca"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/61cce9cf49e2e/cancel"
payload = json.dumps({
"motivo": "01",
"folioSustituto": "8a5c291c-9540-4c20-984c-814de68c3dca"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/61cce9cf49e2e/cancel")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"motivo": "01",
"folioSustituto": "8a5c291c-9540-4c20-984c-814de68c3dca"
})
response = http.request(request)
puts response.read_body
Documentación de cancelaciones CFDI 4.0
A continuación se explica como funciona el servicio con el cual podras realizar cancelaciones de tus comprobantes con la versión de CFDI 3.3.
Para las cancelaciones en la versión 3.3 se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas cancelar. Ejemplo: 55c0fdc67593d |
motivo | string | Requerido |
Indica motivo por el cual es solicitada la cancelación del CFDI. |
folioSustituto | string | Requerido |
Indica el UID o UUID del CFDI que reemplazara el CFDI cancelado. Ejemplo: |
Clave | Motivo | Descripción | Acción |
01 | Comprobante emitido con errores con relación | Aplica cuando la factura generada contiene un error en la clave del producto, valor unitario, descuento o cualquier otro dato, por lo que se debe reexpedir. | Primero se sustituye la factura y cuando se solicita la cancelación, se incorpora el folio de la factura que sustituye a la cancelada. |
02 | Comprobante emitido con errores sin relación | Aplica cuando la factura generada contiene un error en la clave del producto, valor unitario, descuento o cualquier otro dato y no se requiera relacionar con otra factura generada. | No hay acción adicional requerida. |
03 | No se llevó a cabo la operación | Aplica cuando se facturó una operación que no se concreta. | No hay acción adicional requerida. |
04 | Operación nominativa relacionada en la factura global | Aplica cuando se incluye una venta en la factura global de operaciones con el público en general y, posterior a ello, el cliente solicita su factura nominativa; es decir, a su nombre y RFC. | Se cancela la factura global, se reexpide sin incluir la operación por la que se solicita factura. Se expide la factura nominativa. |
Construcción de la URL para cancelar CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi33/cfdi_uid/cancel
Ejemplo: https://api.factura.com/v4/cfdi33/55c0fdc67593d/cancel
Respuesta de cancelación de CFDI 3.3
Respuesta exitosa
{
"response": "success",
"message": "Estimado cliente tu CFDI CED274(10bc80fd-2881-4559-b98f-009cc6f6d28c) se canceló exitosamente",
"respuestaapi": {
"response": "success",
"acuse": "10BC80FD-2881-4559-B98F-009CC6F6D28C<\/UUID>201<\/EstatusUUID><\/Folios>not(ancestor-or-self::*[local-name()='Signature'])<\/XPath><\/Transform><\/Transforms>5p+cQwZ7vlmQ17braGY0x5Fd8KZI65Iif0S8FKsjeOfgT5Jxv5MAjmJRqxTTSaiNerizKFr3WCq9MdmS9V2lgg==<\/DigestValue><\/Reference><\/SignedInfo>Mj7oysYQmbHCiZWMOd8bUMXHPBgPSCJxulvF4xHwM8CqSawNl7WP3F5/7GrDRGndR8covbSqNY+Qg8sP2kKL9w==<\/SignatureValue>00001088888800000031<\/KeyName>ujwIJaMKWWmawqDpHx/OS10pXzEh2SQhY02y64v9Q0+I+0dGlIrjFJeGrsHqAT3JoYnh38Dxwta98t/7++dh2hOgiZEwRignWRIlOgM1MefBHEyY+hi4vHpZgPKq/hJVfHf9nOvlb5UgIHMTCEwrDp3qk9O5XtTEycnWwiqleG0c1J9sfbRxC0gYBHsNTH85OEtSXYMkiWNYNnFbIc7B0sgp2y18jUxUCNFBMMTV0tz2sxRF+V4hblaPjI75RWmvs9E4lD7MVmW3z7LIlSajuSL8eOqoerSkQhPBABIeQenEPQwRTt3ej3XpVaBsOmagIPZZI3RvOVh+5mcXDE5txQ==<\/Modulus>AQAB<\/Exponent><\/RSAKeyValue><\/KeyValue><\/KeyInfo><\/Signature><\/Acuse>"
}
}
Te sugerimos leer cuidadosamente el mensaje del error ya que en el mismo se indica donde es necesario corregir la información.
Descargar acuse CFDI 3.3
Ejemplo para descargar acuse de cancelación CFDI
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/v3/cfdi33/cfdi_uid/acuse',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/cfdi_uid/acuse',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/cfdi_uid/acuse"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/cfdi_uid/acuse")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
A continuación se explica como funciona el servicio con el cual podras descargar el acuse de cancelación de tus comprobantes con la versión de CFDI 3.3.
Para las descargar el acuse de cancelación en la versión 3.3 se utilizaran los siguientes parametros para la creación del metodo:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas cancelar. Ejemplo: 620d79fd116d9 |
Construcción de la URL para descargar el acuse de CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v3/cfdi33/cfdi_uid/acuse
Ejemplo: https://api.factura.com/v3/cfdi33/620d79fd116d9/acuse
Respuesta al descargar acuse de cancelación de CFDI 3.3
Respuesta exitosa
<?xml version="1.0" encoding="utf-8"?>
<Acuse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Fecha="2022-02-17T17:48:15.442673" RfcEmisor="XAXX010101000">
<Folios xmlns="http://cancelacfd.sat.gob.mx">
<UUID>7514234A-2494-482E-8D8F-A4534FFCF793</UUID>
<EstatusUUID>201</EstatusUUID>
</Folios>
<Signature Id="SelloSAT" xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<XPath>not(ancestor-or-self::*[local-name()='Signature'])</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
<DigestValue>gWvERl7xL2AyuO85kwXOKtg6XlYmDUvxdeCp2qLGFIGNaCd2M0W35WRnllFwZlud33mbt2Euhm6RyheD2vGR2A==</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>sKL6tBnlSVEO0cB0IWJlvrmPXLBDeLUzGe+1Gl8veRBp0HZd88m6Xxbhvx5PviY/adPRbVx5U14PHoNqZTkNuA==</SignatureValue>
<KeyInfo>
<KeyName>BF66E582888CC845</KeyName>
<KeyValue>
<RSAKeyValue>
<Modulus>n5YsGT0w5Z70ONPbqszhExfJU+KY3Bscftc2jxUn4wxpSjEUhnCuTd88OK5QbDW3Mupoc61jr83lRhUCjchFAmCigpC10rEntTfEU+7qtX8ud/jJJDB1a9lTIB6bhBN//X8IQDjhmHrfKvfen3p7RxLrFoxzWgpwKriuGI5wUlU=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</Acuse>
Enviar CFDI 3.3
Ejemplo de enviar CFDI
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.factura.com/v3/cfdi33/cfdi_uid/email");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ". 'Ingresa API KEY',
"F-Secret-Key: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v3/cfdi33/616d946410050/email',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v3/cfdi33/616d946410050/email"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v3/cfdi33/616d946410050/email")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
A continuación se explica como enviar un CFDI.
Podemos enviar un CFDI haciendo uso del siguiente parámetro:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
cfdi_uid | string | Requerido | Indica el UID o UUID del CFDI que deseas enviar. Ejemplo: 55c0fdc67593d |
Construcción de la URL para enviar CFDI 3.3:
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v3/cfdi33/cfdi_uid/email
Ejemplo: https://api.factura.com/v3/cfdi33/55c0fdc67593d/email
Consultar estatus de cancelación de un CFDI 3.3
A continuación se explica como consultar el estatus de la cancelación de un CFDI con un ejemplo de como hacerlo.
Podemos consultar el estatus CFDI haciendo uso del siguiente parámetro:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UUID | string | Requerido | Indica el UID o UUID del CFDI que deseas consultar. Ejemplo: 55c0fdc67593d |
Construcción de la URL para consultar estatus de CFDI 3.3:
Ejemplo de estatus de CFDI
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.factura.com/v4/cfdi33/uid/cancel_status");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"F-PLUGIN: " . '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
"F-Api-Key: ". 'Ingresa API KEY',
"F-Secret-Key: " . 'Ingresa SECRET KEY'
));
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/v4/cfdi33/616d946410050/cancel_status',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/v4/cfdi33/616d946410050/cancel_status"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'API.Key',
'F-Secret-Key': 'Secret.Key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/v4/cfdi33/616d946410050/cancel_status")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "API.Key"
request["F-Secret-Key"] = "Secret.Key"
response = http.request(request)
puts response.read_body
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/v4/cfdi33/uid/cancel_status
Ejemplo: https://api.factura.com/v4/cfdi33/c55df8b4-37b3-47cf-9e35-efdb4c3261b4/cancel_status
Ejemplo: https://api.factura.com/v4/cfdi33/c55df8b4/cancel_status
Respuesta de estatus de CFDI 3.3
Estatus vigente cancelable
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Vigente",
"EsCancelable": "Cancelable sin aceptación",
"EstatusCancelacion": []
}
}
Estatus cancelado
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Cancelado",
"EsCancelable": "Cancelable sin aceptación",
"EstatusCancelacion": "Cancelado sin aceptación"
}
}
Estatus vigente no cancelable
{
"response": "success",
"data": {
"CodigoEstatus": "S - Comprobante obtenido satisfactoriamente.",
"Estado": "Vigente",
"EsCancelable": "No Cancelable",
"EstatusCancelacion": []
}
}
Grupos de empleados
Es importante tomar en cuenta que para generar una nómina primero debemos contar al menos con un grupo de empleados y un empleado de no ser asi no podremos generar nuestras nominas la estructura para generar estos componentes es la siguiente:
- Generar un grupo de empleados
- Generar empleados
- Generar nominas
Listar grupos de empleados
A continuación se explica el método con el cual podremos consultar los grupos de empleados con los que contamos
Ejemplo para listar los grupos de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/list',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/list',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/list"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/list")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Construcción de la URL para listar los grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/list
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/list
Respuestas de listar los grupos de empleados
Ejemplo de respuesta exitosa.
{
"status": "success",
"data": [
{
"nombre": "Pruebas",
"uid": "619ead8d6427a",
"inactivo": 0,
"empleados": 7
},
{
"nombre": "Recursos Humanos",
"uid": "62571cd6c6ea9",
"inactivo": 0,
"empleados": 0
},
{
"nombre": "Marketing",
"uid": "62571ce13014b",
"inactivo": 0,
"empleados": 0
}
]
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Listar grupo de empleados por UID
A continuación se explica el método con el cual podremos consultar un grupo de empleados en especifico por medio de su UID
Ejemplo para listar los grupos de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/619ead8d6427a/view',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/619ead8d6427a/view',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/619ead8d6427a/view"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/619ead8d6427a/view")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Podemos listar un grupo de empleados por su UID con los siguientes parametros
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido |
Es el identificador unico asignado a el grupo de empleados |
Construcción de la URL para listar un grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/UID/view
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/619ead8d6427a/view
Respuestas de listar un grupo de empleados por UID
Ejemplo de respuesta exitosa.
{
"status": "success",
"data": {
"nombre": "Pruebas",
"uid": "619ead8d6427a",
"inactivo": 0,
"empleados": 7
}
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Crear grupo de empleados
A continuación se explica el método con el cual podremos crear un grupo de empleados
Ejemplo para crear un nuevo grupo de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"grupo": "Recursos Humanos"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/create',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
},
body: JSON.stringify({
"grupo": "Recursos Humanos"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/create"
payload = json.dumps({
"grupo": "Recursos Humanos"
})
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/create")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
request.body = JSON.dump({
"grupo": "Recursos Humanos"
})
response = http.request(request)
puts response.read_body
Podemos crear un grupo de empleados haciendo uso de los siguientes parametros:
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
grupo | String | Requerido |
Es el nombre que asignaremos a el grupo de empleados que deseamos crear ejemplo: "Recursos Humanos", "Piso 1",......... |
Construcción de la URL para crear un nuevo grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/create
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/create
Respuestas de crear un nuevos grupo de empleados
Ejemplo de respuesta exitosa.
{
"response": "success",
"message": "Grupo creado",
"uid": "6255b96dc9bf9",
"name": "Recursos Humanos"
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Eliminar grupo de empleados
A continuación se explica el método con el cual podremos eliminar un grupo de empleados de nuestra cuenta.
Ejemplo para eliminar un grupo de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/delete',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/delete',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/delete"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/delete")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Podemos eliminar un grupo de empleados con los siguientes parametros
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido |
Es el identificador unico asignado a el grupo de empleados |
Construcción de la URL para eliminar un grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/UID/delete
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/delete
Respuestas de eliminar un grupo de empleados
Ejemplo de respuesta exitosa.
{
"response": "success",
"message": "Grupo eliminado correctamente"
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Desactivar grupo de empleados
A continuación se explica el método con el cual podremos desactivar un grupo de empleados de nuestra cuenta.
Ejemplo para desactivar un grupo de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/down',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/down',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/down"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/down")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Podemos desactivar un grupo de empleados con los siguientes parametros
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido |
Es el identificador unico asignado a el grupo de empleados |
Construcción de la URL para desactivar un grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/UID/down
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/down
Respuestas al desactivar un grupo de empleados
Ejemplo de respuesta exitosa.
{
"response": "success",
"message": "Grupo desactivado"
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Activar grupo de empleados
A continuación se explica el método con el cual podremos activar un grupo de empleados de nuestra cuenta.
Ejemplo para activar un grupo de empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/up',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/up',
'headers': {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/up"
payload = ""
headers = {
'Content-Type': 'application/json',
'F-PLUGIN': '9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key': 'Tu API key',
'F-Secret-Key': 'Tu Secret key'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/up")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-PLUGIN"] = "9d4095c8f7ed5785cb14c0e3b033eeb8252416ed"
request["F-Api-Key"] = "Tu API key"
request["F-Secret-Key"] = "Tu Secret key"
response = http.request(request)
puts response.read_body
Podemos activar un grupo de empleados con los siguientes parametros
Parámetro | Tipo | Requerido | Detalles |
---|---|---|---|
UID | String | Requerido |
Es el identificador unico asignado a el grupo de empleados |
Construcción de la URL para activar un grupo de empleados
Host: https://api.factura.com/ (producción) / https://sandbox.factura.com/ (sandbox)
Endpoint: /api/payroll/employee/group/UID/up
Ejemplo: https://sandbox.factura.com/api/payroll/employee/group/62571c9798aae/up
Respuestas al activar un grupo de empleados
Ejemplo de respuesta exitosa.
{
"response": "success",
"message": "Grupo activado"
}
Ejemplo de respuesta erronea
{
"status": "error",
"message": "La cuenta que intenta autenticarse no existe",
"Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
"Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}
Empleados
Listar empleados
A continuación se explica el método con el cual podremos consultar los empleados que tenemos registrados para nuestras nóminas
Ejemplo para listar empleados
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/list',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'F-PLUGIN: 9d4095c8f7ed5785cb14c0e3b033eeb8252416ed',
'F-Api-Key: Tu API key',
'F-Secret-Key: Tu Secret key'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var request = require('request');
var options = {
'method': 'GET',
'