Odoo ecommerce posting contract¶
Client Odoo databases use the client_online execution profile from the platform specification. Odoo Online cannot install Accountify's HQ Python module, so the platform must not claim transactionally unique Odoo receipts or unconditional exactly-once behavior.
Commands execute only when the source capability profile, mapping set, and tenant accounting policy captured by the posting intent are current and approved.
Approved model surface¶
| Purpose | Odoo model | Pilot access |
|---|---|---|
| Company | res.company |
Read and validate allowed company |
| Customer | res.partner |
Search/read; controlled create/write |
| Product | product.product |
Read mapped product and configuration |
| Sale order | sale.order |
Read/create; action_confirm() after capability proof |
| Sale order line | sale.order.line |
Create through the approved order payload |
| Invoice wizard | sale.advance.payment.inv |
Candidate invoice creation command; clone proof required |
| Delivery | stock.picking |
Read; button_validate() only under approved fulfillment policy |
| Stock move | stock.move |
Read expected quantities; no arbitrary create |
| Customer invoice/credit note | account.move |
Read; action_post() after validation; guarded reversal flow |
| Invoice line | account.move.line |
Read and verify; no direct posted-line mutation |
| Payment wizard | account.payment.register |
Candidate payment command; clone proof required |
| Payment | account.payment |
Read and verify created payments |
| Bank transaction | account.bank.statement.line |
Read; reconciliation only through proven wrapper |
| Reconciliation evidence | account.partial.reconcile, account.full.reconcile |
Read |
| Configuration | account.journal, account.account, account.tax, stock.warehouse |
Read and capability-check |
The runtime metadata export does not prove method signatures, side effects, access, context requirements, or wizard behavior. Each candidate method must pass a clone-based contract test before its capability becomes supported.
Command allowlist¶
| Operation type | Preconditions | Expected result |
|---|---|---|
commerce.create_sale_order.v1 |
Policy, customer, products, taxes, company, currency and source total valid | Draft Odoo sale order with source evidence |
commerce.confirm_sale_order.v1 |
Draft order unchanged and complete | Confirmed order and native delivery records |
commerce.validate_delivery.v1 |
Fulfillment quantities mapped and picking eligible | Validated picking with readback quantities |
commerce.create_invoice.v1 |
Delivery/invoice policy satisfied | Draft invoice linked to sale order |
commerce.post_invoice.v1 |
Draft invoice totals and date validated | Posted customer invoice |
commerce.register_payment.v1 |
Posted invoice and clearing journal validated | Posted payment reconciled to receivable |
commerce.create_credit_note.v1 |
Posted invoice, refund intent and amounts validated | Draft credit note linked to invoice |
commerce.post_credit_note.v1 |
Draft credit note totals validated | Posted credit note and expected residual |
commerce.create_return.v1 |
Original picking and returned quantities eligible | Native return picking |
commerce.validate_return.v1 |
Return picking unchanged and allowed | Validated return and readback stock effect |
commerce.reconcile_payout.v1 |
Approved payout match and bank item unchanged | Odoo clearing reconciliation |
No request payload may choose a model or method. The backend maps operation_type to fixed adapter code, fields, context, domain, and readback schema.
Studio evidence fields¶
The pilot provisions these indexed Studio fields and verifies their technical names per tenant:
| Odoo model | Field | Purpose |
|---|---|---|
sale.order |
x_accountify_source_key |
Stable tenant-scoped source-order evidence |
sale.order |
x_accountify_last_operation_id |
Most recent accepted Accountify operation |
sale.order |
x_accountify_contract_version |
Command contract evidence |
account.move |
x_accountify_source_key |
Source order/refund/settlement evidence |
account.move |
x_accountify_last_operation_id |
Replay and recovery evidence |
stock.picking |
x_accountify_source_key |
Source fulfillment/return evidence |
stock.picking |
x_accountify_last_operation_id |
Replay and recovery evidence |
These fields improve search, readback, and recovery. Odoo Online Studio does not provide the database uniqueness guarantee of the HQ custom module. Platform uniqueness, single-flight leases, preflight reads, and post-mutation readback remain mandatory.
Operation execution¶
- Persist the immutable posting intent and
integration_operation. - Acquire a fenced lease on the operation's business key, such as
(tenant_id, source_connection_id, source_order_id, operation_type). - Read the target Odoo records and configuration with company restrictions.
- Compare source hashes, policy/mapping versions, Odoo
write_date, states, totals, residuals, and expected source markers. - Search for an existing result using the stable source key and operation marker.
- If an equivalent result exists, skip mutation and verify it.
- Execute exactly one allowlisted adapter step. Do not combine unrelated lifecycle steps in a worker attempt.
- On a definite pre-mutation rejection, classify the stable error and apply the retry policy.
- On timeout, connection loss, or ambiguous response, mark
verification_required; never blindly redeliver. - Read back the expected Odoo state and persist a signed/hash-linked readback snapshot.
- Mark
confirmedonly if all command-specific invariants pass.
Readback schemas¶
| Operation | Required authoritative evidence |
|---|---|
| Sale order create/confirm | ID, name, state, company, currency, partner, source marker, lines, untaxed/tax/total, write_date |
| Delivery/return | Picking ID/state, company, locations, move quantities, done quantities, source marker, write_date |
| Invoice/credit note | ID, number, move type, state, company, currency, dates, partner, lines, totals, residual, reversal links, source marker, write_date |
| Payment | ID, state, company, currency, amount, date, journal, partner, matched invoice lines, residuals, write_date |
| Payout reconciliation | Statement line state, payment reference, amount/currency, matched move lines, partial/full reconcile IDs, residuals, write_date |
Readback records the requested values, actual values, comparison result, Odoo IDs, source hash, operation ID, attempt ID, and retrieval time. A mismatch creates repair_required; it is not silently accepted.
Capability tests¶
Enablement proves, per tenant and allowed company:
- models and required fields exist and are accessible to the operating user;
- candidate methods can be called with the documented context and return shape;
- create, confirm, delivery, invoice, posting, payment, credit-note, return, and reconciliation workflows behave as expected;
- Studio evidence fields exist with correct model/type and are writable only by the integration role where possible;
- configured journals, taxes, fiscal positions, accounts, payment methods, warehouses, routes, and locations are active and company-correct;
- lock dates, invoice policy, stock valuation, currency precision, and access rules are captured;
- a timeout-after-mutation test can recover through marker search and readback without duplicate posting.
Capability evidence has an expiry and a code/configuration fingerprint. Drift disables affected commands until reverified.
API¶
POST /api/v1/tenants/{tenant_id}/commerce/orders/{order_id}/posting-intents
POST /api/v1/tenants/{tenant_id}/commerce/posting-intents/{intent_id}/approve
POST /api/v1/tenants/{tenant_id}/commerce/posting-intents/{intent_id}/execute
GET /api/v1/tenants/{tenant_id}/operations/{operation_id}
POST /api/v1/operations/{operation_id}/verification-runs
The execute endpoint returns the existing operation when the same idempotency key and request hash are replayed, and returns 409 IDEMPOTENCY_KEY_REUSED when the hash differs.