---
id: shoptype.protocol
version: "0.1"
status: initial-implementation
---

# Shoptype Protocol v0.1

Shoptype Protocol connects a Game Master's market to Shoptype's seller onboarding,
hosted product integrations, fulfillment automation and operator tools. Market
Protocol remains authoritative for commerce. Seller Commerce API v2 connects a
seller's product to the hosted bridge. These versions are independent.

## Compatibility

A compatible GM implements the baseline below and passes the executable connection
checks. Recurring commerce is an additional capability, certified independently of
one-time purchases. Passing compatibility checks does not authorize live payments.

The reusable Clojure implementation is `game.protocols.shoptype` plus
`game.gm.shoptype` in `ai.intergraph/game-master`. Other stacks implement the same
HTTP contract and verify Intergraph identities through MoM. A GM does not need
custom Shoptype frontend code.

## Discovery

`GET /shoptype/v0.1/manifest` is public and returns no credentials or commercial terms.
The portable discovery schema is [shoptype-manifest.schema.json](/shoptype-manifest.schema.json).

```json
{
  "protocol": "shoptype",
  "version": "0.1",
  "enabled": true,
  "game_id": "stable-game-id",
  "game_name": "example-market",
  "market_id": "example-market",
  "environment": "test",
  "endpoint": "/shoptype/v0.1/operations",
  "operations": ["enable", "query-context", "bind-seller", "query-integrations", "configure-integration", "set-availability", "publish", "query-orders", "report-fulfillment"],
  "optional_operations": ["payment-status", "start-payment-connection"],
  "billing_modes": ["one-time", "recurring"],
  "payment_routes": ["seller-direct"]
}
```

`game_id` and `environment` scope a connection. `market_id` identifies the same
market across isolated test and production deployments; it is not an authorization
credential. Never infer this relationship by stripping suffixes from game names.
Only advertise implemented billing modes and payment routes. Test/preview GMs
must reject a live Stripe key; production GMs must reject a test key.

## Authenticated operations

Send `POST /shoptype/v0.1/operations` with JSON, `Authorization: Bearer <credential>`
and a stable `Idempotency-Key` for each command. Never send browser cookies or
Shoptype's own session key to the GM. Example:

```json
{
  "operation": "query-orders",
  "player_name": "seller-name",
  "data": {"integration-id": "integration-uuid"}
}
```

Replies use `{"success":true,"data":{...}}`; MoM-backed gateways may wrap this
as `{"success":true,"gm-result":{"success":true,"data":{...}}}`. A successful
transport response containing a failed inner operation is still a failure.

| Operation | Authority | Behavior |
| --- | --- | --- |
| `enable` | Current human GM owner | Enable registration and protect the private `shoptype` namespace; preserve other metadata. |
| `query-context` | Human owner or verified member | Return GM identity, verified seat, roles, requirements and onboarding state. An owner may select `seller-name`; members can read only their own onboarding. |
| `bind-seller` | Verified applicant/member | Bind `integration-id` and `organization-id` to the canonical membership. Conflicting organization or membership is rejected. |
| `query-integrations` | Owner or bound member | Return only the caller's permitted integration records. |
| `configure-integration` | Human owner | Approve `integration-id`, `revision-id`, `evidence-hash`, `adapter-id`, `catalog-version` and immutable `catalog`. No credentials enter protocol state. |
| `set-availability` | Human owner | Enable or pause the approved integration after GM policy checks. `test-mode:true` is forbidden in production. |
| `publish` | Bound seller | Publish an approved `sku`. Ignore caller-supplied price/commission overrides; use the approved catalog and GM-authoritative commercial configuration. Confirm the resulting capability. |
| `query-orders` | Bound seller | Return seller-scoped orders and subscriptions. Caller filters cannot widen access. |
| `report-fulfillment` | Bound seller | Record `order-id` and `fulfillment-status` through Market. Verify ownership and payment state. |

Owner operations omit `player_name`. Member operations specify it to select a
seat; it never establishes ownership by itself. Ignore caller-supplied roles or
identity claims. Resolve ownership, membership and roles on every consequential
request. A reused handle with a different membership cannot inherit a binding.

Private state must be protected before binding sellers. In MoM, enabling performs
an owner-authorized compare-and-save that adds `shoptype` to registered and
protected protocols without removing existing entries.

Optional `payment-status` and `start-payment-connection` operations require the
authenticated seller. The latter returns a processor authorization URL. OAuth
completion remains on the GM, consumes a single-use attempt and rechecks the
current membership owner. It does not activate checkout.

## Onboarding and commercial authority

Return requirements as `{kind,url}` items and authoritative seller status. Each GM
defines its own required agreements and approval policy. AoM keeps agreement and
commercial schedule acceptance on AoM; Shoptype links there and reads the current
acceptance. Approval records are never copied into a competing local authority.

An owner reading a seller context receives its accepted `commission-bps` and
`activation-ready` policy result. No universal commission is implied. Activation
also requires current payment readiness, valid worker authorization and passing
evidence for the exact configuration and environment.

## Hosted seller bridge

Shoptype serves each integration at
`/bridge/{integration-id}/seller-commerce/v2/...` with the existing Seller Commerce
API v2 contract and a distinct service credential. Current v1 fulfillment relay
query/ack paths are retained during migration.

Preparation reserves an immutable quote; it does not grant access. A lifecycle
acknowledgment means **durably accepted**, not delivered. The bridge returns
`accepted:true` and queues the effect. Fulfillment is confirmed separately through
the durable outbox after the product API reports success. A timeout or HTTP 202
does not establish delivery. A GM integrating this asynchronous behavior must
wait for fulfillment reporting before presenting a purchase as delivered.

Persist exact lifecycle payload digests. Same ID plus same payload replays the
stored result; different payload returns 409. Product API retries reuse the same
idempotency key. Unknown outcomes remain visible and cannot be blindly retried.

Renewal orders can have new checkout/order IDs while retaining the subscription's
original fulfillment reference. Subscription status events can identify only the
stable Market subscription. Correlate within the integration, retain the original
configuration, and never resolve a reference globally across sellers or GMs.

The bridge supports a `payload.current_period_end` Unix timestamp alongside
`cancel_at_period_end`. Cancellation schedules the configured internal
`subscription.expired` action at the paid-through date. Extensions and cancellation
reversals invalidate stale expiry jobs. Out-of-order status updates cannot undo a
newer status.

The product API remains responsible for its actual entitlement and used-credit
rules. API mappings must implement the accepted seller policy. This protocol
introduces no refund promise or change to a GM's commercial terms.

## Credentials and isolation

Three distinct credentials are involved:

1. The human's authenticated session, for configuration and approval.
2. A revocable worker grant scoped to a GM, membership, integration and permitted
   operations. MoM issues these through `/auth/shoptype-grants` after human seller
   authorization. They expire after 90 days and can be revoked immediately.
3. Seller API credentials encrypted in Shoptype, plus the private GM-to-bridge
   service credential. These never enter public Market state or browser responses.

A worker grant cannot accept agreements, activate sellers, issue refunds, access
admin endpoints or act as the human. Revocation, membership ownership changes and
loss of the Seller role invalidate it. Fulfillment acknowledgment follows GM
confirmation; an interrupted relay resumes with the same references.

## Conformance and release

Run `node scripts/check-gm.mjs` with `SHOPTYPE_GM_URL` and
`SHOPTYPE_OPERATOR_TOKEN` supplied securely through the environment. This checks
discovery, anonymous denial, canonical identity and current ownership; it does not
create products, charge a card or certify commerce.

For each integration: enable test purchases in an isolated GM, publish the
approved catalog, complete the applicable purchase/subscription/refund/dispute
journeys, run product API and lifecycle replay checks, then inspect evidence.
Shoptype derives certification from durable delivery records, acknowledged
fulfillment and an authoritative GM order read. Uploaded pass flags do not count.

Live activation is a separate owner action. Keep new integrations inactive until
all relevant processor, product, protocol and policy checks pass. Monitor job age,
unknown outcomes, delivery failures and relay backlog. Pausing new purchases must
preserve existing subscription obligations and reversals.

## Errors

Use 401 for missing credentials, 403 for insufficient authority, 404 for unavailable
scoped records, 409 for stale state/idempotency/readiness conflicts, 422 for invalid
input or unsupported capabilities and 5xx for service failures. Do not expose raw
processor errors, credentials or another seller's records.
