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.

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:
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
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.
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.
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.
Add Swiss market support. QR codes make customer payments effortless via banking app scanning.
Connect existing systems to automatic invoice generation. Webhook-triggered invoice creation with CRM data.
Multi-language support, proper VAT handling, professional PDFs. Swiss compliance handled automatically.
Offer "Invoice" payment method for B2B. Generate QR invoices immediately after order confirmation.
Automate membership fee collection. Unique QR references for automatic payment matching.
Generate invoices on-the-go. Lightweight API integration for iOS and Android apps.
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.
Production-Ready Implementation
Professional patterns for error handling, testing, performance, and monitoring.
Error Handling
Always wrap API calls in try-catch blocks. Log errors with context including invoice number and customer ID.
- INVALID_IBAN – Format or check digit wrong
- REFERENCE_MISMATCH – QR Reference with regular IBAN
- INVALID_AMOUNT – Negative or zero total
- MISSING_FIELD – Required parameter missing
Testing Strategy
Three-phase testing approach for reliable integration and deployment.
- Development: Free testing endpoint with fake data
- Staging: Real IBAN formats with dummy customers
- Production: Soft launch with internal testing first
- Verify QR codes in multiple banking apps
Performance Optimization
Strategies to maintain fast response times and handle high volumes efficiently.
- Async processing: Queue jobs, don't block requests
- Caching: Store PDF URLs (valid 30 days)
- Batch generation: Parallel requests with rate limits
- Contact us for enterprise rate limits
Monitoring
Track key metrics and set up alerts for production reliability.
- Success rate: Should be >99.5%
- Response time: Average <2 seconds
- Error types: Track patterns and spikes
- Invoice downloads: Monitor PDF access
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
- Unlimited test invoices
- No authentication required
- All features available
- Perfect for proof-of-concept
Production
- Pay per generated invoice
- Volume discounts available
- All features included
- 2025 compliance updates automatic
- Email support included
- Comprehensive documentation
Enterprise
- Dedicated infrastructure
- Priority support
- Custom SLAs
- Higher rate limits
- Ideal for ERP vendors
- High-volume platforms
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?
- Test immediately: Copy the curl command above and run it in your terminal
- Review documentation: Complete API reference with examples
- 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.