Skip to content

Commerce Endpoints ​

Customer-facing and merchant commerce endpoints introduced in KUB-207 (eCommerce + Merchant MVP).

All endpoints use the /api/v1 prefix. Auth is via Bearer token unless noted. Full request/response schemas are in the API Reference and the live OpenAPI spec at GET /api/v1/openapi.

Cart ​

MethodPathAuthDescription
GET/api/v1/cartBearerGet authenticated user's cart (or null)
POST/api/v1/cart/itemsBearerAdd product with required positive-integer product_id and place_id (400 validation; 404 unavailable membership; 409 cross-merchant conflict)
PATCH/api/v1/cart/items/:idBearerUpdate cart line quantity (0 removes)
DELETE/api/v1/cart/items/:idBearerRemove single cart line
DELETE/api/v1/cartBearerClear entire cart

Checkout ​

MethodPathAuthDescription
POST/api/v1/checkoutBearerAtomic checkout: order + PaymentIntent + cart clear. Requires the Idempotency-Key header (400 if missing/empty; max 255 chars).

Storefront (Public) ​

MethodPathAuthDescription
GET/api/v1/places/:id/menuNonePublic {data:{categories,items}} Lunar menu for a published place. categories[].id and items[].category_id are Lunar Collection IDs; Collection Groups are internal Place containers. place_products selects published products as items and preserves menu position order. Product and Collection channel pivots must be enabled and inside their optional starts_at/ends_at windows. A category is omitted unless at least one selected published product represents it; an uncategorized item uses category_id: null. Each product uses its lowest-ID Lunar variant and newest matching base price in the resolved currency (configured default, then existing XCD), with min_quantity = 1 and no customer group. amount, compare_amount, and currency_code retain their nullable response fields; an unsafe or negative price nulls only its own numeric field.

Payment Methods ​

MethodPathAuthDescription
POST/api/v1/me/payment-methods/setup-intentBearerCreate Stripe SetupIntent (rate limiter defined but not wired)
POST/api/v1/me/payment-methodsBearerPersist payment method after SetupIntent flow
GET/api/v1/me/payment-methodsBearerList user's linked payment methods (no PCI fields)
PATCH/api/v1/me/payment-methods/:id/defaultBearerSet a payment method as default
DELETE/api/v1/me/payment-methods/:idBearerDetach and soft-delete payment method

Orders ​

MethodPathAuthDescription
GET/api/v1/me/ordersBearerCustomer order history (paginated, filterable)
GET/api/v1/me/orders/:idBearerSingle order with line items
GET/api/v1/me/orders/:id/statusBearerLightweight status polling (30s during pending_payment)

Place Claims ​

MethodPathAuthDescription
POST/api/v1/place-claimsBearerSubmit ownership claim on a place (5 req/hour rate limit)
GET/api/v1/place-claims?mine=trueBearerList calling user's claims with status

Merchant Onboarding ​

MethodPathAuthDescription
POST/api/v1/me/places/:placeId/payment-detailsBearer + merchantSave payout details (encrypted at rest). Fields: bank_name, account_holder_name, account_number, mobanking_phone_number, currency (default: XCD)
PATCH/api/v1/me/places/:placeId/payment-detailsBearer + merchantUpdate payout details
GET/api/v1/me/places/:placeId/payment-detailsBearer + merchantGet payout details (last4 only for merchant)

Merchant Inventory ​

MethodPathAuthDescription
GET/api/v1/me/placesBearer + merchantList places owned by the authenticated merchant
PATCH/api/v1/me/places/:idBearer + non-guest merchant + active ownershipUpdate only name, summary, description, address_line, city, country_code, website_url, contact_phone, contact_email, paired latitude/longitude, category_ids, and area_id. description is limited to 65,535 Unicode code points. Returns 401, 403, 404, 422, 429, or 502 for auth, ownership, inaccessible-place, validation, rate-limit, and upstream-service failures.
GET/api/v1/me/places/:placeId/ordersBearer + merchantList orders for a place
POST/api/v1/me/places/:placeId/categoriesBearer + merchantCreate a storefront category
PATCH/api/v1/me/places/:placeId/categories/:categoryIdBearer + merchantUpdate a category. {categoryId} is a Lunar Collection ID.
DELETE/api/v1/me/places/:placeId/categories/:categoryIdBearer + merchantDelete a category. {categoryId} is a Lunar Collection ID. Returns 200 { "data": { "deleted": true } }, detaches associated products, and does not delete products.
POST/api/v1/me/places/:placeId/itemsBearer + merchantCreate a storefront item
PATCH/api/v1/me/places/:placeId/items/:itemIdBearer + merchantUpdate an item
DELETE/api/v1/me/places/:placeId/items/:itemIdBearer + merchantDelete an item
POST/api/v1/me/places/:placeId/items/:itemId/pricesBearer + merchantAppend a price (prices are append-only)

Disbursements ​

MethodPathAuthDescription
GET/api/v1/me/disbursementsBearer + merchantMerchant's disbursement history (read-only)
GET/api/v1/me/disbursements/:idBearer + merchantSingle disbursement detail

Push Notifications ​

MethodPathAuthDescription
POST/api/v1/me/push-tokensBearerRegister or refresh device push token
DELETE/api/v1/me/push-tokens/:device_idBearerRemove device push token on logout

Shop QR ​

MethodPathAuthDescription
GET/api/v1/me/places/:place_id/shop-qrBearer + merchant + owns placeDeep-link URL and QR SVG for the place

Internal Endpoints ​

These private Hono↔Laravel routes are behind the InternalOnly middleware (X-Internal-Token header) and are not available to external clients. They handle payment-details encryption, Stripe SetupIntent/customer operations, and order-state transitions. Client documentation is omitted by design — treat this as a trust boundary.

See Also ​

Built with VitePress