Complyance Logo

Germany Implementation Examples

Complete XRechnung and GoBD-compliant examples using the canonical GETS structure. Includes both the final GETS JSON format and Java SDK payload examples. All examples provide 100% field coverage for Germany requirements with XRechnung format, Leitweg-ID routing, GoBD archiving, and SEPA payment integration.

Germany-Specific Features

Compliance Standards

  • Format: XRechnung 2.3.1 (EN 16931-1:2017 compliant)
  • Routing: Leitweg-ID for document routing
  • Archiving: GoBD (Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern)
  • Payment: SEPA (Single Euro Payments Area)
  • VAT Rate: 19% standard rate, 7% reduced rate
  • Tax ID: Steuernummer and USt-IdNr formats

Required Fields

  • Leitweg-ID (routing identifier)
  • Buyer reference (Leitweg-ID in buyer info)
  • Tax number (Steuernummer) or VAT ID (USt-IdNr)
  • IBAN and BIC for SEPA payments
  • GoBD archiving metadata
  • Invoice type code (380, 381, 384, 389)
  • Payment terms with SEPA mandate

Java SDK Examples

Complete B2B Tax Invoice Example

Complete working example demonstrating Germany-specific TAX_INVOICE functionality with XRechnung and GoBD compliance.

package io.complyance.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.complyance.sdk.Country;
import io.complyance.sdk.Environment;
import io.complyance.sdk.GETSUnifySDK;
import io.complyance.sdk.LogicalDocType;
import io.complyance.sdk.Mode;
import io.complyance.sdk.Operation;
import io.complyance.sdk.Purpose;
import io.complyance.sdk.SDKConfig;
import io.complyance.sdk.SDKException;
import io.complyance.sdk.Source;
import io.complyance.sdk.SourceType;
import io.complyance.sdk.UnifyResponse;

/**
 * Germany Tax Invoice Test - Demonstrates Germany-specific TAX_INVOICE functionality
 * 
 * This test class demonstrates:
 * - Germany (DE) country-specific compliance
 * - TAX_INVOICE logical document type mapping
 * - B2B transaction processing with XRechnung
 * - Germany-specific field mappings (Leitweg-ID, Steuernummer, SEPA)
 * - Comprehensive payload with German invoice data
 * - GoBD archiving compliance
 * - XRechnung format compliance
 */
public class GermanyTaxInvoiceTest {

    public static void main(String[] args) {
        System.out.println("=== 🇩🇪 Germany Tax Invoice Test ===");
        System.out.println("Testing Germany-specific TAX_INVOICE functionality");
        System.out.println("Demonstrates B2B mapping, DE compliance, XRechnung, GoBD, and comprehensive payload");

        try {
            // Configure SDK
            configureSDK();

            // Create comprehensive Germany test payload
            Map<String, Object> payload = createGermanyTestPayload();

            System.out.println("✅ Germany test payload created");
            System.out.println("   📊 Expected GETS fields coverage: 40/40 (100%)");
            System.out.println("   🇩🇪 Expected DE country fields coverage: 9/9 (100%)");
            System.out.println("   💰 Expected DE compliance fields coverage: 6/6 (100%)");

            // Test Germany TAX_INVOICE flow
            testGermanyTaxInvoiceFlow(payload);

            System.out.println("\n🎉 Germany Tax Invoice test completed successfully!");

        } catch (Exception e) {
            System.err.println("❌ Unexpected error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Configure the SDK for Germany testing
     */
    private static void configureSDK() {
        Source source = new Source("germany-source-system", "1.0", SourceType.FIRST_PARTY);
        SDKConfig config = new SDKConfig("ak_368d073d3de1f19041612fe6cdcf",
                Environment.SANDBOX, Arrays.asList(source));
        GETSUnifySDK.configure(config);
        System.out.println("✅ SDK Configured for Germany Testing");
    }

    /**
     * Creates Germany test payload with XRechnung and GoBD compliance
     */
    private static Map<String, Object> createGermanyTestPayload() {
        Map<String, Object> payload = new HashMap<>();

        // Invoice Data - Maps to GETS header fields
        Map<String, Object> invoiceData = new HashMap<>();
        invoiceData.put("document_number", "DE-RE-2024-001");
        invoiceData.put("document_type", "tax_invoice");
        invoiceData.put("invoice_type_code", "380"); // Commercial invoice
        invoiceData.put("invoice_date", "2024-01-15");
        invoiceData.put("invoice_time", "10:00:00+01:00");
        invoiceData.put("currency_code", "EUR");
        invoiceData.put("tax_currency_code", "EUR");
        invoiceData.put("due_date", "2024-02-14");
        invoiceData.put("order_reference", "Bestellung-2024-5678");
        invoiceData.put("buyer_reference", "leitweg-id://99-999-99999-99"); // Leitweg-ID
        invoiceData.put("exchange_rate", 1.0);
        invoiceData.put("line_extension_amount", 10000.00);
        invoiceData.put("tax_exclusive_amount", 10000.00);
        invoiceData.put("total_tax_amount", 1900.00); // 19% VAT
        invoiceData.put("total_amount", 11900.00);
        invoiceData.put("total_allowances", 0.00);
        invoiceData.put("total_charges", 0.00);
        invoiceData.put("amount_due", 11900.00);
        
        // GoBD archiving metadata
        invoiceData.put("archiving_date", "2024-01-15T10:00:00+01:00");
        invoiceData.put("retention_period", "10"); // 10 years
        
        payload.put("invoice_data", invoiceData);

        // Seller Info - German company
        Map<String, Object> sellerInfo = new HashMap<>();
        sellerInfo.put("seller_name", "Deutsche Firma GmbH");
        sellerInfo.put("seller_trade_name", "Deutsche Trading");
        sellerInfo.put("seller_party_id", "SELLER-DE-001");
        sellerInfo.put("tax_number", "12/345/67890"); // Steuernummer
        sellerInfo.put("vat_number", "DE123456789"); // USt-IdNr
        sellerInfo.put("vat_number_type", "USt-IdNr");
        sellerInfo.put("registration_type", "DE:VAT");
        sellerInfo.put("seller_email", "kontakt@deutschefirma.de");
        sellerInfo.put("seller_phone", "+49301234567");
        sellerInfo.put("seller_street", "Friedrichstraße");
        sellerInfo.put("seller_building_number", "100");
        sellerInfo.put("seller_city", "Berlin");
        sellerInfo.put("seller_postal_code", "10117");
        sellerInfo.put("seller_state", "Berlin");
        sellerInfo.put("seller_country", "DE");
        sellerInfo.put("seller_country_name", "Germany");
        payload.put("seller_info", sellerInfo);

        // Buyer Info - German public entity
        Map<String, Object> buyerInfo = new HashMap<>();
        buyerInfo.put("buyer_name", "Öffentliche Einrichtung");
        buyerInfo.put("buyer_party_id", "BUYER-DE-001");
        buyerInfo.put("tax_number", "98/765/43210"); // Steuernummer
        buyerInfo.put("vat_number", "DE987654321"); // USt-IdNr
        buyerInfo.put("vat_number_type", "USt-IdNr");
        buyerInfo.put("leitweg_id", "99-999-99999-99"); // Leitweg-ID for routing
        buyerInfo.put("buyer_email", "einkauf@oeffentlich.de");
        buyerInfo.put("buyer_phone", "+49309876543");
        buyerInfo.put("buyer_street", "Unter den Linden");
        buyerInfo.put("buyer_building_number", "77");
        buyerInfo.put("buyer_city", "Berlin");
        buyerInfo.put("buyer_postal_code", "10117");
        buyerInfo.put("buyer_state", "Berlin");
        buyerInfo.put("buyer_country", "DE");
        buyerInfo.put("buyer_country_name", "Germany");
        payload.put("buyer_info", buyerInfo);

        // Line Items
        List<Map<String, Object>> lineItems = new ArrayList<>();
        Map<String, Object> lineItem = new HashMap<>();
        lineItem.put("line_id", "1");
        lineItem.put("item_name", "Beratungsleistungen");
        lineItem.put("item_description", "Consulting services for January 2024");
        lineItem.put("quantity", 100);
        lineItem.put("unit_code", "HUR"); // Hours
        lineItem.put("unit_price", 100.00);
        lineItem.put("line_extension_amount", 10000.00);
        lineItem.put("discount_amount", 0.00);
        lineItem.put("tax_category", "S"); // Standard rate
        lineItem.put("tax_rate", 19.0);
        lineItem.put("tax_amount", 1900.00);
        lineItem.put("total_amount", 11900.00);
        lineItems.add(lineItem);
        payload.put("line_items", lineItems);

        // Tax Breakdown
        List<Map<String, Object>> taxBreakdown = new ArrayList<>();
        Map<String, Object> taxCategory = new HashMap<>();
        taxCategory.put("tax_category_code", "S");
        taxCategory.put("tax_category_name", "Standard Rate");
        taxCategory.put("tax_rate", 19.0);
        taxCategory.put("taxable_amount", 10000.00);
        taxCategory.put("tax_amount", 1900.00);
        taxCategory.put("tax_scheme_id", "VAT");
        taxBreakdown.add(taxCategory);
        payload.put("tax_breakdown", taxBreakdown);

        // Payment Terms with SEPA
        Map<String, Object> paymentTerms = new HashMap<>();
        paymentTerms.put("payment_means_code", "58"); // SEPA credit transfer
        paymentTerms.put("payment_terms_note", "Zahlung innerhalb von 30 Tagen");
        paymentTerms.put("payment_due_date", "2024-02-14");
        paymentTerms.put("iban", "DE89370400440532013000");
        paymentTerms.put("bic", "COBADEFFXXX");
        paymentTerms.put("account_holder", "Deutsche Firma GmbH");
        paymentTerms.put("payment_reference", "DE-RE-2024-001");
        paymentTerms.put("sepa_mandate_id", "MANDATE-2024-001");
        paymentTerms.put("sepa_creditor_id", "DE98ZZZ09999999999");
        payload.put("payment_terms", paymentTerms);

        // Germany Extensions
        Map<String, Object> extensions = new HashMap<>();
        Map<String, Object> deIdentification = new HashMap<>();
        deIdentification.put("leitwegId", "99-999-99999-99");
        deIdentification.put("buyerReference", "leitweg-id://99-999-99999-99");
        deIdentification.put("taxNumber", "12/345/67890");
        deIdentification.put("vatId", "DE123456789");
        extensions.put("de_identification", deIdentification);

        Map<String, Object> deTax = new HashMap<>();
        deTax.put("taxCategoryCode", "S");
        deTax.put("taxSchemeId", "VAT");
        deTax.put("taxRate", 19.0);
        extensions.put("de_tax", deTax);

        Map<String, Object> dePayment = new HashMap<>();
        dePayment.put("iban", "DE89370400440532013000");
        dePayment.put("bic", "COBADEFFXXX");
        dePayment.put("sepaMandateId", "MANDATE-2024-001");
        dePayment.put("sepaCreditorId", "DE98ZZZ09999999999");
        dePayment.put("paymentMeansCode", "58");
        extensions.put("de_payment", dePayment);

        Map<String, Object> deArchiving = new HashMap<>();
        deArchiving.put("archivingDate", "2024-01-15T10:00:00+01:00");
        deArchiving.put("retentionPeriod", "10");
        deArchiving.put("archivingSystem", "GoBD-Archive-v1.0");
        deArchiving.put("documentHash", "sha256:abcd1234...");
        extensions.put("de_archiving", deArchiving);

        payload.put("extensions", extensions);

        return payload;
    }

    /**
     * Test the Germany TAX_INVOICE transformation flow
     */
    private static void testGermanyTaxInvoiceFlow(Map<String, Object> payload) throws SDKException {
        System.out.println("\n📤 Testing Germany TAX_INVOICE transformation...");

        UnifyResponse response = GETSUnifySDK.unify(
            payload,
            Operation.TRANSFORM,
            LogicalDocType.TAX_INVOICE,
            Country.DE,
            Mode.REAL,
            Purpose.INVOICE
        );

        // Verify response
        if (response.isSuccess()) {
            System.out.println("✅ Transformation successful");
            System.out.println("   📊 GETS JSON generated");
            System.out.println("   🇩🇪 XRechnung format compliance verified");
            System.out.println("   ✓ Leitweg-ID validated: 99-999-99999-99");
            System.out.println("   ✓ Tax number: 12/345/67890");
            System.out.println("   ✓ VAT ID: DE123456789");
            System.out.println("   ✓ SEPA mandate: MANDATE-2024-001");
            System.out.println("   ✓ GoBD archiving: compliant");
        } else {
            System.err.println("❌ Transformation failed");
            System.err.println("   Error: " + response.getError());
        }
    }
}

GETS JSON Output

Expected GETS JSON structure after transformation:

{
  "header": {
    "invoice_number": "DE-RE-2024-001",
    "issue_date": "2024-01-15",
    "issue_time": "10:00:00+01:00",
    "document_type": "TAX_INVOICE",
    "invoice_type_code": "380",
    "currency_code": "EUR",
    "due_date": "2024-02-14",
    "buyer_reference": "leitweg-id://99-999-99999-99"
  },
  "seller": {
    "name": "Deutsche Firma GmbH",
    "tax_number": "12/345/67890",
    "vat_number": "DE123456789",
    "address": {
      "street": "Friedrichstraße",
      "building_number": "100",
      "city": "Berlin",
      "postal_code": "10117",
      "state": "Berlin",
      "country": "DE"
    },
    "contact": {
      "email": "kontakt@deutschefirma.de",
      "phone": "+49301234567"
    }
  },
  "buyer": {
    "name": "Öffentliche Einrichtung",
    "tax_number": "98/765/43210",
    "vat_number": "DE987654321",
    "leitweg_id": "99-999-99999-99",
    "address": {
      "street": "Unter den Linden",
      "building_number": "77",
      "city": "Berlin",
      "postal_code": "10117",
      "state": "Berlin",
      "country": "DE"
    },
    "contact": {
      "email": "einkauf@oeffentlich.de",
      "phone": "+49309876543"
    }
  },
  "line_items": [
    {
      "id": "1",
      "name": "Beratungsleistungen",
      "description": "Consulting services for January 2024",
      "quantity": 100,
      "unit_code": "HUR",
      "unit_price": 100.00,
      "line_extension_amount": 10000.00,
      "tax_category": "S",
      "tax_rate": 19.0,
      "tax_amount": 1900.00,
      "total_amount": 11900.00
    }
  ],
  "totals": {
    "line_extension_amount": 10000.00,
    "tax_exclusive_amount": 10000.00,
    "tax_amount": 1900.00,
    "total_amount": 11900.00,
    "amount_due": 11900.00
  },
  "tax_breakdown": [
    {
      "category_code": "S",
      "category_name": "Standard Rate",
      "rate": 19.0,
      "taxable_amount": 10000.00,
      "tax_amount": 1900.00,
      "scheme_id": "VAT"
    }
  ],
  "payment": {
    "means_code": "58",
    "terms_note": "Zahlung innerhalb von 30 Tagen",
    "due_date": "2024-02-14",
    "iban": "DE89370400440532013000",
    "bic": "COBADEFFXXX",
    "account_holder": "Deutsche Firma GmbH",
    "payment_reference": "DE-RE-2024-001",
    "sepa_mandate_id": "MANDATE-2024-001",
    "sepa_creditor_id": "DE98ZZZ09999999999"
  },
  "extensions": {
    "de_identification": {
      "leitwegId": "99-999-99999-99",
      "buyerReference": "leitweg-id://99-999-99999-99",
      "taxNumber": "12/345/67890",
      "vatId": "DE123456789"
    },
    "de_tax": {
      "taxCategoryCode": "S",
      "taxSchemeId": "VAT",
      "taxRate": 19.0
    },
    "de_payment": {
      "iban": "DE89370400440532013000",
      "bic": "COBADEFFXXX",
      "sepaMandateId": "MANDATE-2024-001",
      "sepaCreditorId": "DE98ZZZ09999999999",
      "paymentMeansCode": "58"
    },
    "de_archiving": {
      "archivingDate": "2024-01-15T10:00:00+01:00",
      "retentionPeriod": "10",
      "archivingSystem": "GoBD-Archive-v1.0",
      "documentHash": "sha256:abcd1234..."
    }
  }
}

VAT Rates

Germany supports the following VAT rates:

CodeDescriptionRate
SStandard Rate19%
AAReduced Rate7%
ZZero Rate0%
EExemptN/A

Invoice Type Codes

XRechnung requires specific invoice type codes:

CodeDescription
380Commercial invoice
381Credit note
384Corrected invoice
389Self-billed invoice

Payment Means Codes

SEPA payment methods:

CodeDescription
58SEPA credit transfer
59SEPA direct debit

Leitweg-ID Format

The Leitweg-ID follows this structure:

[Grobadressierung]-[Feinadressierung]-[Prüfziffer]
Example: 99-999-99999-99

GoBD Requirements

  • Retention Period: 10 years for invoices
  • Archiving: Digital archiving with integrity protection
  • Timestamps: ISO 8601 format with timezone
  • Document Hash: SHA-256 or equivalent
  • System Documentation: Required for archiving system

Next Steps