Order state machine
Payment state machine
Types
Orders
GET /market/orders?machineId={id}
Lists orders for a machine.
VALIDATION_ERROR, NOT_FOUND, MACHINE_NOT_ACTIVE, MACHINE_NOT_ACTIVATED.
POST /market/orders
Locks a service from the catalogue into an order. Status starts at created. The recommended payment rail is copied from the service into order.payment.
VALIDATION_ERROR, QUOTE_EXPIRED, AGENT_PAIRING_REQUIRED, AGENT_PAIRING_INACTIVE, AGENT_POLICY_DENIED, AGENT_SPEND_LIMIT_EXCEEDED, AGENT_DAILY_LIMIT_EXCEEDED, MACHINE_NOT_ACTIVE, MACHINE_NOT_ACTIVATED, NOT_FOUND.
GET /market/orders/:orderId
Payment
POST /market/orders/:orderId/payment-intent
Creates or returns the payment record. Idempotent: returns the existing payment if one already exists. For not-required rails the order moves straight to ready.
NOT_FOUND, VALIDATION_ERROR (unsupported rail, invalid address, rail not in service supportedRails when PEAQOS_ENFORCE_SERVICE_PAYMENT_RAILS=true).
POST /market/orders/:orderId/payment-proof
Records a payment proof. recorded mode stores operator attestation. rpc mode queries an EVM RPC for the receipt and validates the ERC-20 Transfer log against expected token, sender, recipient, and raw amount. Solana proofs are always recorded.
NOT_FOUND, ORDER_CLOSED, VALIDATION_ERROR, PAYMENT_RPC_REQUIRED (rpc mode with no RPC URL), PAYMENT_RPC_ERROR (502), PAYMENT_NOT_MINED (409, receipt null), PAYMENT_TX_FAILED (402, receipt status not 0x1), PAYMENT_TRANSFER_NOT_FOUND (400, no matching Transfer log).
On successful verification the type upgrades from wallet to wdk-usdt-transfer. Payment status moves to held; order moves created/payment_pending → ready.
GET /market/orders/:orderId/payment
POST /market/orders/:orderId/payment/escrow-lock
Records an on-chain escrow lock. Payment → held. Order → ready. Idempotent for held.
NOT_FOUND, ORDER_CLOSED, VALIDATION_ERROR.
POST /market/orders/:orderId/payment/release
Releases held funds after confirm. Payment must be release_pending, order must be confirmed. Status → released.
NOT_FOUND, ORDER_CLOSED, ORDER_NOT_DELIVERED. Idempotent for released and not_required.
POST /market/orders/:orderId/payment/refund
Refunds payment. Status → refunded. Open orders move to cancelled.
NOT_FOUND, ORDER_CLOSED. Idempotent for refunded and not_required.
Execute, confirm, dispute
POST /market/orders/:orderId/execute
Materialises the order as a task plus route, runs the skill runtime, writes a Run and an Outcome. Order status moves executing → delivered (outcome completed) / handoff (outcome external) / failed. The HTTP status code is propagated from the inner execution result.
ORDER_CLOSED (order in confirmed / disputed / cancelled), PAYMENT_REQUIRED (when PEAQOS_REQUIRE_PAYMENT_BEFORE_EXECUTE=true, the production default, and payment is not in not_required / held / release_pending / released — except intent_created is allowed for external / vault-stripe rails). All downstream skill-runtime errors are surfaced as well.
x402-rail services (Agentic Market, most pay.sh) execute through the paidHttp adapter. The execute call replays the original 402-challenged request with the operator-supplied payment headers (x-payment, payment-signature, authorization, sign-in-with-x). The payment intent response now preserves the full x402 accepts[] entries including extra (EIP-712 signing metadata: { name: "USD Coin", version: "2" }-style) and outputSchema. Operators that build their own paid-HTTP adapters should pass headers under operatorCredentials.providers[providerKey]; raw headers are stripped from request bodies before forwarding and never persisted.
POST /market/orders/:orderId/confirm
Buyer confirms delivery. Order delivered / handoff → confirmed. Payment held → release_pending.
ORDER_NOT_DELIVERED.
POST /market/orders/:orderId/dispute
Opens a dispute record. Order → disputed. Payment → frozen. Returns 201.
VALIDATION_ERROR (missing reason).

