Skip to content

Contract Flow

A marketplace contract is the record of what a channel said, mirrored into Omnistrate, plus the fulfillment run that acts on it. This page covers what happens between a purchase and a served buyer, and how to read it when something stalls.

Fulfillment States

fulfillmentState is what Omnistrate decided, and it is the only thing that governs whether the buyer can deploy and be metered.

State Meaning Buyer can deploy
DISCOVERED The purchase reached Omnistrate. Nothing exists on our side yet No
IDENTIFIED Organization and root user created. The buyer has an Omnistrate identity No
AWAITING_ISV Subscription request is PENDING. We are waiting on you No
READY You confirmed. The request was approved and the subscription created Yes
SUSPENDED The marketplace suspended the contract, usually non-payment No
DEPROVISIONING A cancellation is being torn down No
CLOSED Cancellation complete No

Branch on fulfillmentState, never on contractStatus

contractStatus is what the marketplace says, and it is normally ACTIVE from the instant of purchase. A contract at ACTIVE / AWAITING_ISV is a buyer who is paying and cannot yet be served. Reading contractStatus to decide whether to serve someone will serve them too early.

Fulfillment stages

The state is a summary. The stages are what actually ran, each stamped with when it started, when it ended and how long it took — recorded by the workflow rather than reconstructed for display.

A contract's fulfillment stages

Stage What happened Parameters shown
Contract received The arrival was resolved against the channel Channel, external reference
Customer identified The buyer became an organization and a root user Buyer reference, buyer name
Contract held The channel was asked to keep the buyer un-charged, where it can Channel, whether it can hold
Subscription request created A PENDING request against the mapped plan Organization, plan, quantity
Handed off to ISV You were told, and the SLA timer armed Organization, root user email, handoff SLA
ISV confirmed Your confirm arrived and the request was approved Plan, quantity
Contract committed The channel was told to begin charging External reference, whether it can hold
Ready The subscription exists. Deployments and metering are open Subscription, organization
Closed The contract ended Contract state

Contract held is a no-op on Suger, which cannot hold a contract — the buyer is already being charged by the marketplace before Omnistrate is called. The stage still appears, and says so, because "we did not do this and here is why" is more useful than a gap.

The handoff stage is the one that waits

Handed off to ISV stays In progress for as long as the contract sits in AWAITING_ISV. That is not a stall — the handoff is not complete when we have handed it over, it is complete when you answer.

The handoff stage, showing how the buyer reached you

Its parameters tell you how the buyer reached you and how long you have:

  • Delivered by — either a signed webhook to your receiver, or the buyer's browser, on your callback URL. This is decided by whether a receiver is registered on the channel, not by the particular run.
  • Handoff SLA — how long before the contract is flagged and fulfillment.failed is emitted.
  • What the ISV has done so far — whether any inbound call has arrived for this contract. If nothing has, start with the receiver rather than with their onboarding.

Reading a contract when something is wrong

The contract screen carries four tabs, and they answer different questions.

Overview — what this stage did, with its timings.

Events — what Omnistrate emitted at this stage.

Contract payload — what the channel said, verbatim. This is the answer to "did the marketplace really tell us that".

Contract interactions — both directions of the integration in one ordered stream: the events we sent you and the calls you made back.

The interaction trail, both directions

The interleaving is usually the diagnosis. "We sent contract.discovered at 09:04, they redeemed the handoff at 09:06 and never confirmed" is one sequence, and splitting it across two screens would make the support answer a manual merge of two lists.

Each outbound row carries the exact request bytes and the signature header that went with them, so when an ISV says a signature does not verify, you compare their digest against the one actually sent rather than against a recomputed copy.

The contracts list

FinOps Center → Marketplace Contracts shows every contract with the channel's state and Omnistrate's state as separate columns, because they answer different questions and a single merged column would hide exactly the case that matters.

The marketplace contracts list

The strip along the top groups contracts into quadrants. The one to watch is paying and not provisioned: a buyer the marketplace is charging whom nobody has confirmed. Simulated contracts are excluded from those totals by construction, so a rehearsal cannot turn the incident tile red.

When nobody confirms

If the handoff SLA passes with no confirm, the contract is flagged for an operator and fulfillment.failed is emitted to a registered receiver. The contract stays in AWAITING_ISV — it is not closed, and the buyer is not refunded — because the usual remedy is that the ISV confirms late.

fulfillment.failed does not carry a handoff token. The token only ever rides on contract.discovered. It outlives the SLA, so if you still hold it you can redeem and confirm afterwards.

Retry fulfillment on the contract re-enters the run and re-emits the handoff, which is the remedy when the first delivery never arrived.