📦 The Story: 2,000 Supplier Invoices. Every Monday. By Hand.
Every Monday morning, Ravi — an Accounts Payable analyst at a large manufacturing company — opens his email to find over 2,000 supplier invoices waiting for him. They arrive as PDF attachments. JPEG scans. PNG images from mobile cameras. Some are neatly formatted. Some are handwritten. Some are in Hindi, some in English, some in both.
His job: open each one, read the invoice number, supplier name, amount, tax lines, due date — and type them all into Oracle Fusion Finance manually. Every. Single. Week.
Sound familiar?
OCI Vision is the technology that reads those invoice images — automatically. It extracts every field. Every line item. Every tax amount. From any image, in any format, in multiple languages. Combined with OIC Gen 3, you can wire this intelligence directly into Oracle Fusion Finance — so by the time Ravi arrives on Monday, 1,900 invoices are already processed, validated, and waiting for his review. He reviews 100 exceptions. Done by 9 AM.
A complete OIC Gen 3 integration that:
① Receives a supplier invoice image (PDF/JPEG/PNG) via REST or picks it up from OCI Object Storage
② Calls OCI Vision Document AI to extract all invoice fields using OCR + Key-Value Detection
③ Validates extracted data against business rules (amounts, tax codes, required fields)
④ Routes: valid invoices → auto-create in Oracle Fusion Finance AP; invalid → exception queue
⑤ Returns a structured JSON with all extracted data + confidence scores + Fusion invoice ID
Full step-by-step configuration. Exact JSON payloads. Every field name explained. Every design decision justified.
👁️ Section 1: What Is OCI Vision
Close your eyes and imagine a super-powered pair of glasses. When you put them on and look at any piece of paper — a bill, a photo, a newspaper, a handwritten note — you can instantly understand every single word, number, and shape on it. You can read blurry text. You can find objects. You can spot if something looks different from normal.
OCI Vision is those glasses — but for computers. It is an Oracle Cloud AI service that lets your OIC integration "look" at any image and extract structured, usable business data from it.
Invoice / Purchase Order / Receipt processing → Document AI (gives structured key-value pairs directly)
Reading any printed or handwritten text → Text Detection (raw OCR, you parse the result)
Warehouse product recognition / shelf audit → Object Detection + Image Classification
Manufacturing quality control → Custom Model (train on your product images)
Employee ID / KYC document verification → Document AI + Face Detection
In this article we focus on Document AI — the most immediately valuable capability for Oracle Fusion Finance and SCM users.
🔌 Section 2: The OCI Vision API — What OIC Actually Calls
OCI Vision exposes two REST API patterns — it is important to choose the right one for your OIC integration design.
POST /20220125/actions/analyzeDocumentHow it works: You send the image in the request body (base64 encoded) OR give an Object Storage reference. OCI Vision processes it and returns the result in the same HTTP response.
Best for: Images under 5MB. Response needed immediately. Single-image processing inside an OIC synchronous flow.
Typical latency: 2–8 seconds for a standard invoice page.
POST /20220125/documentJobsHow it works: You submit a batch of images from Object Storage. OCI Vision processes them and writes results back to Object Storage. You poll or use OCI Events to know when done.
Best for: Batch processing (500+ invoices). Large multi-page PDFs. Nightly bulk runs triggered by OIC Schedule.
Typical latency: 30 seconds to 5 minutes depending on batch size.
Use Synchronous when: a user uploads an invoice via a portal and needs a result on screen within seconds.
Use Asynchronous when: a nightly OIC schedule processes all invoices received today as a batch.
This article builds the Synchronous flow first (real-time), then shows the Async batch pattern.
🔌 OCI Vision Synchronous API — analyzeDocument
Content-Type: application/json
Authorization: Signature {OCI_Signature_V1}
📋 Request Body — Document Features to Extract:
"features": [
{
"featureType": "DOCUMENT_CLASSIFICATION"
},
{
"featureType": "KEY_VALUE_DETECTION"
},
{
"featureType": "TABLE_DETECTION"
},
{
"featureType": "TEXT_DETECTION"
}
],
"document": {
"source": "INLINE",
"data": "<base64-encoded-image-content>",
"mimeType": "application/pdf"
},
"compartmentId": "ocid1.compartment.oc1..aaaa...{your_compartment_ocid}"
}
•
DOCUMENT_CLASSIFICATION — "Is this an INVOICE, RECEIPT, RESUME, DRIVING_LICENSE?"•
KEY_VALUE_DETECTION — "Find all key:value pairs like InvoiceNumber:INV-2024-08472"•
TABLE_DETECTION — "Extract line item tables with rows and columns"•
TEXT_DETECTION — "Read every word on the document (raw OCR)"
📋 OCI Vision Response — What You Get Back
"documentClassificationModelVersion": "1.6.0",
"detectedDocumentTypes": [
{ "documentType": "INVOICE", "confidence": 0.9873 }
],
"documentFields": [
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "InvoiceId" }, "fieldValue": { "text": "INV-2024-08472", "confidence": 0.9912 } },
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "VendorName" }, "fieldValue": { "text": "GlobalParts Manufacturing Ltd", "confidence": 0.9741 } },
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "InvoiceTotal" }, "fieldValue": { "text": "₹1,48,000.00", "confidence": 0.9887 } },
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "TaxTotal" }, "fieldValue": { "text": "₹22,320.00", "confidence": 0.9654 } },
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "DueDate" }, "fieldValue": { "text": "15-Oct-2024", "confidence": 0.9823 } },
{ "fieldType": "KEY_VALUE", "fieldLabel": { "name": "PurchaseOrderNumber" }, "fieldValue": { "text": "PO-2024-03891", "confidence": 0.9778 } }
],
"tables": [ /* line items array */ ],
"pages": [ /* full OCR text per page */ ]
}
🏗️ Section 3: Complete Architecture — Invoice Processing Pipeline
🏗️ OCI Vision Invoice Processing — Complete OIC Gen 3 Flow
File Upload
Attachment (OCI Email)
Bucket Drop
Direct Submit
Invoice Created (PASS)
Invoice (PARTIAL)
+ Teams Alert (FAIL)
Archive (ALL)
⚙️ Section 4: Step-by-Step Build in OIC Gen 3
📌 Step 1: Create the Integration
⚙️ Integration Settings
INVOICE_VISION_PROCESSOR
App Driven Orchestration
📌 Step 2: Configure the REST Trigger
🔌 REST Trigger Configuration
processInvoiceImage
/invoice/process
POST
JSON Sample (define below)
JSON Sample (define below)
📋 Request JSON Sample:
"supplierId": "SUPP-00234",
"invoiceImageBase64": "JVBERi0xLjQKJ...",
"mimeType": "application/pdf",
"fileName": "invoice_aug2024.pdf",
"expectedPoNumber": "PO-2024-03891",
"businessUnit": "IN_CORP",
"submittedBy": "supplier.portal@globalparts.com"
}
📋 Response JSON Sample:
"status": "SUCCESS",
"validationStatus": "PASS",
"fusionInvoiceId": "300000012345678",
"extractedInvoiceNumber": "INV-2024-08472",
"extractedVendorName": "GlobalParts Manufacturing Ltd",
"extractedInvoiceTotal": "148000.00",
"extractedDueDate": "2024-10-15",
"overallConfidence": 0.9823,
"documentType": "INVOICE",
"archiveObjectName": "invoices-archive/2024/08/INV-2024-08472.pdf",
"processingTimeMs": 3241,
"exceptions": []
}
📌 Step 3: Create the OCI Vision REST Connection
🔌 OCI Vision REST Connection
OCI_VISION_AI_CONN
https://vision.aiservice.ap-mumbai-1.oci.oraclecloud.com
OCI Signature Version 1
ocid1.tenancy.oc1..{your_tenancy}
ocid1.user.oc1..{oic_service_user}
ab:cd:ef:12:34:... (from OCI IAM API Key)
Allow group OICIntegrationGroup to use ai-vision in compartment YourCompartmentAlso needed for Object Storage archival:
Allow group OICIntegrationGroup to manage objects in compartment YourCompartment
📌 Step 4: Pre-Validation Assign Activity
⚙️ Assign Activity — "preValidateInput"
if(string-length(normalize-space($triggerRequest.invoiceImageBase64)) > 100, 'true', 'false')Checks image data is not empty or just whitespace
if($triggerRequest.mimeType = 'application/pdf' or $triggerRequest.mimeType = 'image/jpeg' or $triggerRequest.mimeType = 'image/png' or $triggerRequest.mimeType = 'image/tiff', 'true', 'false')
$OICProperties.OCI_COMPARTMENT_IDRead from OIC Properties (configure under integration settings → Properties) — never hardcode OCIDs
fn:current-dateTime()To calculate processing time in the final response
📌 Step 5: Build the OCI Vision Request Payload (Assign)
⚙️ Assign Activity — "buildVisionRequest"
In OIC Gen 3, use an Assign to set a variable visionRequestPayload that will be mapped into the REST invoke body:
"INLINE"
$triggerRequest.invoiceImageBase64The base64-encoded image content passed directly from the trigger
$triggerRequest.mimeType
📌 Step 6: OCI Vision REST Invoke — The AI Call
👁️ REST Invoke — OCI Vision analyzeDocument
analyzeInvoiceDocument
/20220125/actions/analyzeDocument
POST
JSON Sample
JSON Sample
📋 Request JSON Sample (paste in wizard):
"features": [
{ "featureType": "DOCUMENT_CLASSIFICATION" },
{ "featureType": "KEY_VALUE_DETECTION" },
{ "featureType": "TABLE_DETECTION" },
{ "featureType": "TEXT_DETECTION" }
],
"document": {
"source": "INLINE",
"data": "base64encodedstring",
"mimeType": "application/pdf"
},
"compartmentId": "ocid1.compartment.oc1..sample"
}
📋 Response JSON Sample (paste in wizard):
"detectedDocumentTypes": [
{ "documentType": "INVOICE", "confidence": 0.98 }
],
"documentFields": [
{
"fieldType": "KEY_VALUE",
"fieldLabel": { "name": "InvoiceId" },
"fieldValue": { "text": "INV-2024-08472", "confidence": 0.99 }
},
{
"fieldType": "KEY_VALUE",
"fieldLabel": { "name": "VendorName" },
"fieldValue": { "text": "GlobalParts Manufacturing Ltd", "confidence": 0.97 }
},
{
"fieldType": "KEY_VALUE",
"fieldLabel": { "name": "InvoiceTotal" },
"fieldValue": { "text": "148000.00", "confidence": 0.98 }
},
{
"fieldType": "KEY_VALUE",
"fieldLabel": { "name": "DueDate" },
"fieldValue": { "text": "15-Oct-2024", "confidence": 0.98 }
},
{
"fieldType": "KEY_VALUE",
"fieldLabel": { "name": "TaxTotal" },
"fieldValue": { "text": "22320.00", "confidence": 0.96 }
}
],
"pages": [{ "pageNumber": 1 }]
}
📌 Step 7: Field Extraction Mapper (Data Mapper)
⚙️ Assign Activity — "extractInvoiceFields"
These XPath expressions search through the documentFields array for each label name and extract the text value and confidence score:
$visionResponse.documentFields[fieldLabel/name='InvoiceId']/fieldValue/text
$visionResponse.documentFields[fieldLabel/name='InvoiceId']/fieldValue/confidence
$visionResponse.documentFields[fieldLabel/name='VendorName']/fieldValue/text
$visionResponse.documentFields[fieldLabel/name='InvoiceTotal']/fieldValue/text
$visionResponse.documentFields[fieldLabel/name='TaxTotal']/fieldValue/text
xsd:date(xsd:dateTime(concat( ... ))) — use format-dateTime to convert "15-Oct-2024" → "2024-10-15"
$visionResponse.documentFields[fieldLabel/name='PurchaseOrderNumber']/fieldValue/text
$visionResponse.detectedDocumentTypes[1]/documentType
📌 Step 8: Business Validation Assign
⚙️ Assign Activity — "validateExtractedData"
if($documentType = 'INVOICE', 'true', 'false')Reject if Vision says this is a RECEIPT or RESUME — not an invoice
if($extractedInvoiceIdConfidence >= 0.85 and $extractedInvoiceTotalConfidence >= 0.85 and $extractedVendorNameConfidence >= 0.80, 'true', 'false')If AI is not confident enough about critical fields → send for manual review
if(string-length($extractedInvoiceId) > 0 and string-length($extractedVendorName) > 0 and string-length($extractedInvoiceTotal) > 0, 'true', 'false')
if(string-length($triggerRequest.expectedPoNumber) = 0, 'NOT_REQUIRED', if($extractedPoNumber = $triggerRequest.expectedPoNumber, 'MATCH', 'MISMATCH'))If caller provided an expected PO number, verify it matches what the AI extracted
if($isDocumentTypeInvoice='true' and $isConfidenceAcceptable='true' and $hasRequiredFields='true' and ($poMatchStatus='MATCH' or $poMatchStatus='NOT_REQUIRED'), 'PASS',
if($isDocumentTypeInvoice='true' and $hasRequiredFields='true' and $isConfidenceAcceptable='false', 'PARTIAL',
'FAIL'))
📌 Step 9: Switch Activity — Route by Validation Status
🔀 Switch Activity — Three Branches
$validationStatus = 'PASS'Action:
1. Call Oracle Fusion Finance AP REST API: Create Supplier Invoice (status = VALIDATED)
2. Set $fusionInvoiceId from response
3. Set $actionTaken = "AUTO_INVOICE_CREATED"
$validationStatus = 'PARTIAL'Action:
1. Create Draft invoice in Fusion Finance (status = INCOMPLETE)
2. Populate all extracted fields as far as possible
3. Set $actionTaken = "DRAFT_CREATED_REVIEW_REQUIRED"
4. Notify AP team via OIC Notification
Action:
1. Log to exception queue ATP table
2. Send Teams notification with failure reason
3. No Fusion record created
4. Set $actionTaken = "EXCEPTION_MANUAL_PROCESSING_REQUIRED"
📌 Step 10: Create Invoice in Oracle Fusion Finance AP (PASS Branch)
🏛️ Oracle Fusion Finance AP REST Invoke — Create Invoice
ORACLE_FUSION_FINANCE_CONN (Oracle ERP Cloud Adapter or REST Adapter)
/fscmRestApi/resources/11.13.18.05/invoices
POST
📋 Fusion Invoice Payload (Data Mapper mappings):
"InvoiceNumber": $extractedInvoiceId,
"InvoiceCurrency": "INR",
"InvoiceAmount": number($extractedInvoiceTotal),
"InvoiceDate": fn:current-date(),
"DueDate": $extractedDueDateFormatted,
"BusinessUnit": $triggerRequest.businessUnit,
"SupplierNumber": $triggerRequest.supplierId,
"Description": concat("AI-Processed via OCI Vision. VendorName: ", $extractedVendorName, ". PoNumber: ", $extractedPoNumber),
"Source": "OIC_VISION_AI",
"PurchaseOrderNumber": $extractedPoNumber,
"TaxAmount": number($extractedTaxTotal),
"InvoiceStatus": "VALIDATED",
"AIConfidenceScore": $overallConfidence
}
response/InvoiceId → variable $fusionInvoiceId. This is what we return in the final response to prove the invoice was created.
📌 Step 11: Archive to OCI Object Storage
☁️ OCI Object Storage REST Invoke — Archive Invoice Image
OCI_OBJECT_STORAGE_CONN (REST Adapter with OCI Sig V1)
https://objectstorage.{region}.oraclecloud.com
/n/{namespace}/b/invoices-archive/o/{objectName}
PUT
concat("invoices/", format-dateTime(fn:current-dateTime(), "[Y0001]/[M01]/"), $extractedInvoiceId, "_", $triggerRequest.fileName)
$triggerRequest.invoiceImageBase64 (the raw base64 content)
$triggerRequest.mimeType
🔄 Section 5: Asynchronous Batch Pattern — Processing 2,000 Invoices Overnight
For the real-world Monday morning scenario — 2,000 invoices already in Object Storage — we use the OCI Vision Asynchronous Job API. Here is how the architecture differs from the synchronous flow:
🔄 Async Batch Architecture — Sunday Night → Monday 7 AM
Lists all objects in OCI Object Storage bucket:
invoices-inbox/ with prefix date=today. Finds 2,000 invoice files.
POST /20220125/documentJobsInput: Object Storage namespace + bucket + list of all 2,000 invoice object names. Output location: bucket
invoices-results/. OCI Vision starts processing all 2,000 in parallel.
Each invoice gets a result file:
invoices-results/INV-XXXX.json containing all documentFields, confidence scores, and table extractions. Takes ~15–30 minutes for 2,000 invoices.
OIC reads all result JSON files from
invoices-results/, runs validation logic on each, creates Fusion invoices for PASSed records, routes PARTIAL and FAIL to review queues.
OIC sends email/Teams message to AP Manager: "Overnight Invoice Processing Complete: 1,847 auto-created in Fusion Finance. 89 drafts for review. 64 exceptions requiring manual processing. Total: 2,000." Ravi arrives at 9 AM and reviews 153 items — not 2,000. ✅
🏭 Section 6: Beyond Invoices — OCI Vision for Manufacturing Quality Control
OCI Vision is not just for documents. Here is a second powerful enterprise use case: automated defect detection on a manufacturing production line — using OIC + OCI Vision Object Detection + a Custom trained model.
🏭 Manufacturing QC — OIC + OCI Vision Custom Model
🚫 Common Mistakes
KEY_VALUE_DETECTION extracts header fields perfectly (invoice number, totals, dates). But it misses the line items in the invoice table (product descriptions, quantities, unit prices). Always include TABLE_DETECTION in your features list to capture every line item for complete Fusion AP invoice creation with distributions.
The OCI Vision inline API has a maximum request body size limit. A multi-page PDF can easily exceed this. Always check base64 string length before calling the inline API. For files above ~3MB (decoded), switch to the Object Storage source method: upload to OCI Object Storage first, then pass the object reference — not the raw image data.
OCI Vision returns field labels like "InvoiceId" or "Invoice Number" or "Bill No" depending on the invoice format and region. Do not write XPath that assumes exactly one label name. Build a field name resolver: check for all possible variations of each field. Example: InvoiceId = first non-null of [InvoiceId, InvoiceNumber, BillNumber, TaxInvoice].
OCI Vision can occasionally return HTTP 429 (rate limit exceeded) or 503 (temporarily unavailable). Without a fault handler, the integration fails and the invoice is lost. Wrap the OCI Vision invoke in a Scope with Fault Handler. On transient errors (429/503): retry after 2 seconds, up to 3 times. On persistent failure: route to exception queue with flag VISION_UNAVAILABLE for re-run later.
✅ Best Practices
For high-volume batch flows, always upload the image to OCI Object Storage first, then call OCI Vision with source="OBJECT_STORAGE" and the object reference. This avoids base64 encoding overhead, bypasses the inline size limit, and gives you an automatic audit trail of every image processed without a separate archival step.
Add custom descriptive flex fields to your Fusion Finance invoice: AI_CONFIDENCE_SCORE_c, AI_EXTRACTION_STATUS_c, AI_PROCESSING_DATE_c. When an AP analyst reviews a Vision-extracted invoice, they can immediately see how confident the AI was on each field — making their review 3x faster and helping identify which invoice formats the model struggles with.
Do not hardcode 0.85 as the confidence threshold. Different fields have different risk profiles. InvoiceTotal wrong = big problem. VendorAddress wrong = minor issue. Build an OIC Lookup Table or ATP config table with field-level thresholds: InvoiceTotal_MinConfidence=0.92, InvoiceNumber_MinConfidence=0.90, BillingAddress_MinConfidence=0.70. Update without touching integration code.
OCI Vision performs best on clear, well-lit images with resolution above 300 DPI. For supplier portals, add client-side validation: reject images smaller than 50KB (probably too blurry), reject files above 10MB (probably scanned at too high resolution). Good image quality → higher confidence scores → fewer exceptions → less manual work.
🎉 Final Summary — What You Built and Why It Matters
Before OCI Vision + OIC:
2,000 invoices arrive. Ravi spends Monday–Thursday manually entering data. Errors at 2%. Payments delayed 4–7 days. Suppliers complain. Working capital trapped.
After OCI Vision + OIC:
2,000 invoices processed overnight. 92% auto-created in Fusion Finance. 8% reviewed by Ravi in 3 hours on Monday. Errors below 0.3%. Payments on time. Suppliers happy. Working capital optimised.
Ravi now spends his time on analysis and exception management — not data entry. That is what intelligent automation is supposed to do.
See with Intelligence. Process with Precision. 📸⚙️
Comments
Post a Comment