Skip to main content

Accounts Payable

When a supplier sends you an invoice or credit note over the network, GoRoute delivers it to your accounting system as a draft bill, exactly as the supplier sent it, with the supplier's PDF and the original XML attached. Your accountant takes it from there. If your bill was delivered into Odoo before 21 September 2026, read the caution below first โ€” those two attachments may not open.

GoRoute is the mailman, not the accountant. It makes no accounting decisions: it chooses no account, applies no tax, creates no contacts, and never posts, validates or pays anything.

What arrives in Odooโ€‹

Bills delivered before 21 September 2026 into Odoo 18 or earlier: open the PDF before you trust it

The quickest test is to click the attached PDF on the draft bill. If it opens as an invoice, none of this applies to you. If it opens as a wall of unreadable characters, it is affected, and the rest of this box tells you what happened and where to get the real file.

What went wrong. Between 8 August and 21 September 2026, every file GoRoute attached to a draft bill in Odoo 18 or earlier was stored as the file's own base64 text rather than as the file. Both attachments are present and neither opens โ€” a 27,900-byte PDF arrives as a 37,200-byte text file. Odoo 19 was never affected.

And the note could be bare. Over the same period, if GoRoute signs in to your Odoo as a user without Administration / Settings rights โ€” which is the sensible setting for an integration user โ€” the bill's note kept only its summary line, Peppol invoice received: INV-7, and lost the supplier's name, VAT number, Peppol ID, address and stated totals. The two faults compound: when the vendor could not be matched automatically and the note is bare, the only record of who the supplier is was inside the attached files, which are the files that do not open.

Both are fixed, for new deliveries. The product fix for each shipped on 21 September 2026 and reached the production service the same day. Bills delivered after that carry openable files and a note that names the supplier whatever rights the Odoo user has.

Bills already delivered are not repaired. Redelivering the document with POST /api/v1/inbound-documents/{id}/redeliver will not replace an attachment or rewrite a note that GoRoute has already recorded as delivered. That is the "Delivered once" rule below working as designed, and it means an affected bill stays affected.

How to get the correct file. Fetch it from GoRoute instead of from Odoo, with GET /api/v1/inbound-documents/{id}/files/{kind} โ€” see API below. Those bytes are served straight from the stored document and never passed through the Odoo connector, so the PDF and the XML you download there are correct, and the supplier's identity is in them. You can then attach the downloaded file to the bill yourself.

Where the supplier's details are and are not. The bill's own Internal Notes field carries the supplier's stated totals, the reason the vendor was left blank, and the GoRoute document id โ€” but it has never carried the supplier's name, VAT number, Peppol ID or address. Do not rely on it to identify the supplier.

The Odoo 18 and Odoo 19 behaviour above was measured against a real Odoo 18.0 and a real saas~19.4 by the engineer who wrote the fix, and is recorded with it. It is not our own measurement and this page does not present it as one.

For every received invoice, one draft vendor bill (a draft refund for a credit note):

On the billWhere it comes from
Bill reference, bill date, due date, currencythe supplier's invoice
Each line's description, quantity and unit pricethe supplier's invoice, as stated
Document-level charges and allowancestheir own lines
Account on each lineyour Purchases journal's default account โ€” GoRoute sets none
Taxes on each linenone โ€” see below
Vendoryour contact with the same Peppol ID or VAT, if there is exactly one
Payment referencethe reference the supplier asks you to quote when you pay, into Odoo's Payment Reference field (payment_reference), and also into the note
Your purchase orderyour own PO number, where the supplier quoted it, into Odoo's Source Document field (invoice_origin) โ€” and repeated in the note, because Odoo 18 and 19 do not show that field on a vendor bill
Supplier's payment detailsin the note: how they ask to be paid, their bank account, the account name, the BIC, the payment reference and the payment terms โ€” each one only if the supplier sent it. Read the bank account caution below before you pay
Notea summary line โ€” Peppol invoice received: <number> โ€” then the supplier's name, VAT, Peppol ID, address and stated totals, verbatim, plus your PO number and the payment details above. On a bill delivered before 21 September 2026 the summary line may be all there is; see the caution above
Attachmentsthe supplier's own PDF (or GoRoute's rendering, marked -goroute.pdf) and the original XML. On a bill delivered into Odoo 18 or earlier before 21 September 2026 these files are present but do not open; see the caution above

The payment reference and the PO number go into their own Odoo fields only if your Odoo has those fields. GoRoute asks your Odoo rather than assuming. Where a field is absent, the value is still in the note, so nothing is lost either way.

A To-Do can be assigned to a named user by setting inbound_activity_user_id on the Odoo connector.

The supplier's bank account, and why you should still check itโ€‹

Where the supplier sent bank details, the bill's note now shows the account they asked to be paid into, as they sent it. It is repeated there and nowhere else: GoRoute adds it to no Odoo record, creates no bank account for the vendor, and does not set the vendor's bank account on the bill. Nothing is paid or scheduled.

Check the account against the one you already hold for that supplier before you pay it. That is the caution GoRoute writes onto the bill itself, and it is on the page for the same reason: an invoice that arrives with an account you have not seen before is how payment redirection works, and the moment to notice it is while the bill is still a draft.

If the account is one you do not recognise, confirm it with the supplier through a number or contact you already had โ€” not one printed on the invoice โ€” before paying.

"NA" is not a purchase order numberโ€‹

Peppol's rules make a supplier fill the purchase-order field even when there is no purchase order โ€” a supplier quoting only their own sales order puts the literal text NA there. Since 22 September 2026 GoRoute does not treat NA as your PO number, so it no longer lands on your bill as the Source Document. A bill delivered before then may have NA sitting in that field, which in Odoo is read-only once the bill exists.

Availability โ€” on both services, checked 23 September 2026

The payment reference, the purchase-order number, the supplier's payment details in the note and the NA rule are on GoRoute's production service and on its test service. They reached test on 22 September 2026 and production later the same day, on 22 September 2026 at 22:05 UTC, when production was upgraded to the build test was already running.

A bill delivered before your service had them carries what the rest of this section describes, with the supplier's payment details in the attached XML only. Nothing is added to a bill after it is delivered.

Why taxes are emptyโ€‹

Odoo fills in a default purchase tax on any line that arrives without one. That would put a tax on the bill the supplier did not charge โ€” a choice made on your behalf. GoRoute therefore sends every line with taxes explicitly empty, and copies the supplier's stated VAT and totals into the note so your accountant can apply the right tax while reviewing.

When the vendor is blankโ€‹

GoRoute sets the vendor only when exactly one of your contacts has the supplier's Peppol ID or VAT. If none does, or several do, the vendor is left blank and the note says why โ€” your accountant picks the contact. GoRoute never creates contacts in your Odoo.

When lines are missingโ€‹

If the invoice could not be read, or its currency is not active in your Odoo, the draft bill is still created โ€” without lines โ€” with the original XML attached and a note explaining why. The document always reaches your accountant.

Delivered onceโ€‹

Each received document is delivered once, however many times delivery is retried. A retry after a partial failure completes the delivery rather than repeating it.

Invoice Responses and Oman's message-level status replies arrive on the same network endpoint but are protocol messages, not documents to pay: they are not delivered as bills.

APIโ€‹

Every received document is also available through the API:

MethodPathPurpose
GET/api/v1/inbound-documentsList received documents; filter by status, supplier, since
GET/api/v1/inbound-documents/summaryCounts by status
GET/api/v1/inbound-documents/{id}The received document, its parsed invoice and delivery record
GET/api/v1/inbound-documents/{id}/files/{kind}One file from the document. kind is original (the XML as received), pdf (the supplier's own PDF if they attached one, otherwise GoRoute's rendering) or attachment-N (the Nth file the supplier embedded, counting from attachment-0)
POST/api/v1/inbound-documents/{id}/redeliverDeliver again; completed steps are not repeated
POST/api/v1/inbound-documents/{id}/deliveryAn external connector reports where the document landed

The downloaded file is named after the document number: <number>.xml for original, <number>.pdf when the supplier attached the PDF themselves, <number>-goroute.pdf when GoRoute rendered it, and the supplier's own filename for an attachment. A 404 means that particular file is not there, and the reason says which โ€” Original bytes are not stored, No PDF available, No such attachment, Attachment is an external reference (the supplier linked the file instead of embedding it), or Unknown file kind for any value of kind other than the three above.

Webhooks: transaction.received carries inbound_document_id; inbound.delivered fires when the draft bill has been created.

Exception codesโ€‹

An exception is something about a received document that a person may need to look at. It never stops the document: GoRoute records the exception, keeps the document flowing, and delivers what it can. Each exception has a code from the list below, a plain message, and a detail object naming the line, party, currency or role it concerns.

The codes below are the ones GoRoute itself raises, checked against the product on 17 September 2026. A connector that runs outside GoRoute โ€” Xero, QuickBooks, Business Central โ€” reports its own codes through POST /api/v1/inbound-documents/{id}/delivery, and those are whatever that connector chooses to send.

CodeWhat raises itWhat GoRoute did as a result
parse_failedThe document has no stored bytes to parse, or it is not well-formed XMLNothing was parsed. The draft bill is created without lines, with the original XML attached
document_type_unsupportedThe root element is neither Invoice nor CreditNoteParsing stopped there. No invoice was produced
canonical_invalidThe document parsed, but the result could not be held by GoRoute's invoice model. detail lists each field and whyNo invoice was produced
party_missingThere is no AccountingSupplierParty, or no AccountingCustomerParty. detail.role says whichNo invoice was produced
no_linesThe document has no invoice linesNo invoice was produced
totals_missingLegalMonetaryTotal gives neither a net nor a payable amountNo invoice was produced
party_name_missingA party has no name. detail.role says whichThe party's Peppol ID or VAT number is used as the name instead, or Unnamed seller / Unnamed buyer if it has neither
party_endpoint_unrecognisedA party's EndpointID has no 4-digit scheme, so it is not a Peppol ID GoRoute can holdThe raw value is kept on the envelope and left out of the parsed party
issue_date_missingIssueDate is missing or cannot be read as a dateToday's date is used on the parsed invoice. The supplier's stated date, whatever it was, is not in it
currency_unknownEither the document currency is not a three-letter ISO 4217 code, or the currency is valid but not active in your Odoo โ€” two different causes, one code, told apart by the messageFor an unreadable code, the currency is recorded as XXX. For a currency Odoo does not have, the draft bill is created without lines, and activating the currency and redelivering fixes it
line_quantity_non_positiveA line's quantity is zero, negative or absent โ€” legal in UBL for returns and corrections, but not in GoRoute's model. detail carries the originalThe absolute value is used, or 1 where there was no quantity at all
line_price_negativeA line's unit price is negative. detail carries the originalThe absolute value is used
tax_category_unknownA line's tax category is not a known UNCL5305 codeThe line is recorded as standard rate. This does not put a tax on the bill โ€” GoRoute sends every line to Odoo with taxes empty
duplicate_suspectedAnother document from the same supplier already arrived with the same number, issue date and payable amount. detail.earlier_document_ids lists themNothing. The document is delivered as normal and a person decides
delivery_failedThe connector's address was refused as unsafe, or there was no content to deliver, or the adapter itself failedDelivery did not complete. Failures that can be retried are

Routing on exceptionsโ€‹

needs_attention is true whenever the document has at least one unresolved exception, and open_exception_count is how many. Both are computed from the exception list, so they are consistent with it and with the exceptions array in inbound.delivered, which carries the open ones only.

One thing to build around: delivery_failed is the only code GoRoute clears by itself, when a later delivery attempt succeeds. Every other code stays open once raised, so needs_attention stays true for the life of the record. Treat it as "something happened on the way in that a person should see once", not as a queue that empties.