Photo by Pietro Jeng on Unsplash

3 ways to extract receipts and invoices in real-time using Go. No template needed.

Hoanh An

--

Problem

Let’s first clarify 2 important assumptions from the title:

  1. We want to extract our receipts and invoices in real-time. It means that, once we upload our files, we expect to see the results returned almost immediately in seconds, not hours.
  2. We don’t need to provide any template that tells our algorithm to look for specific fields to extract from the documents. The reason is, there are millions of ways receipts and invoices are printed and if every time, we have to provide a new template, it’s incredibly hard to keep up with new requests. That said, by not providing any template, we aim to minimize human work as much as possible.

Solution

Now, Veryfi is a solution that offers the exact promises what we want. It can extract over 50 different fields (including line item data) with absolute speed and accuracy, with no human-in-the-loop. If you would like to play with the Veryfi API and see the results without registration, you can drag and drop your receipts and invoices in the live demo on this page: https://veryfi.com/api/

Now, to use Veryfi with Go, the team has recently released a Veryfi SDK for Go that makes it easy for developers to integrate with. So, let’s walk through how we can extract data with just several lines of code in 3 different ways.

Veryfi SDK for Go

First, we can either clone the project using:

git clone https://github.com/veryfi/veryfi-go.git

or using go get like so:

go get github.com/veryfi/veryfi-go

Once installed, let’s register on the Veryfi website to get the necessary tokens. We will need the client-id, username, and api_key to access the API.

In our main program, import and initialize the client with those keys:

package mainimport (
"fmt"
"log"
"github.com/veryfi/veryfi-go/veryfi"
"github.com/veryfi/veryfi-go/veryfi/scheme"
)
func main() {
client, err := veryfi.NewClientV7(&veryfi.Options{
ClientID: "YOUR_CLIENT_ID",
Username: "YOUR_USERNAME",
APIKey: "YOUR_API_KEY",
})
if err != nil {
log.Fatal(err)
}
}

As mentioned in the title, there are 3 ways to process and extract from documents:

  1. Process an uploaded document.
  2. Process a base64 encoded document.
  3. Process a document via an URL.

Process an uploaded document.

In our main function, use `DocumentUploadOptions` to specify the file to be uploaded. We can also give it a name and a couple of tags to help find it easier later. For more options, please refer to the documentation.

    resp, err := client.ProcessDocumentUpload(scheme.DocumentUploadOptions{
FilePath: "YOUR_FILE_TO_BE_UPLOAD",
DocumentSharedOptions: scheme.DocumentSharedOptions{
FileName: "example-invoice.png",
Tags: []string{"example", "test", "upload"},
},
})
if err != nil {
log.Fatal(err)
}

fmt.Println(resp)

Process a base64 encoded document.

Similarly, we can use `ProcessDocumentUploadBase64` to upload our base64 encoded file. As we can see from the example below, the SDK also provides a handy method `Base64EncodeFile` to help us encode the file to base64 format as well.

    encodedFile, _ := veryfi.Base64EncodeFile("YOUR_FILE_TO_BE_UPLOAD")
resp, err = client.ProcessDocumentUploadBase64(scheme.DocumentUploadBase64Options{
FileData: encodedFile,
DocumentSharedOptions: scheme.DocumentSharedOptions{
FileName: "invoice1.png",
Tags: []string{"example", "test", "upload", "base64"},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp)

Process a document via an URL.

Lastly, in order to process a document via an URL, simply use the `ProcessDocumentURL` method and provide your hosted URL.

    resp, err = client.ProcessDocumentURL(scheme.DocumentURLOptions{
FileURL: "YOUR_HOSTED_INVOICE_URL",
DocumentSharedOptions: scheme.DocumentSharedOptions{
Tags: []string{"example", "test", "url"},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp)

That’s it! Fast and simple to use! Each call returns all the data extracted in ~3–5 seconds for a document, depending on how many pages there are.

A successful response will look something like this:

&{ABNNumber: AccountNumber: BillToAddress: BillToName: BillToVATNumber: CardNumber: Category: Created:2021-05-20 19:21:38 CurrencyCode:USD Date:2019-02-26 00:00:00 DeliveryDate: Discount:0 DocumentReferenceNumber: DueDate:2019-02-26 ExternalID: ID:23002226 ImgFileName:3947f571-a41b-4b79-abc7-c0d9805c8610.png ImgThumbnailURL:https://scdn.veryfi.com/receipts/3947f571-a41b-4b79-abc7-c0d9805c8610_1_t.png?Expires=1621538559&Signature=BokBYv9jyJcXbCXu49DqxHwRdAWEgG8xfMw7LHujXSCA5y4kGd-QaBDwMzMCgCuM0Ezdrv3lgAZa0Cr8A5DKAzymXxnfdEiV46w~iy1zGPRgx6IkqvllB4bWqHFdwuu88CJarfIjvkcaygcECiFHg3RSKuuN4eGUYDP~fK8ER~Awb9Cr5FpTbTMc9kOfyc~vii2Mikg3TBiTbcdshhjgD2oRI4nFh1fpwRpfHAArIR-ijYAetjFEOQycUiu6WnzWAyEV9RCP9KcrKOnY5eKD-mm5mKuGQGXX1OT2AGw80klF1epx7XppeER9kALF1s8Dq87s8gdnnVsrstEF3~e8Yg__&Key-Pair-Id=APKAJCILBXEJFZF4DCHQ ImgURL:https://scdn.veryfi.com/receipts/3947f571-a41b-4b79-abc7-c0d9805c8610.png?Expires=1621538559&Signature=G7T6n7~Gpr1Pi5rfPRn1GoOeTlKZnVxLbWSZf~svnNpytILXvN9tg7y-Ib39lcifHeM6vjVfm4Pa4k63-ri~SySGFq-RWtF4IjQGM3Hw4~8wHB-sPhorn4JeVd~e~CpaUgFJbGSRnbb1cmBDFdkuBMbLkdC7m5ifwE10kanUU87Q~vpDYLkQINzfylHJk21rwtSPvIiEX8rudLK1F1BGl7TWvx-o7BT~PTCJ-RsA~j4eGuOprDXpt5Achpf-LMUa-iRCpMFupWVOZFPGln8rDqp-TcpryTawTbNlajg0nFDtF1eqBlbfoEycb-ZECtV4KECZtle5T7rBqhGQsmUxNQ__&Key-Pair-Id=APKAJCILBXEJFZF4DCHQ Insurance: InvoiceNumber:   US-001 IsDuplicate:0 LineItems:[] OCRText:

INVOICE LOGO
East Repair Inc.
1912 Harvest Lane
New York, NY 12210
BILL TO SHIP TO INVOICE # US-001
John Smith John Smith INVOICE DATE 11/02/2019
2 Court Square 3787 Pineview Drive
New York, NY 12210 Cambridge, MA 12210 P.O. 2312/2019
DUE DATE 26/02/2019

QTY DESCRIPTION UNIT PRICE AMOUNT

1 Front and rear brake cables 100.00 100.00
2 New set of pedal arms 15.00 30.00
3 Labor 3hrs 5.00 15.00

Subtotal 145.00
Sales Tax 6.25% 9.06
TOTAL $154.06

TERMS & CONDITIONS
Thank you , Please make checks payable to: East Repair Inc.
Payment is due within 15 days
John Smith
OrderDate: PaymentDisplayName:No Payment, PaymentTerms: PaymentType:no_payment, PhoneNumber: PurchaseOrderNumber: Rounding:0 ServiceEndDate: ServiceStartDate: ShipDate: ShipToAddress: ShipToName: Shipping:0 StoreNumber: Subtotal:145 Tax:9.06 TaxLines:[] Tip:0 Total:154.06 TotalWeight: TrackingNumber: Updated:2021-05-20 19:21:39 VATNumber: Vendor:{Address:1912 harvest lane new york, ny 12210 2 court square 3787 pineview drive Category: Email: FaxNumber: Name: PhoneNumber: RawName: VendorLogo: VendorRegNumber: VendorType: Web:} VendorAccountNumber: VendorBankName: VendorBankNumber: VendorBankSwift: VendorIban:}%

Once our documents are processed, we can always manage them, manage their line items, manage tags, and so on. As always, documentation is your best friend!

Feel free to leave your questions and feedback below!

--

--