Scenario: “The customer says she already paid”
An accounts-receivable dispute at Alpine Trail Gear. Alex, an AR analyst, gets an email from customer Jane Doe: she keeps receiving a balance-due reminder even though she paid, and she is also asking about a refund on a damaged item. Alex's AI assistant is connected to the Finance Ops MCP server, and resolves the whole case in one short conversation.
See How It WorksThe setup
| System | Account | Records involved |
|---|---|---|
| Online store | gint-dev (dev store) |
Orders #1001 (PAID €112.30) and #1002 (PARTIALLY_REFUNDED €120.50, −€30) for [email protected] |
| QuickBooks | Sandbox realm 9341458591188893 |
Customer Jane Doe #58, invoice 1038 ($250 total, $150 open, $100 paid) |
| Stripe | acct_1U6sztDijhjlcJwy (test) |
Payout po_1UWnWcDijhjlcJwyzGuR27Ou ($380.41, manual) |
The conversation, step by step
1. Morning health check
“Before I touch anything — are all three finance connections healthy?”
→ connections_status confirms the store, Stripe and QuickBooks are CONNECTED,
with granted scopes and token expiry. Everything is green, so Alex proceeds.
2. Pull the customer's full standing
“Jane Doe ([email protected]) says she paid but still owes. Show me her whole picture.”
→ customer_360([email protected]) returns one cross-vendor view:
- Store commerce: 2 orders — #1001 €112.30 PAID, #1002 €120.50 PARTIALLY_REFUNDED (−€30).
- QuickBooks ledger: invoice 1038 — $250 total, $100 paid, $150 still open (PARTIALLY_PAID).
The “I already paid” is half-true: she paid $100, leaving a legitimate $150 balance. Not a system error — a partial payment.
3. Drill into the refund she mentioned
“She also mentioned a refund on a damaged item — which order, how much?”
→ order_financials(orderNumber=#1002) shows the full money trail:
€120.50 sale + €30.00 refund (“Damaged item - partial refund”), both on the
manual gateway, with transaction references #1002.1 / #1002.2.
Alex can now answer the refund question precisely.
4. Reconcile the Stripe payout for the period
“While I'm here, reconcile our latest Stripe payout po_1UWnWcDijhjlcJwyzGuR27Ou.”
→ reconcile_payout(vendor=STRIPE, payoutId=po_1UWnWcDijhjlcJwyzGuR27Ou) — this is a
manual payout, so the engine returns the typed outcome
unsupported_manual_payout rather than guessing: an honest, machine-readable signal that this
payout type isn't auto-reconcilable. The assistant captures the returned runId.
5. Inspect the run ledger
→ get_run(runId=<from step 4>) gives a read-only, step-by-step trail of the run:
which connector was called, each step's status, and the terminal error code. The full audit trail is
persisted for compliance.
6. Review the unreconciled queue
“Anything still outstanding for the close window?”
→ list_unreconciled(from=2026-10-27, to=2026-11-01) reads stored reconciliation state
for the date range — the outstanding-variance worklist.
Outcome
In one short conversation Alex (1) confirmed the connections are healthy, (2) resolved the “already paid” dispute as a legitimate $150 partial balance, (3) quantified the €30 damaged-item refund, and (4) got an honest typed signal that the Stripe payout is manual — all with a persistent run-ledger audit trail.
What the AI client runs, step by step
| # | Tool | Arguments | Expected result |
|---|---|---|---|
| 1 | connections_status | — | status:ok, 3 vendors CONNECTED |
| 2 | customer_360 | [email protected] | 2 store orders + QBO Jane Doe #58, $150 open on invoice 1038 |
| 3 | order_financials | orderNumber=#1002 | PARTIALLY_REFUNDED, €120.50 sale / €30 refund |
| 4 | reconcile_payout | vendor=STRIPE, payoutId=po_1UWnWcDijhjlcJwyzGuR27Ou | status:failed, errorCode:unsupported_manual_payout, returns runId |
| 5 | get_run | runId=<from step 4> | Run trail with terminal unsupported_manual_payout |
| 6 | list_unreconciled | from=2026-10-27, to=2026-11-01 | status:ok, variance worklist for the window |
Want the posting side too? Once a payout reconciles cleanly, continue with approval-gated journal posting.