{"openapi":"3.0.3","info":{"title":"nOfert Public API","description":"REST API for nOfert marketplace. Integrate products, orders, and vendors into your own apps.","version":"2.0.0","contact":{"url":"https:\/\/nofert.net\/api\/docs"}},"servers":[{"url":"https:\/\/nofert.net\/api\/v1","description":"Production"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","description":"Vendor API key from your dashboard (\/vendor\/api-keys)"},"UserTokenAuth":{"type":"http","scheme":"bearer","description":"User token obtained from POST \/api\/v1\/auth\/login"}},"schemas":{"Product":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"slug":{"type":"string"},"price":{"type":"number"},"sale_price":{"type":"number","nullable":true},"description":{"type":"string"},"quantity":{"type":"integer"},"category":{"$ref":"#\/components\/schemas\/Category"},"vendor":{"$ref":"#\/components\/schemas\/Vendor"}}},"Category":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"slug":{"type":"string"}}},"Vendor":{"type":"object","properties":{"name":{"type":"string"},"shop_name":{"type":"string"},"slug":{"type":"string"}}},"Order":{"type":"object","properties":{"order_number":{"type":"string"},"status":{"type":"string","enum":["pending","processing","shipped","delivered","cancelled"]},"payment_status":{"type":"string","enum":["pending","paid","failed","refunded"]},"total":{"type":"number"},"currency":{"type":"string"}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"\/products":{"get":{"summary":"List products","description":"Returns a paginated list of approved products. No authentication required.","tags":["Products"],"parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"ids","in":"query","description":"Comma-separated product IDs for bulk lookup","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"integer"}},{"name":"vendor","in":"query","schema":{"type":"string"}},{"name":"min_price","in":"query","schema":{"type":"number"}},{"name":"max_price","in":"query","schema":{"type":"number"}},{"name":"in_stock","in":"query","schema":{"type":"boolean"}},{"name":"featured","in":"query","schema":{"type":"boolean"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["newest","price_asc","price_desc","popular"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated product list"}}}},"\/products\/{id}":{"get":{"summary":"Get product","tags":["Products"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Product details with variants and images"},"404":{"description":"Not found"}}}},"\/products\/{id}\/related":{"get":{"summary":"Get related products","description":"Returns products from the same category or vendor.","tags":["Products"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Up to 12 related products"}}}},"\/products\/{id}\/reviews":{"get":{"summary":"Get product reviews","tags":["Products"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["newest","highest","lowest","helpful"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":10}}],"responses":{"200":{"description":"Reviews with rating breakdown"}}},"post":{"summary":"Submit a review","description":"Submit a review for a product. Requires a delivered purchase.","tags":["Reviews"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["rating"],"properties":{"rating":{"type":"integer","minimum":1,"maximum":5},"comment":{"type":"string","maxLength":2000},"images[]":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"201":{"description":"Review submitted"},"403":{"description":"No delivered purchase found"},"422":{"description":"Already reviewed"}}}},"\/categories":{"get":{"summary":"List categories","tags":["Categories"],"responses":{"200":{"description":"Category tree with product counts"}}}},"\/vendors":{"get":{"summary":"List vendors","tags":["Vendors"],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated vendor list"}}}},"\/vendors\/{slug}":{"get":{"summary":"Get vendor shop","tags":["Vendors"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Vendor profile with recent products"}}}},"\/vendors\/{slug}\/reviews":{"get":{"summary":"Get vendor reviews","description":"Returns reviews for all products from this vendor, with aggregate stats.","tags":["Vendors"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["newest","highest","lowest"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Vendor reviews with total_reviews and average_rating"}}}},"\/auth\/login":{"post":{"summary":"Login and get user token","description":"Authenticate with email\/password. If the user has 2FA enabled, returns `requires_2fa: true` and a `challenge_token` instead of an API token. Submit the challenge token + TOTP code to POST \/auth\/2fa\/verify to complete login.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"device_name":{"type":"string","description":"Label for this token"}}}}}},"responses":{"200":{"description":"Token returned, or requires_2fa challenge if 2FA is enabled"},"401":{"description":"Invalid credentials"},"429":{"description":"Too many attempts"}}}},"\/auth\/register":{"post":{"summary":"Register new account","description":"Create a new user account (buyer, vendor, or supplier) and get a token.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","last_name","email","password","password_confirmation","phone","address","city","country"],"properties":{"name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"password_confirmation":{"type":"string"},"phone":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"},"role":{"type":"string","enum":["buyer","vendor","supplier"],"default":"buyer"},"shop_name":{"type":"string","description":"Required if role=vendor"},"company_name":{"type":"string","description":"Required if role=supplier"},"device_name":{"type":"string"},"ref":{"type":"string","description":"Referral code"}}}}}},"responses":{"201":{"description":"Account created, token returned"},"422":{"description":"Validation error"},"429":{"description":"Too many attempts"}}}},"\/auth\/forgot-password":{"post":{"summary":"Send password reset email","tags":["Authentication"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Reset link sent"},"422":{"description":"Email not found"},"429":{"description":"Too many attempts"}}}},"\/auth\/reset-password":{"post":{"summary":"Reset password with token","tags":["Authentication"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["token","email","password","password_confirmation"],"properties":{"token":{"type":"string"},"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"password_confirmation":{"type":"string"}}}}}},"responses":{"200":{"description":"Password reset successfully"},"422":{"description":"Invalid token or email"}}}},"\/auth\/social\/{provider}":{"post":{"summary":"Social login (Google\/Facebook\/Apple)","description":"Exchange a social provider access token for an API token. Creates account if new.","tags":["Authentication"],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["google","facebook","apple"]}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["access_token"],"properties":{"access_token":{"type":"string","description":"OAuth access token from mobile SDK"},"device_name":{"type":"string"}}}}}},"responses":{"200":{"description":"Existing user logged in (is_new: false)"},"201":{"description":"New account created (is_new: true)"},"401":{"description":"Invalid access token"},"422":{"description":"Provider not supported or email not provided"}}}},"\/auth\/2fa\/verify":{"post":{"summary":"Verify 2FA code","description":"Complete login for users with 2FA enabled. Submit the challenge_token from the login response along with a TOTP code (6 digits) or a recovery code. The challenge token expires after 5 minutes. Rate limited to 10 attempts per minute.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["challenge_token","code"],"properties":{"challenge_token":{"type":"string","description":"Challenge token from login response"},"code":{"type":"string","description":"6-digit TOTP code or recovery code (XXXX-XXXX format)"}}}}}},"responses":{"200":{"description":"Token returned (login complete). If recovery code was used, includes recovery_codes_remaining count."},"401":{"description":"Invalid or expired challenge token, or invalid 2FA code"},"429":{"description":"Too many attempts"}}}},"\/auth\/refresh":{"post":{"summary":"Refresh token expiry","description":"Extend the current token by 30 days.","tags":["Authentication"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Token expiry extended"}}}},"\/auth\/logout":{"post":{"summary":"Logout (revoke user token)","tags":["Authentication"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Token revoked"}}}},"\/me":{"get":{"summary":"API key info","tags":["API Keys"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"API key details and rate limit info"}}}},"\/user":{"get":{"summary":"Get user profile","tags":["User"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Authenticated user profile"}}},"put":{"summary":"Update user profile","tags":["User"],"security":[{"UserTokenAuth":[]}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"}}}}}},"responses":{"200":{"description":"Profile updated"}}},"delete":{"summary":"Delete account","description":"Permanently delete the authenticated user's account (GDPR \/ App Store requirement). Requires password verification. Active orders must be completed first. Data is anonymized and the account is soft-deleted.","tags":["User"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","description":"Current account password for verification"}}}}}},"responses":{"200":{"description":"Account deleted and data anonymized"},"422":{"description":"Password incorrect or active orders exist"}}}},"\/user\/password":{"put":{"summary":"Change password","tags":["User"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["current_password","password","password_confirmation"],"properties":{"current_password":{"type":"string"},"password":{"type":"string"},"password_confirmation":{"type":"string"}}}}}},"responses":{"200":{"description":"Password updated"},"422":{"description":"Current password incorrect"}}}},"\/user\/orders":{"get":{"summary":"Get user orders","tags":["User"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","shipped","delivered","cancelled"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated order list"}}}},"\/user\/orders\/{orderNumber}\/cancel":{"post":{"summary":"Cancel order","description":"Cancel a pending or processing order.","tags":["User"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order cancelled"},"422":{"description":"Order cannot be cancelled"}}}},"\/user\/orders\/{orderNumber}\/return":{"post":{"summary":"Request return","description":"Request a return for a delivered order.","tags":["User"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","maxLength":2000}}}}}},"responses":{"201":{"description":"Return request submitted"},"422":{"description":"Order not eligible for return"}}}},"\/user\/orders\/{orderNumber}\/invoice":{"get":{"summary":"Get order invoice","description":"Returns full invoice data as JSON for mobile app rendering. Includes items, variants, shipping address, tax, discount, and store info.","tags":["User"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice data"},"404":{"description":"Order not found"}}}},"\/user\/orders\/{orderNumber}\/tracking":{"get":{"summary":"Get order tracking","description":"Returns order tracking timeline with status steps (placed, processing, shipped, delivered). Includes tracking number and carrier if available.","tags":["User"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tracking timeline"},"404":{"description":"Order not found"}}}},"\/user\/reviews\/{id}":{"delete":{"summary":"Delete own review","tags":["Reviews"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Review deleted"},"404":{"description":"Review not found"}}}},"\/orders":{"post":{"summary":"Create order","tags":["Orders"],"security":[{"ApiKeyAuth":[]}],"responses":{"201":{"description":"Order created with checkout_url"},"422":{"description":"Validation error"}}}},"\/orders\/{orderNumber}":{"get":{"summary":"Get order status","tags":["Orders"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order details"}}}},"\/user\/wishlist":{"get":{"summary":"Get wishlist","tags":["Wishlist"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated wishlist with product details"}}},"post":{"summary":"Add to wishlist","tags":["Wishlist"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["product_id"],"properties":{"product_id":{"type":"integer"}}}}}},"responses":{"201":{"description":"Product added to wishlist"}}}},"\/user\/wishlist\/{productId}":{"delete":{"summary":"Remove from wishlist","tags":["Wishlist"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Product removed"},"404":{"description":"Product not in wishlist"}}}},"\/user\/addresses":{"get":{"summary":"List saved addresses","tags":["Addresses"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"List of saved addresses"}}},"post":{"summary":"Create address","tags":["Addresses"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","phone","address","city","country"],"properties":{"label":{"type":"string"},"name":{"type":"string"},"phone":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"},"is_default":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Address created"}}}},"\/user\/addresses\/{id}":{"put":{"summary":"Update address","tags":["Addresses"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Address updated"}}},"delete":{"summary":"Delete address","tags":["Addresses"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Address deleted"}}}},"\/user\/notifications":{"get":{"summary":"List notifications","tags":["Notifications"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated notifications with unread_count"}}}},"\/user\/notifications\/{id}\/read":{"post":{"summary":"Mark notification as read","tags":["Notifications"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Notification marked as read"},"404":{"description":"Notification not found"}}}},"\/user\/notifications\/read-all":{"post":{"summary":"Mark all notifications as read","tags":["Notifications"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"All notifications marked as read"}}}},"\/cart":{"get":{"summary":"Get cart","description":"Get cart contents with product details, subtotal, and item count.","tags":["Cart"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Cart contents"}}},"post":{"summary":"Add item to cart","tags":["Cart"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["product_id"],"properties":{"product_id":{"type":"integer"},"variant_id":{"type":"integer","nullable":true},"quantity":{"type":"integer","default":1,"minimum":1}}}}}},"responses":{"201":{"description":"Item added"},"422":{"description":"Product not available"}}},"delete":{"summary":"Clear cart","tags":["Cart"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Cart cleared"}}}},"\/cart\/{key}":{"patch":{"summary":"Update cart item quantity","description":"Key format: productId:variantId (e.g., 42:7 or 42:0 for no variant).","tags":["Cart"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"},"example":"42:0"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["quantity"],"properties":{"quantity":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Cart updated"},"404":{"description":"Item not in cart"}}},"delete":{"summary":"Remove item from cart","tags":["Cart"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"},"example":"42:0"}],"responses":{"200":{"description":"Item removed"},"404":{"description":"Item not in cart"}}}},"\/coupons\/validate":{"post":{"summary":"Validate coupon code","description":"Check if a coupon code is valid. Rate limited to 30\/minute.","tags":["Coupons"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}}}}},"responses":{"200":{"description":"Coupon details (type, value, min_order)"},"404":{"description":"Invalid coupon"},"422":{"description":"Coupon expired or exhausted"}}}},"\/user\/tickets":{"get":{"summary":"List support tickets","tags":["Support"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["open","in_progress","resolved","closed"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated ticket list"}}},"post":{"summary":"Create support ticket","tags":["Support"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["subject","message"],"properties":{"subject":{"type":"string"},"message":{"type":"string"},"category":{"type":"string","enum":["order_issue","payment","account","product","other"]},"priority":{"type":"string","enum":["low","medium","high"]}}}}}},"responses":{"201":{"description":"Ticket created"}}}},"\/user\/tickets\/{id}":{"get":{"summary":"View ticket details","tags":["Support"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Ticket with message and admin reply"}}}},"\/user\/tickets\/{id}\/reply":{"post":{"summary":"Reply to ticket","description":"Append a reply. Re-opens the ticket if it was resolved.","tags":["Support"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}}}}},"responses":{"200":{"description":"Reply added"},"422":{"description":"Ticket is closed"}}}},"\/blog":{"get":{"summary":"List blog posts","tags":["Blog"],"parameters":[{"name":"category","in":"query","schema":{"type":"string"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated blog posts (excerpts only)"}}}},"\/blog\/{slug}":{"get":{"summary":"Get blog post","tags":["Blog"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Full blog post with content"},"404":{"description":"Post not found"}}}},"\/deals":{"get":{"summary":"Get active deals and promotions","description":"Returns active flash deals with products and active promotions.","tags":["Deals"],"responses":{"200":{"description":"Active deals and promotions"}}}},"\/app\/config":{"get":{"summary":"App bootstrap config","description":"Returns store info, payment methods, categories, features, and contact info. Call on app launch.","tags":["App"],"responses":{"200":{"description":"Store configuration for mobile app bootstrap"}}}},"\/checkout":{"post":{"summary":"Place order from cart","description":"Creates an order from the user's API cart. For Stripe: returns client_secret. For PayPal: returns approval_url. For COD: order is placed immediately.","tags":["Checkout"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["payment_method","shipping_name","shipping_address","shipping_city","shipping_country"],"properties":{"payment_method":{"type":"string","enum":["stripe","paypal","cod"]},"shipping_name":{"type":"string"},"shipping_address":{"type":"string"},"shipping_city":{"type":"string"},"shipping_country":{"type":"string"},"shipping_zip":{"type":"string"},"shipping_phone":{"type":"string"},"notes":{"type":"string"},"coupon_code":{"type":"string"},"shipping_rates":{"type":"object","description":"Map of vendor_id => shipping_rate_id"},"redeem_points":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Order created. Includes stripe.client_secret or paypal.approval_url depending on payment method."},"422":{"description":"Validation error, empty cart, or insufficient stock"}}}},"\/checkout\/shipping-rates":{"post":{"summary":"Get shipping rates for cart","description":"Returns available shipping rates per vendor for the given country.","tags":["Checkout"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["country"],"properties":{"country":{"type":"string"}}}}}},"responses":{"200":{"description":"Shipping rates grouped by vendor"}}}},"\/payment\/stripe\/confirm":{"post":{"summary":"Confirm Stripe payment","description":"After mobile Stripe SDK confirms the PaymentIntent, call this to verify and mark the order as paid.","tags":["Payments"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["payment_intent_id"],"properties":{"payment_intent_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Payment confirmed, order marked as paid"},"404":{"description":"Order not found for this payment"},"422":{"description":"Payment not yet completed or amount mismatch"}}}},"\/payment\/paypal\/confirm":{"post":{"summary":"Confirm PayPal payment","description":"After user approves PayPal order on mobile, call this to capture and confirm payment.","tags":["Payments"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["paypal_order_id"],"properties":{"paypal_order_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Payment captured, order marked as paid"},"404":{"description":"Order not found for this PayPal order"},"422":{"description":"Capture failed or amount mismatch"}}}},"\/user\/push-tokens":{"get":{"summary":"List push tokens","tags":["Push Tokens"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"List of registered push tokens"}}},"post":{"summary":"Register push token","description":"Register a device push token for FCM (Android) or APNS (iOS) notifications.","tags":["Push Tokens"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["token","device_type"],"properties":{"token":{"type":"string"},"device_type":{"type":"string","enum":["ios","android","web"]},"device_name":{"type":"string"}}}}}},"responses":{"201":{"description":"Push token registered"}}}},"\/user\/push-tokens\/{token}":{"delete":{"summary":"Unregister push token","tags":["Push Tokens"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Push token removed"},"404":{"description":"Token not found"}}}},"\/app\/home":{"get":{"summary":"Get homepage data","description":"Returns all data needed for the mobile app homepage in a single request: banners, featured products, new arrivals, on-sale products, flash deals, and top categories.","tags":["App"],"responses":{"200":{"description":"Homepage data with banners, featured, new_arrivals, on_sale, flash_deals, categories"}}}},"\/search\/suggestions":{"get":{"summary":"Search suggestions","description":"Returns up to 8 product name suggestions for autocomplete.","tags":["Search"],"parameters":[{"name":"q","in":"query","required":true,"description":"Search query (min 2 chars)","schema":{"type":"string","minLength":2}}],"responses":{"200":{"description":"Array of product suggestions with id, name, slug, category"}}}},"\/products\/{id}\/questions":{"get":{"summary":"Get product questions","description":"Returns public Q&A for a product with answers.","tags":["Products"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated questions with answers"}}},"post":{"summary":"Ask a product question","description":"Submit a question about a product. Will appear after review.","tags":["Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","minLength":10,"maxLength":1000}}}}}},"responses":{"201":{"description":"Question submitted"},"404":{"description":"Product not found"}}}},"\/user\/returns":{"get":{"summary":"List return requests","description":"Returns the authenticated user's return requests with order and product details.","tags":["User Account"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":15}}],"responses":{"200":{"description":"Paginated return requests with status, reason, refund_amount"}}}},"\/user\/preferences":{"get":{"summary":"Get user preferences","description":"Returns notification and app preferences (push_orders, push_promotions, push_messages, email_orders, email_promotions, language).","tags":["User Account"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"User preferences object"}}},"put":{"summary":"Update user preferences","tags":["User Account"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"push_orders":{"type":"boolean"},"push_promotions":{"type":"boolean"},"push_messages":{"type":"boolean"},"email_orders":{"type":"boolean"},"email_promotions":{"type":"boolean"},"language":{"type":"string","enum":["en","es","mk","sq"]}}}}}},"responses":{"200":{"description":"Updated preferences"}}}},"\/recently-viewed":{"get":{"summary":"Get recently viewed products","description":"Pass comma-separated product IDs (client-tracked) to get product details. Max 10 IDs. Order is preserved.","tags":["Products"],"parameters":[{"name":"ids","in":"query","required":true,"description":"Comma-separated product IDs","schema":{"type":"string"}}],"responses":{"200":{"description":"Array of product details in requested order"}}}},"\/user\/messages":{"get":{"summary":"List conversations","description":"Returns a list of conversations with the latest message from each chat partner. Paginated.","tags":["Messages"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated conversation list"}}}},"\/user\/messages\/{userId}":{"get":{"summary":"Get chat messages","description":"Returns messages with a specific user. Supports polling with ?after= parameter to only get new messages since a timestamp.","tags":["Messages"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"after","in":"query","description":"ISO 8601 timestamp \u2014 only return messages after this time","schema":{"type":"string","format":"date-time"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Paginated message list with partner info and typing status"}}},"post":{"summary":"Send message","description":"Send a message to another user. Supports optional file attachments.","tags":["Messages"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","maxLength":5000},"attachments[]":{"type":"array","items":{"type":"string","format":"binary"},"maxItems":5}}}}}},"responses":{"201":{"description":"Message sent"},"422":{"description":"Validation error"}}}},"\/user\/messages\/{userId}\/typing":{"post":{"summary":"Send typing indicator","description":"Notify that the user is typing. Expires after 30 seconds.","tags":["Messages"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Typing indicator sent"}}}},"\/vendor\/dashboard":{"get":{"summary":"Dashboard stats","description":"Returns vendor dashboard statistics: order count, revenue, products count, recent orders.","tags":["Vendor: Dashboard"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Dashboard stats object"},"401":{"description":"Unauthorized"}}}},"\/vendor\/products":{"get":{"summary":"List vendor products","description":"Paginated list of the authenticated vendor's products.","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","draft","pending"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated product list"},"401":{"description":"Unauthorized"}}},"post":{"summary":"Create product","description":"Create a new product with images. Multipart form data.","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["name","price","category_id"],"properties":{"name":{"type":"string"},"price":{"type":"number"},"category_id":{"type":"integer"},"description":{"type":"string"},"quantity":{"type":"integer"},"images[]":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"201":{"description":"Product created"},"422":{"description":"Validation error"}}}},"\/vendor\/products\/{id}":{"get":{"summary":"Get product detail","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Product detail"},"404":{"description":"Not found"}}},"put":{"summary":"Update product","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":"number"},"category_id":{"type":"integer"},"description":{"type":"string"},"quantity":{"type":"integer"}}}}}},"responses":{"200":{"description":"Product updated"},"404":{"description":"Not found"},"422":{"description":"Validation error"}}},"delete":{"summary":"Delete product","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Product deleted"},"404":{"description":"Not found"}}}},"\/vendor\/products\/{id}\/images":{"post":{"summary":"Upload product images","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"images[]":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"200":{"description":"Images uploaded"},"422":{"description":"Validation error"}}}},"\/vendor\/products\/images\/{imageId}":{"delete":{"summary":"Delete product image","tags":["Vendor: Products"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"imageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Image deleted"},"404":{"description":"Not found"}}}},"\/vendor\/orders":{"get":{"summary":"List vendor orders","description":"Paginated list of orders for the vendor's products.","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","shipped","delivered","cancelled"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated order list"},"401":{"description":"Unauthorized"}}}},"\/vendor\/orders\/{orderNumber}":{"get":{"summary":"Order detail","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order detail with items"},"404":{"description":"Not found"}}}},"\/vendor\/orders\/{orderNumber}\/status":{"patch":{"summary":"Update order status","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["processing","shipped","delivered"]}}}}}},"responses":{"200":{"description":"Status updated"},"422":{"description":"Invalid transition"}}}},"\/vendor\/orders\/{orderNumber}\/tracking":{"post":{"summary":"Add tracking info","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["carrier","tracking_number"],"properties":{"carrier":{"type":"string"},"tracking_number":{"type":"string"}}}}}},"responses":{"200":{"description":"Tracking added"}}}},"\/vendor\/earnings":{"get":{"summary":"Earnings breakdown","description":"Revenue and earnings with optional period filter.","tags":["Vendor: Earnings"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"period","in":"query","schema":{"type":"string","enum":["today","week","month","year","all"]}}],"responses":{"200":{"description":"Earnings data"}}}},"\/vendor\/payouts":{"get":{"summary":"Payout history","tags":["Vendor: Earnings"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated payout list"}}},"post":{"summary":"Request payout","tags":["Vendor: Earnings"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number","minimum":1}}}}}},"responses":{"201":{"description":"Payout requested"},"422":{"description":"Insufficient balance"}}}},"\/vendor\/profile":{"get":{"summary":"Get shop profile","tags":["Vendor: Profile"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Shop profile data"}}},"put":{"summary":"Update shop profile","tags":["Vendor: Profile"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"shop_name":{"type":"string"},"description":{"type":"string"},"phone":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"},"logo":{"type":"string","format":"binary"},"banner":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Profile updated"},"422":{"description":"Validation error"}}}},"\/vendor\/profile\/vacation":{"patch":{"summary":"Toggle vacation mode","tags":["Vendor: Profile"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["vacation_mode"],"properties":{"vacation_mode":{"type":"boolean"},"vacation_message":{"type":"string"}}}}}},"responses":{"200":{"description":"Vacation mode updated"}}}},"\/vendor\/coupons":{"get":{"summary":"List coupons","tags":["Vendor: Coupons"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated coupon list"}}},"post":{"summary":"Create coupon","tags":["Vendor: Coupons"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["code","type","value"],"properties":{"code":{"type":"string"},"type":{"type":"string","enum":["fixed","percentage"]},"value":{"type":"number"},"min_order":{"type":"number"},"max_uses":{"type":"integer"},"starts_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"Coupon created"},"422":{"description":"Validation error"}}}},"\/vendor\/coupons\/{id}":{"get":{"summary":"Get coupon","tags":["Vendor: Coupons"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Coupon detail"},"404":{"description":"Not found"}}},"put":{"summary":"Update coupon","tags":["Vendor: Coupons"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"type":{"type":"string","enum":["fixed","percentage"]},"value":{"type":"number"},"min_order":{"type":"number"},"max_uses":{"type":"integer"},"starts_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Coupon updated"},"422":{"description":"Validation error"}}},"delete":{"summary":"Delete coupon","tags":["Vendor: Coupons"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Coupon deleted"},"404":{"description":"Not found"}}}},"\/vendor\/questions":{"get":{"summary":"List product questions","description":"Paginated list of questions on the vendor's products.","tags":["Vendor: Questions"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["answered","unanswered"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated question list"}}}},"\/vendor\/questions\/{id}\/answer":{"post":{"summary":"Answer a question","tags":["Vendor: Questions"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["answer"],"properties":{"answer":{"type":"string"}}}}}},"responses":{"200":{"description":"Answer saved"},"404":{"description":"Not found"}}}},"\/vendor\/reviews":{"get":{"summary":"List reviews for vendor products","description":"Paginated list of reviews on the vendor's products.","tags":["Vendor: Reviews"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"rating","in":"query","schema":{"type":"integer","minimum":1,"maximum":5}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated review list"}}}},"\/vendor\/reviews\/{id}\/reply":{"post":{"summary":"Reply to a review","tags":["Vendor: Reviews"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["vendor_reply"],"properties":{"vendor_reply":{"type":"string"}}}}}},"responses":{"200":{"description":"Reply saved"},"404":{"description":"Not found"}}}},"\/vendor\/returns":{"get":{"summary":"List return requests","description":"Paginated list of return requests for the vendor's orders.","tags":["Vendor: Returns"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","rejected"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated return list"}}}},"\/vendor\/returns\/{id}":{"get":{"summary":"Return request detail","tags":["Vendor: Returns"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Return detail with order info"},"404":{"description":"Not found"}}}},"\/vendor\/returns\/{id}\/approve":{"patch":{"summary":"Approve return","tags":["Vendor: Returns"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"vendor_notes":{"type":"string"}}}}}},"responses":{"200":{"description":"Return approved"},"404":{"description":"Not found"}}}},"\/vendor\/returns\/{id}\/reject":{"patch":{"summary":"Reject return","tags":["Vendor: Returns"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["vendor_notes"],"properties":{"vendor_notes":{"type":"string"}}}}}},"responses":{"200":{"description":"Return rejected"},"404":{"description":"Not found"}}}},"\/vendor\/shipping":{"get":{"summary":"List shipping zones with rates","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Shipping zones with nested rates"}}},"post":{"summary":"Create shipping zone","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","countries"],"properties":{"name":{"type":"string"},"countries":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Zone created"},"422":{"description":"Validation error"}}}},"\/vendor\/shipping\/{id}":{"put":{"summary":"Update shipping zone","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"countries":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Zone updated"},"404":{"description":"Not found"}}},"delete":{"summary":"Delete shipping zone","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Zone deleted"},"404":{"description":"Not found"}}}},"\/vendor\/shipping\/{id}\/rates":{"post":{"summary":"Add shipping rate","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","price"],"properties":{"name":{"type":"string"},"price":{"type":"number"},"delivery_estimate":{"type":"string"},"min_weight":{"type":"number"},"max_weight":{"type":"number"},"min_order_amount":{"type":"number"}}}}}},"responses":{"201":{"description":"Rate added"},"422":{"description":"Validation error"}}}},"\/vendor\/shipping\/rates\/{rateId}":{"put":{"summary":"Update shipping rate","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"rateId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":"number"},"delivery_estimate":{"type":"string"},"min_weight":{"type":"number"},"max_weight":{"type":"number"},"min_order_amount":{"type":"number"}}}}}},"responses":{"200":{"description":"Rate updated"},"404":{"description":"Not found"}}},"delete":{"summary":"Delete shipping rate","tags":["Vendor: Shipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"rateId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Rate deleted"},"404":{"description":"Not found"}}}},"\/vendor\/wallet":{"get":{"summary":"Wallet balance and transactions","description":"Returns wallet balance and paginated transaction history.","tags":["Vendor: Wallet"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Wallet balance + transaction history"}}}},"\/vendor\/wallet\/topup":{"post":{"summary":"Create Stripe topup checkout","description":"Creates a Stripe Checkout session for wallet topup. Returns the checkout URL.","tags":["Vendor: Wallet"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number","minimum":5,"maximum":1000}}}}}},"responses":{"200":{"description":"Stripe checkout URL"},"422":{"description":"Validation error"}}}},"\/vendor\/onboarding":{"get":{"summary":"Get onboarding status","description":"Returns completion status for each onboarding step.","tags":["Vendor: Onboarding"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Onboarding completion status"}}}},"\/vendor\/onboarding\/shop":{"post":{"summary":"Save shop details","tags":["Vendor: Onboarding"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["shop_name"],"properties":{"shop_name":{"type":"string"},"description":{"type":"string"},"phone":{"type":"string"}}}}}},"responses":{"200":{"description":"Shop details saved"}}}},"\/vendor\/onboarding\/product":{"post":{"summary":"Create first product","tags":["Vendor: Onboarding"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["name","price","category_id"],"properties":{"name":{"type":"string"},"price":{"type":"number"},"category_id":{"type":"integer"},"description":{"type":"string"},"images[]":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"201":{"description":"Product created"}}}},"\/vendor\/onboarding\/shipping":{"post":{"summary":"Create first shipping zone","tags":["Vendor: Onboarding"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","countries","rate_name","rate_price"],"properties":{"name":{"type":"string"},"countries":{"type":"array","items":{"type":"string"}},"rate_name":{"type":"string"},"rate_price":{"type":"number"}}}}}},"responses":{"201":{"description":"Shipping zone created"}}}},"\/vendor\/onboarding\/payout":{"post":{"summary":"Save payout details","tags":["Vendor: Onboarding"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"payout_method":{"type":"string","enum":["bank_transfer","paypal","stripe"]},"bank_name":{"type":"string"},"account_number":{"type":"string"},"paypal_email":{"type":"string"}}}}}},"responses":{"200":{"description":"Payout details saved"}}}},"\/vendor\/dropshipping":{"get":{"summary":"Dropshipping dashboard","description":"Returns available providers and imported product counts.","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Dropshipping dashboard data"}}}},"\/vendor\/dropshipping\/{provider}\/search":{"get":{"summary":"Search products from provider","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"Search results"}}}},"\/vendor\/dropshipping\/{provider}\/preview":{"get":{"summary":"Preview product before import","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}},{"name":"product_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product preview data"}}}},"\/vendor\/dropshipping\/{provider}\/import":{"post":{"summary":"Import product","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["product_id"],"properties":{"product_id":{"type":"string"},"markup":{"type":"number"}}}}}},"responses":{"201":{"description":"Product imported"},"422":{"description":"Validation error"}}}},"\/vendor\/dropshipping\/{provider}\/sync":{"post":{"summary":"Sync all imported products","description":"Syncs prices and stock for all products imported from this provider.","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sync started or completed"}}}},"\/vendor\/dropshipping\/api-settings":{"get":{"summary":"Get API credentials (masked)","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Masked API credentials per provider"}}}},"\/vendor\/dropshipping\/api-settings\/{provider}":{"put":{"summary":"Save API credentials","tags":["Vendor: Dropshipping"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string"},"api_secret":{"type":"string"}}}}}},"responses":{"200":{"description":"Credentials saved"}}}},"\/vendor\/supplier-catalog":{"get":{"summary":"Browse supplier products","description":"Paginated catalog of supplier products available for import.","tags":["Vendor: Supplier Catalog"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"integer"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated supplier product list"}}}},"\/vendor\/supplier-catalog\/{id}":{"get":{"summary":"Supplier product detail","tags":["Vendor: Supplier Catalog"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Supplier product detail"},"404":{"description":"Not found"}}}},"\/vendor\/supplier-catalog\/{id}\/import":{"post":{"summary":"Import supplier product to own catalog","tags":["Vendor: Supplier Catalog"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Product imported to vendor catalog"}}}},"\/vendor\/import\/template":{"get":{"summary":"Download CSV template","description":"Returns a CSV template file for bulk product import.","tags":["Vendor: Import"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"CSV file download"}}}},"\/vendor\/import":{"post":{"summary":"Upload CSV to import products","tags":["Vendor: Import"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Import results (created, skipped, errors)"},"422":{"description":"Invalid CSV"}}}},"\/vendor\/api-keys":{"get":{"summary":"List API keys","description":"Returns vendor's API keys with usage stats.","tags":["Vendor: API Keys"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"List of API keys with usage stats"}}},"post":{"summary":"Create API key","tags":["Vendor: API Keys"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"expiry":{"type":"string","format":"date"}}}}}},"responses":{"201":{"description":"API key created (shown only once)"},"422":{"description":"Validation error"}}}},"\/vendor\/api-keys\/{id}\/toggle":{"patch":{"summary":"Enable\/disable API key","tags":["Vendor: API Keys"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Key toggled"}}}},"\/vendor\/api-keys\/{id}":{"delete":{"summary":"Delete API key","tags":["Vendor: API Keys"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Key deleted"},"404":{"description":"Not found"}}}},"\/vendor\/webhooks":{"get":{"summary":"List webhooks","tags":["Vendor: Webhooks"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"List of webhook endpoints"}}},"post":{"summary":"Create webhook","tags":["Vendor: Webhooks"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Webhook created"},"422":{"description":"Validation error"}}}},"\/vendor\/webhooks\/{id}\/toggle":{"patch":{"summary":"Enable\/disable webhook","tags":["Vendor: Webhooks"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Webhook toggled"}}}},"\/vendor\/webhooks\/{id}\/test":{"post":{"summary":"Send test ping","tags":["Vendor: Webhooks"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Test payload sent"},"404":{"description":"Not found"}}}},"\/vendor\/webhooks\/{id}":{"delete":{"summary":"Delete webhook","tags":["Vendor: Webhooks"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Webhook deleted"},"404":{"description":"Not found"}}}},"\/vendor\/domains":{"get":{"summary":"Current subdomain and custom domain status","tags":["Vendor: Domains"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Domain configuration status"}}}},"\/vendor\/domains\/subdomain":{"put":{"summary":"Update subdomain","tags":["Vendor: Domains"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string"}}}}}},"responses":{"200":{"description":"Subdomain updated"},"422":{"description":"Slug taken or invalid"}}}},"\/vendor\/domains\/custom":{"put":{"summary":"Set custom domain","tags":["Vendor: Domains"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}}}}},"responses":{"200":{"description":"Custom domain set \u2014 verify DNS next"}}},"delete":{"summary":"Remove custom domain","tags":["Vendor: Domains"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Custom domain removed"}}}},"\/vendor\/domains\/verify":{"post":{"summary":"Verify DNS TXT record","tags":["Vendor: Domains"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Domain verified or verification failed"}}}},"\/vendor\/verification":{"get":{"summary":"Verification status","description":"Returns the vendor's verification status and submitted documents.","tags":["Vendor: Verification"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Verification status"}}},"post":{"summary":"Submit verification documents","description":"Upload business documents for vendor verification.","tags":["Vendor: Verification"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["business_name","business_type","country","id_document","business_document"],"properties":{"business_name":{"type":"string"},"business_type":{"type":"string"},"registration_number":{"type":"string"},"tax_id":{"type":"string"},"country":{"type":"string"},"id_document":{"type":"string","format":"binary"},"business_document":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Documents submitted for review"},"422":{"description":"Validation error"}}}},"\/vendor\/stripe-connect":{"get":{"summary":"Stripe Connect status","description":"Returns whether the vendor has connected their Stripe account.","tags":["Vendor: Stripe Connect"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Connection status"}}}},"\/vendor\/stripe-connect\/connect":{"post":{"summary":"Start Stripe Express onboarding","description":"Creates a Stripe Express account and returns the onboarding URL.","tags":["Vendor: Stripe Connect"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Stripe onboarding URL"}}}},"\/vendor\/stripe-connect\/dashboard":{"get":{"summary":"Get Stripe dashboard login link","description":"Returns a one-time login link to the vendor's Stripe Express dashboard.","tags":["Vendor: Stripe Connect"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Stripe dashboard URL"},"400":{"description":"No connected account"}}}},"\/vendor\/orders\/{orderNumber}\/invoice":{"get":{"summary":"Invoice data as JSON","description":"Returns structured invoice data for the order.","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice JSON data"},"404":{"description":"Not found"}}}},"\/vendor\/orders\/{orderNumber}\/shipping-label":{"get":{"summary":"Shipping label data as JSON","description":"Returns structured shipping label data for the order.","tags":["Vendor: Orders"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"orderNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipping label JSON data"},"404":{"description":"Not found"}}}},"\/user\/affiliate":{"get":{"summary":"Affiliate status and earnings","description":"Returns affiliate status, referral code, and earnings summary.","tags":["Affiliate"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Affiliate status, code, earnings"}}}},"\/user\/affiliate\/apply":{"post":{"summary":"Apply to affiliate program","tags":["Affiliate"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"bio":{"type":"string"},"website":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Application submitted"},"409":{"description":"Already applied"}}}},"\/user\/affiliate\/generate-link":{"post":{"summary":"Generate referral link","tags":["Affiliate"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Referral link generated"}}}},"\/user\/affiliate\/commissions":{"get":{"summary":"Commission history","description":"Paginated list of affiliate commissions.","tags":["Affiliate"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Paginated commission list"}}}},"\/user\/2fa\/status":{"get":{"summary":"2FA enabled status","description":"Returns whether two-factor authentication is enabled for the user.","tags":["Two-Factor Auth"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"2FA status object"}}}},"\/user\/2fa\/enable":{"post":{"summary":"Generate 2FA secret and QR","description":"Generates a TOTP secret, QR code URL, and recovery codes. Must be confirmed with \/user\/2fa\/confirm.","tags":["Two-Factor Auth"],"security":[{"UserTokenAuth":[]}],"responses":{"200":{"description":"Secret, QR URL, and recovery codes"}}}},"\/user\/2fa\/confirm":{"post":{"summary":"Confirm 2FA setup","description":"Verifies the TOTP code to activate 2FA.","tags":["Two-Factor Auth"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","minLength":6,"maxLength":6}}}}}},"responses":{"200":{"description":"2FA activated"},"422":{"description":"Invalid code"}}}},"\/user\/2fa\/disable":{"delete":{"summary":"Disable 2FA","description":"Disables two-factor authentication. Requires current password.","tags":["Two-Factor Auth"],"security":[{"UserTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string"}}}}}},"responses":{"200":{"description":"2FA disabled"},"422":{"description":"Wrong password"}}}},"\/products\/{id}\/report":{"post":{"summary":"Report a product","tags":["Reports"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","enum":["spam","counterfeit","inappropriate","misleading","prohibited","other"]},"description":{"type":"string"}}}}}},"responses":{"201":{"description":"Report submitted"},"422":{"description":"Validation error"}}}},"\/vendors\/{slug}\/report":{"post":{"summary":"Report a vendor","tags":["Reports"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","enum":["spam","counterfeit","inappropriate","misleading","prohibited","other"]},"description":{"type":"string"}}}}}},"responses":{"201":{"description":"Report submitted"},"422":{"description":"Validation error"}}}},"\/products\/{id}\/reviews\/{reviewId}\/vote":{"post":{"summary":"Vote on a review","description":"Mark a review as helpful or not helpful.","tags":["Reviews"],"security":[{"UserTokenAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"reviewId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["is_helpful"],"properties":{"is_helpful":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Vote recorded"},"404":{"description":"Review not found"}}}},"\/newsletter\/subscribe":{"post":{"summary":"Subscribe to newsletter","description":"Subscribe an email address to the marketplace newsletter. No authentication required.","tags":["Newsletter"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Subscribed successfully"},"422":{"description":"Invalid email or already subscribed"}}}}}}