{
    "openapi": "3.0.3",
    "info": {
        "title": "Shoppex Partner API",
        "version": "1.0.0",
        "description": "External partner API for catalog retrieval, order creation, partner order lookup, and Shoppex-compatible routes. Authentication uses API key plus HMAC SHA-256 headers."
    },
    "servers": [
        {
            "url": "https://partners-api.shoppexcorp.com",
            "description": "Shoppex Partner API"
        }
    ],
    "tags": [
        {
            "name": "Modern Partner API",
            "description": "Shoppex Partner API /api/v1 routes."
        }
    ],
    "components": {
        "securitySchemes": {
            "ShoppexHmacKey": {
                "type": "apiKey",
                "in": "header",
                "name": "X-Shoppex-Key",
                "description": "Partner API key. Requests must also send X-Shoppex-Timestamp, X-Shoppex-Nonce, and X-Shoppex-Signature."
            }
        },
        "parameters": {
            "ShoppexTimestamp": {
                "name": "X-Shoppex-Timestamp",
                "in": "header",
                "required": true,
                "schema": {
                    "type": "string",
                    "example": "1775726400"
                },
                "description": "Unix timestamp in seconds. Must be within the configured HMAC skew window."
            },
            "ShoppexNonce": {
                "name": "X-Shoppex-Nonce",
                "in": "header",
                "required": true,
                "schema": {
                    "type": "string",
                    "example": "req-demo-001"
                },
                "description": "Unique nonce per request. Reuse is rejected."
            },
            "ShoppexSignature": {
                "name": "X-Shoppex-Signature",
                "in": "header",
                "required": true,
                "schema": {
                    "type": "string",
                    "example": "hmac_sha256_signature_placeholder"
                },
                "description": "HMAC SHA-256 signature over METHOD, ROUTE, TIMESTAMP, NONCE, and SHA256(raw body), joined with newline characters. ROUTE is the path only, without domain or query string."
            },
            "Page": {
                "name": "page",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1
                }
            },
            "PerPage": {
                "name": "per_page",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 200,
                    "default": 100
                }
            },
            "ProductPerPage": {
                "name": "per_page",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 100
                }
            },
            "Limit": {
                "name": "limit",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 200
                },
                "description": "Alias for per_page on order list endpoints when per_page is not sent."
            },
            "Search": {
                "name": "search",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string"
                }
            },
            "Brand": {
                "name": "brand",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string"
                }
            },
            "Type": {
                "name": "type",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string"
                }
            },
            "Status": {
                "name": "status",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string",
                    "example": "queued"
                }
            },
            "FromDate": {
                "name": "from",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string",
                    "format": "date"
                }
            },
            "ToDate": {
                "name": "to",
                "in": "query",
                "required": false,
                "schema": {
                    "type": "string",
                    "format": "date"
                }
            },
            "OrderId": {
                "name": "order_id",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "string"
                },
                "description": "Local order ID, partner order ID, OrderSourceOrderID, or SellerCloud order ID."
            }
        },
        "schemas": {
            "BusinessError": {
                "type": "object",
                "required": [
                    "success",
                    "code",
                    "message"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": false
                    },
                    "code": {
                        "type": "string",
                        "example": "order_amount_not_allowed"
                    },
                    "message": {
                        "type": "string",
                        "example": "Current order amount is not allowed for this partner."
                    },
                    "product_id": {
                        "type": "string",
                        "nullable": true,
                        "example": "WHO-ZAK-731529"
                    }
                }
            },
            "RateLimitError": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": false
                    },
                    "code": {
                        "type": "string",
                        "example": "rate_limited"
                    },
                    "message": {
                        "type": "string",
                        "example": "Rate limit exceeded."
                    },
                    "retry_after": {
                        "type": "integer",
                        "example": 32
                    },
                    "limit": {
                        "type": "integer",
                        "example": 60
                    },
                    "window_seconds": {
                        "type": "integer",
                        "example": 60
                    }
                }
            },
            "ModernProduct": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "string",
                        "example": "WHO-ZAK-731529"
                    },
                    "sku": {
                        "type": "string",
                        "example": "WHO-ZAK-731529"
                    },
                    "name": {
                        "type": "string",
                        "nullable": true,
                        "example": "ZAKAT Z6 100ML EDP"
                    },
                    "price": {
                        "type": "string",
                        "example": "19.99"
                    },
                    "stock_quantity": {
                        "type": "integer",
                        "example": 24
                    },
                    "type": {
                        "type": "string",
                        "nullable": true,
                        "example": "Perfume"
                    },
                    "brand": {
                        "type": "string",
                        "nullable": true,
                        "example": "Demo Brand"
                    },
                    "upc": {
                        "type": "string",
                        "nullable": true,
                        "example": "000000000001"
                    },
                    "image_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "Product image resolved from SellerCloud and cached server-side. May be null on a rare cache miss and populate on a subsequent request.",
                        "example": "https://cdn.shoppexcorp.com/products/demo-product.jpg"
                    },
                    "origin": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "SC",
                            "*",
                            "Suppliers"
                        ],
                        "example": "SC"
                    },
                    "stock_sc": {
                        "type": "integer",
                        "nullable": true,
                        "example": 24
                    },
                    "qty_per_case": {
                        "type": "integer",
                        "nullable": true,
                        "example": 12
                    },
                    "min_start": {
                        "type": "integer",
                        "nullable": true,
                        "example": 12
                    }
                }
            },
            "ProductPagination": {
                "type": "object",
                "properties": {
                    "page": {
                        "type": "integer",
                        "example": 1
                    },
                    "per_page": {
                        "type": "integer",
                        "example": 100
                    },
                    "total": {
                        "type": "integer",
                        "example": 348
                    },
                    "total_pages": {
                        "type": "integer",
                        "example": 4
                    },
                    "has_next": {
                        "type": "boolean",
                        "example": true
                    },
                    "has_prev": {
                        "type": "boolean",
                        "example": false
                    }
                }
            },
            "ModernProductsResponse": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ModernProduct"
                        }
                    },
                    "pagination": {
                        "$ref": "#/components/schemas/ProductPagination"
                    }
                }
            },
            "CreateOrderRequest": {
                "type": "object",
                "required": [
                    "items",
                    "id_order_partner"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                            "$ref": "#/components/schemas/CreateOrderItem"
                        }
                    },
                    "id_order_partner": {
                        "type": "string",
                        "example": "PARTNER-ORDER-12345"
                    },
                    "comments": {
                        "type": "string",
                        "nullable": true,
                        "example": "Demo order created by an external partner integration."
                    },
                    "tax_id": {
                        "type": "string",
                        "nullable": true
                    },
                    "resale_tax": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "CreateOrderItem": {
                "type": "object",
                "required": [
                    "quantity"
                ],
                "anyOf": [
                    {
                        "required": [
                            "product_id"
                        ]
                    },
                    {
                        "required": [
                            "sku"
                        ]
                    }
                ],
                "properties": {
                    "product_id": {
                        "type": "string",
                        "description": "data-sc.csv ProductID/SKU, or another configured product alias such as UPC.",
                        "example": "WHO-ZAK-731529"
                    },
                    "sku": {
                        "type": "string",
                        "nullable": true,
                        "description": "Alternative product identifier. If sku and product_id are both sent, they must resolve to the same product.",
                        "example": "WHO-ZAK-731529"
                    },
                    "quantity": {
                        "type": "integer",
                        "minimum": 1,
                        "example": 2
                    }
                }
            },
            "ModernCreateOrderResponse": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "order_id": {
                        "type": "integer",
                        "example": 98765
                    },
                    "order_source_order_id": {
                        "type": "string",
                        "example": "SP15O98765"
                    },
                    "partner_order_id": {
                        "type": "string",
                        "example": "PARTNER-ORDER-12345"
                    },
                    "status": {
                        "type": "string",
                        "example": "queued"
                    },
                    "sellercloud_order_id": {
                        "type": "string",
                        "nullable": true,
                        "example": null
                    }
                }
            },
            "OrdersResponse": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderSummary"
                        }
                    },
                    "pagination": {
                        "$ref": "#/components/schemas/OrderPagination"
                    }
                }
            },
            "OrderPagination": {
                "type": "object",
                "properties": {
                    "page": {
                        "type": "integer",
                        "example": 1
                    },
                    "per_page": {
                        "type": "integer",
                        "example": 100
                    },
                    "total": {
                        "type": "integer",
                        "example": 8
                    },
                    "total_pages": {
                        "type": "integer",
                        "example": 1
                    }
                }
            },
            "OrderSummary": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 98765
                    },
                    "order": {
                        "type": "string",
                        "nullable": true,
                        "example": null
                    },
                    "partner_order_id": {
                        "type": "string",
                        "example": "PARTNER-ORDER-12345"
                    },
                    "order_source_order_id": {
                        "type": "string",
                        "example": "SP15O98765"
                    },
                    "date": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "status": {
                        "type": "string",
                        "example": "queued"
                    },
                    "price": {
                        "type": "number",
                        "format": "float",
                        "example": 1999.98
                    },
                    "invoiceAvailable": {
                        "type": "boolean",
                        "example": false
                    },
                    "shipping_service": {
                        "type": "string",
                        "example": "Local Delivery"
                    }
                }
            },
            "OrderDetailResponse": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "data": {
                        "$ref": "#/components/schemas/OrderDetail"
                    }
                }
            },
            "OrderDetail": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 98765
                    },
                    "partner_order_id": {
                        "type": "string",
                        "example": "PARTNER-ORDER-12345"
                    },
                    "order_source_order_id": {
                        "type": "string",
                        "example": "SP15O98765"
                    },
                    "sellercloud_order_id": {
                        "type": "string",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "example": "queued"
                    },
                    "subtotal": {
                        "type": "number",
                        "format": "float",
                        "example": 1999.98
                    },
                    "total": {
                        "type": "number",
                        "format": "float",
                        "example": 1999.98
                    },
                    "billing": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true
                    },
                    "shipping": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        }
                    },
                    "sellercloud": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true
                    }
                }
            },
            "OrderItem": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "string",
                        "example": "WHO-ZAK-731529"
                    },
                    "name": {
                        "type": "string",
                        "nullable": true,
                        "example": "ZAKAT Z6 100ML EDP"
                    },
                    "quantity": {
                        "type": "integer",
                        "example": 2
                    },
                    "price": {
                        "type": "number",
                        "format": "float",
                        "example": 1000
                    },
                    "total": {
                        "type": "number",
                        "format": "float",
                        "example": 2000
                    },
                    "upc": {
                        "type": "string",
                        "nullable": true,
                        "example": "6291108731529"
                    }
                }
            }
        }
    },
    "paths": {
        "/api/v1/products": {
            "get": {
                "tags": [
                    "Modern Partner API"
                ],
                "operationId": "productsIndex",
                "summary": "List partner-visible products",
                "description": "Product list for Shoppex partner integrations. Uses data-sc.csv ProductID as product_id and sku. Required partner permission: products.read.",
                "security": [
                    {
                        "ShoppexHmacKey": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ShoppexTimestamp"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexNonce"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexSignature"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/ProductPerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Search"
                    },
                    {
                        "$ref": "#/components/parameters/Brand"
                    },
                    {
                        "$ref": "#/components/parameters/Type"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Products returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ModernProductsResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Permission denied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limited.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RateLimitError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/orders": {
            "get": {
                "tags": [
                    "Modern Partner API"
                ],
                "operationId": "ordersIndex",
                "summary": "List partner orders",
                "description": "Returns orders owned by the authenticated partner only. Required partner permission: orders.read.",
                "security": [
                    {
                        "ShoppexHmacKey": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ShoppexTimestamp"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexNonce"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexSignature"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Status"
                    },
                    {
                        "$ref": "#/components/parameters/FromDate"
                    },
                    {
                        "$ref": "#/components/parameters/ToDate"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Orders returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/OrdersResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Permission denied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limited.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RateLimitError"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Modern Partner API"
                ],
                "operationId": "ordersStore",
                "summary": "Create partner order",
                "description": "Creates a local partner order, validates business rules, and queues SellerCloud send. It is idempotent by partner and id_order_partner. Required partner permission: orders.create.",
                "security": [
                    {
                        "ShoppexHmacKey": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ShoppexTimestamp"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexNonce"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexSignature"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order created or existing idempotent order returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ModernCreateOrderResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Permission or business rule denied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Product or customer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Duplicate partner order ID with different payload.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Partner customer configuration incomplete.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limited.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RateLimitError"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateOrderRequest"
                            },
                            "example": {
                                "items": [
                                    {
                                        "product_id": "WHO-ZAK-731529",
                                        "quantity": 2
                                    }
                                ],
                                "id_order_partner": "PARTNER-ORDER-12345",
                                "comments": "Demo order created by an external partner integration."
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/orders/{order_id}": {
            "get": {
                "tags": [
                    "Modern Partner API"
                ],
                "operationId": "ordersShow",
                "summary": "Get partner order detail",
                "description": "Finds an order owned by the authenticated partner by local ID, partner order ID, OrderSourceOrderID, or SellerCloud order ID. Required partner permission: orders.read.",
                "security": [
                    {
                        "ShoppexHmacKey": []
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/ShoppexTimestamp"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexNonce"
                    },
                    {
                        "$ref": "#/components/parameters/ShoppexSignature"
                    },
                    {
                        "$ref": "#/components/parameters/OrderId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/OrderDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Permission denied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Order not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BusinessError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limited.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RateLimitError"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}