Async invoicing
When the size of your invoices is very large, or you need to invoice many invoices at the same time, it is advisable (and in some cases required) to use asynchronous invoicing. This allows you to register an invoice in Facturapi and receive an immediate response with the Invoice object and its ID, but without stamping yet. The stamping of the invoice is done in the background, and you can check the status of the invoice at any time using the get invoice method.
Automatic recovery after a temporary error
When creating an invoice synchronously, the SAT or the certification provider may return a temporary error after stamping the CFDI. When Facturapi detects one of these cases, it preserves the invoice with status: "pending" and responds with HTTP 202 Accepted instead of returning a definitive error. This response means that the request was accepted, but processing has not finished yet.
Facturapi will automatically try to recover the CFDI up to 5 times, with a 10-minute interval between attempts. The attempts occur approximately 10, 20, 30, 40, and 50 minutes after the initial response.
- If Facturapi recovers the CFDI, the invoice changes to
status: "valid", its UUID and stamp are saved, and theinvoice.status_updatedwebhook is sent. - If it cannot be recovered after the fifth attempt, the invoice changes to
status: "failed"and no further attempts are made.
While the invoice remains pending, do not create it again or assign its folio to another document. You can check its state using the get invoice method or subscribe to the invoice.status_updated webhook.
Create an asynchronous invoice
An invoice will be created asynchronously in either of these 2 cases:
- If the
asyncparameter is sent with the valuetruewhen creating the invoice. - If the size of the information sent exceeds 2MB (CFDIs with around 5,000 items or with a very extensive Carta Porte complement).
In either case, you will receive the invoice object as a response, with the status field in pending. This means that the invoice is being processed in the background. While this is happening, it is important
to note that the stamp and uuid fields will be null. Once the invoice is stamped, the status field will change to valid and the stamp and uuid fields will be filled with the stamping information.
Request
- Node.js
- C#
- PHP
- cURL
const invoice = await facturapi.invoices.create({
customer: {
legal_name: 'Dunder Mifflin',
email: 'email@example.com',
tax_id: 'ABC101010111',
tax_system: '601',
address: {
zip: '85900'
}
},
items: [{
quantity: 2,
product: {
description: 'Ukelele',
product_key: '60131324', // ClaveProdServ del SAT
price: 345.60,
taxes: [
{
type: 'IVA',
rate: 0.16
}
]
}
}],
use: 'G01',
payment_form: "28" // "Debit card"
}, { async: true });
var invoice = await facturapi.Invoice.CreateAsync(new Dictionary<string, object>
{
["customer"] = new Dictionary<string, object>
{
["legal_name"] = "Dunder Mifflin",
["email"] = "email@example.com",
["tax_id"] = "ABC101010111",
["tax_system"] = "601",
["address"] = new Dictionary<string, object>
{
["zip"] = "85900"
},
},
["items"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["quantity"] = 2,
["product"] = new Dictionary<string, object>
{
["description"] = "Ukelele",
["product_key"] = "60131324",
["price"] = 345.60,
["taxes"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["type"] = "IVA",
["rate"] = 0.16
}
}
}
}
},
["use"] = "G01",
["payment_form"] = "28" // "Debit card"
}, new Dictionary<string, object>
{
["async"] = true
});
$invoice = $facturapi->Invoices->create([
"customer" => [
"legal_name" => "Dunder Mifflin",
"email" => "email@example.com",
"tax_id" => "ABC101010111",
"tax_system" => "601",
"address" => [
"zip" => "85900"
]
],
"items" => [
[
"quantity" => 2,
"product" => [
"description" => "Ukelele",
"product_key" => "60131324",
"price" => 345.60,
"taxes" => [
[
"type" => "IVA",
"rate" => 0.16
]
]
]
]
],
"use" => "G01",
"payment_form" => "28" // "Debit card"
], [
"async" => true
]);
curl https://www.facturapi.io/v2/invoices \
-H "
Authorization Bearer sk_test_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"legal_name": "Dunder Mifflin",
"email": "email@example.com",
"tax_id": "ABC101010111",
"tax_system": "601",
"address": {
"zip": "85900"
}
},
"items": [
{
"quantity": 2,
"product": {
"description": "Ukelele",
"product_key": "60131324",
"price": 345.60,
"taxes": [
{
"type": "IVA",
"rate": 0.16
}
]
}
}
],
"use": "G01",
"payment_form": "28" // "Debit card"
}'
Response
{
"id": "5f4b1b4b4b4b4b4b4b4b4b4a",
"created_at": "2020-08-29T00:00:00.000Z",
"status": "pending",
"customer": {
"id": "5f4b1b4b4b4b4b4b4b4b4b4b",
"legal_name": "Dunder Mifflin",
"email": "email@example.com",
"tax_id": "ABC101010111",
"tax_system": "601",
"address": {
"country": "MEX",
"zip": "85900"
}
},
"items": [
{
"quantity": 2,
"product": {
"description": "Ukelele",
"product_key": "60131324",
"price": 345.60,
"taxes": [
{
"type": "IVA",
"rate": 0.16
}
]
}
}
],
"use": "G01",
"payment_form": "28",
"stamp": null,
"uuid": null
}