Reading Invoices
How to interpret invoice data returned by the API and compute income correctly from it.
Invoices in BDI come from CFDIs (Comprobantes Fiscales Digitales) reported to the SAT. The same record can mean very different things depending on its type and on which side of the transaction the subject sits. This page explains how to read them and how to compute monthly income.
Invoice types
Each invoice has a type field. The type determines whether the amount counts as income, and for which party.
| Code | Counts as income? | For whom |
|---|---|---|
nomina | Yes | The rfc_receiver (the employee being paid) |
ingreso | Yes | The rfc_issuer (the party selling goods/services) |
egreso | No, it is a correction | Reduces a previously issued ingreso from the same RFC |
pago | No, it is a collection complement | Documents the actual payment of a previously issued ingreso |
Perspective: rfc_issuer vs rfc_receiver
rfc_issuer vs rfc_receiverThe same invoice means different things depending on which side of the transaction the subject is on. When querying by CURP or RFC, always check which field the subject appears in:
- A
nominawhere the subject isrfc_receivermeans the subject received a salary. - An
ingresowhere the subject isrfc_issuermeans the subject received an income. - An
ingresowhere the subject isrfc_receivermeans the subject bought goods or services.
Computing monthly income
Monthly income for an identifier is the sum of two components:
- Salary income: sum of
amountfornominainvoices whererfc_receiveris the subject. - Self-employment income: sum of
amountforingresoinvoices issued by the subject, minus the sum ofamountforegresoinvoices issued against thoseingresos by the same RFC.
monthly_income =
Σ nomina.amount (subject as receiver)
+ Σ ingreso.amount (subject as issuer)
− Σ egreso.amount (subject as issuer)
This formula applies to both individuals and businesses. For businesses, salary income is typically zero — they receive income through ingreso invoices, not nomina.
pago invoices: how to read them
pago invoices: how to read thempago invoices are SAT's "Recibo Electrónico de Pago" — a complement issued when a customer pays an invoice that was originally issued under deferred or installment payment terms (PPD). The pago CFDI itself does not represent new revenue; it documents a payment against a previously-issued invoice.
Because of this, per SAT spec the top-level amount, subtotal, total_taxes_transferred, and total_taxes_retained on a pago CFDI are zero or near zero. The actual payment value (amount paid, payment date, payment method) lives in a separate node called "Complemento de Pagos," which is not exposed in the default /invoices response.
To retrieve payment details, pass include_payment_info=true on the request. Each invoice will include a payment_info[] array of payment records, and each entry contains a nested payment_relations[] array linking that specific payment to the ingreso invoices it was applied to.
Use this when:
- Validating whether PPD invoices have been paid.
- Measuring payment behavior (timeliness, partial payments).
- Reconciling invoiced revenue against cash collected in a given period.
incomes and deductions arrays
incomes and deductions arraysFor nomina invoices, the response includes incomes and deductions arrays with the line-item breakdown (Percepciones and Deducciones in SAT terminology). Each item has amount, currency, and a free-form detail label (e.g., Sueldo, Aguinaldo, ISR, IMSS).
For ingreso, egreso, and pago invoices, both arrays are returned empty. The SAT structure for these types is based on line items ("Conceptos") and tax breakdowns, not Percepciones/Deducciones.
Common pitfalls
- Summing
pagoas income → double-counting.pagodocuments a payment, not new revenue. - Treating
egresoas a generic expense → understates income.egresois a correction to a previously issuedingreso, not an arbitrary debit. - Ignoring perspective: a
nominawhere the subject isrfc_issueris not received salary — the subject paid it. - Treating self-issued CFDIs (subject on both sides) as non-income → they are income.
- Expecting
incomes/deductionsoningresoorpagoinvoices → those fields are nómina-specific. - Aggregating across mixed currencies without normalizing (
currencyfield).
Field reference
For the full invoice field list (per identifier type), see:
- Individual Data — invoice fields returned for an individual CURP.
- Business Data — invoice fields returned for a business RFC.
Updated 8 days ago
