openapi: 3.0.3 info: title: B2B Shopping AI Assistant - Hyperf API Contract description: | API contract for the Hyperf PHP backend to support the AI Assistant. This document defines the expected endpoints and data structures. version: 1.0.0 contact: name: AI Assistant Team servers: - url: http://hyperf-api:9501/api/v1 description: Internal Docker network - url: http://localhost:9501/api/v1 description: Local development security: - BearerAuth: [] components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: # Common response wrapper ApiResponse: type: object properties: code: type: integer description: "0 for success, non-zero for errors" example: 0 message: type: string example: "success" data: type: object meta: type: object properties: timestamp: type: integer request_id: type: string # Pagination Pagination: type: object properties: total: type: integer page: type: integer page_size: type: integer total_pages: type: integer # Order schemas Order: type: object properties: order_id: type: string example: "ORD20260114001" status: type: string enum: [pending, paid, processing, shipped, delivered, cancelled] items: type: array items: $ref: '#/components/schemas/OrderItem' total_amount: type: number format: float shipping_address: $ref: '#/components/schemas/Address' tracking_number: type: string created_at: type: string format: date-time updated_at: type: string format: date-time OrderItem: type: object properties: item_id: type: string product_id: type: string name: type: string quantity: type: integer unit_price: type: number format: float subtotal: type: number format: float Address: type: object properties: province: type: string city: type: string district: type: string detail: type: string contact: type: string phone: type: string LogisticsTimeline: type: object properties: time: type: string format: date-time location: type: string status: type: string description: type: string # Product schemas Product: type: object properties: product_id: type: string name: type: string description: type: string brand: type: string category: type: string price: type: number format: float price_tiers: type: array items: type: object properties: min_qty: type: integer price: type: number image: type: string images: type: array items: type: string stock: type: integer min_order_quantity: type: integer specifications: type: object Quote: type: object properties: quote_id: type: string product_id: type: string quantity: type: integer unit_price: type: number subtotal: type: number discount: type: number discount_reason: type: string tax: type: number shipping_fee: type: number total_price: type: number validity: type: string payment_terms: type: string estimated_delivery: type: string # Aftersale schemas AftersaleRecord: type: object properties: aftersale_id: type: string type: type: string enum: [return, exchange, complaint, ticket] status: type: string order_id: type: string items: type: array items: type: object description: type: string progress: type: array items: type: object properties: step: type: string status: type: string time: type: string note: type: string created_at: type: string format: date-time paths: # ============ Order APIs ============ /orders/query: post: summary: Query orders operationId: queryOrders tags: [Orders] requestBody: required: true content: application/json: schema: type: object required: [user_id, account_id] properties: user_id: type: string account_id: type: string order_id: type: string status: type: string date_range: type: object properties: start: type: string format: date end: type: string format: date page: type: integer default: 1 page_size: type: integer default: 20 responses: '200': description: Orders list content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: orders: type: array items: $ref: '#/components/schemas/Order' pagination: $ref: '#/components/schemas/Pagination' /orders/{order_id}/logistics: get: summary: Get logistics tracking operationId: getLogistics tags: [Orders] parameters: - name: order_id in: path required: true schema: type: string - name: tracking_number in: query schema: type: string responses: '200': description: Logistics information content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: tracking_number: type: string courier: type: string status: type: string estimated_delivery: type: string timeline: type: array items: $ref: '#/components/schemas/LogisticsTimeline' /orders/{order_id}/modify: put: summary: Modify order operationId: modifyOrder tags: [Orders] parameters: - name: order_id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object required: [user_id, modifications] properties: user_id: type: string modifications: type: object properties: shipping_address: $ref: '#/components/schemas/Address' items: type: array items: type: object properties: product_id: type: string quantity: type: integer responses: '200': description: Modified order content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: order: $ref: '#/components/schemas/Order' price_diff: type: number /orders/{order_id}/cancel: post: summary: Cancel order operationId: cancelOrder tags: [Orders] parameters: - name: order_id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object required: [user_id, reason] properties: user_id: type: string reason: type: string responses: '200': description: Cancellation result content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: order_id: type: string status: type: string refund_info: type: object properties: amount: type: number method: type: string estimated_arrival: type: string /orders/{order_id}/invoice: get: summary: Get invoice operationId: getInvoice tags: [Orders] parameters: - name: order_id in: path required: true schema: type: string - name: type in: query schema: type: string enum: [normal, vat] default: normal responses: '200': description: Invoice information content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: invoice_number: type: string invoice_url: type: string amount: type: number tax: type: number issued_at: type: string # ============ Product APIs ============ /products/search: post: summary: Search products operationId: searchProducts tags: [Products] requestBody: required: true content: application/json: schema: type: object required: [query] properties: query: type: string filters: type: object properties: category: type: string brand: type: string price_range: type: object properties: min: type: number max: type: number sort: type: string enum: [relevance, price_asc, price_desc, sales, latest] page: type: integer page_size: type: integer responses: '200': description: Search results content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: products: type: array items: $ref: '#/components/schemas/Product' total: type: integer pagination: $ref: '#/components/schemas/Pagination' /products/{product_id}: get: summary: Get product details operationId: getProduct tags: [Products] parameters: - name: product_id in: path required: true schema: type: string responses: '200': description: Product details content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: $ref: '#/components/schemas/Product' /products/recommend: post: summary: Get product recommendations operationId: recommendProducts tags: [Products] requestBody: required: true content: application/json: schema: type: object required: [user_id, account_id] properties: user_id: type: string account_id: type: string context: type: object properties: current_query: type: string recent_views: type: array items: type: string strategy: type: string enum: [collaborative, content_based, hybrid] limit: type: integer responses: '200': description: Recommendations content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: recommendations: type: array items: type: object properties: product: $ref: '#/components/schemas/Product' score: type: number reason: type: string /products/quote: post: summary: Get B2B price quote operationId: getQuote tags: [Products] requestBody: required: true content: application/json: schema: type: object required: [product_id, quantity, account_id] properties: product_id: type: string quantity: type: integer account_id: type: string delivery_address: type: object properties: province: type: string city: type: string responses: '200': description: Price quote content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: $ref: '#/components/schemas/Quote' /products/inventory/check: post: summary: Check inventory operationId: checkInventory tags: [Products] requestBody: required: true content: application/json: schema: type: object required: [product_ids] properties: product_ids: type: array items: type: string warehouse: type: string responses: '200': description: Inventory status content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: inventory: type: array items: type: object properties: product_id: type: string available_stock: type: integer reserved_stock: type: integer warehouse: type: string # ============ Aftersale APIs ============ /aftersales/return: post: summary: Apply for return operationId: applyReturn tags: [Aftersales] requestBody: required: true content: application/json: schema: type: object required: [order_id, user_id, items, description] properties: order_id: type: string user_id: type: string items: type: array items: type: object properties: item_id: type: string quantity: type: integer reason: type: string description: type: string images: type: array items: type: string responses: '200': description: Return application result content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: aftersale_id: type: string status: type: string estimated_refund: type: number process_steps: type: array items: type: string /aftersales/exchange: post: summary: Apply for exchange operationId: applyExchange tags: [Aftersales] requestBody: required: true content: application/json: schema: type: object required: [order_id, user_id, items, description] properties: order_id: type: string user_id: type: string items: type: array items: type: object properties: item_id: type: string reason: type: string new_specs: type: object description: type: string responses: '200': description: Exchange application result /aftersales/complaint: post: summary: Create complaint operationId: createComplaint tags: [Aftersales] requestBody: required: true content: application/json: schema: type: object required: [user_id, type, title, description] properties: user_id: type: string type: type: string enum: [product_quality, service, logistics, pricing, other] title: type: string description: type: string related_order_id: type: string attachments: type: array items: type: string responses: '200': description: Complaint creation result /aftersales/ticket: post: summary: Create support ticket operationId: createTicket tags: [Aftersales] requestBody: required: true content: application/json: schema: type: object required: [user_id, category, priority, title, description] properties: user_id: type: string category: type: string priority: type: string enum: [low, medium, high, urgent] title: type: string description: type: string responses: '200': description: Ticket creation result /aftersales/query: get: summary: Query aftersale records operationId: queryAftersales tags: [Aftersales] parameters: - name: user_id in: query required: true schema: type: string - name: aftersale_id in: query schema: type: string responses: '200': description: Aftersale records content: application/json: schema: allOf: - $ref: '#/components/schemas/ApiResponse' - type: object properties: data: type: object properties: records: type: array items: $ref: '#/components/schemas/AftersaleRecord' tags: - name: Orders description: Order management APIs - name: Products description: Product catalog and pricing APIs - name: Aftersales description: Returns, exchanges, and complaints APIs