> ## Documentation Index
> Fetch the complete documentation index at: https://docs.visitoai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Commerce ticket automation

> Inspect purchase evidence and manage fulfillment or verified reconciliation with separate concurrency controls.

Commerce is a source of general tickets. The system creates one open item per purchase/review cycle for eligible fulfillment work and booking exceptions. Manual ticket creation still requires a conversation; callers cannot create arbitrary purchase-only tickets through `create_ticket`.

## Discover and inspect

Use `list_tickets` with `includeCommerce=true`, optionally `source=commerce`, `purchaseId`, status and ownership filters. Counts follow the same scope and mode. Legacy/default lists and streams exclude Commerce unless explicitly opted in.

Rows contain source references without loading purchase evidence per item. Read `get_ticket` for `commerce.contextStatus` and, when allowed, `commerce.review`:

* `contextStatus`: `available`, `permission_denied`, or `unavailable`. Purchase evidence requires `commerce:sales:read` in addition to ticket visibility.
* Source identity: tenant, purchase ID, `stripeMode`, reason and cycle; conversation context is optional.
* Current facts: payment, fulfillment, refund and booking states, amount in minor units, currency, provider booking IDs, reconciliation and last command when available.
* Freshness and concurrency: `asOf`, review revision and opaque `sourceVersion`.
* Allowed Commerce commands: `permittedActions` (`fulfill`, `reconcile`) and separately `humanActions` (`refund`, `retry_reservation`, `payout`).

`bookingConfirmed` requires successful provider state plus the required stored provider identifiers. A paid purchase or recorded external reconciliation alone never sets it to true. `historical` identifies historical evidence; financial records remain immutable.

## Two concurrency domains

| Change | Required state token | Idempotency |
| - | - | - |
| Ticket title, description, human assignment, Start work, note | Integer ticket `revision` | Creation needs a key; later ticket commands use revisions. |
| Purchase fulfillment or non-financial reconciliation | Fresh 64-character hex `sourceVersion` from Commerce evidence | `Idempotency-Key` required for each intent. |

Do not substitute a ticket revision for a Commerce token. Inspect fresh purchase evidence before deciding to issue a command.

## Update fulfillment

`PATCH /commerce/sales/{saleId}/fulfillment` requires both `commerce:sales:read` and `commerce:sales:fulfillment:write`. The body is `sourceVersion` plus `fulfillmentStatus` (`fulfilled` or `unfulfilled`). Use only when permitted for the purchase.

MCP tool `update_commerce_sale_fulfillment`:

```json theme={null}
{"saleId":"YOUR_PURCHASE_ID","idempotencyKey":"fulfill-basket-01","input":{"sourceVersion":"COPY_THE_CURRENT_64_CHARACTER_HEX_TOKEN","fulfillmentStatus":"fulfilled"}}
```

The token above is a placeholder, not a valid request value. Replace it with the exact returned `sourceVersion`. Fulfillment records the supported purchase's delivery state; it does not manufacture booking confirmation, payment or a guest message.

## Record verified reconciliation

`POST /commerce/sales/{saleId}/reconciliation` requires both `commerce:sales:read` and `commerce:sales:reconciliation:write`.

| Field | Requirement |
| - | - |
| `sourceVersion` | Fresh Commerce token |
| `outcome` | `completed_externally` or `verified_no_action_required` |
| `reference` | Supporting reference, 1–500 characters |
| `note` | Explanation verifying the current issue, 1–1,000 characters |

MCP tool `reconcile_commerce_sale`:

```json theme={null}
{"saleId":"YOUR_PURCHASE_ID","idempotencyKey":"reconcile-class-01","input":{"sourceVersion":"COPY_THE_CURRENT_64_CHARACTER_HEX_TOKEN","outcome":"completed_externally","reference":"studio-register-DEMO-042","note":"Front desk verified attendance against the studio register."}}
```

The service stores a separate reconciliation record attributed to the credential/grant identity. It does not rewrite historical financial records or label an external outcome as provider-confirmed success. Built-in Agent approvals remain in force. Refunds, payouts and booking retries are human actions in this version; these two tools do not provide them.

## Completion and recovery

Generic ticket Resolve and Cancel reject Commerce work. Valid completion is fulfilled routine work, a confirmed full refund, successful booking evidence or verified reconciliation of the current issue. Pending, partial, failed or uncertain operations keep the obligation open. Obsolete obligations may be system-cancelled with an audit reason.

Read the returned Commerce state and the exact ticket after the change. Ticket synchronization is asynchronous: a successful Commerce command alone is not proof the ticket projection has already advanced. Use existing lifecycle/event recovery and bounded read-back; add no idle polling loop.

On a stale source token (409), inspect current evidence and reconsider. On an uncertain command, inspect `lastCommand`, reconciliation, current purchase facts and ticket cycle before retrying the identical intent with the same key. A different payload is a new intent and requires a new key. Never change keys merely to bypass uncertainty.

Review changes update an open ticket's reason while preserving its owner and edited text. A genuinely new actionable incident after completion creates a linked cycle and preserves the terminal item. Balance or transfer metadata alone does not create a new incident. Duplicate or out-of-order source events do not replace newer outcomes.

## Authorization and event opt-in

All discovery, counts, source references, commands and delivery are workspace- and test/live-mode scoped. Existing grants receive no extra scopes. Ticket assignment, Start work and notes keep ticket permissions; human Commerce changes retain their administrator requirement.

Subscribe to `ticket.created` / `ticket.updated` with `includeCommerce=true`. Purchase-only event envelopes omit conversation IDs. Deduplicate `eventId`, compare revision and inspect current state before acting. Delivery rechecks mode, opt-in and grant authority. See [webhooks](https://docs.visitoai.com/api-docs/webhooks.md) and the [complete operation matrix](https://docs.visitoai.com/api-docs/tickets.md#routes-tools-and-permissions).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.