php node js python ruby

Documentacion

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:

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://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:

Por ejemplo, para traer listado de facturas en el entorno de producción la url es la siguiente:

https://factura.com/api/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:

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/list

Ejemplo: https://factura.com/api/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",
            "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",
            "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",
            "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"
}

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:
"Receptor":
{
"ResidenciaFiscal": "",
"UID": "55c0fdc67593d"
}
TipoDocumento string Requerido Indica la clave del tipo de documento que deseas timbrar.

Ver listado de tipos de documentos.

Ejemplo:
"TipoDocumento": "factura"
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:
"Conceptos": [
{
"ClaveProdServ": "43232408",
"NoIdentificacion": "0021",
"Cantidad": "1.000000",
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"Descripcion": "Desarrollo web a la medida",
"ValorUnitario": "15000.000000",
"Importe":
"15000.000000",
"Descuento": "0",
"Impuestos": {
"Traslados": [
{
"Base":
"15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [],
"Locales": []
},
}
]
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:
"UsoCFDI": "G01"
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:
"Serie": 1247
FormaPago string Requerido Indica la clave de la forma de pago.

Ésta puedes consultarla en el Catálogo de formas de pago.

Ejemplo:
"FormaPago": "01"
MetodoPago string Requerido Indica la clave del método de pago

Ésta puedes consultarla en el Catálogo de métodos de pago.

Ejemplo:
"MetodoPago": "PUE",
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:
"CondicionesDePago": "Pago en 9 meses"
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:
"CfdiRelacionados": {
"TipoRelacion": "01",
"UUID": [
"29c98cb2-f72a-4cbe-a297-606da335e187",
"a96f6b9a-70aa-4f2d-bc5e-d54fb7371236"
]
}
Moneda string Requerido Indica la clave de la moneda del CFDI.

Ésta puedes consultarla en el Catálogo de monedas

Ejemplo:
"Moneda": "MXN"
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:
"TipoCambio": "19.85"
NumOrder number Opcional Indica el número de orden o pedido.

Este dato es solo para control interno.

Ejemplo:
"NumOrder": "85abf36"
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:
"Fecha": "2020-03-20\T12:53:23"
Comentarios string Opcional Indica si deseas que aparezcan comentarios en el PDF de tu CFDI.

Ejemplo:
"Comentarios": "El pedido aún no es entregado"
Cuenta string Opcional En caso de desearlo, indica los últimos 4 dígitos de la tarjeta o cuenta bancaria del cliente.

Ejemplo:
"Cuenta": "0025"
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:
"EnviarCorreo": "true"
LugarExpedicion string Opcional Indica el Código postal del lugar de expedición del CFDI.

Éste debe tener 5 caracteres.

Ejemplo:
"LugarExpedicion": "44650"

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/create

Ejemplo: https://factura.com/api/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"
}

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:

Los impuestos que pueden incluirse dentro de retenciones son:

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 CFDI
Pará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://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 borradores
Pará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://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://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://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://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://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://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:

Para obtener uno u otro solo es necesario cambiar el endpoint al que estamos apuntando:

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

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.

Ejemplo:
01

folioSustituto string Requerido

Indica el UID o UUID del CFDI que reemplazara el CFDI cancelado.

Ejemplo:
3336cbb9-ebd4-45e8-b60b-e7bfa6f6b5e0

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/cfdi_uid/cancel

Ejemplo: https://factura.com/api/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>"
    }
}




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

Acuse de cancelación CFDI 3.3

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/cfdi_uid/acuse

Ejemplo: https://factura.com/api/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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/cfdi_uid/email

Ejemplo: https://factura.com/api/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 ejemplo@mail.com"
}

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://factura.com/api/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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi40/uid/cancel_status

Ejemplo: https://factura.com/api/v4/cfdi40/c55df8b4-37b3-47cf-9e35-efdb4c3261b4/cancel_status

Ejemplo: https://factura.com/api/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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v3/cfdi33/list

Ejemplo: https://factura.com/api/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"
}

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:
"Receptor":
{
"ResidenciaFiscal": "",
"UID": "55c0fdc67593d"
}
TipoDocumento string Requerido Indica la clave del tipo de documento que deseas timbrar.

Ver listado de tipos de documentos.

Ejemplo:
"TipoDocumento": "factura"
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:
"Conceptos": [
{
"ClaveProdServ": "43232408",
"NoIdentificacion": "0021",
"Cantidad": "1.000000",
"ClaveUnidad": "E48",
"Unidad": "Unidad de servicio",
"Descripcion": "Desarrollo web a la medida",
"ValorUnitario": "15000.000000",
"Importe":
"15000.000000",
"Descuento": "0",
"Impuestos": {
"Traslados": [
{
"Base":
"15000.000000",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.16",
"Importe": "2400.000000"
}
],
"Retenidos": [],
"Locales": []
},
}
]
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:
"UsoCFDI": "G01"
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:
"Serie": 1247
FormaPago string Requerido Indica la clave de la forma de pago.

Ésta puedes consultarla en el Catálogo de formas de pago.

Ejemplo:
"FormaPago": "01"
MetodoPago string Requerido Indica la clave del método de pago

Ésta puedes consultarla en el Catálogo de métodos de pago.

Ejemplo:
"MetodoPago": "PUE",
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:
"CondicionesDePago": "Pago en 9 meses"
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:
"CfdiRelacionados": {
"TipoRelacion": "01",
"UUID": [
"29c98cb2-f72a-4cbe-a297-606da335e187",
"a96f6b9a-70aa-4f2d-bc5e-d54fb7371236"
]
}
Moneda string Requerido Indica la clave de la moneda del CFDI.

Ésta puedes consultarla en el Catálogo de monedas

Ejemplo:
"Moneda": "MXN"
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:
"TipoCambio": "19.85"
NumOrder number Opcional Indica el número de orden o pedido.

Este dato es solo para control interno.

Ejemplo:
"NumOrder": "85abf36"
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:
"Fecha": "2020-03-20\T12:53:23"
Comentarios string Opcional Indica si deseas que aparezcan comentarios en el PDF de tu CFDI.

Ejemplo:
"Comentarios": "El pedido aún no es entregado"
Cuenta string Opcional En caso de desearlo, indica los últimos 4 dígitos de la tarjeta o cuenta bancaria del cliente.

Ejemplo:
"Cuenta": "0025"
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:
"EnviarCorreo": "true"
LugarExpedicion string Opcional Indica el Código postal del lugar de expedición del CFDI.

Éste debe tener 5 caracteres.

Ejemplo:
"LugarExpedicion": "44650"

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v3/cfdi33/create

Ejemplo: https://factura.com/api/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"
}

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:

Los impuestos que pueden incluirse dentro de retenciones son:

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 CFDI
Pará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 borradores
Pará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://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://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://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://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://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://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:

Para obtener uno u otro solo es necesario cambiar el endpoint al que estamos apuntando:

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://factura.com/api/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://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://factura.com/api/v3/cfdi33/55c0fdc67593d/pdf

Ejemplo para descargar CFDI en formato XML

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://factura.com/api/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:

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.

Ejemplo:
01

folioSustituto string Requerido

Indica el UID o UUID del CFDI que reemplazara el CFDI cancelado.

Ejemplo:
8a5c291c-9540-4c20-984c-814de68c3dca

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi33/cfdi_uid/cancel

Ejemplo: https://factura.com/api/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>"
   }
}




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

Acuse de cancelación CFDI 4.0

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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v3/cfdi33/cfdi_uid/acuse

Ejemplo: https://factura.com/api/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://factura.com/api/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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v3/cfdi33/cfdi_uid/email

Ejemplo: https://factura.com/api/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://factura.com/api/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://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/v4/cfdi33/uid/cancel_status

Ejemplo: https://factura.com/api/v4/cfdi33/c55df8b4-37b3-47cf-9e35-efdb4c3261b4/cancel_status

Ejemplo: https://factura.com/api/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:

  1. Generar un grupo de empleados
  2. Generar empleados
  3. 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://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://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://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://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://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://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',
  'url': 'https://sandbox.factura.com/api/payroll/employee/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/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/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 empleados

Host: https://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/payroll/employee/list

Ejemplo: https://sandbox.factura.com/api/payroll/employee/list

Respuestas de listar los empleados

Ejemplo de respuesta exitosa.

{
    "status": "success",
    "data": [
        {
            "uid": "619eb06d2390b",
            "nombre": "Pruebas salarios asimilados",
            "paterno": "Apellido1",
            "materno": "Apellido2",
            "puesto": "Pruebas",
            "departamento": "Pruebas",
            "inicio": null,
            "salario": null,
            "metodo_pago": "03",
            "periodo_pago": "04",
            "banco": "002",
            "clabe": "000000000000000000",
            "numero_empleado": "2",
            "patronal": null,
            "riesgo": null,
            "regimen": "09",
            "email": "knocker060@gmail.com",
            "curp": "QUPL861121HJCNRS05",
            "imss": null,
            "rfc": "XAXX010101000",
            "calle": "Calle Prueba",
            "colonia": "Circunvalación Guevara",
            "numero_interior": 0,
            "numero_exterior": 1,
            "codigopostal": 44680,
            "localidad": "Guadalajara",
            "municipio": "Guadalajara",
            "estado": "Jalisco"
        },
        {
            "uid": "61c4b569c0baf",
            "nombre": "XOCHILT",
            "paterno": "CASAS",
            "materno": "CHAVEZ",
            "puesto": "Empleado 1 pruebas",
            "departamento": "Puebas",
            "inicio": "2021-12-01",
            "salario": "500.0000",
            "metodo_pago": "03",
            "periodo_pago": "04",
            "banco": "012",
            "clabe": "000000000000000000",
            "numero_empleado": "01",
            "patronal": "01293846471873",
            "riesgo": 99,
            "regimen": "02",
            "email": "luis@factura.com",
            "curp": "CACX760510MNEXXXA8",
            "imss": "123456789098765",
            "rfc": "CACX7605101P8",
            "calle": "Calle Prueba",
            "colonia": "Santa Teresa",
            "numero_interior": 0,
            "numero_exterior": 1,
            "codigopostal": 10740,
            "localidad": "Guadalajara",
            "municipio": "La Magdalena Contreras",
            "estado": "Jalisco"
        }
    ]
}

Ejemplo de respuesta erronea

{
    "status": "error",
    "message": "La cuenta que intenta autenticarse no existe",
    "Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
    "Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}

Listar empleados por UID

A continuación se explica el método con el cual podremos consultar un empleado en especifico por medio de su UID

Ejemplo para listar los empleados

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/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/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/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/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 consultar un empleado por su UID con los siguientes parametros

Parámetro Tipo Requerido Detalles
UID String Requerido

Es el identificador unico asignado a cada empleado en nuestra cuenta

Construcción de la URL para listar un empleado

Host: https://factura.com (producción) / https://sandbox.factura.com (sandbox)

Endpoint: /api/payroll/employee/UID/view

Ejemplo: https://sandbox.factura.com/api/payroll/employee/619ead8d6427a/view

Respuestas de consultar un empleado por UID

Ejemplo de respuesta exitosa.

{
    "status": "success",
    "data": {
        "uid": "61c4b569c0baf",
        "nombre": "XOCHILT",
        "paterno": "CASAS",
        "materno": "CHAVEZ",
        "puesto": "Empleado 1 pruebas",
        "departamento": "Puebas",
        "inicio": "2021-12-01",
        "salario": "500.0000",
        "metodo_pago": "03",
        "periodo_pago": "04",
        "banco": "012",
        "clabe": "000000000000000000",
        "numero_empleado": "01",
        "patronal": "01293846471873",
        "riesgo": 99,
        "regimen": "02",
        "email": "pruebas@factura.com",
        "curp": "CACX760510MNEXXXA8",
        "imss": "123456789098765",
        "rfc": "CACX7605101P8",
        "calle": "Calle Prueba",
        "colonia": "Santa Teresa",
        "numero_interior": 0,
        "numero_exterior": 1,
        "codigopostal": 10740,
        "localidad": "Guadalajara",
        "municipio": "La Magdalena Contreras",
        "estado": "Jalisco"
    }
}

Ejemplo de respuesta erronea

{
    "status": "error",
    "message": "La cuenta que intenta autenticarse no existe",
    "Data": "$2y$10$8a9S8o8WeiRhPh1YT6bnXun6uPs1ZdiZBUHjGwSqn3X44mbYSmY4.",
    "Secret": "$2y$10$c5KNUW06w8r9OhH4MVPNz.BgpQfjHVZjPPYsVbX13WPQZomnYtxq"
}

Crear empleado

A continuación se explica el método con el cual podremos crear un empleado

Como crear un grupo de empleados

Ejemplo para crear un nuevo empleado

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://sandbox.factura.com/api/payroll/employee/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": "619ead8d6427a",
    "noempleado": 10,
    "nombre": "NombrePrueba",
    "paterno": "ApellidoPrueba1",
    "materno": "ApellidoPrueba2",
    "metodopago": "01",
    "periodo": "01",
    "regimen": "02",
    "puesto": "Contador",
    "departamento": "Contaduría",
    "curp": "ZDSM130545HJFMNG09",
    "imss": "04242412413",
    "rfc": "ZDSM130541886",
    "calle": "Av Independencia",
    "colonia": "Ladron de guevara",
    "noext": 12413,
    "cp": 44680,
    "municipio": "Guadalajara",
    "estado": "Jalisco",
    "tipo_contrato": "1",
    "asimilados": "0",
    "sindicalizado":"no",
    "entidad_emite": "JAL",
    "banco": "006",
    "clabe": "0000000000000000000",
    "no_int": "12-A",
    "localidad": "Guadalajara",
    "email": "pruebas@factura.com",
    "tipo_jornada": "01",
    "patronal": "IJDX73431JFI",
    "cuota_diaria": 120.00,
    "salario": 12000,
    "riesgo":"1",
    "inicio": "2021-12-02"
}',
  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/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": "619ead8d6427a",
    "noempleado": 10,
    "nombre": "NombrePrueba",
    "paterno": "ApellidoPrueba1",
    "materno": "ApellidoPrueba2",
    "metodopago": "01",
    "periodo": "01",
    "regimen": "02",
    "puesto": "Contador",
    "departamento": "Contaduría",
    "curp": "ZDSM130545HJFMNG09",
    "imss