Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/veryfi/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
use veryfi\documents\lineitems\GetLineItem;
use veryfi\documents\lineitems\GetLineItems;
use veryfi\documents\lineitems\UpdateLineItem;
use veryfi\split\GetSplitDocument;
use veryfi\split\GetSplitDocuments;
use veryfi\split\ProcessSplitDocumentBase64;
use veryfi\split\ProcessSplitDocumentUrl;
use veryfi\classify\ProcessClassifyDocumentBase64;
use veryfi\classify\ProcessClassifyDocumentUrl;



Expand Down Expand Up @@ -143,14 +149,15 @@ class Client
* @param string $api_version Api version to use Veryfi, currently v8
* @param int $api_timeout Api timeout for call Veryfi api, by default 120
*/
public function __construct(string $client_id,
string $client_secret,
string $username,
string $api_key,
string $base_url = 'https://api.veryfi.com/api/',
string $api_version = 'v8',
int $api_timeout = 120)
{
public function __construct(
string $client_id,
string $client_secret,
string $username,
string $api_key,
string $base_url = 'https://api.veryfi.com/api/',
string $api_version = 'v8',
int $api_timeout = 120
) {
$this->client_id = $client_id;
$this->client_secret = $client_secret;
$this->username = $username;
Expand All @@ -173,5 +180,7 @@ public function __construct(string $client_id,
use DeleteW8BENE, GetW8BENE, GetW8BENEs, ProcessW8BENE, ProcessW8BENEBase64, ProcessW8BENEUrl;
use DeleteW9, GetW9, GetW9s, ProcessW9, ProcessW9Base64, ProcessW9Url;
use AddLineItem, DeleteLineItem, DeleteLineItems, GetLineItem, GetLineItems, UpdateLineItem;
use GetSplitDocument, GetSplitDocuments, ProcessSplitDocumentBase64, ProcessSplitDocumentUrl;
use ProcessClassifyDocumentBase64, ProcessClassifyDocumentUrl;

}
24 changes: 24 additions & 0 deletions src/veryfi/classify/ProcessClassifyDocumentBase64.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace veryfi\classify;

trait ProcessClassifyDocumentBase64
{
/**
* Classify a document and extract all the fields from it. https://docs.veryfi.com/api/classify/classify-a-document/
*
* @param string $base64_encoded_string Buffer string of a file to submit for classify extraction
* @param string $file_name The file name including the extension
* @param array $kwargs Additional request parameters
* @return string Data extracted from the document
*/
public function classify_document_from_base64(string $base64_encoded_string, string $file_name, array $kwargs = []): string
{
$endpoint_name = '/classify/';
$request_arguments = [
'file_name' => $file_name,
'file_data' => $base64_encoded_string,
];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('POST', $endpoint_name, $request_arguments);
}
}
24 changes: 24 additions & 0 deletions src/veryfi/classify/ProcessClassifyDocumentUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace veryfi\classify;

trait ProcessClassifyDocumentUrl
{
/**
* Classify document from url and extract all the fields from it. https://docs.veryfi.com/api/classify/classify-a-document/
*
* @param string|null $file_url Required if file_urls isn't specified. Publicly accessible URL to a file.
* @param array|null $file_urls Required if file_url isn't specified. List of publicly accessible URLs to multiple files.
* @param array $kwargs Additional request parameters
* @return string Data extracted from the document.
*/
public function classify_document_from_url(?string $file_url = null, ?array $file_urls = null, array $kwargs = []): string
{
$endpoint_name = '/classify/';
$request_arguments = [
'file_url' => $file_url,
'file_urls' => $file_urls
];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('POST', $endpoint_name, $request_arguments);
}
}
2 changes: 1 addition & 1 deletion src/veryfi/client/GetHeaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait GetHeaders
private function get_headers(): array
{
return array(
'User-Agent' => 'php veryfi-php/1.1.0',
'User-Agent' => 'php veryfi-php/1.0.5',
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Client-ID' => $this->client_id,
Expand Down
20 changes: 20 additions & 0 deletions src/veryfi/split/GetSplitDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
namespace veryfi\split;

trait GetSplitDocument
{
/**
* Veryfi's Get a Documents from PDF endpoint allows you to retrieve a collection of previously processed documents. https://docs.veryfi.com/api/receipts-invoices/get-documents-from-pdf/
*
* @param string $document_id ID of the document you'd like to retrieve
* @param array $kwargs Additional request parameters
* @return string Data extracted from the Document
*/
public function get_split_document(string $document_id, array $kwargs = []): string
{
$endpoint_name = "/documents-set/$document_id/";
$request_arguments = ['id' => $document_id];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('GET', $endpoint_name, $request_arguments);
}
}
24 changes: 24 additions & 0 deletions src/veryfi/split/GetSplitDocuments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace veryfi\split;

trait GetSplitDocuments
{
/**
* Veryfi's Get a Submitted PDF endpoint allows you to retrieve a collection of previously processed documents. https://docs.veryfi.com/api/receipts-invoices/get-submitted-pdf/
*
* @param int $page The page number. The response is capped to maximum of 50 results per page.
* @param int $page_size The number of Documents per page.
* @param array $kwargs Additional request parameters
* @return string JSON object of previously processed documents
*/
public function get_split_documents(int $page = 1, int $page_size = 50, array $kwargs = []): string
{
$endpoint_name = '/documents-set/';
$request_arguments = [
'page' => $page,
'page_size' => $page_size
];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('GET', $endpoint_name, $request_arguments);
}
}
24 changes: 24 additions & 0 deletions src/veryfi/split/ProcessSplitDocumentBase64.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace veryfi\split;

trait ProcessSplitDocumentBase64
{
/**
* Split document PDF from url and extract all the fields from it. https://docs.veryfi.com/api/receipts-invoices/split-and-process-a-pdf/
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation incorrectly states 'from url' but this method processes documents from base64-encoded data. Update to 'Split document PDF from base64 and extract all the fields from it.'

Suggested change
* Split document PDF from url and extract all the fields from it. https://docs.veryfi.com/api/receipts-invoices/split-and-process-a-pdf/
* Split document PDF from base64 and extract all the fields from it. https://docs.veryfi.com/api/receipts-invoices/split-and-process-a-pdf/

Copilot uses AI. Check for mistakes.
*
* @param string $base64_encoded_string Buffer string of a file to submit for classify extraction
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter documentation incorrectly mentions 'classify extraction' but this is for split operations. Update to 'Buffer string of a file to submit for split extraction'.

Suggested change
* @param string $base64_encoded_string Buffer string of a file to submit for classify extraction
* @param string $base64_encoded_string Buffer string of a file to submit for split extraction

Copilot uses AI. Check for mistakes.
* @param string $file_name The file name including the extension
* @param array $kwargs Additional request parameters
* @return string Data extracted from the document
*/
public function split_document_from_base64(string $base64_encoded_string, string $file_name, array $kwargs = []): string
{
$endpoint_name = '/documents-set/';
$request_arguments = [
'file_name' => $file_name,
'file_data' => $base64_encoded_string,
];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('POST', $endpoint_name, $request_arguments);
}
}
24 changes: 24 additions & 0 deletions src/veryfi/split/ProcessSplitDocumentUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace veryfi\split;

trait ProcessSplitDocumentUrl
{
/**
* Split document PDF from url and extract all the fields from it. https://docs.veryfi.com/api/receipts-invoices/split-and-process-a-pdf/
*
* @param string|null $file_url Required if file_urls isn't specified. Publicly accessible URL to a file.
* @param array|null $file_urls Required if file_url isn't specified. List of publicly accessible URLs to multiple files.
* @param array $kwargs Additional request parameters
* @return string Data extracted from the document.
*/
public function split_document_from_url(?string $file_url = null, ?array $file_urls = null, array $kwargs = []): string
{
$endpoint_name = '/documents-set/';
$request_arguments = [
'file_url' => $file_url,
'file_urls' => $file_urls
];
$request_arguments = array_replace($request_arguments, $kwargs);
return $this->request('POST', $endpoint_name, $request_arguments);
}
}
59 changes: 59 additions & 0 deletions tests/ClientClassifyDocumentsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

use veryfi\Client;

require_once __DIR__ . '/ClientTestCase.php';

class ClientClassifyDocumentsTest extends ClientTestCase
{
public function test_classify_document_from_base64(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/processDocument.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +18 to +19
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
}

$file_path = $this->receipt_path;
$file_name = 'receipt.jpg';
$base64_encoded_string = base64_encode(file_get_contents($file_path));

$json_response = json_decode($veryfi_client->classify_document_from_base64($base64_encoded_string, $file_name), true);
$this->assertIsArray($json_response);
}

public function test_classify_document_from_url(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/processDocument.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +45 to +46
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
}

$url = 'https://raw.githubusercontent.com/veryfi/veryfi-python/master/tests/assets/receipt_public.jpg';
$json_response = json_decode($veryfi_client->classify_document_from_url($url), true);
$this->assertIsArray($json_response);
}
}
111 changes: 111 additions & 0 deletions tests/ClientSplitDocumentsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

use veryfi\Client;

require_once __DIR__ . '/ClientTestCase.php';

class ClientSplitDocumentsTest extends ClientTestCase
{
public function test_get_split_documents(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/getDocuments.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +18 to +19
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
}
$json_response = json_decode($veryfi_client->get_split_documents(), true);
$this->assertIsArray($json_response);
}

public function test_get_split_document(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/getDocument.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +40 to +41
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);
$document_id = '125661908';

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
$documents = json_decode($veryfi_client->get_split_documents(), true);
if (isset($documents['documents'][0]['id'])) {
$document_id = $documents['documents'][0]['id'];
} else {
$this->markTestSkipped('No documents found to test get_split_document');
}
}

$json_response = json_decode($veryfi_client->get_split_document($document_id), true);
$this->assertEquals($document_id, $json_response['id']);
}

public function test_split_document_from_base64(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/processDocument.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +70 to +71
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
}

$file_path = $this->receipt_path;
$file_name = 'receipt.jpg';
$base64_encoded_string = base64_encode(file_get_contents($file_path));

$json_response = json_decode($veryfi_client->split_document_from_base64($base64_encoded_string, $file_name), true);
$this->assertIsArray($json_response);
}

public function test_split_document_from_url(): void
{
if ($this->mock_responses) {
$veryfi_client = $this->getMockBuilder(Client::class)
->onlyMethods(['exec_curl'])
->setConstructorArgs([$this->client_id, $this->client_secret, $this->username, $this->api_key])
->getMock();

$file_path = __DIR__ . '/resources/processDocument.json';
$file = fopen($file_path, 'r');
$file_data = mb_convert_encoding(fread($file, filesize($file_path)), 'UTF-8');
Comment on lines +97 to +98
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File handle opened with fopen() is never closed with fclose(). This creates a resource leak. Add fclose($file) after reading the file data to properly release the resource.

Copilot uses AI. Check for mistakes.
$veryfi_client->expects($this->once())
->method('exec_curl')
->willReturn($file_data);

} else {
$veryfi_client = new Client($this->client_id, $this->client_secret, $this->username, $this->api_key);
}

$url = 'https://raw.githubusercontent.com/veryfi/veryfi-python/master/tests/assets/receipt_public.jpg';
$json_response = json_decode($veryfi_client->split_document_from_url($url), true);
$this->assertIsArray($json_response);
}
}