This repository has no description
4.8 kB
175 lines
1#!/usr/bin/env bash
2set -euo pipefail
3
4# SEPA Payment QR Code Generator
5# Generates EPC QR codes for SEPA payments according to EPC069-12 standard
6
7usage() {
8 cat >&2 <<EOF
9Usage: payment-qr [OPTIONS]
10
11Generate SEPA payment QR code (EPC QR code format)
12
13OPTIONS:
14 -n, --name NAME Beneficiary name (required)
15 -i, --iban IBAN IBAN (required)
16 -b, --bic BIC BIC (optional, auto-detected from IBAN if not provided)
17 -a, --amount AMOUNT Amount in EUR (optional, e.g., 123.45)
18 -d, --desc DESCRIPTION Payment description/reference (optional)
19 -h, --help Show this help message
20
21EXAMPLES:
22 payment-qr -n "John Doe" -i DE89370400440532013000 -a 50.00 -d "Invoice 123"
23 payment-qr --name "Acme Corp" --iban DE89370400440532013000 --bic COBADEFFXXX --amount 100
24
25OUTPUT:
26 Displays the QR code in terminal using UTF-8 characters
27EOF
28 exit "${1:-0}"
29}
30
31# BIC lookup from IBAN (simplified - maps country code to common banks)
32# In production, this would use a proper BIC database/API
33get_bic_from_iban() {
34 local iban="$1"
35 # Remove spaces and convert to uppercase
36 iban="${iban// /}"
37 iban="${iban^^}"
38
39 # Extract country code (first 2 characters)
40 local country="${iban:0:2}"
41
42 # For now, we'll use NOTPROVIDED as fallback
43 # A real implementation would query a BIC database
44 echo "NOTPROVIDED"
45}
46
47# Validate IBAN format (basic check)
48validate_iban() {
49 local iban="$1"
50 iban="${iban// /}"
51 iban="${iban^^}"
52
53 # Basic validation: starts with 2 letters, followed by 2 digits, then alphanumeric
54 if [[ ! "$iban" =~ ^[A-Z]{2}[0-9]{2}[A-Z0-9]+$ ]]; then
55 echo "Error: Invalid IBAN format" >&2
56 return 1
57 fi
58
59 # Length should be between 15 and 34 characters
60 if [ "${#iban}" -lt 15 ] || [ "${#iban}" -gt 34 ]; then
61 echo "Error: IBAN length must be between 15 and 34 characters" >&2
62 return 1
63 fi
64
65 echo "$iban"
66}
67
68# Parse command line arguments
69NAME=""
70IBAN=""
71BIC=""
72AMOUNT=""
73DESCRIPTION=""
74
75while [[ $# -gt 0 ]]; do
76 case $1 in
77 -n|--name)
78 NAME="$2"
79 shift 2
80 ;;
81 -i|--iban)
82 IBAN="$2"
83 shift 2
84 ;;
85 -b|--bic)
86 BIC="$2"
87 shift 2
88 ;;
89 -a|--amount)
90 AMOUNT="$2"
91 shift 2
92 ;;
93 -d|--desc|--description)
94 DESCRIPTION="$2"
95 shift 2
96 ;;
97 -h|--help)
98 usage 0
99 ;;
100 *)
101 echo "Error: Unknown option: $1" >&2
102 usage 1
103 ;;
104 esac
105done
106
107# Validate required parameters
108if [ -z "$NAME" ]; then
109 echo "Error: Beneficiary name is required (-n/--name)" >&2
110 usage 1
111fi
112
113if [ -z "$IBAN" ]; then
114 echo "Error: IBAN is required (-i/--iban)" >&2
115 usage 1
116fi
117
118# Validate and normalize IBAN
119IBAN=$(validate_iban "$IBAN") || exit 1
120
121# Auto-detect BIC if not provided
122if [ -z "$BIC" ]; then
123 BIC=$(get_bic_from_iban "$IBAN")
124 echo "BIC not provided, using: $BIC" >&2
125fi
126
127# Validate amount format if provided
128if [ -n "$AMOUNT" ]; then
129 if [[ ! "$AMOUNT" =~ ^[0-9]+(\.[0-9]{1,2})?$ ]]; then
130 echo "Error: Invalid amount format. Use format: 123.45" >&2
131 exit 1
132 fi
133 # Format with exactly 2 decimal places
134 AMOUNT=$(printf "%.2f" "$AMOUNT")
135fi
136
137# Build EPC QR code data according to EPC069-12 standard
138# Format:
139# Line 1: BCD (Service Tag)
140# Line 2: 002 (Version)
141# Line 3: 1 (Character set: UTF-8)
142# Line 4: SCT (Identification: SEPA Credit Transfer)
143# Line 5: BIC
144# Line 6: Beneficiary Name
145# Line 7: Beneficiary Account (IBAN)
146# Line 8: Amount (EUR123.45 or empty)
147# Line 9: Purpose (empty for general)
148# Line 10: Structured Reference (empty)
149# Line 11: Unstructured Remittance (description)
150# Line 12: Beneficiary to Originator Information (empty)
151
152EPC_DATA=""
153EPC_DATA+="BCD"$'\n' # Service Tag
154EPC_DATA+="002"$'\n' # Version
155EPC_DATA+="1"$'\n' # Character set (UTF-8)
156EPC_DATA+="SCT"$'\n' # Identification
157EPC_DATA+="${BIC}"$'\n' # BIC
158EPC_DATA+="${NAME}"$'\n' # Beneficiary name
159EPC_DATA+="${IBAN}"$'\n' # IBAN
160
161if [ -n "$AMOUNT" ]; then
162 EPC_DATA+="EUR${AMOUNT}"$'\n' # Amount
163else
164 EPC_DATA+=$'\n' # Empty amount
165fi
166
167EPC_DATA+=$'\n' # Purpose (empty)
168EPC_DATA+=$'\n' # Structured reference (empty)
169EPC_DATA+="${DESCRIPTION}"$'\n' # Unstructured remittance
170EPC_DATA+=$'\n' # Beneficiary to originator info (empty)
171
172# Generate QR code using qrencode
173# -t utf8: Output as UTF-8 text
174# -l M: Error correction level Medium
175echo "$EPC_DATA" | qrencode -t utf8 -l M