Guide: German invoice / payment / advisor walkthrough
Status: fixture-rehearsed. Walks the worked example end-to-end against the fixture cloud. The German invoice/VAT/GoBD authority package is
planned_fixture_family(see authority-packages/catalog.fixture.json); this guide uses the existing fixture capabilities.
This guide walks the German SMB wedge flow: issue an invoice, observe
a matching payment, admit a bookkeeping fact backed by Steuerberater
review evidence, and close the period. It is the worked example that
vertical.de.invoicePaymentAdvisor
orchestrates as a single call, broken down here so you can see each
crossing.
# in one terminalcargo run -p gestalt-cli -- cloud serve-fixture --addr 127.0.0.1:3011import { GestaltClient } from "@gestalt/sdk";
const client = new GestaltClient({ baseUrl: "http://127.0.0.1:3011", token: "fixture-session-token",});
const tenant = "tenant_node:rheinwerk_calibration";Step 1 — issue the invoice
Section titled “Step 1 — issue the invoice”const invoice = await client.economicInvoice({ tenant, amount_cents: 11900, currency: "EUR", evidence: ["evidence_bundle:invoice_payload"],});
console.log(invoice.outcome); // "admitted"console.log(invoice.body);// {// invoice: "invoice:fixture",// receivableObligation: "obligation:fixture",// closureSurface: "closure_surface:fixture",// rawConnectorPayloadExposed: false// }What just happened:
- An invoice atom was admitted.
- It opened a receivable obligation (the customer owes us €119,00).
- It opened a closure surface (the period containing this invoice cannot close until the receivable is settled and bookkept).
If you skip the evidence:
await client.economicInvoice({ tenant, amount_cents: 11900, currency: "EUR", evidence: [] });// outcome: "refused"// body.refusalReason: "economic_invoice_evidence_missing"Step 2 — observe the matching payment
Section titled “Step 2 — observe the matching payment”const payment = await client.economicPaymentObservation({ tenant, invoice: invoice.body.invoice, amount_cents: 11900, currency: "EUR", evidence: ["evidence_bundle:payment_observation"],});
console.log(payment.outcome); // "admitted"console.log(payment.body);// {// paymentObservation: "payment_observation:fixture",// settlement: "settlement:fixture",// rawConnectorPayloadExposed: false// }What just happened:
- A payment observation atom was admitted.
- The amounts and currencies match the invoice.
- A settlement atom closed the receivable closure surface.
The closure surface is now resolved. But the period close is still gated on bookkeeping with advisor evidence.
Step 3 — admit the bookkeeping fact (with Steuerberater review)
Section titled “Step 3 — admit the bookkeeping fact (with Steuerberater review)”Without advisor evidence:
const incomplete = await client.economicBookkeepingFact({ tenant, invoice: invoice.body.invoice, payment_observation: payment.body.paymentObservation, advisor_evidence: null,});// outcome: "refused"// body.refusalReason: "economic_bookkeeping_evidence_incomplete"With Steuerberater review evidence:
const bookkeeping = await client.economicBookkeepingFact({ tenant, invoice: invoice.body.invoice, payment_observation: payment.body.paymentObservation, advisor_evidence: "evidence_bundle:steuerberater_review",});
console.log(bookkeeping.outcome); // "admitted"console.log(bookkeeping.body);// {// bookkeepingFact: "bookkeeping_fact:fixture",// rawConnectorPayloadExposed: false// }The bookkeeping fact ties invoice + payment + advisor evidence into a single admitted accounting interpretation.
Step 4 — close the period
Section titled “Step 4 — close the period”Without clearance evidence:
const earlyClose = await client.economicPeriodClose({ tenant, period: "2026-04", evidence: [],});// outcome: "refused"// body.refusalReason: "economic_closure_surface_open"With clearance evidence:
const close = await client.economicPeriodClose({ tenant, period: "2026-04", evidence: ["evidence_bundle:closure_clearance"],});
console.log(close.outcome); // "admitted"console.log(close.body);// {// periodClose: "period_close:fixture",// productionAdmission: false// }The period is closed.
Same flow as one membrane crossing
Section titled “Same flow as one membrane crossing”Everything above can be done as one call:
const response = await fetch( "http://127.0.0.1:3011/v1/verticals/de/invoice-payment-advisor", { method: "POST", headers: { authorization: "Bearer fixture-session-token", "content-type": "application/json", }, body: JSON.stringify({ tenant: "tenant_node:rheinwerk_calibration", invoice: { amount_cents: 11900, currency: "EUR" }, paymentEvidence: "evidence_bundle:payment_observation", advisorEvidence: "evidence_bundle:steuerberater_review", period: "2026-04", }), });See api/vertical-de-invoice-payment-advisor.md.
Inspect what you produced
Section titled “Inspect what you produced”const recent = await client.recentCommits();// recent.body.commits — the invoice, payment, bookkeeping, period close
const readiness = await client.readPeriodCloseReadiness({ tenant, period: "2026-04",});// readiness.body — derived period-close readiness from durable// obligations and closure surfaces
const gaps = await client.readConnectorEvidenceGaps({ tenant });// gaps.body — connector evidence gap summary without raw connector// payload exposureTension inspection conceptually fits here too. The membrane exposes
/v1/tensions/query for unresolved closure surfaces, but the TS SDK
does not have a thin wrapper for it yet — call it through the
membrane directly when you need it and render the result alongside
the read-model panels above.
const why = await client.zeitgestaltQuery({ tenant, reality: "reality:record", question: "why did the period close?", entitlement: "entitlement:fixture_zeitgestalt",});// receiptBacked: true (today; full structured answer roadmapped)What this proves
Section titled “What this proves”- The substrate carries an end-to-end German SMB invoice/payment flow as a sequence of admitted atoms with structured refusals at every step where evidence is missing.
- The closure-surface discipline (period close gates on resolved surfaces) works.
- Steuerberater review evidence is a first-class admission precondition.
- Receipts and the recent commits journal preserve the chain
durably (
staging-durablefor the economy operations).
What this does not prove
Section titled “What this does not prove”- That the German VAT / GoBD authority package is real (it is fixture; see 022 gap report item 3).
- That the Steuerberater “review” is a real signed advisor opinion (it is a fixture evidence bundle).
- That the period close is durable in any production sense.
- That a real accountant would accept the resulting bookkeeping fact as binding.