Docs detail
API Ordering Flow
End-to-end menu to order-status flow with card and crypto curl snippets.
Owner: genesis-api
This page documents the canonical order flow:
GET /v1/menuPOST /v1/orders/quotePOST /v1/orders/confirmGET /v1/orders/{id}
Core contract references:
Base URL
Development:
export BASE_URL="http://localhost:3000"
1) Fetch menu
curl -sS "$BASE_URL/v1/menu"
2) Create quote
curl -sS -X POST "$BASE_URL/v1/orders/quote" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "sku": "PZ-MAR", "qty": 1 },
{ "sku": "DR-COL", "qty": 1 }
],
"fulfillment": { "type": "pickup" },
"contact": {
"name": "API Flow Test",
"phone": "+33600000000",
"email": "api-flow@example.com"
}
}'
Save values from quote response:
quoteIdquoteHashtotalCentscurrencyexpiresAtmerchantIdmerchantAddress
3A) Confirm flow (card branch)
curl -sS -X POST "$BASE_URL/v1/orders/confirm" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "YOUR_QUOTE_ID",
"paymentMethod": "card",
"assertions": {
"expectedQuoteHash": "sha256:YOUR_QUOTE_HASH",
"expectedTotalCents": 1200,
"maxTotalCents": 1200,
"expectedCurrency": "EUR",
"expectedPaymentMethod": "card",
"expectedExpiresAt": "2026-03-03T18:30:00Z",
"expectedMerchantId": "au-comptoir-a-patons",
"expectedMerchantAddress": "111 Rue Sebastien Gryphe, 69007 Lyon, France"
}
}'
Expected response: paymentIntentId, clientSecret, and amount details.
3B) Confirm flow (crypto branch)
First call (expect 402 with payment requirements):
curl -i -sS -X POST "$BASE_URL/v1/orders/confirm" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "YOUR_QUOTE_ID",
"paymentMethod": "crypto"
}'
From the 402 body, capture paymentRequestId and paymentRequirements.
Second call:
- local mock adapter: reuse
paymentRequestId - live Coinbase/x402 adapter: build a real payment proof from
paymentRequirements
The proof can be sent in the legacy PAYMENT-SIGNATURE header or the JSON paymentSignature field.
Example header form:
curl -sS -X POST "$BASE_URL/v1/orders/confirm" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: YOUR_PAYMENT_REQUEST_ID" \
-d '{
"quoteId": "YOUR_QUOTE_ID",
"paymentMethod": "crypto"
}'
Expected response: orderId with paid status.
Recovery branches
When confirm fails, use the error code to choose the smallest safe retry path:
ASSERTION_FAILED_*: quote state drifted; recreate the quote and reuse the newquoteHash, amount, expiry, and merchant assertions.PAYMENT_INVALIDwithdetails.reason = invalid_signature: rebuild the proof payload instead of replaying the same broken bytes.PAYMENT_INVALIDwithdetails.reason = expired: create a fresh quote before retrying payment.PAYMENT_INVALIDwithdetails.reason = wrong_network: switch the wallet back to Base (eip155:8453) before retrying.PAYMENT_INVALIDwithdetails.reason = insufficient_funds: top up the wallet before retrying;details.requiredAtomicis the exact minimum.
4) Fetch order status
curl -sS "$BASE_URL/v1/orders/YOUR_ORDER_ID"
Notes
- Quote expiry matters: if expired, create a new quote.
- For crypto, wallet setup is available at
GET /v1/wallet-setup. - Always use confirm-time assertions in agentic/automated flows to prevent silent divergence.
- For merchant-configurable deployments, read the actual rail from merchant bootstrap and quote responses instead of assuming one global payment method.
- Prefer the on-domain AGENTS and OpenAPI assets above when linking builders into the contract surface.