Files
backend/docs/website-api/openapi.json
T
Alireza HassaniandCursor 0f92307fcd Allow register to link existing Meshkee accounts after acknowledgement.
Adds optional acknowledgeExistingAccount and documents the CELL_EXISTS_OTHER_SITE → SMS link flow for storefronts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 09:53:15 +03:30

1082 lines
39 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"openapi": "3.0.3",
"info": {
"title": "Meshkee Website API",
"version": "1.0.0",
"description": "Global storefront API for every Meshkee business website.\n\n**Not domain-specific.** Replace `{domain}` with the website apex (e.g. `sanihome.ir`).\n\n**Base URL:** `https://api.meshkee.com/api/v1` (or `https://api.{domain}/api/v1` if that alias is configured).\n\n**Tenant rule:** public content uses `/tenants/{domain}/...`. After login, cart/orders/favorites use `/businesses/{businessId}/...` with Bearer JWT.\n\n**Docs:** https://api.meshkee.com/docs/website"
},
"servers": [
{
"url": "https://api.meshkee.com/api/v1",
"description": "Production (central) — use this for all websites"
},
{
"url": "https://api.{domain}/api/v1",
"description": "Optional per-site alias (same backend). {domain} = website apex",
"variables": {
"domain": {
"default": "example.com"
}
}
}
],
"tags": [
{ "name": "Tenant" },
{ "name": "Homepage" },
{ "name": "Categories" },
{ "name": "Products" },
{ "name": "User Products" },
{ "name": "Store" },
{ "name": "Blogs" },
{ "name": "Portfolios" },
{ "name": "Comments" },
{ "name": "Expert Reviews" },
{ "name": "Contact" },
{ "name": "Auth" },
{ "name": "Addresses" },
{ "name": "Cities" },
{ "name": "Cart" },
{ "name": "Orders" },
{ "name": "Favorites" },
{ "name": "Partner SMS" }
],
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
},
"apiKeyAuth": {
"type": "apiKey",
"in": "header",
"name": "X-Api-Key",
"description": "Partner SMS API key (server-to-server only). Issued per allowlisted domain."
}
},
"parameters": {
"domain": {
"name": "domain",
"in": "path",
"required": true,
"description": "Website apex host only (e.g. sanihome.ir). No www/api/customer/business prefix.",
"schema": { "type": "string", "example": "example.com" }
},
"businessId": {
"name": "businessId",
"in": "path",
"required": true,
"description": "From GET /tenants/{domain} → id",
"schema": { "type": "string" }
}
}
},
"paths": {
"/tenants/{domain}": {
"get": {
"tags": ["Tenant"],
"summary": "Resolve website domain → business",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": {
"200": {
"description": "Business branding",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"nameFa": { "type": "string" },
"slug": { "type": "string" },
"domain": { "type": "string" },
"primaryColor": { "type": "string", "nullable": true },
"defaultLocale": { "type": "string", "enum": ["en", "fa"] },
"logoUrl": { "type": "string", "nullable": true },
"faviconUrl": { "type": "string", "nullable": true }
}
}
}
}
}
}
}
},
"/tenants/{domain}/website/business-info": {
"get": {
"tags": ["Homepage"],
"summary": "About, contacts, addresses, social",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": { "200": { "description": "Business public profile" } }
}
},
"/tenants/{domain}/website/sliders": {
"get": {
"tags": ["Homepage"],
"summary": "Homepage sliders + slides",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": { "200": { "description": "{ items: Slider[] }" } }
}
},
"/tenants/{domain}/website/category-groups": {
"get": {
"tags": ["Homepage"],
"summary": "Homepage category groups",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": { "200": { "description": "{ items: CategoryGroup[] } — each group has id, key, title, items[]" } }
}
},
"/tenants/{domain}/website/brand-groups": {
"get": {
"tags": ["Homepage"],
"summary": "Homepage brand groups",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": { "200": { "description": "{ items: BrandGroup[] } — each group has id, key, title, items[]" } }
}
},
"/tenants/{domain}/store-specials": {
"get": {
"tags": ["Homepage", "Store"],
"summary": "Active store specials",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"responses": { "200": { "description": "{ items: StoreSpecial[] } — each special has id, key, title, items[]" } }
}
},
"/tenants/{domain}/categories": {
"get": {
"tags": ["Categories"],
"summary": "Public categories",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{
"name": "entityType",
"in": "query",
"schema": {
"type": "string",
"enum": ["product", "blog", "portfolio"],
"default": "product"
}
}
],
"responses": { "200": { "description": "{ items: Category[] }" } }
}
},
"/tenants/{domain}/products": {
"get": {
"tags": ["Products"],
"summary": "List published products",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 12 } },
{ "name": "name", "in": "query", "schema": { "type": "string" } },
{ "name": "categoryId", "in": "query", "schema": { "type": "string" } },
{ "name": "brandId", "in": "query", "schema": { "type": "string" } },
{ "name": "tag", "in": "query", "schema": { "type": "string" } },
{ "name": "inStore", "in": "query", "schema": { "type": "boolean" } }
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
}
},
"/tenants/{domain}/products/{slug}": {
"get": {
"tags": ["Products"],
"summary": "Product by slug",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ product }" } }
}
},
"/tenants/{domain}/products/{slug}/variations": {
"get": {
"tags": ["Products"],
"summary": "Product variation options",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ variations }" } }
}
},
"/tenants/{domain}/products/{slug}/technical-info": {
"get": {
"tags": ["Products"],
"summary": "Product technical specs",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ form, values }" } }
}
},
"/tenants/{domain}/user-products": {
"get": {
"tags": ["User Products"],
"summary": "List published customer / stock listings",
"description": "Public marketplace-style listings created by customers (user products). Only `status=published`. Search with `name` or `q` (title/description). Filter by category, city, country, condition, or promoted.",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 12 } },
{ "name": "name", "in": "query", "description": "Search title/description (alias of q)", "schema": { "type": "string" } },
{ "name": "q", "in": "query", "description": "Search title/description (alias of name)", "schema": { "type": "string" } },
{ "name": "categoryId", "in": "query", "schema": { "type": "string" } },
{ "name": "cityId", "in": "query", "schema": { "type": "string" } },
{ "name": "countryId", "in": "query", "schema": { "type": "string" } },
{
"name": "condition",
"in": "query",
"schema": {
"type": "string",
"enum": ["new", "stock", "needs_repair", "scrap"]
}
},
{ "name": "promoted", "in": "query", "schema": { "type": "boolean" } }
],
"responses": {
"200": {
"description": "{ items: UserProductListItem[], total, page, pageSize }. Each item includes id, slug, titleFa/titleEn, price, priceCurrency, condition, city/country names, imageUrl, category*, promoted, publishedAt."
}
}
}
},
"/tenants/{domain}/user-products/{slug}": {
"get": {
"tags": ["User Products"],
"summary": "User product details by slug",
"description": "Full published listing: location IDs, gallery images (`images`, `galleryMediaIds`), technical field values, delivery/technical notes.",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": {
"description": "{ product } with gallery (`images`: [{ mediaId, url }]), featuredMediaId, technicalValues, countryId, cityId, countrySlug"
},
"404": { "description": "Not found or not published" }
}
}
},
"/tenants/{domain}/user-products/{slug}/technical-info": {
"get": {
"tags": ["User Products"],
"summary": "User product technical form + values",
"description": "Category technical form schema plus the listings submitted values (same shape as dashboard technical values).",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ form, values }" } }
}
},
"/tenants/{domain}/store-items": {
"get": {
"tags": ["Store"],
"summary": "List sellable variants",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 20 } },
{ "name": "categoryId", "in": "query", "schema": { "type": "string" } },
{ "name": "brandId", "in": "query", "schema": { "type": "string" } },
{ "name": "productId", "in": "query", "schema": { "type": "string" } },
{ "name": "name", "in": "query", "schema": { "type": "string" } },
{ "name": "inStock", "in": "query", "schema": { "type": "boolean" } },
{ "name": "isFestival", "in": "query", "schema": { "type": "boolean" } },
{ "name": "minPrice", "in": "query", "schema": { "type": "number" } },
{ "name": "maxPrice", "in": "query", "schema": { "type": "number" } }
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
}
},
"/tenants/{domain}/store-items/by-product/{productId}": {
"get": {
"tags": ["Store"],
"summary": "Variants for one product",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "productId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ storeItem }" } }
}
},
"/tenants/{domain}/store-items/{variantId}": {
"get": {
"tags": ["Store"],
"summary": "One variant",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "variantId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ variant }" } }
}
},
"/tenants/{domain}/blogs": {
"get": {
"tags": ["Blogs"],
"summary": "List published blogs",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 12 } },
{ "name": "type", "in": "query", "schema": { "type": "string", "enum": ["news", "article", "blog"] } },
{ "name": "categoryId", "in": "query", "schema": { "type": "string" } },
{ "name": "title", "in": "query", "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
}
},
"/tenants/{domain}/blogs/{slug}": {
"get": {
"tags": ["Blogs"],
"summary": "Blog by slug",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ blog }" } }
}
},
"/tenants/{domain}/blogs/{blogId}/comments": {
"get": {
"tags": ["Blogs", "Comments"],
"summary": "Approved blog comments",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "blogId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items }" } }
},
"post": {
"tags": ["Blogs", "Comments"],
"summary": "Submit blog comment",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "blogId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["authorName", "text"],
"properties": {
"authorName": { "type": "string" },
"authorEmail": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ comment, message }" } }
}
},
"/tenants/{domain}/portfolios": {
"get": {
"tags": ["Portfolios"],
"summary": "List published portfolios",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 12 } },
{ "name": "categoryId", "in": "query", "schema": { "type": "string" } },
{ "name": "title", "in": "query", "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
}
},
"/tenants/{domain}/portfolios/{slug}": {
"get": {
"tags": ["Portfolios"],
"summary": "Portfolio by slug",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ portfolio }" } }
}
},
"/tenants/{domain}/portfolios/{portfolioId}/comments": {
"get": {
"tags": ["Portfolios", "Comments"],
"summary": "Approved portfolio comments",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "portfolioId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items }" } }
},
"post": {
"tags": ["Portfolios", "Comments"],
"summary": "Submit portfolio comment",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "portfolioId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["authorName", "text"],
"properties": {
"authorName": { "type": "string" },
"authorEmail": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ comment, message }" } }
}
},
"/tenants/{domain}/comments": {
"get": {
"tags": ["Comments"],
"summary": "List approved comments for any entity",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{
"name": "entityType",
"in": "query",
"required": true,
"schema": { "type": "string", "enum": ["product", "blog", "portfolio"] }
},
{ "name": "entityId", "in": "query", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items }" } }
},
"post": {
"tags": ["Comments"],
"summary": "Submit comment (product/blog/portfolio)",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["entityType", "entityId", "authorName", "text"],
"properties": {
"entityType": { "type": "string", "enum": ["product", "blog", "portfolio"] },
"entityId": { "type": "string" },
"authorName": { "type": "string" },
"authorEmail": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ comment, message }" } }
}
},
"/tenants/{domain}/expert-reviews": {
"get": {
"tags": ["Expert Reviews"],
"summary": "Approved expert reviews for a product",
"parameters": [
{ "$ref": "#/components/parameters/domain" },
{ "name": "productId", "in": "query", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items }" } }
},
"post": {
"tags": ["Expert Reviews"],
"summary": "Submit expert review",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["productId", "authorName", "rate", "positivePoints", "negativePoints", "text"],
"properties": {
"productId": { "type": "string" },
"authorName": { "type": "string" },
"authorEmail": { "type": "string" },
"rate": { "type": "integer", "minimum": 1, "maximum": 10 },
"positivePoints": { "type": "array", "items": { "type": "string" } },
"negativePoints": { "type": "array", "items": { "type": "string" } },
"text": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ review, message }" } }
}
},
"/tenants/{domain}/contact-submissions": {
"post": {
"tags": ["Contact"],
"summary": "Contact form",
"parameters": [{ "$ref": "#/components/parameters/domain" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["title", "name", "text"],
"properties": {
"title": { "type": "string" },
"name": { "type": "string" },
"email": { "type": "string" },
"cellNumber": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ submission, message }" } }
}
},
"/auth/register": {
"post": {
"tags": ["Auth"],
"summary": "Register customer on a website",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber", "password", "firstName", "lastName", "domain"],
"properties": {
"cellNumber": { "type": "string", "description": "E.164 e.g. +98912..." },
"password": { "type": "string", "minLength": 8 },
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"email": { "type": "string" },
"domain": { "type": "string", "description": "Same website apex as {domain}" },
"acknowledgeExistingAccount": {
"type": "boolean",
"description": "If true, link an existing Meshkee account from another website without matching its password. Existing password and profile stay unchanged."
}
}
}
}
}
},
"responses": { "201": { "description": "{ user, accessToken, refreshToken, registeredBusiness }" } }
}
},
"/auth/login": {
"post": {
"tags": ["Auth"],
"summary": "Login",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber", "password"],
"properties": {
"cellNumber": { "type": "string" },
"password": { "type": "string" }
}
}
}
}
},
"responses": { "200": { "description": "{ user, accessToken, refreshToken }" } }
}
},
"/auth/login-otp": {
"post": {
"tags": ["Auth"],
"summary": "Passwordless login with SMS OTP",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber", "code"],
"properties": {
"cellNumber": { "type": "string" },
"code": { "type": "string", "minLength": 6, "maxLength": 6 }
}
}
}
}
},
"responses": { "200": { "description": "{ user, accessToken, refreshToken }" } }
}
},
"/auth/reset-password": {
"post": {
"tags": ["Auth"],
"summary": "Reset password with SMS OTP",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber", "code", "newPassword"],
"properties": {
"cellNumber": { "type": "string" },
"code": { "type": "string", "minLength": 6, "maxLength": 6 },
"newPassword": { "type": "string", "minLength": 8 }
}
}
}
}
},
"responses": { "200": { "description": "{ message }" } }
}
},
"/auth/refresh": {
"post": {
"tags": ["Auth"],
"summary": "Refresh tokens",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["refreshToken"],
"properties": { "refreshToken": { "type": "string" } }
}
}
}
},
"responses": { "200": { "description": "{ user, accessToken, refreshToken }" } }
}
},
"/auth/me": {
"get": {
"tags": ["Auth"],
"summary": "Current user",
"security": [{ "bearerAuth": [] }],
"responses": { "200": { "description": "{ user }" } }
}
},
"/auth/profile": {
"patch": {
"tags": ["Auth"],
"summary": "Update profile",
"security": [{ "bearerAuth": [] }],
"responses": { "200": { "description": "{ message, user }" } }
}
},
"/auth/change-password": {
"post": {
"tags": ["Auth"],
"summary": "Change password",
"security": [{ "bearerAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["currentPassword", "newPassword"],
"properties": {
"currentPassword": { "type": "string" },
"newPassword": { "type": "string", "minLength": 8 }
}
}
}
}
},
"responses": { "200": { "description": "{ message }" } }
}
},
"/auth/send-otp": {
"post": {
"tags": ["Auth"],
"summary": "Send OTP SMS",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber"],
"properties": {
"cellNumber": { "type": "string" },
"domain": {
"type": "string",
"description": "Tenant host/apex used to brand the OTP SMS with the business Farsi name"
}
}
}
}
}
},
"responses": { "200": { "description": "{ enabled, message, expiresInSeconds? }" } }
}
},
"/auth/verify-otp": {
"post": {
"tags": ["Auth"],
"summary": "Verify OTP",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["cellNumber", "code"],
"properties": {
"cellNumber": { "type": "string" },
"code": { "type": "string", "minLength": 6, "maxLength": 6 }
}
}
}
}
},
"responses": { "200": { "description": "{ enabled, verified, message }" } }
}
},
"/auth/addresses": {
"get": {
"tags": ["Addresses"],
"summary": "List my shipping addresses",
"security": [{ "bearerAuth": [] }],
"responses": { "200": { "description": "{ items }" } }
},
"post": {
"tags": ["Addresses"],
"summary": "Create address",
"security": [{ "bearerAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["province", "city", "address"],
"properties": {
"label": { "type": "string" },
"province": { "type": "string" },
"city": { "type": "string" },
"address": { "type": "string" },
"postalCode": { "type": "string" },
"landline": { "type": "string" }
}
}
}
}
},
"responses": { "201": { "description": "{ address }" } }
}
},
"/auth/addresses/{addressId}": {
"patch": {
"tags": ["Addresses"],
"summary": "Update address",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "name": "addressId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ address }" } }
},
"delete": {
"tags": ["Addresses"],
"summary": "Delete address",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "name": "addressId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ message }" } }
}
},
"/cities": {
"get": {
"tags": ["Cities"],
"summary": "Location tree (countries / provinces / cities)",
"parameters": [
{
"name": "level",
"in": "query",
"schema": { "type": "string", "enum": ["country", "province", "city"] }
},
{ "name": "parentId", "in": "query", "schema": { "type": "string" } },
{ "name": "parentSlug", "in": "query", "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ items }" } }
}
},
"/cities/{cityId}": {
"get": {
"tags": ["Cities"],
"summary": "Get one location node",
"parameters": [
{ "name": "cityId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ city }" } }
}
},
"/businesses/{businessId}/cart": {
"get": {
"tags": ["Cart"],
"summary": "Get cart",
"security": [{ "bearerAuth": [] }],
"parameters": [{ "$ref": "#/components/parameters/businessId" }],
"responses": { "200": { "description": "{ cart }" } }
},
"delete": {
"tags": ["Cart"],
"summary": "Clear cart",
"security": [{ "bearerAuth": [] }],
"parameters": [{ "$ref": "#/components/parameters/businessId" }],
"responses": { "200": { "description": "{ message, cart }" } }
}
},
"/businesses/{businessId}/cart/items": {
"post": {
"tags": ["Cart"],
"summary": "Add variant to cart",
"security": [{ "bearerAuth": [] }],
"parameters": [{ "$ref": "#/components/parameters/businessId" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["storeItemVariantId"],
"properties": {
"storeItemVariantId": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1, "default": 1 }
}
}
}
}
},
"responses": { "201": { "description": "{ message, cart }" } }
}
},
"/businesses/{businessId}/cart/items/{itemId}": {
"patch": {
"tags": ["Cart"],
"summary": "Update cart line quantity",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "itemId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["quantity"],
"properties": { "quantity": { "type": "integer", "minimum": 1 } }
}
}
}
},
"responses": { "200": { "description": "{ message, cart }" } }
},
"delete": {
"tags": ["Cart"],
"summary": "Remove cart line",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "itemId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ message, cart }" } }
}
},
"/businesses/{businessId}/cart/checkout": {
"post": {
"tags": ["Cart"],
"summary": "Checkout → create order",
"security": [{ "bearerAuth": [] }],
"parameters": [{ "$ref": "#/components/parameters/businessId" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["payment"],
"properties": {
"addressId": { "type": "string" },
"shippingAddress": {
"type": "object",
"properties": {
"province": { "type": "string" },
"city": { "type": "string" },
"address": { "type": "string" },
"postalCode": { "type": "string" },
"landline": { "type": "string" }
}
},
"customerNotes": { "type": "string" },
"payment": {
"type": "object",
"required": ["type"],
"properties": {
"type": {
"type": "string",
"enum": ["pos", "cash", "transfer", "e_payment_gate"]
},
"posType": { "type": "string" },
"transferAccount": { "type": "string" },
"transferRefNumber": { "type": "string" },
"gatewayType": { "type": "string" },
"notes": { "type": "string" }
}
}
}
}
}
}
},
"responses": { "201": { "description": "{ message, order }" } }
}
},
"/businesses/{businessId}/orders": {
"get": {
"tags": ["Orders"],
"summary": "My orders",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 20 } },
{
"name": "status",
"in": "query",
"schema": {
"type": "string",
"enum": ["pending", "confirmed", "processing", "shipped", "delivered", "cancelled"]
}
}
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
}
},
"/businesses/{businessId}/orders/{orderId}": {
"get": {
"tags": ["Orders"],
"summary": "My order detail",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "orderId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ order }" } }
}
},
"/businesses/{businessId}/favorites": {
"get": {
"tags": ["Favorites"],
"summary": "List favorites",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "page", "in": "query", "schema": { "type": "integer" } },
{ "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 20 } }
],
"responses": { "200": { "description": "{ items, total, page, pageSize }" } }
},
"post": {
"tags": ["Favorites"],
"summary": "Add favorite",
"security": [{ "bearerAuth": [] }],
"parameters": [{ "$ref": "#/components/parameters/businessId" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["productId"],
"properties": { "productId": { "type": "string" } }
}
}
}
},
"responses": { "201": { "description": "{ favorite, message }" } }
}
},
"/businesses/{businessId}/favorites/{productId}": {
"delete": {
"tags": ["Favorites"],
"summary": "Remove favorite",
"security": [{ "bearerAuth": [] }],
"parameters": [
{ "$ref": "#/components/parameters/businessId" },
{ "name": "productId", "in": "path", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "{ message }" } }
}
},
"/public/sms/send": {
"post": {
"tags": ["Partner SMS"],
"summary": "Send SMS via Meshkee (partner gateway)",
"description": "Server-to-server only. For external/partner backends (e.g. Balout) that need to send SMS through Meshkee → Gama. Not for browser/storefront JS. Requires an allowlisted `domain` + matching `X-Api-Key`. See /docs/website/SMS.md.",
"security": [{ "apiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["domain", "to", "message"],
"properties": {
"domain": {
"type": "string",
"example": "baloutpastry.com",
"description": "Allowlisted partner apex (www. is stripped)"
},
"to": {
"type": "string",
"example": "09127004945",
"description": "Iranian mobile: 09…, 9…, +989…, or 989…"
},
"message": {
"type": "string",
"maxLength": 700,
"example": "سفارش شما به شماره ی ۱۲۱۱۳۲۲ اماده می باشد."
}
}
}
}
}
},
"responses": {
"200": {
"description": "Accepted by Gama",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": true },
"serverId": { "type": "string", "example": "1136923081051406337" }
}
}
}
}
},
"400": { "description": "Invalid phone or message" },
"401": { "description": "Missing/invalid X-Api-Key or domain" },
"429": { "description": "Rate limited (30/partner/min or 5/destination/min)" },
"503": { "description": "SMS disabled or provider unreachable" }
}
}
}
}
}