Swiss QR Invoice API: Generate Compliant Invoices in Seconds

Developer-friendly RESTful API for Swiss QR invoice generation. ISO 20022 compliant, multi-language support, QR-IBAN ready. One API call, fully compliant PDF.

Swiss QR Invoice Generation

Building invoicing features for the Swiss market? Stop wrestling with QR-Rechnung specifications and ISO 20022 standards. Our developer-friendly API generates compliant Swiss QR invoices with a single API call—no complex libraries, no compliance headaches.

Whether you're building a SaaS platform, integrating invoicing into your ERP, or creating a freelancer tool, you'll have fully compliant QR invoices up and running in under 30 minutes.

Why Use an API Instead of Building In-House?

Swiss QR invoice generation looks simple until you dive into the details. Here's what you're actually signing up for if you build it yourself:

📋
Compliance Complexity67-page Implementation Guidelines v2.3. ISO 20022 standards, QR-IBAN validation, check digits, structured addresses.
🔄
Ongoing MaintenanceSwiss banking standards evolve. 2025 update alone introduced structured addresses, expanded character sets, new validation rules.
🧪
Testing BurdenEvery combination of IBAN type, reference format, currency, and language needs testing. Plus edge cases, VAT rates, PDF formatting.
⏱️
Time to MarketBuilding from scratch: 2-3 months. Using our API: Generate invoices within hours.
Complete Features

Built for Professional Developers

Everything you need to generate compliant Swiss QR invoices, maintained and updated automatically.

QR-IBAN and Regular IBAN Support

Both payment methods work seamlessly. QR-IBAN (IID 30000-31999) for automated reconciliation with 27-digit references. Regular IBAN with Creditor Reference or no reference for simple invoicing.

  • Automatic IBAN format validation
  • Check digit calculation included
  • Reference number validation by IBAN type
  • No manual validation required

2025-Ready Structured Addresses

Critical update: From November 21, 2025, QR invoices require structured addresses. Our API already supports the new format.

  • Structured address format (type S)
  • Separate street name and building number
  • Postal code and city validation
  • Country code support

Multi-Language Invoice Generation

Generate invoices in all Swiss official languages plus English. Language affects labels, formatting, and date display.

  • German (Deutsch) – QR-Rechnung
  • French (Français) – Facture QR
  • Italian (Italiano) – Fattura QR
  • English – QR Invoice

Smart Reference Number Handling

All reference formats supported with automatic validation and check digit calculation.

  • QR Reference (27 digits) with auto check digit
  • Creditor Reference (ISO 11649, 5-25 chars)
  • No reference option for simple invoicing
  • Format validation against IBAN type

VAT Management Built-In

Swiss VAT at standard rates or custom rates. Automatic calculation and Swiss-standard formatting.

  • Standard rates (8.1%, 2.6%, 3.8%)
  • Custom VAT rates supported
  • Multiple VAT rates per invoice
  • Automatic gross and net calculation

Custom Branding Options

Professional invoices with your brand identity and document management integration.

  • Logo integration (PNG, max 2MB)
  • Custom PDF filenames
  • Invoice numbering control
  • Internal ID assignment
Quick Start

Test the API Right Now

No authentication required for testing. Copy this command and run it in your terminal:

curl --location --request POST \
  'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "data": {
      "user_details": {
        "name": "Your Company GmbH",
        "address": "Bahnhofstrasse 1",
        "zip": "8001",
        "city": "Zürich",
        "iban": "CH0700700112900411647"
      },
      "customer_details": {
        "name": "Customer AG",
        "address": "Rue du Rhône 1",
        "zip": "1204",
        "city": "Genève"
      },
      "invoice_items": [
        {
          "description": "Software Development",
          "quantity": 8.5,
          "unit_price": 150.00
        }
      ]
    }
  }'

You'll receive a complete PDF invoice with a scannable QR code. No API key needed for testing.

Parameters

Request Parameters Explained

Simple JSON structure with required and optional fields.

Required Fields

{
  "user_details": {
    "name": "Creditor name (max 70 chars)",
    "address": "Street and number", 
    "zip": "Postal code",
    "city": "City name",
    "iban": "CH76 0070 0112 3456 7890 1"
  },
  "customer_details": {
    "name": "Debtor name (max 70 chars)",
    "address": "Street and number",
    "zip": "Postal code", 
    "city": "City name"
  },
  "invoice_items": [
    {
      "description": "Service or product",
      "quantity": 1.0,
      "unit_price": 100.00
    }
  ]
}

Optional Parameters

{
  "invoice_number": "INV-2024-001",
  "invoice_date": "2024-01-15",
  "reference": "210000000003139471430009017",
  "language": "de",
  "currency": "CHF",
  "vat_rate": 8.1,
  "filename": "invoice_customer_2024_001",
  "logo_url": "https://yoursite.com/logo.png"
}

Response Handling

Success (HTTP 200):

{
  "result": {
    "pdf_url": "https://storage.googleapis.com/...",
    "invoice_id": "abc123",
    "total_amount": 1275.00
  }
}

Error (HTTP 400):

{
  "error": {
    "code": "INVALID_IBAN",
    "message": "IBAN check digit validation failed"
  }
}

The PDF URL remains accessible for 30 days. Download and store it in your system immediately.

Code Examples

Implementation in Your Language

Copy-paste examples for JavaScript, Python, PHP, Ruby, Go, and Java.

JavaScript / Node.js

const axios = require('axios');

async function generateInvoice() {
  const response = await axios.post(
    'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d',
    {
      data: {
        user_details: {
          name: "Tech Solutions AG",
          address: "Technoparkstrasse 1",
          zip: "8005",
          city: "Zürich",
          iban: "CH0700700112900411647"
        },
        customer_details: {
          name: "Client Corp",
          address: "Avenue de la Gare 10",
          zip: "1003",
          city: "Lausanne"
        },
        invoice_items: [
          {
            description: "API Integration Service",
            quantity: 5,
            unit_price: 200.00
          }
        ]
      }
    }
  );
  
  return response.data.result.pdf_url;
}

Python

import requests
import json

def generate_qr_invoice():
    url = "https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d"
    
    payload = {
        "data": {
            "user_details": {
                "name": "Your Company GmbH",
                "address": "Bahnhofstrasse 1",
                "zip": "8001",
                "city": "Zürich",
                "iban": "CH0700700112900411647"
            },
            "customer_details": {
                "name": "Customer Name",
                "address": "Street Address",
                "zip": "1000",
                "city": "Lausanne"
            },
            "invoice_items": [
                {
                    "description": "Consulting Services",
                    "quantity": 10,
                    "unit_price": 180.00
                }
            ]
        }
    }
    
    response = requests.post(url, json=payload)
    return response.json()['result']['pdf_url']

PHP

<?php
$curl = curl_init();

$data = [
    'data' => [
        'user_details' => [
            'name' => 'Swiss Services SA',
            'address' => 'Route de Berne 5',
            'zip' => '1010',
            'city' => 'Lausanne',
            'iban' => 'CH0700700112900411647'
        ],
        'customer_details' => [
            'name' => 'Client Company',
            'address' => 'Via Nassa 1',
            'zip' => '6900',
            'city' => 'Lugano'
        ],
        'invoice_items' => [
            [
                'description' => 'Web Development',
                'quantity' => 20,
                'unit_price' => 125.00
            ]
        ]
    ]
];

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($data),
    CURLOPT_HTTPHEADER => ['Content-Type: application/json']
]);

$response = curl_exec($curl);
$result = json_decode($response, true);

echo $result['result']['pdf_url'];
?>

Ruby

require 'net/http'
require 'json'
require 'uri'

uri = URI('https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d')

payload = {
  data: {
    user_details: {
      name: "Development Studio GmbH",
      address: "Seestrasse 20",
      zip: "8002",
      city: "Zürich",
      iban: "CH0700700112900411647"
    },
    customer_details: {
      name: "Client Business AG",
      address: "Spalenring 5",
      zip: "4055",
      city: "Basel"
    },
    invoice_items: [
      {
        description: "Design Services",
        quantity: 15,
        unit_price: 160.00
      }
    ]
  }
}

response = Net::HTTP.post(uri, payload.to_json, 
  'Content-Type' => 'application/json')

result = JSON.parse(response.body)
puts result['result']['pdf_url']

Go

package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

type InvoiceRequest struct {
    Data struct {
        UserDetails struct {
            Name    string `json:"name"`
            Address string `json:"address"`
            Zip     string `json:"zip"`
            City    string `json:"city"`
            IBAN    string `json:"iban"`
        } `json:"user_details"`
        CustomerDetails struct {
            Name    string `json:"name"`
            Address string `json:"address"`
            Zip     string `json:"zip"`
            City    string `json:"city"`
        } `json:"customer_details"`
        InvoiceItems []struct {
            Description string  `json:"description"`
            Quantity    float64 `json:"quantity"`
            UnitPrice   float64 `json:"unit_price"`
        } `json:"invoice_items"`
    } `json:"data"`
}

func generateInvoice() (string, error) {
    url := "https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d"
    
    var req InvoiceRequest
    req.Data.UserDetails.Name = "Swiss Tech AG"
    req.Data.UserDetails.Address = "Technoparkstrasse 1"
    req.Data.UserDetails.Zip = "8005"
    req.Data.UserDetails.City = "Zürich"
    req.Data.UserDetails.IBAN = "CH0700700112900411647"
    
    jsonData, _ := json.Marshal(req)
    resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
    
    // Handle response...
    return "pdf_url", err
}

Java

import java.net.http.*;
import java.net.URI;
import org.json.JSONObject;

public class QRInvoiceGenerator {
    public static String generateInvoice() throws Exception {
        String url = "https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d";
        
        JSONObject payload = new JSONObject()
            .put("data", new JSONObject()
                .put("user_details", new JSONObject()
                    .put("name", "Software GmbH")
                    .put("address", "Europaallee 1")
                    .put("zip", "8004")
                    .put("city", "Zürich")
                    .put("iban", "CH0700700112900411647"))
                .put("customer_details", new JSONObject()
                    .put("name", "Client AG")
                    .put("address", "Bahnhofstrasse 10")
                    .put("zip", "3011")
                    .put("city", "Bern"))
                .put("invoice_items", new JSONArray()
                    .put(new JSONObject()
                        .put("description", "Development")
                        .put("quantity", 40)
                        .put("unit_price", 150.00))));
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload.toString()))
            .build();
            
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
            
        JSONObject result = new JSONObject(response.body());
        return result.getJSONObject("result").getString("pdf_url");
    }
}

Common Use Cases & Integration Patterns

Real-world scenarios where our API solves Swiss invoicing challenges for developers and businesses.

2-second response time
🔒 ISO 20022 compliant
🌍 Multi-language ready
2025 structured addresses
💼
SaaS Invoicing Platforms

Add Swiss market support. QR codes make customer payments effortless via banking app scanning.

🔄
ERP and CRM Integration

Connect existing systems to automatic invoice generation. Webhook-triggered invoice creation with CRM data.

👨‍💼
Freelancer Tools

Multi-language support, proper VAT handling, professional PDFs. Swiss compliance handled automatically.

🛒
E-commerce Checkout

Offer "Invoice" payment method for B2B. Generate QR invoices immediately after order confirmation.

🏢
Membership Organizations

Automate membership fee collection. Unique QR references for automatic payment matching.

📱
Mobile Applications

Generate invoices on-the-go. Lightweight API integration for iOS and Android apps.

Technical Details

Understanding QR-IBAN vs Regular IBAN

This trips up most developers initially. Here's the practical difference:

When to Use QR-IBAN

Use QR-IBAN when: You need automated payment reconciliation. The 27-digit QR reference connects incoming payments to specific invoices automatically. Your bank matches the reference and notifies you which invoice was paid.

How to recognize QR-IBAN: The 5th to 9th characters (IID) range from 30000 to 31999.

  • Example: CH12 30123 4567 8901 2345 6 (30123 = QR-IID)

How to get QR-IBAN: Contact your Swiss bank. They'll issue QR-IBANs alongside your regular IBANs. Most Swiss banks offer this free for business accounts.

When to Use Regular IBAN

Use Regular IBAN when: Simple invoicing suffices. You manually match incoming payments to invoices, or you use the Creditor Reference field (ISO 11649 format) for semi-automated matching.

Regular IBAN recognition: Standard Swiss IBAN format with IID outside the 30000-31999 range.

Reference Compatibility

  • QR-IBAN → Must use QR Reference (27 digits)
  • Regular IBAN → Can use Creditor Reference or no reference

The API validates this automatically. Pass a QR Reference with a regular IBAN? You'll get an error before generating an invalid invoice.

FAQ

Frequently Asked Questions

Why isn't my IBAN working?

First, verify it's a Swiss or Liechtenstein IBAN (starts with CH or LI). QR bills only support these countries. Second, check if you're mixing IBAN types—QR References require QR-IBAN, not regular IBAN.

Do I need a special bank account?

No special account needed for regular IBAN invoices. For QR-IBAN invoices with automated payment matching, contact your bank to activate QR-IBAN service. Most Swiss business accounts include this.

What's the transition deadline for structured addresses?

Mandatory from November 21, 2025. Full compliance required by September 30, 2026. Our API already supports structured format—you're covered.

Can I use international IBANs?

No. The Swiss QR-bill specification only accepts Swiss (CH) and Liechtenstein (LI) IBANs. For international invoicing, consider SEPA invoices instead.

How do I calculate the QR Reference check digit?

You don't need to. Pass your 26-digit reference, and we calculate the 27th digit (Modulo 10, recursive). The API handles check digit validation for both IBAN and reference.

What if my customer's banking app doesn't recognize the QR code?

This indicates either: (1) QR code quality issue in PDF printing/display, (2) non-compliant QR code generation, or (3) outdated banking app. Our API generates fully compliant QR codes tested with all major Swiss banking apps. Ensure customers scan from the original PDF, not a low-quality photocopy.

Can I customize the invoice layout?

Logo and colors yes, structural layout no. Swiss QR invoices follow strict formatting requirements for bank compatibility. You can add your logo, but payment slip positioning and QR code placement are regulated.

What's your API uptime?

We maintain 99.9% uptime. That's less than 9 hours of downtime per year. Enterprise customers get priority support and can request dedicated infrastructure.

How quickly can I integrate this?

Most developers complete basic integration in 2-4 hours. A production-ready implementation with error handling, webhook integration, and testing typically takes 1-2 days.

Simple, Transparent Pricing

Pay only for what you use. Volume discounts available for high-volume applications.

Free Testing

CHF0/month
Unlimited Test Invoices
  • Unlimited test invoices
  • No authentication required
  • All features available
  • Perfect for proof-of-concept
Start Testing Now

Enterprise

CHFCustom/month
Dedicated Infrastructure
  • Dedicated infrastructure
  • Priority support
  • Custom SLAs
  • Higher rate limits
  • Ideal for ERP vendors
  • High-volume platforms
Contact Sales
🛡️All plans include complete API access, multi-language support, QR-IBAN compatibility, and automatic compliance updates.

Start Building Today

Test immediately with no signup. Generate your first compliant Swiss QR invoice in the next 5 minutes.

Ready to integrate Swiss QR invoicing?

  1. Test immediately: Copy the curl command above and run it in your terminal
  2. Review documentation: Complete API reference with examples
  3. Get your API key: Request access now

Questions about implementation? Our developer support team responds within 24 hours.
Email support@magicheidi.ch with your use case.


Built by developers, for developers. We understand Swiss invoicing complexity because we've solved it for ourselves. Now we're sharing that solution with you.

Try the API free – no credit card, no signup required for testing.