IRONSOFTWAREHOME
VIDEOS

Umstellung von Veryfi auf IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1. August 2026

Dieser Leitfaden führt .NET-Entwickler durch den Austausch der Cloud-Dokumentenverarbeitungs-API von Veryfidurch IronOCR, eine lokale OCR-Bibliothek. Sie umfasst den Paketwechsel, die Bereinigung von Namespaces sowie vier vollständige Beispiele für die Codemigration, die sich auf die am häufigsten mit Veryfierstellten Muster konzentrieren: Client-Initialisierung, regionbasierte Feldextraktion, Ausgabenkategorisierung mit strukturierten Daten und Webhook-Ersatz. Das vorherige Lesen des Vergleichsartikels ist nicht erforderlich.

Warum von Veryfimigrieren?

Finanzdokumente durchlaufen die Pipeline von Veryfiin einer Richtung: aus Ihrer Infrastruktur heraus und in deren Infrastruktur hinein. Diese architektonische Tatsache ist der Hauptgrund für die meisten Migrationen. Hier sind die konkreten Probleme, die Teams dazu bewegen, den Wechsel vorzunehmen.

Jeder Dokumentenaufruf übermittelt sensible Finanzdaten an einen Server eines Drittanbieters. Quittungen enthalten die letzten vier Ziffern der Kartennummer sowie Angaben zu Lieferantenbeziehungen. Rechnungen enthalten Bankkontonummern, Bankleitzahlen und Umsatzsteuer-Identifikationsnummern von Lieferanten. Kontoauszüge enthalten die vollständige Transaktionshistorie. Mit Veryfilädt jeder einzelne ProcessDocumentAsync-Aufruf diese Bytes zu api.veryfi.com hoch, verarbeitet sie auf der Infrastruktur von Veryfiund gibt JSON zurück. Ihre Kontrolle über diese Daten endet in dem Moment, in dem die HTTP-Anfrage gesendet wird.

Vier Anmeldedaten sind erforderlich und müssen in jeder Umgebung synchronisiert werden. VeryfiClient erfordert clientId, clientSecret, username und apiKey – vier separate Geheimnisse, die in der Konfiguration gespeichert, planmäßig rotiert, in CI/CD-Pipelines injiziert und auf Offenlegung geprüft werden müssen. Ein einziger Leak von Anmeldedaten unterbricht die Authentifizierung für jedes Dokument, das in der gesamten Anwendung verarbeitet wird.IronOCR benötigt einen Lizenzschlüssel.

Die Preise pro Dokument summieren sich ohne Obergrenze. Quittungen kosten etwa 0,05–0,15 $ pro Stück, Rechnungen 0,10–0,25 $, Kontoauszüge 0,15–0,30 $. Bei 50.000 Dokumenten pro Monat ergibt sich ein Betrag von 5.000–15.000 $ pro Monat bei nutzungsabhängiger Abrechnung, ohne Reduzierung im zweiten oder dritten Jahr. Die IronOCR Professional License für 2.999 US-Dollar deckt unbegrenzt viele Dokumente auf unbefristeter Basis ab – die Amortisationszeit gegenüber monatlichen Veryfi-Kosten von 5.000 US-Dollar beträgt weniger als drei Wochen.

Die API ist ausschließlich asynchron, weil die zugrunde liegende Arbeit remote erfolgt. ProcessDocumentAsync ist nicht asynchron, weil die Verarbeitung rechnerisch aufwendig ist; Es handelt sich um einen asynchronen Vorgang, da das Dokument an einen Server gesendet werden muss, sich hinter anderen Anfragen in die Warteschlange einreiht, die Verarbeitung abgeschlossen wird und eine Antwort über das Netzwerk zurückgesendet wird. Die Latenz ist nicht deterministisch. Die HTTP-429-Ratenbegrenzung erfordert eine Wiederholungslogik. HTTP-402-Zahlungsfehler stoppen die Stapelverarbeitung vollständig. HTTP-500-Fehler in der Infrastruktur von Veryfibringen Ihren Arbeitsablauf zum Erliegen.

Der Dokumentumfang von Veryfiendet an der Grenze des Belegdokuments. Die trainierten Modelle liefern zuverlässig strukturierte Felder für Quittungen, Rechnungen, Schecks, Kontoauszüge, W-2-Formulare und Visitenkarten. Außerhalb dieser Liste – allgemeine Geschäftsdokumente, Verträge, Krankenakten, Versanddokumente, benutzerdefinierte interne Formulare – verschlechtern sich die Ergebnisse oder erfordern ein kostenpflichtiges Training des benutzerdefinierten Modells. Unternehmen, die Veryfifür die Automatisierung der Spesenabrechnung einsetzen, stellen in der Regel innerhalb von 6 bis 12 Monaten fest, dass andere Teams OCR für Dokumente benötigen, für die Veryfinicht ausgelegt ist.

Das proprietäre JSON-Schema von Veryfikoppelt alle Extraktionslogik an einen einzigen Anbieter. Jede Codezeile, die response.Vendor?.Name, response.BankAccount?.RoutingNumber oder response.LineItems liest, ist Code, der nur mit Veryfifunktioniert. Ein Anbieterwechsel – oder der Umstieg auf lokale OCR – bedeutet, die gesamte Extraktionslogik von Grund auf neu zu schreiben.

Das grundsätzliche Problem

// Veryfi: financial data leaves your infrastructure on every call
var client = new VeryfiClient(clientId, clientSecret, username, apiKey); // 4 secrets
var bytes = File.ReadAllBytes("invoice-with-routing-number.pdf");
var response = await client.ProcessDocumentAsync(bytes); // bank details transmitted
var routingNumber = response.BankAccount?.RoutingNumber; // arrived via Veryficloud
C#
// IronOCR: routing numbers never leave your server
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; // 1 key
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf("invoice-with-routing-number.pdf"); // processed locally
var result = ocr.Read(input);
var routingNumber = Regex.Match(result.Text, @"Routing\s*#?\s*:?\s*(\d{9})").Groups[1].Value;
C#

##IronOCR vs. Veryfi: Funktionsvergleich

Die folgende Tabelle stellt die Funktionen beider Produkte gegenüber, um die technische Bewertung zu unterstützen.

FeatureVeryfiIronOCR
VerarbeitungsortVeryfiCloud-ServerIhre Infrastruktur
BereitstellungsmodellNur Cloud-APIOn-Premise, Docker, Azure, AWS, Linux
Offline-UnterstützungNeinJa
Internet erforderlichJa (jedes Dokument)Nein
Daten verlassen die InfrastrukturJa (bei jedem Anruf)Niemals
HIPAA-konform ohne BAANeinJa
Unterstützung für luftgesicherte UmgebungenNicht möglichVollständig unterstützt
PreismodellPro Dokument (0,05–0,30 $)Unbefristete Lizenz ($999–2.999 $)
Erforderliche Qualifikationen4 (clientId, clientSecret, benutzername, apiKey)1 Lizenzschlüssel
Synchrone APINein (nur asynchr)Ja
RatenbegrenzungJa (HTTP 429)None
DokumentumfangQuittungen, Rechnungen, Schecks, Kontoauszüge, W-2-Formulare, VisitenkartenJeder Dokumenttyp
Benutzerdefinierte DokumenttypenSchulung zum bezahlten Modell erforderlichBeliebiges Layout mittels Regex/Musterextraktion
PDF-EingabeJa (Byte-Upload)Ja (einheimisch, lokal)
Durchsuchbare PDF-AusgabeNeinJa (result.SaveAsSearchablePdf())
Regionsbasierte OCRNeinJa (CropRectangle)
Barcode-LesungNeinJa (derselbe OCR-Durchlauf)
Strukturierter Zugriff auf ErgebnisseVorverarbeitete JSON-FelderSeiten, Absätze, Zeilen, Wörter mit Koordinaten
KonfidenzbewertungPro Feld (proprietär)Pro-Wort und insgesamt (result.Confidence)
Unterstützung für mehr als 125 SprachenBeschränktJa (NuGet-Sprachpakete)
Thread-sichere parallele VerarbeitungEs gelten HTTP-ParallelitätsbeschränkungenVollständig (ein IronTesseract pro Thread)
Unit-Tests ohne MocksErfordert HTTP-MockingDirekte lokale Tests

Schnellstart: Migration von Veryfizu IronOCR

Schritt 1: Ersetzen des NuGet-Pakets

Entfernen Sie das VeryfiSDK:

dotnet remove package Veryfi
SHELL

Installieren Sie IronOCR über NuGet :

dotnet add package IronOcr

Schritt 2: Namespaces aktualisieren

Ersetzen Sie Veryfi-Namespaces durch den IronOCR-Namespace:

// Before (Veryfi)
using Veryfi;
using Veryfi.Models;

// After (IronOCR)
using IronOcr;
using System.Text.RegularExpressions;
C#

Schritt 3: Lizenz initialisieren

Fügen Sie diese Zeile einmal beim Start der Anwendung ein, vor jedem OCR-Aufruf:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

Beispiele für die Code-Migration

Ersatz für den Dokumentenverarbeitungs-Client

Veryfi-Dienste basieren auf Konstruktorinjektion von VeryfiClient. Der Konstruktor mit vier Anmeldedaten ist ein naheliegender Ansatz für die Abhängigkeitsinjektion, erzeugt jedoch vier Geheimnisse, die verwaltet und rotiert werden müssen. Durch den Austausch gegen IronOCR werden die Anmeldedaten in einem einzigen Lizenzschlüssel zusammengefasst und die Instanziierung der Verarbeitungs-Engine in die Service-Klasse selbst verlagert.

Ansatz von Veryfi:

using Veryfi;
using Microsoft.Extensions.Configuration;

public class ExpenseDocumentService
{
    private readonly VeryfiClient _client;

    // Four credentials injected — four secrets to manage, store, rotate
    public ExpenseDocumentService(IConfiguration config)
    {
        _client = new VeryfiClient(
            config["Veryfi:ClientId"],       // secret 1
            config["Veryfi:ClientSecret"],   // secret 2
            config["Veryfi:Username"],       // secret 3
            config["Veryfi:ApiKey"]          // secret 4
        );
    }

    public async Task<string> GetVendorNameAsync(string documentPath)
    {
        var bytes = File.ReadAllBytes(documentPath);
        // Document uploaded to Veryfion this call
        var response = await _client.ProcessDocumentAsync(bytes);
        return response.Vendor?.Name;
    }

    public async Task<decimal?> GetTotalAsync(string documentPath)
    {
        var bytes = File.ReadAllBytes(documentPath);
        var response = await _client.ProcessDocumentAsync(bytes);
        return response.Total;
    }
}
C#

IronOCR Ansatz:

using IronOcr;
using System.Text.RegularExpressions;

public class ExpenseDocumentService
{
    private readonly IronTesseract _ocr;

    // One license key — set once at startup, not per-instance
    public ExpenseDocumentService()
    {
        _ocr = new IronTesseract();
    }

    public string GetVendorName(string documentPath)
    {
        // All processing local — document bytes never leave this server
        var result = _ocr.Read(documentPath);

        // Vendor is typically the first non-whitespace line on a receipt
        return result.Pages[0].Paragraphs
            .OrderBy(p => p.Y)
            .Select(p => p.Text.Trim())
            .FirstOrDefault(t => t.Length > 3);
    }

    public decimal? GetTotal(string documentPath)
    {
        var result = _ocr.Read(documentPath);
        var match = Regex.Match(result.Text,
            @"(?:Total|Grand Total|Amount Due):?\s*\$?\s*([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase);
        return match.Success
            ? decimal.Parse(match.Groups[1].Value.Replace(",", ""))
            : (decimal?)null;
    }
}
C#

Die Änderung des Konstruktors beseitigt vier Konfigurationseinträge aus jeder Umgebung: appsettings.json, Docker-Geheimnisse, Azure-Schlüsselverweise und CI/CD-Pipeline-Variablen. Die IronTesseract-Instanz ist über mehrere Aufrufe im selben Thread wiederverwendbar. Siehe die IronTesseract-Einrichtungsanleitung für Singleton-Registrierungsmuster in .NET Core-Dependency-Injection-Containern.

Extraktion von Feldern aus Belegen mit regionenbasierter OCR

Veryfi extrahiert Belegfelder, indem es seine trainierten ML-Modelle auf das gesamte Dokumentbild anwendet und eine vorstrukturierte JSON-Antwort zurückgibt. Das Äquivalent von IronOCR ist ein regionsbasiertes OCR mit CropRectangle, das auf spezifische Zonen des Empfangsbildes zielt – Kopfzeile für Anbieter, Fußzeile für Summen – anstatt einen Vollseiten-Durchgang zu laufen und die Ausgabe nach Mustern zu durchsuchen. Dies ist bei bekannten Layouts schneller und genauer, wenn der relevante Bereich klar definiert ist.

Ansatz von Veryfi:

using Veryfi;

public class ReceiptFieldExtractor
{
    private readonly VeryfiClient _client;

    public ReceiptFieldExtractor(VeryfiClient client)
    {
        _client = client;
    }

    public async Task<(string Vendor, decimal? Total, decimal? Tax)>
        ExtractReceiptFieldsAsync(string imagePath)
    {
        var bytes = File.ReadAllBytes(imagePath);

        // Full document uploaded — Veryfi's ML returns structured fields
        var response = await _client.ProcessDocumentAsync(bytes);

        return (
            Vendor: response.Vendor?.Name,
            Total:  response.Total,
            Tax:    response.Tax
        );
    }
}
C#

IronOCR Ansatz:

using IronOcr;
using System.Text.RegularExpressions;

public class ReceiptFieldExtractor
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public (string Vendor, decimal? Total, decimal? Tax)
        ExtractReceiptFields(string imagePath)
    {
        // Region 1: Header zone — vendor name typically in top 15% of receipt
        var headerRegion = new CropRectangle(0, 0, 800, 150);
        using var headerInput = new OcrInput();
        headerInput.LoadImage(imagePath, headerRegion);
        headerInput.Deskew();
        var headerResult = _ocr.Read(headerInput);

        // Region 2: Footer zone — totals typically in bottom 20% of receipt
        var footerRegion = new CropRectangle(0, 650, 800, 200);
        using var footerInput = new OcrInput();
        footerInput.LoadImage(imagePath, footerRegion);
        footerInput.DeNoise();
        var footerResult = _ocr.Read(footerInput);

        var vendor = headerResult.Pages[0].Paragraphs
            .OrderBy(p => p.Y)
            .Select(p => p.Text.Trim())
            .FirstOrDefault(t => t.Length > 3);

        var footerText = footerResult.Text;

        var totalMatch = Regex.Match(footerText,
            @"(?:Total|Grand Total):?\s*\$?\s*([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase);

        var taxMatch = Regex.Match(footerText,
            @"(?:Tax|Sales Tax|VAT):?\s*\$?\s*([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase);

        return (
            Vendor: vendor,
            Total: totalMatch.Success
                ? decimal.Parse(totalMatch.Groups[1].Value.Replace(",", ""))
                : (decimal?)null,
            Tax: taxMatch.Success
                ? decimal.Parse(taxMatch.Groups[1].Value.Replace(",", ""))
                : (decimal?)null
        );
    }
}
C#

CropRectangle nimmt (x, y, width, height) in Pixeln. Die Verarbeitung nur der Kopf- und Fußzeilenbereiche ist schneller als ein vollständiges Einlesen der Seite und vermeidet falsche Übereinstimmungen mit Einzelpostenbeträgen im Hauptteil des Belegs. Der Leitfaden zur regionenbasierten OCR behandelt Koordinatenmessstrategien für Dokumente variabler Größe, und das Beispiel zum Zuschneiden von Regionen zeigt das vollständige Muster.

Kostenkategorisierung mit strukturierten Absatzdaten

Veryfi gibt response.LineItems als vorstrukturiertes Array von Objekten mit bereits analysierten Description, Quantity, UnitPrice und Total zurück.IronOCR bietet das Äquivalent durch result.Pages[0].Paragraphs und result.Lines, die jeden Textblock mit seinen X/Y-Koordinaten offenlegen. Die Logik zur Kategorisierung von Ausgaben – also die Entscheidung, ob es sich bei einem Posten um eine Mahlzeit, eine Reise, Material oder eine Softwaregebühr handelt – funktioniert in beiden Fällen auf der Grundlage desselben Textes. Der Unterschied besteht darin, dass Sie bei IronOCR die Kategorisierungslogik selbst besitzen, anpassen und erweitern können, ohne einen kostenpflichtigen ML-Umschulungszyklus durchlaufen zu müssen.

Ansatz von Veryfi:

using Veryfi;

public class ExpenseCategorizer
{
    private readonly VeryfiClient _client;

    public ExpenseCategorizer(VeryfiClient client)
    {
        _client = client;
    }

    public async Task<Dictionary<string, decimal>> CategorizeExpensesAsync(string receiptPath)
    {
        var bytes = File.ReadAllBytes(receiptPath);
        var response = await _client.ProcessDocumentAsync(bytes);

        var categories = new Dictionary<string, decimal>();

        // Line items arrive pre-parsed from Veryfi's ML pipeline
        foreach (var item in response.LineItems ?? Enumerable.Empty<dynamic>())
        {
            var category = response.Category ?? "Uncategorized";
            var amount   = (decimal)(item.Total ?? 0m);

            if (!categories.ContainsKey(category))
                categories[category] = 0m;

            categories[category] += amount;
        }

        return categories;
    }
}
C#

IronOCR Ansatz:

using IronOcr;
using System.Text.RegularExpressions;

public class ExpenseCategorizer
{
    private readonly IronTesseract _ocr = new IronTesseract();

    // Keyword-based categorization — tune these for your expense policy
    private static readonly Dictionary<string, string[]> CategoryKeywords = new()
    {
        ["Meals & Entertainment"] = new[] { "restaurant", "cafe", "coffee", "lunch", "dinner", "food", "bar" },
        ["Travel"]                = new[] { "airline", "hotel", "uber", "lyft", "taxi", "parking", "gas", "fuel" },
        ["Office Supplies"]       = new[] { "staples", "office depot", "paper", "ink", "toner", "supplies" },
        ["Software & Subscriptions"] = new[] { "adobe", "microsoft", "github", "aws", "azure", "slack" }
    };

    public Dictionary<string, decimal> CategorizeExpenses(string receiptPath)
    {
        var result = _ocr.Read(receiptPath);

        // Use paragraph coordinates to isolate line items
        // Line items typically appear in the middle vertical band of the receipt
        var lineItemParagraphs = result.Pages[0].Paragraphs
            .Where(p => p.Y > 150 && p.Y < 650) // skip header/footer regions
            .OrderBy(p => p.Y)
            .ToList();

        var categories = new Dictionary<string, decimal>();
        var pricePattern = new Regex(@"\$?([\d,]+\.\d{2})$");
        var vendorText   = result.Text.ToLower();

        // Determine top-level category from vendor name
        var topCategory = "Uncategorized";
        foreach (var (cat, keywords) in CategoryKeywords)
        {
            if (keywords.Any(kw => vendorText.Contains(kw)))
            {
                topCategory = cat;
                break;
            }
        }

        // Extract individual line item amounts
        foreach (var para in lineItemParagraphs)
        {
            var priceMatch = pricePattern.Match(para.Text.Trim());
            if (!priceMatch.Success)
                continue;

            if (!decimal.TryParse(priceMatch.Groups[1].Value.Replace(",", ""), out var amount))
                continue;

            // Classify individual items where keywords appear in the description
            var itemCategory = topCategory;
            var descriptionText = para.Text.ToLower();
            foreach (var (cat, keywords) in CategoryKeywords)
            {
                if (keywords.Any(kw => descriptionText.Contains(kw)))
                {
                    itemCategory = cat;
                    break;
                }
            }

            if (!categories.ContainsKey(itemCategory))
                categories[itemCategory] = 0m;

            categories[itemCategory] += amount;
        }

        return categories;
    }
}
C#

Die Paragraphs-Sammlung liefert die Y-Koordinate jedes Textblocks, was es einfach macht, die vertikale Zone zu isolieren, in der Positionen auf einem Standard-Empfangslayout erscheinen. Der Leitfaden für strukturierten Datenzugriff erklärt die vollständige Hierarchie von Pages, Paragraphs, Lines, Words und Characters mit ihren Koordinateneigenschaften. Für Belege mit schlechter Scanqualität – zerknittertes Papier, kontrastarmer Thermodruck – behandelt der Leitfaden zur Bildqualitätskorrektur Vorverarbeitungsfilter, die die Genauigkeit verbessern, bevor die Kategorisierungslogik ausgeführt wird.

Webhook-Eliminierung und synchrone Batch-Ersetzung

Bei hohen Dokumentenvolumina empfiehlt Veryfieine Webhook-basierte Benachrichtigung anstelle von Polling. Das Muster erfordert einen öffentlich zugänglichen HTTPS-Endpunkt, einen Webhook-Schlüssel zur Signaturüberprüfung, eine Warteschlange zur Speicherung der Ergebnisse bis zum Auslösen des Webhooks sowie eine Wiederholungslogik für fehlgeschlagene Übermittlungen. Dies ist eine wichtige Infrastruktur für eine Lösung, die letztlich darauf abzielt, die Tatsache zu umgehen, dass Cloud-OCR im Vergleich zur lokalen Verarbeitung langsam ist.IronOCR verarbeitet synchron. Es gibt keine Async-Lücke, die mit einem Webhook überbrückt werden muss.

Ansatz von Veryfi:

using Veryfi;
using Microsoft.AspNetCore.Mvc;

// Veryfiwebhook receiver — required for high-volume reliable processing
[ApiController]
[Route("webhooks")]
public class VeryfiWebhookController : ControllerBase
{
    private readonly IDocumentResultQueue _queue;

    public VeryfiWebhookController(IDocumentResultQueue queue)
    {
        _queue = queue;
    }

    [HttpPost("veryfi")]
    public IActionResult ReceiveWebhook([FromBody] VeryfiWebhookPayload payload,
                                        [FromHeader(Name = "X-Veryfi-Token")] string token)
    {
        // Validate webhook signature — prevents spoofed payloads
        if (!IsValidSignature(token, payload))
            return Unauthorized();

        // Enqueue result for async downstream consumption
        _queue.Enqueue(new DocumentResult
        {
            DocumentId = payload.Id,
            Vendor     = payload.Data?.Vendor?.Name,
            Total      = payload.Data?.Total
        });

        return Ok();
    }

    private bool IsValidSignature(string token, VeryfiWebhookPayload payload) =>
        // HMAC validation against webhook secret — infrastructure requirement
        token == ComputeHmac(payload, Environment.GetEnvironmentVariable("VERYFI_WEBHOOK_SECRET"));
}

// Document batch submission — fire and forget, results arrive via webhook
public class VeryfiDocumentBatchSubmitter
{
    private readonly VeryfiClient _client;

    public async Task SubmitBatchAsync(string[] documentPaths)
    {
        foreach (var path in documentPaths)
        {
            var bytes = File.ReadAllBytes(path);
            // Submit — result arrives asynchronously via webhook, not here
            await _client.ProcessDocumentAsync(bytes);
        }
    }
}
C#

IronOCR Ansatz:

using IronOcr;
using System.Text.RegularExpressions;
using System.Collections.Concurrent;

//Neinwebhook controller needed — results are synchronous and local
public class DocumentBatchProcessor
{
    // IronTesseract is thread-safe when one instance is created per thread
    public List<DocumentResult> ProcessBatch(string[] documentPaths)
    {
        var results = new ConcurrentBag<DocumentResult>();

        Parallel.ForEach(documentPaths, documentPath =>
        {
            // One IronTesseract per thread — thread-safe pattern
            var ocr    = new IronTesseract();
            var result = ocr.Read(documentPath);

            results.Add(new DocumentResult
            {
                FilePath   = documentPath,
                Vendor     = ExtractVendor(result),
                Total      = ExtractTotal(result.Text),
                Confidence = result.Confidence,
                // Result is available immediately — no queue, no webhook
                ProcessedAt = DateTime.UtcNow
            });
        });

        return results.OrderBy(r => r.FilePath).ToList();
    }

    private string ExtractVendor(OcrResult result)
    {
        // Vendor: first substantive paragraph ordered by vertical position
        return result.Pages[0].Paragraphs
            .OrderBy(p => p.Y)
            .Select(p => p.Text.Trim())
            .FirstOrDefault(t => !string.IsNullOrWhiteSpace(t) && t.Length > 3);
    }

    private decimal? ExtractTotal(string text)
    {
        var match = Regex.Match(text,
            @"(?:Total|Grand Total|Amount Due):?\s*\$?\s*([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase);
        return match.Success
            ? decimal.Parse(match.Groups[1].Value.Replace(",", ""))
            : (decimal?)null;
    }
}

public class DocumentResult
{
    public string FilePath   { get; set; }
    public string Vendor     { get; set; }
    public decimal? Total    { get; set; }
    public double Confidence { get; set; }
    public DateTime ProcessedAt { get; set; }
}
C#

Durch das Entfernen der Webhook-Schicht entfallen der HTTPS-Endpunkt, die Anforderung zur Rotation des Webhook-Geheimnisses, die Ergebniswarteschlange, die HMAC-Validierungslogik und die Konfiguration für Wiederholungsversuche. Die gesamte nachgelagerte Infrastruktur existiert nur, weil die Ergebnisse von Veryfiasynchron von einem Remote-Server eintreffen. Mit IronOCR ersetzt Parallel.ForEach alles. Das Multithreading-Beispiel zeigt das pro-Thread IronTesseract-Muster im Detail, und der asynchrone OCR-Leitfaden behandelt Task.Run-Integration für UI-Reaktionsfähigkeit. Der Leitfaden zur Geschwindigkeitsoptimierung behandelt die Instanzkonfiguration für maximalen Durchsatz bei Batch-Workloads.

VeryfiAPI zu IronOCR Mapping-Referenz

VeryfiIronOCR-Äquivalent
new VeryfiClient(clientId, clientSecret, username, apiKey)new IronTesseract() + IronOcr.License.LicenseKey = "key"
_client.ProcessDocumentAsync(bytes)ocr.Read(filePath) oder ocr.Read(ocrInput)
_client.ProcessDocumentAsync(bytes, categories: new[] { "invoices" }) input.LoadPdf(path); ocr.Read(input)
_client.ProcessDocumentAsync(bytes, categories: new[] { "bank_statements" })input.LoadPdf(path); ocr.Read(input)
response.Vendor?.NameErster Absatz geordnet nach p.Y von result.Pages[0].Paragraphs
response.TotalRegex.Match(result.Text, @"Total:?\s*\$?([\d,]+\.\d{2})")
response.TaxRegex.Match(result.Text, @"Tax:?\s*\$?([\d,]+\.\d{2})")
response.DateRegex.Match(result.Text, @"\d{1,2}/\d{1,2}/\d{4}")
response.LineItemsresult.Pages[0].Paragraphs gefiltert nach Y-Koordinatenbereich
response.InvoiceNumberRegex.Match(result.Text, @"Invoice\s*#?\s*:?\s*(\w+[-\w]*)")
response.BankAccount?.AccountNumberRegex.Match(result.Text, @"Account\s*#?\s*:?\s*(\d{4,})")
response.BankAccount?.RoutingNumberRegex.Match(result.Text, @"Routing\s*#?\s*:?\s*(\d{9})")
response.ConfidenceScoreresult.Confidence (insgesamt) oder word.Confidence (pro Wort)
response.Payment?.Last4Regex.Match(result.Text, @"\*{4}\s*(\d{4})")
VeryfiApiException (401/402/429/500)Standardmäßige .NET-Ausnahmen – keine HTTP-Fehlercodes für die lokale Verarbeitung
Base64-Kodierung vor dem UploadNicht erforderlich — ocr.Read(filePath) akzeptiert Dateipfade direkt
response.CategoryBenutzerdefiniertes Schlüsselwort-Matching gegen result.Text
Deserialisierung der Webhook-NutzdatenNicht erforderlich — ocr.Read() returned synchron das Ergebnis
ProcessDocumentAsync mit Wiederholungen/AusfallsicherungNicht erforderlich – keine Ratenbeschränkungen bei der lokalen Verarbeitung

Gängige Migrationsprobleme und Lösungen

Problem 1: Fehlende vorverarbeitete Felder

Veryfi: response.Vendor?.Name, response.Total und response.LineItems kommen als strukturierte Felder aus einem vortrainierten ML-Modell. Auf der Client-Seite ist keine Extraktionslogik erforderlich.

Lösung: Schreiben Sie Regex-Muster für jedes Feld, das Ihre Anwendung verwendet. Der Zeitaufwand für die Migration beträgt in der Regel 8–24 Stunden, je nachdem, wie viele unterschiedliche Dokumentlayouts Sie bearbeiten. Für gängige Quittungs- und Rechnungsmuster bieten das OCR-Tutorial für Rechnungen und das Tutorial zum Scannen von Quittungen vollständige Implementierungen von Extraktionsmustern.

// Map each Veryfifield to a Regex extraction
private static readonly Dictionary<string, string> FieldPatterns = new()
{
    ["InvoiceNumber"] = @"Invoice\s*#?\s*:?\s*(\w+[-\w]*)",
    ["PurchaseOrder"]  = @"(?:PO|P\.O\.|Purchase Order)\s*#?\s*:?\s*(\w+)",
    ["DueDate"]        = @"Due\s*(?:Date)?:?\s*(\d{1,2}/\d{1,2}/\d{4})",
    ["PaymentTerms"]   = @"(?:Terms|Net)\s*:?\s*(\w+\s*\d+)"
};

public string ExtractField(string text, string fieldName)
{
    if (!FieldPatterns.TryGetValue(fieldName, out var pattern))
        return null;
    var match = Regex.Match(text, pattern, RegexOptions.IgnoreCase);
    return match.Success ? match.Groups[1].Value.Trim() : null;
}
C#

Problem 2: Asynchrone Methodensignaturen im gesamten Code

Veryfi: ProcessDocumentAsync ist asynchron auf der Veryfi-SDK-Ebene. Teams propagieren typischerweise await durch jede aufrufende Methode bis zum Aufrufstack, was bedeutet, dass Dienstklassen, Controller und Hintergrundjobs alle async Task<t>-Signaturen tragen.

Lösung: IronOCRs Read() ist synchron. Bestehende async-Methodensignaturen können beibehalten werden, indem sie während der Übergangsperiode mit Task.Run umwickelt werden. Dadurch werden umfangreiche Signaturänderungen im gesamten Code vermieden, während die Cloud-Abhängigkeit dennoch beseitigt wird.

// Preserve async signature during transition — no codebase-wide refactor needed
public async Task<string> GetVendorNameAsync(string documentPath)
{
    return await Task.Run(() =>
    {
        var result = _ocr.Read(documentPath);
        return result.Pages[0].Paragraphs
            .OrderBy(p => p.Y)
            .Select(p => p.Text.Trim())
            .FirstOrDefault(t => t.Length > 3);
    });
}
C#

Problem 3: Über verschiedene Umgebungen verteilte Konfiguration von Anmeldedaten

Veryfi: Vier Anmeldedaten (Veryfi:ClientId, Veryfi:ClientSecret, Veryfi:Username, Veryfi:ApiKey) erscheinen in appsettings.json, Blockumgebungen von Umgebungsvariablen in Docker Compose-Dateien, GitHub Actions-Geheimnissen, Azure-Schlüsselverweisen und CI/CD-Pipeline-Konfigurationen.

Lösung: Suchen und entfernen Sie alle vier Anmeldeinformationen aus jeder Umgebung. Fügen Sie eine einzige IRONOCR_LICENSE_KEY-Umgebungsvariable hinzu. Beim Start laden.

# Find all Veryficredential references
grep -r "Veryfi:ClientId\|Veryfi:ClientSecret\|Veryfi:Username\|Veryfi:ApiKey" \
    --include="*.json" --include="*.yml" --include="*.yaml" --include="*.env" .
SHELL
// Load from environment at startup
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
    ?? throw new InvalidOperationException("IRONOCR_LICENSE_KEY not set");
C#

Problem 4: Probleme mit der Scanqualität, die zuvor nicht sichtbar waren

Veryfi: Die Cloud-Verarbeitung umfasst die serverseitige Bildverbesserung vor der Ausführung von ML-Inferenz. Scans von Belegen in schlechter Qualität – zerknittertes Papier, verblasste Thermodrucke, schräge Handyfotos – wurden vor der Feldextraktion automatisch korrigiert.

Lösung: Wenden Sie die Vorverarbeitungs-Pipeline von IronOCR explizit an. Deskew(), DeNoise() und Contrast() decken die Mehrheit der realen Scanqualitätsprobleme von Quittungen ab.

using var input = new OcrInput();
input.LoadImage("receipt-phone-photo.jpg");
input.Deskew();        // correct rotation from angled phone capture
input.DeNoise();       // remove compression artifacts
input.Contrast();      // improve faded thermal print
input.Sharpen();       // recover edge detail

var result = _ocr.Read(input);
C#

Der Leitfaden zur Bildqualitätskorrektur und das Tutorial zu Bildfiltern behandeln, welche Filter bei bestimmten Arten von Scan-Qualitätsverlusten anzuwenden sind.

Thema 5: Durchsatz bei der Verarbeitung großer Datenmengen

Veryfi: Ratenbegrenzungen drosseln die Geschwindigkeit der Dokumentenübermittlung. HTTP-429-Antworten erfordern eine Exponential-Backoff-Logik. Der Durchsatz wird durch das von Veryfifestgelegte Ratenlimit pro Plan begrenzt, nicht durch Ihre Hardware.

**Lösung:**IronOCR ist nur durch die Anzahl der CPU-Kerne begrenzt. Verwenden Sie Parallel.ForEach mit einer IronTesseract-Instanz pro Thread. Auf einem 8-Kern-Server skaliert der Durchsatz in etwa linear mit der Anzahl der Kerne.

// One IronTesseract per thread — do not share instances across threads
Parallel.ForEach(
    documentPaths,
    new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
    path =>
    {
        var ocr    = new IronTesseract();
        var result = ocr.Read(path);
        SaveResult(path, result.Text, result.Confidence);
    });
C#

Problem 6: Proprietäres JSON-Schema, das an Veryfigebunden ist

Veryfi: Der gesamte Extraktionscode liest aus dem Antwortschema von Veryfi: response.Vendor?.Name, response.LineItems, response.BankAccount?.RoutingNumber. Dieser Code funktioniert nur mit dem SDK von Veryfi. Jede Änderung von Feldnamen in einem Veryfi-API-Update führt zu Fehlern im Anwendungscode.

Lösung: IronOCR-Extraktion verwendet die Standard-.NET System.Text.RegularExpressions.Regex gegen einfachen Text. Die Muster sind portabel, ohne Mocking eines SDK testbar und unter Ihrer Kontrolle. Unit-Tests laufen ohne Netzwerkverbindung.

// Extraction logic that is fully portable and unit-testable
[Fact]
public void ExtractsRoutingNumberFromInvoiceText()
{
    const string sampleText = "Routing Number: 021000021\nAccount: 1234567890";
    var match = Regex.Match(sampleText, @"Routing\s*(?:Number)?:?\s*(\d{9})",
                            RegexOptions.IgnoreCase);
    Assert.True(match.Success);
    Assert.Equal("021000021", match.Groups[1].Value);
}
C#

Veryfi-Migrationscheckliste

Vor der Migration

Überprüfen Sie den Code, um alle Verwendungen von Veryfizu erfassen, bevor Sie Änderungen am Code vornehmen:

# Find all Veryfiusing statements
grep -rn "using Veryfi" --include="*.cs" .

# Find all VeryfiClient instantiations
grep -rn "VeryfiClient\|ProcessDocumentAsync" --include="*.cs" .

# Find all Veryfiresponse field accesses
grep -rn "response\.Vendor\|response\.Total\|response\.LineItems\|response\.BankAccount" --include="*.cs" .

# Find all credential configuration references
grep -r "Veryfi:ClientId\|Veryfi:ClientSecret\|Veryfi:Username\|Veryfi:ApiKey" \
    --include="*.json" --include="*.yml" --include="*.yaml" --include="*.env" .

# Find all webhook-related code
grep -rn "VeryfiWebhook\|X-Veryfi-Token\|webhook" --include="*.cs" .
SHELL

Nehmen Sie die Gesamtanzahl der ProcessDocumentAsync-Aufrufstellen auf, die Liste der Antwortfelder, die pro Aufrufstelle zugegriffen werden, und die Liste der Umgebungen mit Veryfi-Anmeldedaten.

Code-Migration

  1. Entfernen Sie das Veryfi NuGet-Paket aus allen Projekten in der Lösung.
  2. Installieren Sie das IronOcr NuGet-Paket in allen Projekten, die zuvor auf Veryfi verwiesen haben.
  3. Fügen Sie IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; zum Anwendungsstart hinzu (vor jedem OCR-Aufruf).
  4. Ersetzen Sie alle using Veryfi; und using Veryfi.Models; Aussagen durch using IronOcr;.
  5. Ersetzen Sie VeryfiClient Konstruktorinjektion durch IronTesseract Feldinitialisierung.
  6. Entfernen Sie alle vier Veryfi-Anmeldedateneinträge aus jedem appsettings.json, appsettings.*.json und Geheimniskonfigurationsdatei.
  7. Konvertieren Sie ProcessDocumentAsync(bytes)-Aufrufe zu ocr.Read(filePath) oder ocr.Read(ocrInput).
  8. Ersetzen Sie response.Vendor?.Name-Zugriffe durch absatzgeordnete Textextraktion aus result.Pages[0].Paragraphs.
  9. Ersetzen Sie response.Total, response.Tax, response.InvoiceNumber und andere strukturierte Feldzugriffe durch Regex-Muster gegen result.Text.
  10. Ersetzen Sie response.LineItems Iteration mit Y-Koordinaten-gefilterter result.Pages[0].Paragraphs Iteration.
  11. Löschen Sie die Webhook-Controller-Klassen und entfernen Sie die Webhook-Endpunkt-Registrierungen.
  12. Entfernen Sie die geheimen Webhook-Umgebungsvariablen aus allen Umgebungen.
  13. Fügen Sie OcrInput mit Vorverarbeitung (Deskew(), DeNoise(), Contrast()) für gescannte Bildinputs hinzu.
  14. Ersetzen Sie einsträngige sequentielle Schleifen mit Parallel.ForEach mit einem IronTesseract pro Thread.
  15. Fügen Sie IRONOCR_LICENSE_KEY zu allen Umgebungsvariablenkonfigurationen und CI/CD-Geheimnisspeichern hinzu.

Nach der Migration

  • Stellen Sie sicher, dass nach der Migrationsbereitstellung keine Veryfi-Netzwerkaufrufe in den HTTP-Traffic-Protokollen erscheinen.
  • Überprüfen Sie anhand einer Stichprobe von 20–50 Belegen, ob die extrahierten Anbieternamen mit den erwarteten Werten übereinstimmen.
  • Überprüfen Sie, ob die extrahierten Summen innerhalb einer Toleranz von 0,01 $ mit den erwarteten Werten für denselben Datensatz übereinstimmen.
  • Überprüfen Sie, ob die Extraktion der Rechnungsnummern für jedes Rechnungsformat im Dokumentenkorpus erfolgreich ist.
  • Testen Sie den Durchsatz der Stapelverarbeitung im Vergleich zum Veryfi-Basisdurchsatz, um die Aufhebung der Ratenbegrenzung zu bestätigen.
  • Führen Sie die vollständige Suite der Tests ohne Netzwerkverbindung aus, um die vollständige Unabhängigkeit von der Cloud zu bestätigen.
  • Bestätigen Sie, dass result.Confidence-Ergebnisse über 80 % für saubere Dokumentenscans liegen; Ein Wert unter 80 % deutet darauf hin, dass ein Vorverarbeitungsschritt hinzugefügt werden sollte.
  • Stellen Sie sicher, dass alle vier Veryfi-Anmeldedaten aus jeder Umgebung (Entwicklung, Staging, Produktion) entfernt wurden.
  • Stellen Sie sicher, dass Webhook-Endpunkte den Status 404 zurückgeben oder aus der Routing-Tabelle entfernt wurden.
  • Testen Sie das Verhalten bei Scans von Belegen in schlechter Qualität (zerknittert, verblasst, schräg) bei aktivierter Vorverarbeitungs-Pipeline.

Wichtigste Vorteile der Migration zu IronOCR

Lokal verarbeitete Finanzdokumente sind Dokumente, die nicht an Dritte weitergegeben werden können. Nach der Migration werden Bankkontonummern, die aus Rechnungen extrahiert wurden, Bankleitzahlen, die aus Schecks ausgelesen wurden, sowie Transaktionsverläufe, die aus Kontoauszügen gelesen wurden, vollständig auf Ihrer Hardware verarbeitet. Weder Sicherheitsvorfälle bei Dritten noch der Datenzugriff durch Unterauftragsverarbeiter oder eine Verletzung der Veryfi-Infrastruktur können Dokumente offenlegen, die Ihre Server nie verlassen haben.

Die Kosten pro Dokument sinken am Tag der Migrationsbereitstellung auf null. Bei 50.000 Dokumenten pro Monat entfällt der monatliche Veryfi-Posten in Höhe von 5.000 bis 15.000 US-Dollar. The once-only IronOCR Professional License worth 2.999 US dollars amortizes in the first week of the first month. Bei höheren Volumina summieren sich die Einsparungen jedes Jahr, ohne dass Mengenrabatte ausgehandelt oder Verträge verlängert werden müssen.

Der Verarbeitungsdurchsatz skaliert mit der Hardware, nicht mit den Ratenbeschränkungen eines Anbieters. HTTP-429-Antworten, Durchsatzbegrenzungen auf Planebene und saisonale Überziehungsgebühren sind architektonische Artefakte von Cloud-APIs. Mit IronOCR erhöht das Hinzufügen von CPU-Kernen den Durchsatz proportional. Ein Stapel von 10.000 Belegen wird nach Ihrem Zeitplan verarbeitet, nicht nach dem Ratenlimit-Zeitplan von Veryfi.

Jeder Dokumenttyp wird mit derselben API verarbeitet. Das Unternehmen benötigt kein zweites OCR-Tool mehr, wenn die Personalabteilung die Verarbeitung von Onboarding-Formularen anfordert, die Rechtsabteilung die Extraktion von Vertragstexten benötigt oder der Betrieb Daten aus Versanddokumenten benötigt. ocr.Read() verarbeitet alle. Das Tutorial zum Lesen von Text aus Bildern und die speziellen Dokumentenhandbücher decken die gesamte Bandbreite der von IronOCR verarbeiteten Dokumentformate ab.

Die Extraktionslogik wird zu einem integralen Bestandteil des Code-Basis. Regex-Muster befinden sich in der Quellcodeverwaltung, können in Pull-Anfragen überprüft, in Unit-Tests ohne Mocking eines SDK getestet und auf Basis von Produktions-Feedback angepasst werden. Wenn das vortrainierte Modell von Veryfieinen falschen Anbieternamen zurückgibt, gibt es nichts anzupassen. Wenn das Extraktionsmuster von IronOCR einen falschen Anbieternamen zurückgibt, besteht die Korrektur aus einer einzeiligen Änderung des regulären Ausdrucks mit einem Unit-Test. Die Lizenzierungsseite von IronOCR behandelt verschiedene Tarifoptionen, darunter das SaaS-Abonnement für Teams, die eine jährliche Abrechnung einem einmaligen Kauf vorziehen.

**Der Platzbedarf für die Bereitstellung reduziert sich auf ein einziges NuGet-Paket, das überall ausgeführt werden kann.**IronOCR wird als ein einziges Paket installiert, ohne externe Abhängigkeiten, ohne Verwaltung nativer Binärdateien und ohne Konfiguration des Tessdata-Ordners. Die gleiche Paketreferenz wird unter Windows, Linux, macOS, Docker, Azure App Service und AWS Lambda ohne plattformabhängigen Code aufgelöst. Siehe den Docker-Bereitstellungsleitfaden und den Linux-Bereitstellungsleitfaden für containerisierte Umgebungen, in denen die Anforderungen von Veryfian den Netzwerkausgang ein Hindernis für die Bereitstellung darstellen.

Hinweis:: Tesseract und Veryfisind eingetragene Marken ihrer jeweiligen Inhaber. Diese Seite ist in keiner Weise mit Google oder Veryfiverbunden, unterstützt oder gesponsert von diesen. Alle Produktnamen, Logos und Marken sind Eigentum ihrer jeweiligen Eigentümer. Vergleiche dienen nur zu Informationszwecken und spiegeln öffentlich zugängliche Informationen zum Zeitpunkt des Schreibens wider.

Verwandte Artikel

Key in blue circle

Holen Sie sich sofort Ihren kostenlosen 30-Tage-Testschlüssel.

Your trial license will be sent to your email address

Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.

bullet_checkedIhr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Erhalten Sie Ihre unverbindliche Beratung
Füllen Sie das Formular unten aus oder senden Sie eine E-Mail an sales@ironsoftware.com
Ihre Daten werden immer vertraulich behandelt.
Von Millionen von Ingenieur*innen weltweit vertraut
Kundenlogos von Iron Software
Erhalten Sie sofort Ihren kostenlosen 30-Tage-Testschlüssel.
Ihr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.