Skip to main content

Norway ๐Ÿ‡ณ๐Ÿ‡ด

EHF (Elektronisk Handelsformat) and e-invoicing in Norway.

Overviewโ€‹

AspectDetails
B2G MandateRequired since 2012
B2B StatusWidely adopted (highest adoption globally)
CIUSEHF (Norwegian Peppol extension)
Primary Scheme0192 (Organisasjonsnummer)
AuthorityDifi / Digitaliseringsdirektoratet
Norway - Peppol Pioneer

Norway has the highest Peppol adoption rate in the world. Nearly all businesses can receive Peppol invoices.

Identifier Schemesโ€‹

Organisasjonsnummer (0192) โ€” Standardโ€‹

The Norwegian organization number from Brรธnnรธysund:

# Format: 9 digits
participant = {
"scheme": "0192",
"identifier": "123456789",
"name": "Eksempel AS",
"country": "NO"
}

Validation:

def validate_norwegian_org(org_nr: str) -> bool:
"""Validate Norwegian organization number."""
if len(org_nr) != 9 or not org_nr.isdigit():
return False

# Mod 11 check digit
weights = [3, 2, 7, 6, 5, 4, 3, 2]
total = sum(int(d) * w for d, w in zip(org_nr[:8], weights))
remainder = 11 - (total % 11)

if remainder == 11:
check = 0
elif remainder == 10:
return False # Invalid org number
else:
check = remainder

return int(org_nr[8]) == check

VAT Number (9908)โ€‹

For cross-border invoicing:

# Format: NO + 9 digits + MVA
participant = {
"scheme": "9908",
"identifier": "NO123456789MVA",
"name": "Eksempel AS",
"country": "NO"
}

EHF Formatโ€‹

What is EHF?โ€‹

EHF (Elektronisk Handelsformat) is Norway's national CIUS built on Peppol BIS. It's fully compatible with Peppol BIS 3.0.

CustomizationIDโ€‹

<!-- Standard Peppol BIS 3.0 (works for Norway) -->
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>

<!-- Legacy EHF 3.0 (also accepted) -->
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:difi.no:2017:ehf:postaward:g3:3.0</cbc:CustomizationID>

Norway-Specific Requirementsโ€‹

<Invoice>
<!-- Norwegian seller -->
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0192">123456789</cbc:EndpointID>

<!-- Norwegian VAT format -->
<cac:PartyTaxScheme>
<cbc:CompanyID>NO123456789MVA</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>

<cac:PartyLegalEntity>
<cbc:RegistrationName>Eksempel AS</cbc:RegistrationName>
<cbc:CompanyID schemeID="0192">123456789</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
</Invoice>

VAT Requirementsโ€‹

Norwegian VAT Formatโ€‹

# Norwegian VAT: NO + 9 digits + MVA
def validate_norwegian_vat(vat: str) -> bool:
if not vat.startswith("NO") or not vat.endswith("MVA"):
return False
number = vat[2:-3]
if len(number) != 9:
return False
return validate_norwegian_org(number)

VAT Ratesโ€‹

CodeRateDescription
S25%Standard rate
AA15%Reduced (food)
H12%Reduced (travel, cultural)
Z0%Zero rate (exports)
E0%Exempt

Example Invoiceโ€‹

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">

<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>

<cbc:ID>NO-FAK-2024-00123</cbc:ID>
<cbc:IssueDate>2024-01-15</cbc:IssueDate>
<cbc:DueDate>2024-02-15</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>NOK</cbc:DocumentCurrencyCode>

<!-- Order reference often expected -->
<cac:OrderReference>
<cbc:ID>PO-2024-001</cbc:ID>
</cac:OrderReference>

<!-- Norwegian Seller -->
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0192">123456789</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Eksempel AS</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Karl Johans gate 1</cbc:StreetName>
<cbc:CityName>Oslo</cbc:CityName>
<cbc:PostalZone>0154</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>NO</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>NO123456789MVA</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Eksempel AS</cbc:RegistrationName>
<cbc:CompanyID schemeID="0192">123456789</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Ola Nordmann</cbc:Name>
<cbc:ElectronicMail>faktura@eksempel.no</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>

<!-- Norwegian Buyer -->
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0192">987654321</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Kunde AS</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Storgata 10</cbc:StreetName>
<cbc:CityName>Bergen</cbc:CityName>
<cbc:PostalZone>5003</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>NO</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Kunde AS</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>

<!-- Norwegian bank account -->
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<!-- KID number (structured reference) -->
<cbc:PaymentID>1234567890123</cbc:PaymentID>
<cac:PayeeFinancialAccount>
<cbc:ID>NO9386011117947</cbc:ID>
<cbc:Name>Eksempel AS</cbc:Name>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>

<cac:TaxTotal>
<cbc:TaxAmount currencyID="NOK">250.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="NOK">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="NOK">250.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>

<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="NOK">1000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="NOK">1000.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="NOK">1250.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="NOK">1250.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="NOK">1000.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Konsulenttjenester</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="NOK">100.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>

KID Number (Structured Reference)โ€‹

Norwegian payments often use KID (kundeidentifikasjon):

<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<!-- KID number for bank payment reference -->
<cbc:PaymentID>1234567890123</cbc:PaymentID>
</cac:PaymentMeans>

KID Validationโ€‹

def validate_kid(kid: str) -> bool:
"""Validate Norwegian KID using Mod10 or Mod11."""
if not kid.isdigit() or len(kid) < 2 or len(kid) > 25:
return False
# Mod10 (Luhn) or Mod11 validation
return True # Implement based on agreed algorithm

Looking Up Norwegian Companiesโ€‹

# Lookup in Brรธnnรธysundregistrene
response = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/participants/lookup",
params={
"scheme": "0192",
"identifier": "123456789"
},
headers={"X-API-Key": "your_api_key"}
)

# Returns Peppol registration status

Government E-invoicingโ€‹

Public Sectorโ€‹

All Norwegian public entities require EHF/Peppol invoices:

# Sending to Norwegian government
invoice = {
"receiver": {
"scheme": "0192",
"identifier": "974760673" # Example government entity
},
"buyer_reference": "REQUIRED-123" # Always required for B2G
}

Altinnโ€‹

Some government interactions go through Altinn, but invoicing uses Peppol.

Resourcesโ€‹

Next Stepsโ€‹