This repository has no description
4.8 kB
172 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 # For now, we'll use NOTPROVIDED as fallback
40 # A real implementation would query a BIC database based on country code (${iban:0:2})
41 echo "NOTPROVIDED"
42}
43
44# Validate IBAN format (basic check)
45validate_iban() {
46 local iban="$1"
47 iban="${iban// /}"
48 iban="${iban^^}"
49
50 # Basic validation: starts with 2 letters, followed by 2 digits, then alphanumeric
51 if [[ ! "$iban" =~ ^[A-Z]{2}[0-9]{2}[A-Z0-9]+$ ]]; then
52 echo "Error: Invalid IBAN format" >&2
53 return 1
54 fi
55
56 # Length should be between 15 and 34 characters
57 if [ "${#iban}" -lt 15 ] || [ "${#iban}" -gt 34 ]; then
58 echo "Error: IBAN length must be between 15 and 34 characters" >&2
59 return 1
60 fi
61
62 echo "$iban"
63}
64
65# Parse command line arguments
66NAME=""
67IBAN=""
68BIC=""
69AMOUNT=""
70DESCRIPTION=""
71
72while [[ $# -gt 0 ]]; do
73 case $1 in
74 -n|--name)
75 NAME="$2"
76 shift 2
77 ;;
78 -i|--iban)
79 IBAN="$2"
80 shift 2
81 ;;
82 -b|--bic)
83 BIC="$2"
84 shift 2
85 ;;
86 -a|--amount)
87 AMOUNT="$2"
88 shift 2
89 ;;
90 -d|--desc|--description)
91 DESCRIPTION="$2"
92 shift 2
93 ;;
94 -h|--help)
95 usage 0
96 ;;
97 *)
98 echo "Error: Unknown option: $1" >&2
99 usage 1
100 ;;
101 esac
102done
103
104# Validate required parameters
105if [ -z "$NAME" ]; then
106 echo "Error: Beneficiary name is required (-n/--name)" >&2
107 usage 1
108fi
109
110if [ -z "$IBAN" ]; then
111 echo "Error: IBAN is required (-i/--iban)" >&2
112 usage 1
113fi
114
115# Validate and normalize IBAN
116IBAN=$(validate_iban "$IBAN") || exit 1
117
118# Auto-detect BIC if not provided
119if [ -z "$BIC" ]; then
120 BIC=$(get_bic_from_iban "$IBAN")
121 echo "BIC not provided, using: $BIC" >&2
122fi
123
124# Validate amount format if provided
125if [ -n "$AMOUNT" ]; then
126 if [[ ! "$AMOUNT" =~ ^[0-9]+(\.[0-9]{1,2})?$ ]]; then
127 echo "Error: Invalid amount format. Use format: 123.45" >&2
128 exit 1
129 fi
130 # Format with exactly 2 decimal places
131 AMOUNT=$(printf "%.2f" "$AMOUNT")
132fi
133
134# Build EPC QR code data according to EPC069-12 standard
135# Format:
136# Line 1: BCD (Service Tag)
137# Line 2: 002 (Version)
138# Line 3: 1 (Character set: UTF-8)
139# Line 4: SCT (Identification: SEPA Credit Transfer)
140# Line 5: BIC
141# Line 6: Beneficiary Name
142# Line 7: Beneficiary Account (IBAN)
143# Line 8: Amount (EUR123.45 or empty)
144# Line 9: Purpose (empty for general)
145# Line 10: Structured Reference (empty)
146# Line 11: Unstructured Remittance (description)
147# Line 12: Beneficiary to Originator Information (empty)
148
149EPC_DATA=""
150EPC_DATA+="BCD"$'\n' # Service Tag
151EPC_DATA+="002"$'\n' # Version
152EPC_DATA+="1"$'\n' # Character set (UTF-8)
153EPC_DATA+="SCT"$'\n' # Identification
154EPC_DATA+="${BIC}"$'\n' # BIC
155EPC_DATA+="${NAME}"$'\n' # Beneficiary name
156EPC_DATA+="${IBAN}"$'\n' # IBAN
157
158if [ -n "$AMOUNT" ]; then
159 EPC_DATA+="EUR${AMOUNT}"$'\n' # Amount
160else
161 EPC_DATA+="EUR0"$'\n' # Amount (0 when not specified)
162fi
163
164EPC_DATA+=$'\n' # Purpose (empty)
165EPC_DATA+=$'\n' # Structured reference (empty)
166EPC_DATA+="${DESCRIPTION}"$'\n' # Unstructured remittance
167EPC_DATA+=$'\n' # Beneficiary to originator info (empty)
168
169# Generate QR code using qrencode
170# -t utf8: Output as UTF-8 text
171# -l M: Error correction level Medium
172echo "$EPC_DATA" | qrencode -t utf8 -l M