sales
The v2 sale is the same as v1 (same fields, point of sale, cost centers, and document types) with three differences: it accepts a currency (currency_code, exchange_rate), it requires tax_ids per line, and it validates taxes in strict mode. Its errors carry a code; see API v2: what changes.
Fields not described here (
observation, is_credit, credit_days, point_of_sale_id, cost_center_id, project_id, etc.) are the ones from Create sale in v1. The GET /sales listing remains v1 only.Create sale
0.128 (1 GTQ = 0.128 USD).
New or different fields from v1
200 response
The remaining response fields (
sale_id, generation_code, control_number, etc.) are those from v1.
A document in base currency responds the same way, with the base currency as currency_code, rate "1.00000000", and foreign_total null:
Taxes by id
In v2 each line declares the taxes that apply to it withtax_ids, and the document totals them in totals.taxes and totals.withholdings. Before transmitting the DTE, the server validates and recalculates the taxes:
- Each id must exist, be active, belong to the branch’s country, and have the correct effect (those in
tax_idsandtaxesadd; those inwithholdingswithhold). - The sum of the declared amounts must match
totalTax,totalRetein, andtotalRent. - In strict mode (always on in v2), if
totalTax,totalRetein, ortotalRentdiffer from what the server calculates by more than 0.02, the sale is rejected and nothing is transmitted. This includes the 1 % VAT withholding and income tax when the customer’s rules require them (for example, a large taxpayer with taxed sales of 100 or more).
totalRent with its amount and a row in withholdings with the income tax’s tax_id. Taxed sales of 300.00 with VAT of 39.00 and 10 % income tax (30.00) pay 309.00.
tax_invalid error
tax_invalid, errors is a list; each element carries field, message, a detail code, and, when applicable, tax_id. The field names are the document’s internal ones (invoiceResumenDetail.*, invoiceProductsDetail.tax_ids).
If a
tax_ids value is not a UUID, the response is validation_error (not tax_invalid).
Validation scope: the server does not compare the declared amount of fixed-per-unit taxes (for example FOVIAL and COTRANS) against quantity × catalog value; it validates percentage-based taxes (VAT), withholdings, and income tax. Also, a sale with no value in
tax_ids, totals.taxes, or totals.withholdings is treated as legacy and is not validated. In foreign currency, fixed-tax amounts are sent in the document’s currency.Currency errors
They are validated before issuing; no error saves or transmits the document.Get sale
totals and products are in base currency; the total in the document’s currency is in foreign_total.
404 with { "status": false, "message": "..." }.
Payment methods: use the id
Each payment_details line identifies its payment method with payment_method_id, the id returned by GET /countries/{code} in payment_methods[]. The code ("01") is not unique: another country may use the same code for a different method, and within a country there can be repeated methods.
If the payment method does not exist, is not from the country, or both the
id and the code are missing, the sale is rejected with 422 and code: "payment_method_invalid" (in errors, the field payment_details.N.payment_method_id). Previously an unknown code left the sale without that payment, with no warning.
Let FileXpress calculate the totals
Instead of declaring every amount, you can send only the lines and FileXpress calculates each line’s amounts, the taxes, the withholdings, and the total to pay. It is the recommended mode for new integrations: there can be no difference of cents between your system and ours. When it activates: whentotals does not include saleTotalToPayment. If you send it, the mode above is used (you declare and we validate).
What you send per line
totals can include only freight and insurance. If the customer qualifies (for example, a large taxpayer or a public institution), the 1 % withholding is applied automatically.
data.calculated_totals:
- Everything is calculated with exact decimals and rounded only once per total, rounding half up (
0.115→0.12). - The taxed amount is the sum of
quantity × price × (1 − discount)without rounding per line, rounded at the end; exempt and not-subject amounts are rounded per line. - Each percentage-based tax is the sum of each line’s taxed amount times its rate, rounded at the end. Fixed-per-unit taxes (FOVIAL, COTRANS) are
quantity × catalog value. - In foreign currency the amounts are in the document’s currency; the catalog’s fixed taxes (in base currency) are expressed in it by dividing them by the rate.
- The amounts we return never have more decimals than the currency.