Skip to content

Contract Lifecycle

A marketplace contract connects the purchase reported by the channel to its fulfillment and subscription lifecycle in Omnistrate. This page covers what happens between a purchase and a served buyer, and how to diagnose a contract that needs attention.

Fulfillment States

fulfillmentState is what Omnistrate decided and governs whether the buyer can deploy. Usage reporting also requires the marketplace contract to permit reporting; see Billing and Usage Reporting.

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 Cancellation is in progress; access is revoked while final usage is handled No
CLOSED Cancellation is complete; the contract remains as an audit record 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.

Subscription Lifecycle

Marketplace changes arrive from the channel and are reflected in both the contract and its Omnistrate subscription. When the corresponding event has a receiver configured, Omnistrate delivers it after applying any access change.

Marketplace change Omnistrate behavior What you should do
Purchase confirmed Approves the pending request, creates the subscription, and moves fulfillment to READY Enable the tenant after the confirm call succeeds
Plan, quantity, or term changed Emits entitlement.updated; the subscription is not automatically moved to a different Plan Apply the new limits or product configuration in your system
Contract suspended Revokes subscription access, moves fulfillment to SUSPENDED, then emits contract.suspended Restrict access, but preserve the buyer's data
Contract reinstated Restores subscription access, returns fulfillment to READY, then emits contract.reinstated Restore access and resume normal service
Cancellation scheduled Leaves the subscription active and emits contract.ending with the remaining usage-reporting window Keep serving the buyer and ensure remaining usage is submitted before the deadline
Contract cancelled or expired Revokes subscription access and emits contract.cancelled Begin your product-specific offboarding and retention process

Cancellation does not delete your product data

Omnistrate prevents further use of the marketplace-backed subscription. Your product is responsible for applying its retention, export, and deletion policy after contract.cancelled.

For access purposes, cancellation or expiration is the terminal subscription lifecycle transition. The contract remains visible in Omnistrate for audit and troubleshooting.

The initial purchase uses the browser callback unless contract.discovered has a receiver route. Later lifecycle changes have no browser handoff, so configure a receiver for each event you need before enabling a production listing.

Fulfillment stages

The state is a summary. The stages show what happened, when each step started and ended, and how long it took.

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 are open; usage reporting starts when the marketplace permits it 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 the contract.discovered receiver, or the buyer's browser, on your callback URL. This is decided by the effective route for contract.discovered.
  • 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 effective contract.discovered route rather than with the onboarding code.

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 not included in those totals.

When nobody confirms

If the handoff SLA passes with no confirm, the contract is flagged for an operator and fulfillment.failed is emitted when that event has a configured receiver. The contract stays in AWAITING_ISV — it is not closed, and the buyer is not refunded — because the usual remedy is that the SaaS Provider 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 contract.discovered when that event has a configured receiver. A callback-only integration cannot reopen or repeat the buyer's browser redirect; retry redeeming and confirming with the token from the original callback instead.