Crear CFDIs mediante API Web

Ruby
PHP
Javascript
.Net >= 4.5
Java
Phyton

En un Comprobante Fiscal Digital por Internet (CFDI), recuerda que:
los datos del emisor son los que fueron cargados en la sección de perfil fiscal ver en la guía

La factura es el CFDI más común, pero hay varios de ellos.
Y cuentan con una estructura base común y de acuerdo al tipo, algunos elementos que lo forman cambian, o se agregan

URL para la petición

POST

https://api.facturama.mx/2/cfdis
    

Datos generales

Nombre que se mostrará en el PDF, tiene finalidad ilustrativa, para que rápidamente el receptor conozca a lo que se refiere el comprobante. ver en la guía
El efecto del comprobante fiscal para el contribuyente emisor: ingreso, egreso, traslado, nota de credito, pago; Representados por los valores: (I|E|T|N|P)
Dependiendo del lenguaje del SDK se tiene una enumeración que permite colocar el valor
Forma de pago (Efectivo, Tarjeta, Por definir, etc), algún valor válido del catálogo. ver en la guía
Método de pago (PUE = Una sola exhibición, PPD = Parcialidades) ver en la guía
La moneda puede ser cualquiera del catálogo, por ejemplo el peso mexicano es MXN ver en la guía
Cantidad de decimales, que se contemplarán en las operacioónes.
En el caso de que la moneda sea MXN, se toma un valor decimal de 2, sin importar que se especifique en este campo (esto es por disposición del SAT) ver en la guía
Opcional, fecha de emisión del comprobante
Nota: en el caso de que Date sea null, Facturama asignará la correspondiente a la del código postal de "ExpeditionPlace"

Lugar de expedición, es representado por un Código Postal, que pertenece a una sucursal, pero toma en cuenta que:
Opcional, se puede especificar el Folio (atributo para control interno).
Puede ser conceptualmente:
  • Numérico (de 1 a 10 caracteres): Contiene exclusivamente números,
    ejemplo: "238746"
  • Alfanumérico (de 1 a 40 caracteres) : Formado por letras y números conjuntamente, no puede contener el caracter "pipe" (|),
    ejemplo: "vLDZ-Ve1RBy_SAuej5ofCA2"
En ambos casos se colocan en éste atributo, la diferencia está en que:
Para hacer uso de las consultas de CFDI por intervalo de folios será necesario que el folio sea numérico, ya que los alfanuméricos no serán considerados.
Nota: en el caso de que el Folio sea null, Facturama asignará uno automáticamente y lo irá incrementando.

Datos generales

    "NameId": "1",          
    "CfdiType": Facturama::CfdiType::INGRESO,
    "ExpeditionPlace": "78116",
    "PaymentForm": "03",    
    "PaymentMethod": "PUE",
    "Folio": "100",
        

Datos generales

    "NameId" => "1",
    "CfdiType" => "I",      
    "ExpeditionPlace" => "78116",
    "PaymentForm" => "03",
    "PaymentMethod" => "PUE",    
    "Folio": "100",
        

Datos generales

    "NameId": "1",
    "CfdiType": "I",      
    "ExpeditionPlace": "78116",
    "PaymentForm": "03",
    "PaymentMethod": "PUE",
    "Folio": "100",
        

Datos generales

        
    cfdi.setNameId(facturama.Catalogs().NameIds().get(1).getValue());
    cfdi.setCfdiType( CfdiType.Ingreso.getValue() );    
    cfdi.setExpeditionPlace("78216");
    cfdi.setPaymentForm(facturama.Catalogs().PaymentForms().get(3).getValue());
    cfdi.setPaymentMethod("PUE");
    cfdi.setCurrency(currency.getValue());    

Datos generales

    NameId = "1",
    CfdiType = CfdiType.Ingreso,
    ExpeditionPlace = "78116",
    PaymentForm = "03",
    PaymentMethod = "PUE",
    "Folio": "100",

Datos generales

    
    "NameId": "1",
    "CfdiType": "I",
    "ExpeditionPlace": "78116",
    "PaymentForm": "03",
    "PaymentMethod": "PUE",
    "Folio": "100",

Receptor

Es a quien va dirigido el CFDI. En la estructura es representado por un nodo que se coloca en el atributo Receiver
puedes ver en la documentación de la API

Expresar la clave del uso que dará a esta factura el receptor del CFDI. ver en la guía
Nombre del cliente
Clave del Registro Federal de Contribuyentes

Datos del receptor

    "Receiver": {
            "CfdiUse": "P01",
            "Name": "Entidad receptora",
            "Rfc": "XAXX010101000"
        },
        

Datos del receptor

    "Receiver" => {
        "Name" => "Entidad receptora",
        "CfdiUse" => "P01",
        "Rfc" => "XAXX010101000"        
    },
        

Datos del receptor

    "Receiver": {
        "Name": "Entidad receptora",
        "CfdiUse": "P01",
        "Rfc": "XAXX010101000"        
    },
        

Datos del receptor

        
    Receiver  receiver = new Receiver();

    receiver.setName("Entidad receptora");
    receiver.setCfdiUse("P01");
    receiver.setRfc("XAXX010101000");    

    cfdi.setReceiver(receiver);

Datos del receptor

    Receiver = new Receiver
    {
        Name = "Entidad receptora",
        CfdiUse = "P01",
        Rfc = "XAXX010101000"        
    },

Datos del receptor

    
    "Receiver": {
            "CfdiUse": "P01",
            "Name": "Entidad receptora",
            "Rfc": "XAXX010101000"
        },

Conceptos

Son el conjunto de productos y servicio que cubre el comprobante, especificando la cantidad, montos e impuestos en cada uno de los conceptos.
En la estructura es representado por un nodo que se coloca en el atributo Items puedes ver en la documentación de la API

Descripción del concepto
Monto del descuento
Opcional, para especificar el número de serie de un producto
Clave del producto o servicio segun las claves del catalogo ver en la guía
Atributo requerido para precisar la unidad de medida aplicable al producto ver catálogo en SAT
Número de artículos del concepto, aplicables al CFDI
Conjunto de impuestos aplicables al concepto

Conceptos

    "Items": [
        {
            "Description": " API folios adicionales",
            "Discount": "10",                        
            "IdentificationNumber": "23",
            "ProductCode": "84111506",
            "Quantity": "100",
            "Subtotal": "50.00",
            "Total": "46.40",            
            "UnitCode": "E48",
            "UnitPrice": "0.50"
            "Taxes": [
                {
                    "Base": "40",
                    "IsRetention": "false",
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "6.4"
                }
            ],
            "Total": "46.40",            
            "UnitCode": "E48",
            "UnitPrice": "0.50"
        }, ...
    ]
        

Conceptos

    "Items" => [
    {
        "Quantity" => "100",
        "ProductCode" => "84111506",
        "UnitCode" => "E48",        
        "Description" => " API folios adicionales",
        "IdentificationNumber" => "23",
        "UnitPrice" => "0.50",
        "Subtotal" => "50.00",            
        "Discount" => "10",            
        "Taxes" => [
            {
                "Name" => "IVA",
                "Rate" => "0.16",
                "Total" => "6.4",
                "Base" => "40",
                "IsRetention" => "false"
            }],
        "Total" => "46.40"
    }]
        

Conceptos

    "Items": [
        {
            "Quantity": "100",
            "ProductCode": "84111506",
            "UnitCode": "E48",            
            "Description": " API folios adicionales",
            "IdentificationNumber": "23",
            "UnitPrice": "0.50",
            "Subtotal": "50.00",            
            "Discount": "10",            
            "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "6.4",
                    "Base": "40",
                    "IsRetention": "false"
                }],
            "Total": "46.40"
        }]
        

Conceptos

            
    List<Item> lstItems = new ArrayList<>();
    Item item = new Item();

    item.setProductCode("84111506");
    item.setUnitCode("E48");    
    item.setDescription(" API folios adicionales");
    item.setIdentificationNumber("23");
    item.setQuantity(100.00);
    item.setDiscount(10.00 );
    item.setUnitPrice(0.50);
    item.setSubtotal(50.00);

    List<Tax> lstTaxes = new ArrayList<>();    
    Tax tax = new Tax();

    tax.setName("IVA");
    tax.setIsQuota(false);
    tax.setIsRetention(false);
    tax.setRate( 0.160000d );
    tax.setBase( 40 );
    tax.setTotal(6.4);
    lstTaxes.add(tax);

    item.setTaxes(lstTaxes);
    item.setTotal(46.40);

    lstItems.add(item);

    cfdi.setItems(lstItems);

Conceptos

    Items = new List<Item> {
        new Item {
            Quantity = 100,
            ProductCode = "84111506",
            UnitCode = "E48",            
            Description = " API folios adicionales",
            IdentificationNumber = "23",
            UnitPrice = 0.50m,
            Subtotal = 50.00m,
            Discount = 10.00m,
            Taxes = new List<Tax> {            
                new Tax {
                    Name = "IVA",
                    Rate = 0.16m,
                    Total = 6.4m,
                    Base = 40.00m,
                    IsRetention = false
                }
            },
            Total = 46.40m
        }
    }

Conceptos

    
    "Items": [
        {
            "Quantity": "100",
            "ProductCode": "84111506",
            "UnitCode": "E48",            
            "Description": " API folios adicionales",
            "IdentificationNumber": "23",
            "UnitPrice": "0.50",
            "Subtotal": "50.00",            
            "Discount": "10",            
            "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "6.4",
                    "Base": "40",
                    "IsRetention": "false"
                }],
            "Total": "46.40"
        },
        {
            "Quantity": "1",
            "ProductCode": "84111506",
            "UnitCode": "E48",            
            "Description": " API Implementación ",
            "IdentificationNumber": "21",
            "UnitPrice": "6000.00",
            "Subtotal": "6000.00",
            "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "960",
                    "Base": "6000",
                    "IsRetention": "false"
                }],
        "Total": "6960.00"
    }]

Impuestos

Los hay de 2 tipos, Impuestos federales e Impuestos locales pero en general tienen la misma estructura. En la estructura es representado por un nodo que se coloca en el atributo Taxes de un Item puedes ver en la documentación de la API

Moto base al que se le aplica el impuesto
Especfica si es una retención
Especifica si es el impuesto es Cuota, si no se toma como Tasa
(solo se puede marcar como "true" cuando el impuesto es IEPS *El IEPS puede tener impuesto por Cuota y por Tasa)
Nombre del impuesto (IVA|ISR|IEPS|IVA RET|IVA Exento).
O en el caso de los impuestos locales, se le puede colocar el nombre que el cliente especifique
Porcentaje de impuesto
Monto total del impuesto

Impuestos

   
    "Taxes": [
        {
            "Base": "40",
            "IsRetention": "false",
            "Name": "IVA",
            "Rate": "0.16",
            "Total": "6.4"
        }, ...
    ],           
        

Impuestos

    "Taxes" => [
        {
            "Base" => "40",
            "IsRetention" => "false",
            "Name" => "IVA",
            "Rate" => "0.16",
            "Total" => "6.4"
        }, ...
    ],  
        

Impuestos

    "Taxes": [
        {
            "Base": "40",
            "IsRetention": "false",
            "Name": "IVA",
            "Rate": "0.16",
            "Total": "6.4"
        }, ...
    ],           
        

Impuestos

        
    List lstTaxes = new ArrayList<>();              
    Tax tax = new Tax();
                
    tax.setName("IVA");
    tax.setIsQuota(false);
    tax.setIsRetention(false);
    tax.setRate( 0.160000d );
    tax.setBase( 40 );
    tax.setTotal(6.4);                
    lstTaxes.add(tax);    

Impuestos

    Taxes = new List {
        new Tax {
            Name = "IVA",
            Rate = 0.16m,
            Total = 6.4m,
            Base = 40.00m,
            IsRetention = false
        }, ...
    },

Impuestos

    
    "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "6.4",
                    "Base": "40",
                    "IsRetention": "false"
                }, ...
            ]

La forma completa del ejemplo es

CFDI Factura

    cfdi = {
        "NameId": "1",          
        "PaymentForm": "03",
        "PaymentMethod": "PUE",
        "Folio": "100",
        "CfdiType": Facturama::CfdiType::INGRESO,                
        "ExpeditionPlace": "78116",
        "Receiver": {
            "CfdiUse": "P01",
            "Name": "Entidad receptora",
            "Rfc": "XAXX010101000"
        },
        "Items": [
            {
                "Description": " API folios adicionales",
                "Discount": "10",                
                "IdentificationNumber": "23",
                "ProductCode": "84111506",
                "Quantity": "100",
                "Subtotal": "50.00",
                "Taxes": [
                    {
                        "Base": "40",
                        "IsRetention": "false",
                        "Name": "IVA",
                        "Rate": "0.16",
                        "Total": "6.4"
                    }
                ],
                "Total": "46.40",                
                "UnitCode": "E48",
                "UnitPrice": "0.50"
            },
            {
                "Description": " API Implementación ",
                "IdentificationNumber": "21",
                "ProductCode": "84111506",
                "Quantity": "1",
                "Subtotal": "6000.00",
                "Taxes": [
                    {
                        "Base": "6000",
                        "IsRetention": "false",
                        "Name": "IVA",
                        "Rate": "0.16",
                        "Total": "960"
                    }
                ],
                "Total": "6960.00",                
                "UnitCode": "E48",
                "UnitPrice": "6000.00"
            }
        ]
    }


    # Creación del CFDI mediante la API
    cfdi = facturama.cfdis.create(cfdi)
        

CFDI Factura

    $cfdi = {
        "Receiver" => {
            "Name" => "Entidad receptora",
            "CfdiUse" => "P01",
            "Rfc" => "XAXX010101000"        
        },
        "CfdiType" => "I",
        "NameId" => "1",
        "ExpeditionPlace" => "78216",
        "PaymentForm" => "03",
        "PaymentMethod" => "PUE",
        "Decimals" => "2",
        "Currency" => "MXN",
        "Date" => "2018-04-16T09:51:39",
        "Items" => [
            {
                "Quantity" => "100",
                "ProductCode" => "84111506",
                "UnitCode" => "E48",
                "Unit" => "Unidad de servicio",
                "Description" => " API folios adicionales",
                "IdentificationNumber" => "23",
                "UnitPrice" => "0.50",
                "Subtotal" => "50.00",            
                "Discount" => "10",
                "DiscountVal" => "10",
                "Taxes" => [
                    {
                        "Name" => "IVA",
                        "Rate" => "0.16",
                        "Total" => "6.4",
                        "Base" => "40",
                        "IsRetention" => "false"
                    }],
                "Total" => "46.40"
            },
            {
                "Quantity" => "1",
                "ProductCode" => "84111506",
                "UnitCode" => "E48",
                "Unit" => "Unidad de servicio",
                "Description" => " API Implementación ",
                "IdentificationNumber" => "21",
                "UnitPrice" => "6000.00",
                "Subtotal" => "6000.00",
                "Taxes" => [
                    {
                        "Name" => "IVA",
                        "Rate" => "0.16",
                        "Total" => "960",
                        "Base" => "6000",
                        "IsRetention" => "false"
                    }],
                "Total" => "6960.00"
            }
        ]
    };

    $result = $facturama->post('2/cfdis', $params);
        

En este ejemplo se considera que Facturama es una instancia de Facturama API ver en la guía

CFDI Factura

    var newCfdi = {
    "Receiver": {
        "Name": "Entidad receptora",
        "CfdiUse": "P01",
        "Rfc": "XAXX010101000"        
    },
    "CfdiType": "I",
    "NameId": "1",
    "ExpeditionPlace": "78216",
    "PaymentForm": "03",
    "PaymentMethod": "PUE",    
    "Folio": "100",
    "Date": "2018-04-16T09:51:39",
    "Items": [
        {
            "Quantity": "100",
            "ProductCode": "84111506",
            "UnitCode": "E48",            
            "Description": " API folios adicionales",
            "IdentificationNumber": "23",
            "UnitPrice": "0.50",
            "Subtotal": "50.00",            
            "Discount": "10",
            "DiscountVal": "10",
            "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "6.4",
                    "Base": "40",
                    "IsRetention": "false"
                }],
            "Total": "46.40"
        },
        {
            "Quantity": "1",
            "ProductCode": "84111506",
            "UnitCode": "E48",            
            "Description": " API Implementación ",
            "IdentificationNumber": "21",
            "UnitPrice": "6000.00",
            "Subtotal": "6000.00",
            "Taxes": [
                {
                    "Name": "IVA",
                    "Rate": "0.16",
                    "Total": "960",
                    "Base": "6000",
                    "IsRetention": "false"
                }],
            "Total": "6960.00"
        }]
    };

    //llamada para la creacion
    Facturama.Cfdi.Create(newCfdi, function (result) {
        var cfdi = result;
        console.log("creacion de una factura", result);

    }, function (error) {
        if (error && error.responseJSON) {
            console.log("errores", error.responseJSON);
        }
    });
    

En este ejemplo se considera que facturama es una instancia de Facturama API ver en la guía

CFDI Factura

    
    List<Currency> lstCurrencies = facturama.Catalogs().Currencies();

    Currency currency = lstCurrencies.stream().filter(p -> p.getValue().equals("MXN")).findFirst().get();

    // Modelo de CFDI (datos de envío)
    com.Facturama.sdk_java.Models.Request.Cfdi cfdi = new com.Facturama.sdk_java.Models.Request.Cfdi();


    cfdi.setCfdiType( CfdiType.Ingreso.getValue() );
    cfdi.setNameId(facturama.Catalogs().NameIds().get(1).getValue());
    cfdi.setCfdiType( CfdiType.Ingreso.getValue() );
    cfdi.setNameId(facturama.Catalogs().NameIds().get(1).getValue());
    cfdi.setExpeditionPlace("78216");
    cfdi.setPaymentForm(facturama.Catalogs().PaymentForms().get(3).getValue());
    cfdi.setPaymentMethod("PUE");
    cfdi.setCurrency(currency.getValue());
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = new Date();
    cfdi.setDate(dateFormat.format(date));
    Receiver  receiver = new Receiver();

    receiver.setName("Entidad receptora");
    receiver.setCfdiUse("P01");
    receiver.setRfc("XAXX010101000");    

    cfdi.setReceiver(receiver);

    List<Item> lstItems = new ArrayList<>();

    
    Item item = new Item();

    item.setProductCode("84111506");
    item.setUnitCode("E48");
    item.setUnit("Unidad de servicio");
    item.setDescription(" API folios adicionales");
    item.setIdentificationNumber("23");
    item.setQuantity(100.00);
    item.setDiscount(10.00 );
    item.setUnitPrice(0.50);
    item.setSubtotal(50.00);

    List<Tax> lstTaxes = new ArrayList<>();
        
    Tax tax = new Tax();

    tax.setName("IVA");
    tax.setIsQuota(false);
    tax.setIsRetention(false);
    tax.setRate( 0.160000d );
    tax.setBase( 40 );
    tax.setTotal(6.4);
    lstTaxes.add(tax);

    item.setTaxes(lstTaxes);
    item.setTotal(46.40);

    lstItems.add(item);

    Item item2 = new Item();

    item2.setProductCode("84111506");
    item2.setUnitCode("E48");
    item2.setUnit("Unidad de servicio");
    item2.setDescription(" API Implementación");
    item2.setIdentificationNumber("21");
    item2.setQuantity(1);
    item2.setUnitPrice(6000.00);
    item2.setSubtotal(6000.00);

    List<Tax> lstTaxes2 = new ArrayList<>();
    
    Tax tax2 = new Tax();

    tax2.setName("IVA");
    tax2.setIsQuota(false);
    tax2.setIsRetention(false);
    tax2.setRate( 0.160000d );
    tax2.setBase( 6000 );
    tax2.setTotal(960);
    lstTaxes2.add(tax2);

    item2.setTaxes(lstTaxes2);
    item2.setTotal(6960);

    lstItems.add(item2);

    cfdi.setItems(lstItems);

    // Creación del CFDI mediante la API (Modelo con datos de respuesta)
    com.Facturama.sdk_java.Models.Response.Cfdi cfdiCreated = facturama.Cfdis().Create(cfdi);

En este ejemplo se considera que facturama es una instancia de Facturama API ver en la guía

CFDI Factura

    var cfdi = new Cfdi
    {
        Receiver = new Receiver
        {
            Name = "Entidad receptora",
            CfdiUse = "P01",
            Rfc = "XAXX010101000"            
        },
        CfdiType = CfdiType.Ingreso,
        NameId = "1",
        ExpeditionPlace = "78216",
        PaymentForm = "03",
        PaymentMethod = "PUE",
        Currency = "MXN",
        Items = new List<Item> {        
            new Item {
                Quantity = 100,
                ProductCode = "84111506",
                UnitCode = "E48",
                Unit = "Unidad de servicio",
                Description = " API folios adicionales",
                IdentificationNumber = "23",
                UnitPrice = 0.50m,
                Subtotal = 50.00m,
                Discount = 10.00m,
                Taxes = new List<Tax> {                        
                    new Tax {
                        Name = "IVA",
                        Rate = 0.16m,
                        Total = 6.4m,
                        Base = 40.00m,
                        IsRetention = false
                    }
                },
                Total = 46.40m
            },
            new Item {
                Quantity = 1,
                ProductCode = "84111506",
                UnitCode = "E48",
                Unit = "Unidad de servicio",
                Description = " API Implementación ",
                IdentificationNumber = "21",
                UnitPrice = 6000.00m,
                Subtotal = 6000.00m,
                Taxes = new List<Tax> {               
                    new Tax {
                        Name = "IVA",
                        Rate = 0.16m,
                        Total = 960.00m,
                        Base = 6000.00m,
                        IsRetention = false
                    }
                },
                Total = 6960.00m
            }
        }
    };

CFDI Factura

    newCfdi = {
        "Receiver": {
            "Name": "Entidad receptora",
            "CfdiUse": "P01",
            "Rfc": "XAXX010101000"            
        },
        "CfdiType": "I",
        "NameId": "1",
        "ExpeditionPlace": "78216",
        "PaymentForm": "03",
        "PaymentMethod": "PUE",
        "Folio": "100",
        "Date": "2018-04-16T09:51:39",
        "Items": [
            {
                "Quantity": "100",
                "ProductCode": "84111506",
                "UnitCode": "E48",                
                "Description": " API folios adicionales",
                "IdentificationNumber": "23",
                "UnitPrice": "0.50",
                "Subtotal": "50.00",            
                "Discount": "10",            
                "Taxes": [
                    {
                        "Name": "IVA",
                        "Rate": "0.16",
                        "Total": "6.4",
                        "Base": "40",
                        "IsRetention": "false"
                    }],
                "Total": "46.40"
            },
            {
                "Quantity": "1",
                "ProductCode": "84111506",
                "UnitCode": "E48",                
                "Description": " API Implementación ",
                "IdentificationNumber": "21",
                "UnitPrice": "6000.00",
                "Subtotal": "6000.00",
                "Taxes": [
                    {
                        "Name": "IVA",
                        "Rate": "0.16",
                        "Total": "960",
                        "Base": "6000",
                        "IsRetention": "false"
                    }],
                "Total": "6960.00"
            }]
    }
    #llamada para la creacion
    try:
        cfdi = client.Cfdi.create(newCfdi.copy())
        print "se creo factura", cfdi
    except Exception, ex:
        print "Error al crear factura", ex