IRONSOFTWAREHOME
FILMY

Migracja z Veryfi do IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 sierpnia 2026

Ten przewodnik przeprowadza programistów .NET przez proces zastępowania chmurowego API przetwarzania dokumentówVeryfilokalną biblioteką OCR IronOCR. Obejmuje on zamianę pakietów, czyszczenie przestrzeni nazw oraz cztery kompletne przykłady migracji kodu skupione na wzorcach najczęściej tworzonych w oparciu o Veryfi: inicjalizacja klienta, ekstrakcja pól oparta na regionach, kategoryzacja wydatków przy użyciu danych strukturalnych oraz zastąpienie webhooków. Nie jest wymagana wcześniejsza lektura artykułu porównawczego.

Dlaczego warto przejść z Veryfi

Dokumenty finansowe przepływają przez systemVeryfiw jednym kierunku: z Twojej infrastruktury do ich. Ten fakt architektoniczny stanowi podstawę większości migracji. Oto konkretne problemy, które skłaniają zespoły do zmiany.

Każde wywołanie dokumentu przekazuje poufne dane finansowe do serwera strony trzeciej. Potwierdzenia zawierają cztery ostatnie cyfry karty oraz informacje o relacjach z dostawcami. Faktury zawierają numery kont bankowych, numery rozliczeniowe oraz numery identyfikacji podatkowej dostawców. Wyciągi bankowe zawierają pełną historię transakcji. Z Veryfi, każde wywołanie ProcessDocumentAsync przesyła te bajty do api.veryfi.com, przetwarza je na infrastrukturzeVeryfii zwraca JSON. Twoja kontrola nad tymi danymi kończy się w momencie wysłania żądania HTTP.

Wymagane są cztery poświadczenia i muszą być zsynchronizowane we wszystkich środowiskach. VeryfiClient wymaga clientId, clientSecret, username i apiKey - cztery oddzielne sekrety do przechowywania w konfiguracji, rotowania zgodnie z harmonogramem, wstrzykiwania do potoków CI/CD i audytu pod względem ujawnienia. Pojedynczy wyciek danych uwierzytelniających uniemożliwia uwierzytelnianie każdego dokumentu przetwarzanego w całej aplikacji.IronOCR wymaga jednego ciągu klucza licencyjnego.

Ceny za dokument są naliczane bez limitu. Koszt pojedynczego paragonu wynosi około 0,05–0,15 USD, faktury 0,10–0,25 USD, a wyciągi bankowe 0,15–0,30 USD. Przy 50 000 dokumentów miesięcznie daje to 5 000–15 000 USD miesięcznie w ramach rozliczeń według rzeczywistego zużycia, bez obniżki w drugim lub trzecim roku. Licencja IronOCR Professional w cenie 2999 USD obejmuje nieograniczoną liczbę dokumentów na czas nieokreślony — próg rentowności w porównaniu z miesięcznym wydatkiem 5000 USD naVeryfiwynosi mniej niż trzy tygodnie.

API jest wyłącznie asynchroniczne, ponieważ praca bazowa jest zdalna. ProcessDocumentAsync nie jest asynchroniczne, ponieważ przetwarzanie jest obliczeniowo długie; Jest to operacja asynchroniczna, ponieważ dokument musi zostać przesłany na serwer, ustawiony w kolejce za innymi żądaniami, poddany przetwarzaniu, a następnie zwrócony w odpowiedzi przez sieć. Opóźnienie jest niedeterministyczne. Ograniczenie szybkości HTTP 429 wymaga logiki ponownych prób. Błędy płatności HTTP 402 całkowicie wstrzymują przetwarzanie wsadowe. Błędy HTTP 500 w infrastrukturzeVeryfipowodują przerwanie przepływu pracy.

Zakres dokumentówVeryfikończy się na granicy dokumentu rozliczeniowego. Wyszkolone modele niezawodnie zwracają uporządkowane pola dla paragonów, faktur, czeków, wyciągów bankowych, formularzy W-2 i wizytówek. Poza tą listą — ogólne dokumenty biznesowe, umowy, dokumentacja medyczna, dokumenty wysyłkowe, niestandardowe formularze wewnętrzne — wyniki ulegają pogorszeniu lub wymagają płatnego szkolenia modelu niestandardowego. Organizacje, które wdrażająVeryfido automatyzacji rozliczania wydatków, zazwyczaj w ciągu 6–12 miesięcy odkrywają, że inne zespoły potrzebują OCR do dokumentów, którychVeryfinie obsługuje.

Proprietarny schemat JSONVeryfiłączy całą logikę ekstrakcji z jednym dostawcą. Każda linia kodu, która odczytuje response.Vendor?.Name, response.BankAccount?.RoutingNumber lub response.LineItems, to kod, który działa wyłącznie z Veryfi. Zmiana dostawcy — lub przejście na lokalny OCR — oznacza przepisanie całej logiki ekstrakcji od podstaw.

Podstawowy 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 viaVeryficloud
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: Porównanie funkcji

Poniższa tabela przedstawia funkcje obu produktów, aby ułatwić ocenę techniczną.

FunkcjaVeryfiIronOCR
Miejsce przetwarzaniaSerwery w chmurzeVeryfiTwoja infrastruktura
Model wdrożeniaTylko Cloud APILokalnie, Docker, Azure, AWS, Linux
Wsparcie offlineNieTak
Wymagane połączenie z InternetemTak (każdy dokument)Nie
Dane opuszczają infrastrukturęTak (każde wywołanie)Nigdy
Zgodność z HIPAA bez umowy BAANieTak
Obsługa środowisk odizolowanychNiemożliweW pełni obsługiwane
Model cenowyZa dokument (0,05–0,30 USD)Licencja wieczysta ($999–2 999 USD)
Wymagane kwalifikacje4 (clientId, clientSecret, username, apiKey)1 klucz licencyjny
Synchroniczne APINie (tylko asynchronicznie)Tak
Ograniczanie szybkościTak (HTTP 429)None
Zakres dokumentuRachunki, faktury, czeki, wyciągi bankowe, formularze W-2, wizytówkiDowolny typ dokumentu
Niestandardowe typy dokumentówWymagane przeszkolenie w zakresie modelu płatnościDowolny układ poprzez ekstrakcję wyrażenia regularnego/wzoru
Plik wejściowy PDFTak (przesyłanie bajtów)Tak (język ojczysty, lokalny)
Wynik w formacie PDF z możliwością wyszukiwaniaNieTak (result.SaveAsSearchablePdf())
OCR oparte na regionieNieTak (CropRectangle)
Odczytywanie BarCodeNieTak (ten sam przebieg OCR)
Strukturalny dostęp do wynikówWstępnie przeanalizowane pola JSONStrony, akapity, wiersze, słowa z współrzędnymi
Ocena pewnościNa pole (zastrzeżone)Per-word i ogółem (result.Confidence)
Obsługa ponad 125 językówOgraniczoneTak (pakiety językowe NuGet)
Przetwarzanie równoległe bezpieczne dla wątkówObowiązują ograniczenia dotyczące współbieżności HTTPFull (one IronTesseract per thread)
Testowanie jednostkowe bez makietWymaga symulacji HTTPBezpośrednie testy lokalne

Szybki start: Migracja zVeryfido IronOCR

Krok 1: Zastąp pakiet NuGet

UsuńVeryfiSDK:

dotnet remove package Veryfi
SHELL

Zainstaluj IronOCR z NuGet:

dotnet add package IronOcr

Krok 2: Aktualizacja przestrzeni nazw

Zastąp przestrzenie nazwVeryfiprzestrzenią nazw IronOCR:

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

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

Krok 3: Inicjalizacja licencji

Dodaj tę linię raz podczas uruchamiania aplikacji, przed jakimkolwiek wywołaniem OCR:

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

Przykłady migracji kodu

Wymiana klienta przetwarzania dokumentów

UsługiVeryfisą zbudowane wokół wstrzykiwania za pomocą konstruktora VeryfiClient. Konstruktor z czterema poświadczeniami stanowi naturalne miejsce na wstrzykiwanie zależności, ale tworzy cztery sekrety, którymi należy zarządzać i które należy rotować. Zastąpienie tego przez IronOCR konsoliduje poświadczenia w jednym kluczu licencyjnym i przenosi instancję silnika przetwarzania do samej klasy usługi.

Podejście 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 toVeryfion 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#

Podejście IronOCR:

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#

Zmiana konstruktora eliminuje cztery wpisy konfiguracji z każdego środowiska: appsettings.json, Docker secrets, odwołania Azure Key Vault oraz zmienne w potokach CI/CD. Instancja IronTesseract jest wielokrotnego użytku dla wielu wywołań w tym samym wątku. Zobacz przewodnik konfiguracji IronTesseract, aby zapoznać się z wzorcami rejestracji singletonów w kontenerach wstrzykiwania zależności .NET Core.

Wyodrębnianie pól z paragonów za pomocą OCR opartego na regionach

Veryfi wyodrębnia pola z paragonów, uruchamiając swoje wyszkolone modele ML na całym obrazie dokumentu i zwracając wstępnie ustrukturyzowaną odpowiedź JSON. Ekwiwalent IronOCR to oparte na regionach OCR za pomocą CropRectangle, które skupia się na określonych strefach obrazu paragonu — strefa nagłówka dla dostawcy, strefa dolna dla sum — zamiast przeprowadzać pełnopagewalkę i szukać wzorców w wyniku. Jest to szybsze w przypadku znanych układów i dokładniejsze, gdy obszar zainteresowania jest dobrze zdefiniowany.

Podejście 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#

Podejście IronOCR:

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 przyjmuje (x, y, width, height) w pikselach. Przetwarzanie tylko stref nagłówka i stopki jest szybsze niż odczyt całej strony i pozwala uniknąć fałszywych dopasowań wynikających z kwot pozycji w treści paragonu. Przewodnik po OCR opartym na regionach obejmuje strategie pomiaru współrzędnych dla dokumentów o zmiennym rozmiarze, a przykład przycinania regionu pokazuje pełny wzór.

Kategoryzacja wydatków przy użyciu ustrukturyzowanych danych akapitowych

Veryfi zwraca response.LineItems jako wstępnie strukturyzowaną tablicę obiektów z Description, Quantity, UnitPrice i Total już zanalizowanymi.IronOCR dostarcza ekwiwalent za pomocą result.Pages[0].Paragraphs i result.Lines, które ujawniają każdy blok tekstu z jego współrzędnymi X/Y. Logika kategoryzacji wydatków — decydująca o tym, czy dana pozycja dotyczy posiłku, podróży, materiałów eksploatacyjnych czy opłaty za oprogramowanie — działa w ten sam sposób niezależnie od języka. Różnica polega na tym, że w przypadku IronOCR logika kategoryzacji należy do Ciebie – możesz ją dostosowywać i rozszerzać bez konieczności ponownego szkolenia modeli uczenia maszynowego.

Podejście 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#

Podejście IronOCR:

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#

Kolekcja Paragraphs zapewnia współrzędną Y każdego bloku tekstu, co ułatwia izolację strefy pionowej, gdzie elementy linii pojawiają się na standardowym układzie paragonu. Przewodnik po dostępie do danych strukturyzowanych wyjaśnia pełną hierarchię Pages, Paragraphs, Lines, Words, i Characters wraz z ich właściwościami współrzędnych. W przypadku paragonów o słabej jakości skanowania — pogniecionego papieru, druku termicznego o niskim kontraście — przewodnik po korekcji jakości obrazu obejmuje filtry przetwarzania wstępnego, które poprawiają dokładność przed uruchomieniem logiki kategoryzacji.

Eliminacja webhooków i synchroniczna wymiana partii

W przypadku dużej liczby dokumentów firmaVeryfizaleca powiadomienia oparte na webhookach zamiast odpytywania. Wzorzec wymaga publicznie dostępnego punktu końcowego HTTPS, tajnego klucza webhooka do weryfikacji podpisu, kolejki do przechowywania wyników do momentu uruchomienia webhooka oraz logiki ponownych prób w przypadku nieudanych dostaw. Jest to istotna infrastruktura, która stanowi w ostatecznym rozrachunku obejście faktu, że chmurowe OCR działa wolniej w porównaniu z przetwarzaniem lokalnym.IronOCR działa synchronicznie. Nie ma luki asynchronicznej, którą należałoby wypełnić za pomocą webhooka.

Podejście 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#

Podejście IronOCR:

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

// Nie webhook 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#

Usunięcie warstwy webhook eliminuje punkt końcowy HTTPS, wymóg rotacji klucza tajnego webhook, kolejkę wyników, logikę walidacji HMAC oraz konfigurację ponownych prób. Cała infrastruktura niższego szczebla istnieje wyłącznie dlatego, że wynikiVeryfidocierają asynchronicznie z serwera zdalnego. Z IronOCR, Parallel.ForEach zastępuje to wszystko. Przykład wielowątkowości szczegółowo demonstruje wzorzec IronTesseract na wątek, a przewodnik po asynchronicznym OCR omawia integrację Task.Run dla responsywności interfejsu użytkownika. Przewodnik po optymalizacji szybkości obejmuje konfigurację instancji w celu uzyskania maksymalnej przepustowości przy obciążeniach wsadowych.

Dokumentacja APIVeryfido IronOCR

VeryfiOdpowiednik IronOCR
new VeryfiClient(clientId, clientSecret, username, apiKey)new IronTesseract() + IronOcr.License.LicenseKey = "key"
_client.ProcessDocumentAsync(bytes)ocr.Read(filePath) or 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?.NamePierwszy akapit uporządkowany według p.Y z 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 przefiltrowane według zakresu współrzędnych Y
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 (ogółem) or word.Confidence (per-word)
response.Payment?.Last4Regex.Match(result.Text, @"\*{4}\s*(\d{4})")
VeryfiApiException (401/402/429/500)Standardowe wyjątki .NET Standard — brak kodów błędów HTTP w przetwarzaniu lokalnym
Kodowanie Base64 przed przesłaniemNie wymagane — ocr.Read(filePath) akceptuje ścieżki plików bezpośrednio
response.CategoryDopasowanie niestandardowych słów kluczowych wobec result.Text
Deseryalizacja ładunku webhookaNie wymagane — ocr.Read() zwraca wynik synchronicznie
ProcessDocumentAsync z ponowną próbą/odroczeniemNie jest wymagane — brak limitów szybkości przetwarzania lokalnego

Typowe problemy związane z migracją i ich rozwiązania

Problem 1: Brakujące pola wstępnie przetworzone

Veryfi: response.Vendor?.Name, response.Total i response.LineItems docierają jako pola strukturalne z wstępnie wytrenowanego modelu ML. Po stronie klienta nie jest wymagana żadna logika ekstrakcji.

Rozwiązanie: Napisz wzorce Regex dla każdego pola używanego przez aplikację. Czas potrzebny na migrację wynosi zazwyczaj od 8 do 24 godzin, w zależności od liczby różnych układów dokumentów, które przetwarzasz. W przypadku typowych wzorów paragonów i faktur, samouczek dotyczący OCR faktur oraz samouczek dotyczący skanowania paragonów zawierają pełne implementacje wzorów ekstrakcji.

// Map eachVeryfifield 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: Sygnatury metod asynchronicznych w całym kodzie źródłowym

Veryfi: ProcessDocumentAsync jest asynchroniczne na poziomie SDK Veryfi. Zespoły zazwyczaj propagują await poprzez każdą wywoływaną metodę w stosie wywołań, co oznacza, że klasy usług, kontrolery i zadania w tle zawierają wszystkie sygnatury async Task<t>.

Rozwiązanie: Read()IronOCR jest synchroniczne. Istniejące sygnatury metod async można zachować, opakowując je za pomocą Task.Run podczas okresu przejściowego. Pozwala to uniknąć masowych zmian sygnatur w całym kodzie źródłowym, jednocześnie eliminując zależność od chmury.

// 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: Konfiguracja poświadczeń rozproszona w różnych środowiskach

Veryfi: Cztery poświadczenia (Veryfi:ClientId, Veryfi:ClientSecret, Veryfi:Username, Veryfi:ApiKey) pojawiają się w appsettings.json, blokach zmiennych środowiskowych w plikach Docker Compose, tajemnicach GitHub Actions, odwołaniach Azure Key Vault i konfiguracjach potoków CI/CD.

Rozwiązanie: Wyszukaj i usuń wszystkie cztery wpisy poświadczeń ze wszystkich środowisk. Dodaj pojedynczą zmienną środowiskową IRONOCR_LICENSE_KEY. Załaduj to przy uruchomieniu.

# Find allVeryficredential 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: Problemy z jakością skanowania, które wcześniej nie były widoczne

Veryfi: Przetwarzanie w chmurze obejmuje poprawę jakości obrazu po stronie serwera przed uruchomieniem wnioskowania ML. Skanowane paragony niskiej jakości — pognieciony papier, wyblakły druk termiczny, przekrzywione zdjęcia z telefonu — zostały po cichu poprawione przed ekstrakcją pól.

Rozwiązanie: Wyraźnie zastosuj proces przetwarzania wstępnego IronOCR. Deskew(), DeNoise() i Contrast() obejmują większość prawdziwych problemów z jakością skanowania paragonów.

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#

Przewodnik po korekcji jakości obrazu oraz samouczek dotyczący filtrów obrazu opisują, jakie filtry należy zastosować w przypadku konkretnych rodzajów pogorszenia jakości skanów.

Problem 5: Przepustowość przetwarzania partii o dużej objętości

Veryfi: Limity szybkości ograniczają tempo przesyłania dokumentów. Odpowiedzi HTTP 429 wymagają logiki wykładniczego cofania się. Przepustowość jest ograniczona limitem szybkościVeryfidla danego planu, a nie przez sprzęt użytkownika.

**Rozwiązanie:**IronOCR jest ograniczony jedynie przez liczbę rdzeni procesora. Użyj Parallel.ForEach z jedną instancją IronTesseract na wątek. Na serwerze z 8 rdzeniami przepustowość skaluje się w przybliżeniu liniowo wraz z liczbą rdzeni.

// 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: Zastrzeżony schemat JSON zablokowany w Veryfi

Veryfi: Cały kod ekstrakcji odczytuje ze schematu odpowiedzi Veryfi: response.Vendor?.Name, response.LineItems, response.BankAccount?.RoutingNumber. Ten kod działa wyłącznie z SDK Veryfi. Każda zmiana nazwy pola w aktualizacji APIVeryfipowoduje uszkodzenie kodu aplikacji.

Rozwiązanie: Ekstrakcja IronOCR wykorzystuje standardowy .NET System.Text.RegularExpressions.Regex z tekstem zwykłym. Wzorce są przenośne, można je testować bez konieczności tworzenia makiet SDK i pozostają pod Państwa kontrolą. Testy jednostkowe działają bez połączenia z siecią.

// 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#

Lista kontrolna migracji Veryfi

Przed migracją

Przed rozpoczęciem pracy nad kodem należy przeprowadzić audyt kodu źródłowego w celu zidentyfikowania wszystkich miejsc użycia Veryfi:

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

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

# Find allVeryfiresponse 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

Zarejestruj całkowitą liczbę miejsc wywołań ProcessDocumentAsync, listę pól odpowiedzi uzyskanych w każdym miejscu wywołania oraz listę środowisk zawierających poświadczenia Veryfi.

Migracja kodu

  1. Usuń pakiet NuGet Veryfi ze wszystkich projektów w rozwiązaniu.
  2. Zainstaluj pakiet NuGet IronOcr do wszystkich projektów, które wcześniej odwoływały się do Veryfi.
  3. Dodaj IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; do uruchamiania aplikacji (przed jakimkolwiek wywołaniem OCR).
  4. Zamień wszystkie instrukcje using Veryfi; i using Veryfi.Models; na using IronOcr;.
  5. Zamień wstrzykiwanie konstruktora VeryfiClient na inicjalizację pola IronTesseract.
  6. Usuń wszystkie cztery wpisy z poświadczeniamiVeryfiz każdego appsettings.json, appsettings.*.json i pliku konfiguracyjnego tajemnic.
  7. Konwertuj wywołania ProcessDocumentAsync(bytes) na ocr.Read(filePath) lub ocr.Read(ocrInput).
  8. Zamień dostęp do response.Vendor?.Name na ekstrakcję tekstu według paragrafów z result.Pages[0].Paragraphs.
  9. Zamień response.Total, response.Tax, response.InvoiceNumber i inne dostępy do pól strukturalnych na wzorce Regex wobec result.Text.
  10. Zamień iterację response.LineItems na iterację result.Pages[0].Paragraphs z filtrem współrzędnych Y.
  11. Usuń klasy kontrolerów webhooków i usuń rejestracje punktów końcowych webhooków.
  12. Usuń zmienne środowiskowe sekretu webhooka ze wszystkich środowisk.
  13. Dodaj OcrInput z wstępnym przetwarzaniem (Deskew(), DeNoise(), Contrast()) dla obrazów skanowanych jako dane wejściowe.
  14. Zamień jednowątkowe pętle sekwencyjne na Parallel.ForEach używając jednego IronTesseract na wątek.
  15. Dodaj IRONOCR_LICENSE_KEY do wszystkich konfiguracji zmiennych środowiskowych i magazynów tajemnic CI/CD.

Po migracji

  • Sprawdź, czy po wdrożeniu migracji w logach ruchu HTTP nie pojawiają się żadne wywołania sieci Veryfi.
  • Sprawdź, czy wyodrębnione nazwy dostawców są zgodne z oczekiwanymi wartościami w próbie 20–50 paragonów.
  • Sprawdź, czy wyodrębnione sumy odpowiadają oczekiwanym wartościom z tolerancją 0,01 USD dla tego samego zestawu próbek.
  • Sprawdź, czy wyodrębnianie numerów faktur przebiega pomyślnie dla każdego formatu faktury w korpusie dokumentów.
  • Przetestuj przepustowość przetwarzania wsadowego w porównaniu z przepustowością bazową Veryfi, aby potwierdzić usunięcie ograniczenia szybkości.
  • Uruchom pełną Suite testów bez połączenia sieciowego, aby potwierdzić zerową zależność od chmury.
  • Potwierdź, że wyniki result.Confidence przekraczają 80% dla czystych skanów dokumentów; Wynik poniżej 80% oznacza, że należy dodać etap przetwarzania wstępnego.
  • Sprawdź, czy wszystkie cztery poświadczeniaVeryfizostały usunięte ze wszystkich środowisk (dev, staging, production).
  • Sprawdź, czy punkty końcowe webhooków zwracają kod 404 lub zostały usunięte z tabeli routingu.
  • Sprawdź, jak zachowuje się system przy skanach paragonów o niskiej jakości (pomiętych, wyblakłych, przekrzywionych) przy włączonym procesie wstępnego przetwarzania.

Kluczowe korzyści z migracji do IronOCR

Dokumenty finansowe przetwarzane lokalnie to dokumenty, do których osoby trzecie nie mają dostępu. Po migracji numery kont bankowych wyodrębnione z faktur, numery rozliczeniowe z czeków oraz historie transakcji odczytane z wyciągów bankowych są przetwarzane na Twoim sprzęcie. Żadne zdarzenie związane z bezpieczeństwem stron trzecich, dostępem podwykonawców do danych ani naruszeniem infrastrukturyVeryfinie może spowodować ujawnienia dokumentów, które nigdy nie opuściły Państwa serwerów.

Koszty na dokument spadają do zera w dniu wdrożenia migracji. Przy 50 000 dokumentów miesięcznie znika pozycjaVeryfio wartości 5 000–15 000 USD miesięcznie. Jednorazowa Professional License IronOCR w cenie 2999 USD zwraca się w pierwszym tygodniu pierwszego miesiąca. Przy większych nakładach oszczędności rosną z roku na rok bez konieczności negocjowania rabatów ilosciowych lub odnawiania umowy.

Przepustowość przetwarzania skaluje się wraz ze sprzętem, a nie z limitami szybkości narzuconymi przez dostawcę. Odpowiedzi HTTP 429, limity przepustowości na poziomie planu oraz sezonowe opłaty za przekroczenie limitu to artefakty architektury interfejsów API w chmurze. Dzięki IronOCR dodanie rdzeni procesora proporcjonalnie zwiększa przepustowość. Partia 10 000 paragonów jest przetwarzana zgodnie z Twoim harmonogramem, a nie zgodnie z harmonogramem limitów Veryfi.

Każdy typ dokumentu jest przetwarzany za pomocą tego samego API. Organizacja nie potrzebuje już drugiego narzędzia OCR, gdy dział HR prosi o przetworzenie formularzy rekrutacyjnych, dział prawny potrzebuje wyodrębnienia tekstu umów, a dział operacyjny potrzebuje danych z dokumentów wysyłkowych. ocr.Read() zajmuje się wszystkimi z nich. Samouczek dotyczący odczytywania tekstu z obrazów oraz specjalistyczne przewodniki po dokumentach obejmują pełen zakres formatów dokumentów obsługiwanych przez IronOCR.

Logika ekstrakcji staje się pierwszorzędną częścią kodu źródłowego. Wzorce Regex znajdują się w kontroli źródła, można je przeglądać w pull requestach, testować w testach jednostkowych bez symulowania żadnego SDK oraz dostosowywać na podstawie informacji zwrotnych z produkcji. Gdy wstępnie wytrenowany modelVeryfizwraca nieprawidłową nazwę dostawcy, nie ma nic do dostosowywania. Gdy wzorzec ekstrakcji IronOCR zwraca nieprawidłową nazwę dostawcy, poprawka polega na zmianie jednego wiersza wyrażenia regularnego wraz z testem jednostkowym. Strona licencyjna IronOCR zawiera opcje poziomów, w tym ścieżkę subskrypcji SaaS dla zespołów, które preferują rozliczenie roczne zamiast zakupu wieczystego.

**Zajmowana przestrzeń po wdrożeniu zmniejsza się do jednego pakietu NuGet, który działa wszędzie.**IronOCR instaluje się jako jeden pakiet bez zewnętrznych zależności, bez zarządzania plikami binarnymi i bez konfiguracji folderu tessdata. To samo odwołanie do pakietu działa w systemach Windows, Linux, macOS, Docker, Azure App Service i AWS Lambda bez kodu zależnego od platformy. Zobacz przewodnik wdrażania Docker oraz przewodnik wdrażania Linux dla środowisk kontenerowych, w których wymaganiaVeryfidotyczące ruchu wychodzącego z sieci stanowią przeszkodę we wdrożeniu.

Zwróć uwagę: Tesseract iVeryfisa zarejestrowanymi znakami towarowymi ich odpowiednich wlascicieli. Ta witryna nie jest powiazana z, zatwierdzona ani sponsorowana przez Google ani Veryfi. Wszystkie nazwy produktów, logo i marki są własnością ich odpowiednich właścicieli. Porównania mają charakter wyłącznie informacyjny i odzwierciedlają informacje dostępne publicznie w momencie pisania.

Powiązane artykuły

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Otrzymaj swoją Konsultację Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta