⚙️ Autonomous 💬 Approval gates

Procure-to-Pay Invoice Exception

SAP S/4HANAivaluaKyribaServiceNowTeams
1📋

Overview & business value

This agent clears the accounts-payable queue. For every incoming invoice it runs the three-way match (PO ↔ goods receipt ↔ invoice) in SAP; clean matches within tolerance post for payment automatically, and mismatches are investigated across SAP, the ivalua contract and prior invoices, then resolved under policy or routed to AP with a recommendation. It reads and reasons freely; posting an invoice and releasing a payment go through an Action Ticket carrying a MOP.

Problem

AP queues fill with invoices. Most match cleanly, yet every one waits for a human to open it, check the PO and receipt, and post it. Exceptions (price variance, partial delivery, missing GR) take real investigation. Slow cycles mean late-payment penalties and missed early-pay discounts.

Solution approach

Event-driven on an invoice entering the AP queue. The agent runs the deterministic three-way match; within tolerance it posts for payment; on a mismatch it reasons across ERP, contract terms and history, then resolves under policy or routes to AP. Payment release is gated and executed via Kyriba.

Core capabilities

  • Three-way match (PO / GR / invoice)
  • Contract-tolerance evaluation (ivalua)
  • Price + quantity variance investigation
  • Duplicate-invoice detection
  • Vendor-approval and tax checks
  • Auto-post within policy via SAP BAPI
  • Payment release via Kyriba
  • Exception routing with recommendation

How it helps

Invoice cycle time drops; AP staff handle only true exceptions; late-payment penalties fall and early-pay discounts get captured. Every posting and payment is gated and auditable.

Illustrative value model — plug in your own figures

V
Invoices / year
M%
Auto-matched within tolerance
$D
Penalties avoided + discounts captured

Value = V × M% × handling minutes saved × rate, plus $D. Placeholders — substitute your baseline.

2📖

The story (for the sales conversation)

The one-liner

"Most invoices match their order and receipt perfectly — but a human still opens every one. This agent posts the clean ones, investigates the exceptions, and only asks you when something genuinely doesn't add up."

😣 Today, without the agent

Dana in AP has 400 invoices in the queue. She opens each one, pulls up the PO, checks the goods receipt, eyeballs the price. Most are fine — but the checking still takes all morning. One invoice is $2.55 over the PO price; she has to dig out the contract to see if that's within tolerance. By the time the exceptions are sorted, two invoices have slipped past their early-pay discount.

😌 The same queue, with the agent

The agent runs the three-way match on all 400. The clean ones within tolerance post for payment automatically. For the $2.55 variance it reads the ivalua contract, sees the tolerance is ±2% and this is 5.3%, and routes it to Dana with the contract clause and a recommendation attached. The partial-delivery one it holds and explains. Dana opens her queue to a handful of real exceptions, each pre-investigated.

"It never posts an invoice or releases a payment on its own beyond policy tolerance. Within tolerance it acts; outside it, it investigates and recommends, and a human approves. The audit trail is automatic."

The trust point — lead with this for Finance and Controllership
1
The villain: the queue

Every invoice waits for manual matching, even the clean majority.

2
The hero: match + investigate

The agent posts clean matches and pre-investigates exceptions with contract context.

3
The reason to trust it

Posting and payment are reversible Action Tickets; beyond-tolerance needs a human.

💡How to use this tab: open here for Finance, tell the before/after, land the trust line, then show "Sample questions" and "Live scenarios". Keep Tools/Governance for the technical buyer.
3📥

Input data

Source systemField / entityTypePurpose
SAP S/4HANASupplierInvoice (amount, qty, price, vendor)objectThe invoice to clear
SAP S/4HANAPurchaseOrder (price, qty, terms)objectMatch reference (PO leg)
SAP S/4HANAGoodsReceipt (qty received)objectMatch reference (GR leg)
ivaluacontract tolerance, termsobjectAllowed price/qty variance
Kyribacash position, payment runobjectPayment release
ServiceNowAP exception recordrecordRoute + track true exceptions
ℹ️Developer note: trigger is an invoice entering the AP queue (SAP event or scheduled sap.read of parked invoices). The payload carries the invoice id.
4⚙️

Processing flow (tools mapped per step)

ℹ️Each step shows its path and whether it is read-only or a write via Action Ticket.
1

Fetch invoice + references deterministic

Read the invoice, its PO and goods receipt from SAP.

sap.read · SupplierInvoice / PO / GR
2

Three-way match deterministic

Compare price, quantity and amount across the three legs.

match(PO, GR, invoice)
3

Tolerance check deterministic

Read the ivalua contract tolerance; classify within/outside policy.

ivalua.contractRead · tolerance
4

Duplicate + vendor checks deterministic

Check for duplicate invoices and approved-vendor status.

sap.read · prior invoices / vendor master
5

Investigate mismatch non-deterministic

On a variance, reason across PO history, contract and prior invoices for the likely cause.

reasoning over SAP + ivalua evidence
6

Post within policy deterministic Action Ticket

Clean match within tolerance → post the invoice for payment.

sap.write · BAPI_INCOMINGINVOICE_CREATE (via ticket)
7

Release payment deterministic approval if > threshold Action Ticket

Submit the payment instruction via Kyriba with approval-pending routing.

kyriba.paymentSubmit (via ticket)
8

Route exception non-deterministic Action Ticket

Beyond tolerance → open a ServiceNow AP exception with the evidence and recommendation; notify AP.

servicenow.incident · teams.post (via ticket)
5🔧

Skills & tools (real connectors)

ℹ️Each tool maps to a real processorKey. Read tools are direct; writes only run inside an Action Ticket.
sap.readOData v4SOURCE
erp.processors.SAPS4HanaPull
Pulls SAP S/4HANA OData v4 services: supplier invoices, purchase orders, goods receipts, vendor master.
{baseUrl}/sap/opu/odata4/sap/{serviceName}/{entitySet}
READ · direct
sap.writeBAPI / RFCTRANSFORM
erp.processors.SAPBAPICall
Executes SAP BAPI/RFC via the BTP API Management proxy; parses bapiret2; commit/rollback. Invoice post = BAPI_INCOMINGINVOICE_CREATE; GL post = BAPI_ACC_DOCUMENT_POST.
BAPI_INCOMINGINVOICE_CREATE · BAPI_ACC_DOCUMENT_POST
WRITE · via Action Ticket
ivalua.contractReadRESTSOURCE
procurement.processors.IvaluaContractRead
Reads contract metadata, clauses, obligations and tolerances (signed attachment URLs ~24h TTL).
contracts · clauses · tolerance (read)
READ · direct
kyriba.cashReadRESTSOURCE
treasury.processors.KyribaCashPositionRead
Pulls cash positions and forecasts to confirm funds before a payment run.
cash positions (read)
READ · direct
kyriba.paymentSubmitREST · MT/MXSINK
treasury.processors.KyribaPaymentSubmit
Submits payment instructions (wire, ACH) with approval-pending routing. Pairs with SwiftMTBuilder.
payment instruction · approval-pending
WRITE · via Action Ticket
servicenow.incidentTable APISOURCE
itsm.processors.ServiceNowIncident
Creates/updates AP exception records via the Table API with idempotency by external-id.
/api/now/v2/table/incident
WRITE · via Action Ticket
teams.postGraphSINK
collaboration.processors.TeamsSendMessage
Notifies AP of routed exceptions with the recommendation attached.
TeamsSendMessage · channel/chat
WRITE · via Action Ticket
⚠️Connectivity honesty: SAP invoice posting uses the BAPI path (BAPI_INCOMINGINVOICE_CREATE) via SAPBAPICall; there is no separate "post invoice" sink in the library. ivalua is read-only here (contract terms/tolerance). Payment release is a real Kyriba submit with approval-pending routing.
6🤖

Agent prompt (production)

🤖 System prompt
You are the Procure-to-Pay Invoice Exception Orchestrator.

## Operating rules
1. Read/reason freely across SAP, ivalua and Kyriba.
2. You NEVER write directly. Posting an invoice or releasing a payment is an
   Action Ticket carrying a MOP; ProcBot executes, Sherlock validates, reversible.
3. Deterministic for: the three-way match, tolerance check by contract policy,
   duplicate/vendor checks, posting a clean match within tolerance.
4. Non-deterministic for: investigating a mismatch (price/qty/missing GR),
   inferring the likely cause, deciding resolve-vs-route.
5. Human approval before: posting outside contract tolerance, and any payment
   release over the configured threshold.
6. Cite the tool and record for every figure. Never invent amounts.

## Tools
READ (direct): sap.read, ivalua.contractRead, kyriba.cashRead
WRITE (Action Ticket only): sap.write (BAPI_INCOMINGINVOICE_CREATE,
  BAPI_ACC_DOCUMENT_POST), kyriba.paymentSubmit, servicenow.incident, teams.post

## Output (every step)
{ "decision":"...", "path":"deterministic | non-deterministic", "confidence":0.0,
  "action_ticket": { "mop":"...", "scope":"...", "approval":"auto | human" } | null,
  "evidence":[ { "tool":"...", "record":"..." } ], "message_to_user":"..." }
7🛡️

Execution governance — Action Ticket → MOP

No invoice posting or payment reaches a system from the model. The agent reasons; an Action Ticket carries the MOP; ProcBot executes; Sherlock validates; the ticket is reversible. Posting beyond tolerance and payments over the threshold require human approval.

1 · Reason

Agent decides to post / pay / route.

2 · Action Ticket

MOP id, scope, parameters, approval level.

3 · ProcBot executes

Runs the SAP BAPI / Kyriba payment. Model never writes.

4 · Sherlock validates

Checks bapiret2 / payment ack; closes or rolls back.

{
  "action_ticket": "AT-6001",
  "mop": "MOP-AP-POST-INVOICE",
  "approval": "auto",
  "target": { "tool": "sap.write", "processorKey": "erp.processors.SAPBAPICall" },
  "procedure": { "bapi": "BAPI_INCOMINGINVOICE_CREATE",
                 "import": { "HEADERDATA": { "INVOICE_IND":"X", "DOC_DATE":"2026-06-01",
                             "GROSS_AMOUNT":48500.00, "CURRENCY":"USD", "PO_NUMBER":"4500088" } } },
  "validation": { "owner":"sherlock", "expect":"bapiret2.TYPE in ['S']" },
  "reversible": true
}
8🔀

Data flow

flowchart TD A([Invoice enters AP queue]) --> B[Fetch invoice + PO + GR sap.read] B --> C[Three-way match] C --> D{Match within tolerance?} D -->|Yes| E{{MOP-AP-POST-INVOICE}} E --> F[BAPI_INCOMINGINVOICE_CREATE] F --> G{Payment over threshold?} G -->|No| H{{MOP-AP-PAYMENT}} G -->|Yes| I[Human approval] I --> H H --> J[kyriba.paymentSubmit] D -->|No| K[Investigate variance SAP + ivalua contract] K --> L{Resolvable under policy?} L -->|No| M{{MOP-AP-EXCEPTION}} M --> N[ServiceNow + notify AP]
9🏗️

Systems touched

🟡 SAP S/4HANA — invoice/PO/GR (read OData), post (write BAPI)
📑 ivalua — contract tolerance + terms
💰 Kyriba — payment release
🛠️ ServiceNow — AP exception record
💬 Microsoft Teams — AP notification
10🗄️

Mock data (seed to demo)

Invoice
Purchase order
Goods receipt
Contract tolerance
Match result
// sap.read SupplierInvoice INV-77310
{ "invoice":"INV-77310", "vendor":"SUP-AROMA-09", "po":"4500088",
  "qty":1000, "unitPrice":51.05, "gross":51050.00, "currency":"USD" }
// sap.read PurchaseOrder 4500088
{ "po":"4500088", "vendor":"SUP-AROMA-09", "qty":1000, "unitPrice":48.50,
  "net":48500.00, "paymentTerms":"NET30 / 2% 10" }
// sap.read GoodsReceipt for PO 4500088
{ "po":"4500088", "qtyReceived":1000, "status":"complete" }
// ivalua.contractRead { vendor:"SUP-AROMA-09" }
{ "priceTolerancePct":2.0, "qtyTolerancePct":0, "autoApproveUnder":25000 }
// computed match
{ "priceVariancePct":5.26,        // 51.05 vs 48.50
  "qtyMatch":true, "grMatch":true,
  "withinTolerance":false }        // 5.26% > 2% → route to AP
11💬

Sample questions (conversational triggers)

The natural-language prompts this agent is built to answer. Each maps to the live scenarios below.

"Why is invoice INV-77310 blocked?"→ Scenarios 2, 5 (variance)
🔍"Does INV-77310 match its PO and receipt?"→ Scenarios 1–2 (three-way match)
📏"Is this price variance within contract tolerance?"→ Scenario 3 (ivalua)
"Post the matched invoices for payment."→ Scenarios 6–7
"Any duplicate invoices this week?"→ Scenario 4 (duplicate detection)
💵"Can we capture the early-pay discount on these?"→ Scenario 9 (payment timing)
🎯 Recommended demo run
Seed the invoice/PO/GR/contract, then ask "Clear the AP queue" — the agent auto-posts clean matches (1–2, 6), captures the discount (9), and on INV-77310 runs the variance investigation (3, 5) and routes it to AP with the contract clause (8). Scenarios 4, 7, 10 cover duplicates, payment release and a missing-GR hold.
12🎬

Live scenarios (tool-execution traces)

ℹ️Ten end-to-end runs. Each step is a read (SOURCE), reasoning, an Action Ticket with a MOP, or an agent message.