← Docs / Guides
Sending and receiving invoices with Peppol
Connect your company's own Peppol access point (Recommand, Storecove or e-invoice.be) to Nordlet, send invoices and credit notes over Peppol, follow their delivery, and turn received e-invoices into purchase invoices.
Peppol is the European network for exchanging structured e-invoices between businesses and public bodies. Every invoice travels from the sender's access point to the receiver's access point. Nordlet builds Peppol BIS Billing 3.0 invoices and credit notes, and sends and receives them through your company's own access point account.
Peppol sets the rules for how access points exchange documents with each other, but not how your software talks to your own access point: every provider has its own API. Nordlet works with these providers:
| Provider | Sends | Delivery status | Receives |
|---|---|---|---|
| Recommand | yes | by webhook and on request | yes |
| Storecove | yes | by webhook only | yes |
| e-invoice.be | yes | by webhook and on request | yes |
Without an access point, Nordlet still builds the Peppol file of every issued invoice and credit note for you to download and pass on another way; it does not send or receive anything.
What you need
- An account with one of the providers above, with your company registered on Peppol through it. Each provider charges for its service; see its own price list.
- In Nordlet, the company's VAT number or registration number, or its Peppol ID (Settings → Companies → Peppol ID). Each customer you send to needs one of these too, on its partner card.
Connecting your access point
Open Settings → Compliance → EU → Peppol access point, choose your provider in Provider, fill in the fields for that provider as described below and save. Leave API base URL empty unless your provider gave you a different address. After saving, the page shows the Webhook URL of your company: https://api.nordlet.com/v1/peppol/webhooks/{provider}/{companyId}, where {provider} is recommand, storecove or e-invoice-be and {companyId} is your company's ID. Each Nordlet company has its own webhook URL.
Nordlet accepts a webhook call only when it proves it knows your webhook secret, so a call that does not come from your access point account is refused. Nordlet only contacts public internet addresses when it calls your access point.
Recommand
- In Recommand, open your company and copy its company ID into Account ID at the access point.
- In Recommand, create an API key and copy the key and its secret into API key and API secret.
- Make up a long random text that only you and Recommand will know, and enter it in Webhook secret. Save.
- In Recommand, create a webhook for your company with the Webhook URL Nordlet shows and the same webhook secret.
Recommand signs every webhook call with that secret.
Storecove
- In Storecove, create a legal entity for your company, set to send and to receive, and copy its ID into Account ID at the access point.
- In Storecove, under API Keys, create an API key and copy it into API key. Leave API secret empty.
- Make up a long random text and enter it in Webhook secret. Save.
- In Storecove, set up a push webhook with the Webhook URL Nordlet shows, protected with HTTP Basic authentication: any user name, and the webhook secret as the password.
Storecove has no call for the status of a sent document, so with Storecove the delivery status comes only from its webhook and the invoice page has no Check Peppol status button. A Storecove sandbox account sends on the Peppol test network; production API keys come from Storecove support.
e-invoice.be
- In the e-invoice.be app, under API Settings, copy your company's API key into API key. Leave Account ID at the access point and API secret empty. Save.
- Create a webhook with the e-invoice.be API (
POST https://api.e-invoice.be/api/webhooks/) with the Webhook URL Nordlet shows and the eventsdocument.received,document.sentanddocument.sent.failed. - Copy the
secretthe API returns for the new webhook into Webhook secret in Nordlet and save again.
e-invoice.be signs every webhook call with that secret. A sandbox company at e-invoice.be emails the documents it would send instead of sending them over Peppol.
Sending an invoice
- Issue the invoice or credit note.
- Check that the customer has a Peppol ID, VAT number or registration number on its partner card.
- On the invoice page, in the Delivery section, click Send via Peppol and confirm. The Delivery section is shown for issued invoices that are not paid yet, and the button only when the access point is connected.
Nordlet builds the Peppol file and hands it to your access point. The invoice page then shows a Peppol delivery section:
| Status | Meaning |
|---|---|
| pending | Handed to the access point; the customer's access point has not confirmed it yet |
| delivered | The customer's access point confirmed it received the invoice |
| rejected | The customer refused the invoice; the reason is shown below the status |
| failed | The invoice could not be delivered; the reason is shown below the status when the access point gives one |
The status updates by itself when the access point reports a change through its webhook. Check Peppol status asks Recommand or e-invoice.be for the current status at once; with e-invoice.be it also reads the customer's invoice response, and a refusal (response code RE) shows as rejected. A rejected or failed invoice can be sent again after you correct the cause. When the access point refuses an invoice outright, for example because the customer is not registered on Peppol, Nordlet shows the reason and the invoice stays unsent.
The Peppol XML button at the top of the invoice page downloads the same Peppol file without sending it.
An intra-EU supply carries the issue date as its delivery date and the customer's country as the delivery country, as the Peppol rules require.
Receiving invoices
When the access point reports a received document through its webhook, Nordlet downloads the Peppol file from the access point. Invoices and credit notes your company receives appear in Purchases → Document capture, marked as received over Peppol from the sender's Peppol ID. Nordlet reads the Peppol file itself, so receiving uses no document recognition credits.
- Open the received document.
- Check the supplier, the dates and the lines; choose the supplier from your partners or create it.
- Click Save draft. Nordlet creates a draft purchase invoice, or a draft purchase credit note for a received credit note, with the original Peppol file attached. Register it as you would any other purchase invoice.
Nordlet purchase invoice lines cannot be negative. Discounts and charges for the whole document, and negative lines, are spread over the lines with the same VAT rate. An amount that no line of its VAT rate can carry, such as a returned item at a VAT rate the invoice has no other line for, is shown in a second table: Credit note lines for a received invoice, or Invoice lines for a received credit note. Those lines are saved as a second document for the same supplier: a purchase credit note against the new invoice, numbered "
Checking whether a customer is on Peppol
POST /v1/peppol/participants/lookup with a partnerId or a participantId ("
Doing the same through the API
| Task | Call |
|---|---|
| Connect the access point | POST /v1/declarations/configs/update with system: "peppol" and config holding provider (recommand, storecove or e-invoice-be), accountId, apiKey, apiSecret, webhookSecret and optional apiBaseUrl |
| Receive the access point's webhook | POST /v1/peppol/webhooks/{provider}/{companyId}, called by the access point |
| Download the Peppol file | POST /v1/sales/invoices/peppol-xml |
| Send | POST /v1/sales/invoices/peppol-send (422 without an access point) |
| Read the delivery status | POST /v1/sales/invoices/peppol-status (422 with Storecove); invoices carry peppolMessageId, peppolStatus, peppolDetail, peppolSentAt, peppolCheckedAt |
| Find received documents | POST /v1/capture/documents/list; received ones have provider: "peppol" and senderId |
| Turn one into a purchase invoice | POST /v1/capture/documents/confirm, with oppositeLines for the second document |
Webhook events: sale_invoice.peppol_sent, sale_invoice.peppol_delivered, sale_invoice.peppol_rejected, sale_invoice.peppol_failed and document_capture.peppol_received. See API conventions for errors, idempotency and webhooks.