package web import ( "fmt" "regexp" "strings" "unicode/utf8" qrcode "github.com/skip2/go-qrcode" ) var validAccount = regexp.MustCompile(`^[A-Z]{2}\d{2,34}$|^\d{1,16}/\d{4}$`) // BuildSPD builds a Czech QR Platba SPD string, matching Python's qr_code handler. // Invalid account falls back to defaultAccount. // Amount is clamped to [0, 10_000_000]; non-numeric input becomes "0.00". // Message is truncated to 60 runes and stripped of '*' characters. func BuildSPD(account, amount, message, defaultAccount string) string { if !validAccount.MatchString(account) { account = defaultAccount } var amtStr string var f float64 if _, err := fmt.Sscanf(amount, "%f", &f); err != nil || f < 0 || f > 10_000_000 { amtStr = "0.00" } else { amtStr = fmt.Sprintf("%.2f", f) } if utf8.RuneCountInString(message) > 60 { runes := []rune(message) message = string(runes[:60]) } message = strings.ReplaceAll(message, "*", "") var accStr string if parts := strings.SplitN(account, "/", 2); len(parts) == 2 { accStr = parts[0] + "*BC:" + parts[1] } else { accStr = account } return fmt.Sprintf("SPD*1.0*ACC:%s*AM:%s*CC:CZK*MSG:%s", accStr, amtStr, message) } // RenderQRCode encodes payload as a PNG QR code (256×256, error correction Medium). func RenderQRCode(payload string) ([]byte, error) { return qrcode.Encode(payload, qrcode.Medium, 256) }