Open Markets Protocol
Resolution
Existing mechanisms for terminal order states, cancellation, shipping outcomes, public reviews, product supersession, and reputation boundaries.
Scope
Resolution describes how participants record the outcome of an order using mechanisms already present in Gamma Markets and related Nostr specifications. It covers:
- valid order-state transitions;
- cancellation before and after payment;
- delivery outcomes;
- product and merchant reviews;
- review continuity when an offer is superseded.
Open Markets does not define escrow, arbitration, mediators, dispute evidence, chargebacks, forced refunds, or a judgment event. Clients MUST NOT imply that an order status or review can reverse a payment or compel another party.
Order outcome model
Order status is carried by private kind 16, type 3 rumors as defined in Orders.
created ──→ pending ──→ confirmed ──→ processing ──→ completed
│ │ │ │
└───────────┴─────────────┴──────────────┴──→ cancelled*
* Cancellation after payment or confirmation records intent but does not undo settlement.
Authorization
| Transition | Authorized author | Effect |
|---|---|---|
| created → pending | Merchant | Acknowledges receipt |
| pending → confirmed | Merchant | States payment was verified |
| confirmed → processing | Merchant | Fulfillment began |
| processing → completed | Merchant | Fulfillment considered complete |
| unpaid → cancelled | Buyer or merchant | Stops the unpaid order |
| paid/confirmed → cancelled | Buyer or merchant | Records a request or position only |
Only a merchant may publish pending, confirmed, processing, or completed. A buyer may publish only cancelled. The p tag identifies the recipient, so a merchant update points to the buyer and a buyer cancellation points to the merchant.
Clients MUST ignore role-invalid transitions when calculating current state. They SHOULD retain them for audit or support display rather than deleting evidence silently.
Payment and confirmation
Kind 17 is a buyer's receipt claim. The merchant MUST independently verify its proof before sending confirmed. The following are not sufficient on their own:
- receiving a kind
17rumor; - a NIP-57 zap receipt;
- a screenshot or human message;
- a
clientattribution tag; - an application recommendation;
- an unredeemed eCash token.
The Payments proof rules determine whether the merchant can treat payment as settled.
Cancellation
For an unpaid order, a valid cancelled message is terminal. Clients SHOULD stop presenting active payment actions after cancellation.
Before confirmed, the buyer SHOULD be able to cancel when:
- the merchant changes the payable total;
- an offered item becomes unavailable;
- the payment request expires;
- shipping terms change;
- the buyer no longer wishes to proceed.
After payment, cancellation does not define what happens to funds. Parties SHOULD use encrypted kind 14 communication to agree on next steps. A merchant MAY issue a refund using an external payment method, but Open Markets defines no refund request, refund receipt, or mandatory refund policy in this version.
Clients MUST describe this limitation clearly. They MUST NOT display a paid cancellation as proof that money was returned.
Shipping outcomes
Shipping uses private kind 16, type 4 rumors with these states:
| State | Meaning |
|---|---|
processing | Package preparation has begun |
shipped | Package was transferred to a carrier |
delivered | Merchant or carrier reports delivery |
exception | A delay, failed attempt, loss, or other issue occurred |
Shipping status is evidence supplied by the merchant, not an independent carrier attestation. delivered does not automatically publish order completed, and exception does not automatically cancel an order.
Participants SHOULD discuss exceptions using kind 14. Tracking URLs and identifiers are untrusted input; clients MUST escape display values and SHOULD restrict external navigation schemes.
Reviews
Reviews are public signed opinions. They are not judgments, payment proofs, or proof that a purchase occurred. Open Markets uses addressable kind 31555 for both product and merchant reviews, incorporating Gamma PR #7.
Common rules
Every review MUST contain:
- exactly one canonical
dtarget; - exactly one primary
ratingwhose category isthumb; - human-readable review text in
content, which MAY be empty.
Ratings are decimal values from 0 through 1, inclusive. Every rating category MUST appear at most once. Clients MUST reject non-finite values and values outside the range.
Because kind 31555 is addressable, the latest valid review from one reviewer with the same d replaces that reviewer's earlier event for that subject. This model represents one current review per reviewer and subject, not one review per purchase.
Product review
The canonical identity is:
["d", "a:30402:<merchant-pubkey>:<offer-d>"]
Clients SHOULD include a matching a tag for relay filtering:
["a", "30402:<merchant-pubkey>:<offer-d>"]
{
"id": "<event-id>",
"pubkey": "<reviewer-pubkey>",
"created_at": 1787040000,
"kind": 31555,
"tags": [
["d", "a:30402:<merchant-pubkey>:coffee-250g"],
["a", "30402:<merchant-pubkey>:coffee-250g"],
["rating", "1", "thumb"],
["rating", "0.8", "value"],
["rating", "1", "quality"],
["rating", "0.7", "delivery"],
["rating", "0.9", "communication"]
],
"content": "The product matched the listing and arrived on time.",
"sig": "<signature>"
}
If both d and a are present, they MUST name the same offer.
Merchant review
The canonical identity is:
["d", "p:<merchant-pubkey>"]
Clients SHOULD include a matching p tag:
["p", "<merchant-pubkey>"]
{
"id": "<event-id>",
"pubkey": "<reviewer-pubkey>",
"created_at": 1787040100,
"kind": 31555,
"tags": [
["d", "p:<merchant-pubkey>"],
["p", "<merchant-pubkey>"],
["rating", "1", "thumb"],
["rating", "0.9", "communication"],
["rating", "0.8", "delivery"]
],
"content": "The merchant communicated clearly and resolved the delay.",
"sig": "<signature>"
}
Gamma PR #7 contained ambiguous and malformed merchant-target syntax. Open Markets resolves it with a stable d value plus an ordinary p indexing hint.
Rating calculation
The primary thumb rating represents the review's overall positive or negative assessment. Optional categories provide detail.
When no category ratings exist:
review score = thumb
When categories exist:
review score = (thumb × 0.5) + (average(category ratings) × 0.5)
Aggregating multiple reviews is client policy. Clients SHOULD disclose weighting, filtering, trust, and anti-spam rules. They MUST NOT imply that a simple average is a protocol-level reputation judgment.
Purchase verification
The public review schema contains no public order reference because order data is private. A client MUST NOT label a review as a verified purchase solely from its kind and tags.
A participant MAY prove purchase privately to a service, but publishing a link between a public identity and a private order has privacy consequences and is outside this protocol. Future verified-purchase extensions require a separately versioned design.
Superseded offers
An offer MAY identify a predecessor with:
["supersedes", "30402:<pubkey>:<old-d>"]
Reviews always remain attached to the exact address named in their d and a tags. Clients MAY show reviews from predecessor offers, but they MUST:
- label them as historical or aggregated from prior versions;
- keep current-version and historical scores distinguishable;
- detect cycles in supersession chains;
- avoid treating cross-author claims as verified continuity;
- never rewrite the original review target.
This adopts Gamma PR #8 while preventing review history from being silently transferred to a materially different product.
Trusted assertions
NIP-85 defines assertions published by separately trusted providers. It does not define kind 31555 reviews. A client MAY use NIP-85 results as an additional reputation signal, but MUST label the provider and MUST NOT present the assertion as a replacement for the underlying reviews.
Abuse and moderation
Public reviews are vulnerable to spam, retaliation, sock puppets, and selective relay publication. Clients SHOULD support:
- local and user-selected trust policies;
- reviewer blocking and moderation lists;
- transparent aggregation rules;
- duplicate and replacement handling;
- separate display of product and merchant ratings;
- clear labels for historical review roll-ups.
Merchants cannot delete another author's review. Review clients MUST validate signatures and addressable-event replacement rules before display.
Explicit non-goals
Version 1 does not define:
- an escrow event or bond;
- an arbitrator or mediator role;
- dispute opening, evidence, judgment, or appeal events;
- a refund protocol;
- chargeback semantics;
- proof of delivery from a carrier;
- verified-purchase public credentials;
- legally binding terms or jurisdiction.
NIP-69's optional bond field is not imported into Open Markets. Applications adding any of these features MUST identify them as extensions and MUST NOT make ordinary Open Markets orders depend on undocumented behavior.
Source and decision ledger
The consolidation baseline is Gamma Markets commit 5dc79c5. It already includes merged PRs #3 and #4.
| Pull request | Incorporated outcome |
|---|---|
| #1 | Adopted the full-commerce framing under implementation-neutral Open Markets branding. |
| #2 | Adopted direct, manual, and service-assisted flow explanations; retained Gamma kinds, preference values, defaults, subjects, and tuple ordering where the patch conflicts. |
| #3 | Preserved recipient-based status direction: merchant updates point to buyers; buyer cancellations point to merchants. |
| #4 | Preserved optional payment-request expiration in Unix seconds. |
| #5 | Added interoperable address components while retaining the existing free-form address and avoiding invalid pseudo-JSON. |
| #7 | Added product and merchant reviews with corrected canonical targets and relay-indexing hints. |
| #8 | Added advisory product supersession, cycle handling, authority boundaries, and version-specific review continuity. |
| #11 | Added automatic merchant-preference resolution and optional, privacy-aware, non-authoritative client attribution. |
PR #2 cannot be merged literally while preserving the selected compatibility baseline. Its incompatible changes are explicitly resolved in Payments, rather than being omitted silently.