{"openapi":"3.1.0","info":{"title":"AOV Security Market API","version":"2.0.0","description":"API-first wholesale catalog, ordering and three-level distribution platform."},"servers":[{"url":"https://aovsolar.com"}],"components":{"securitySchemes":{"distributionBearer":{"type":"http","scheme":"bearer"},"automationBearer":{"type":"http","scheme":"bearer","description":"AUTOMATION_TOKEN for AI Agent operations"},"cookieSession":{"type":"apiKey","in":"cookie","name":"aov_session"}},"schemas":{"ConfirmReceiptRequest":{"type":"object","required":["buyerId"],"properties":{"buyerId":{"type":"string"}},"additionalProperties":false},"CreateOrderRequest":{"type":"object","required":["buyerId","items"],"properties":{"buyerId":{"type":"string"},"items":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","required":["productId","quantity"],"properties":{"productId":{"type":"string"},"quantity":{"type":"integer","minimum":1}}}}},"additionalProperties":false},"DistributorApplicationRequest":{"type":"object","required":["companyName","country","whatsapp","salesChannels","monthlyBuyers"],"properties":{"companyName":{"type":"string","minLength":2,"maxLength":160},"country":{"type":"string","minLength":2,"maxLength":80},"whatsapp":{"type":"string","minLength":5,"maxLength":50},"salesChannels":{"type":"string","minLength":2,"maxLength":500},"monthlyBuyers":{"type":"integer","minimum":0,"maximum":100000},"note":{"type":"string","maxLength":1200}},"additionalProperties":false},"CommissionPolicyRequest":{"type":"object","required":["ratesBps","updatedAt"],"properties":{"ratesBps":{"type":"array","minItems":3,"maxItems":3,"description":"Level 1, 2 and 3 rates in integer basis points. Each rate is at most 2000; total is at most 3000.","items":{"type":"integer","minimum":0,"maximum":2000}},"updatedAt":{"type":"integer","minimum":0,"description":"Optimistic concurrency version returned by GET."}},"additionalProperties":false},"PaymentSubmissionRequest":{"type":"object","required":["method","paymentReference","proofUrl"],"properties":{"method":{"type":"string","enum":["BANK_TRANSFER","PAYPAL","MOBILE_MONEY","USDT","OTHER"]},"paymentReference":{"type":"string","minLength":4,"maxLength":160},"proofUrl":{"type":"string","pattern":"^/media/payment-proofs/","maxLength":500},"buyerNote":{"type":"string","maxLength":1000}},"additionalProperties":false},"PaymentReviewRequest":{"type":"object","required":["action","submissionId","version"],"properties":{"action":{"type":"string","enum":["APPROVE","REJECT"]},"submissionId":{"type":"string"},"version":{"type":"integer","minimum":0,"description":"Optimistic concurrency version shown in the admin review queue."},"note":{"type":"string","maxLength":2000,"description":"Required with at least 3 characters when rejecting."}},"additionalProperties":false},"FeatureSettingsRequest":{"type":"object","required":["paymentsEnabled","distributionEnabled","updatedAt"],"properties":{"paymentsEnabled":{"type":"boolean","description":"Allow new carts, checkout, orders and buyer payment submissions."},"distributionEnabled":{"type":"boolean","description":"Allow new invitation relationships, distributor applications and commission creation."},"updatedAt":{"type":"integer","minimum":0,"description":"Optimistic concurrency version returned by GET."}},"additionalProperties":false},"WebhookEndpointRequest":{"type":"object","required":["name","url","events"],"properties":{"name":{"type":"string","minLength":2,"maxLength":100},"url":{"type":"string","format":"uri","description":"HTTPS is mandatory in production."},"events":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string"}}},"additionalProperties":false},"WholesaleRfqRequest":{"type":"object","required":["contactName","email","country","quantity","message"],"properties":{"productSlug":{"type":"string","maxLength":200},"contactName":{"type":"string","minLength":2,"maxLength":100},"email":{"type":"string","format":"email","maxLength":254},"whatsapp":{"type":"string","maxLength":50},"country":{"type":"string","minLength":2,"maxLength":80},"quantity":{"type":"integer","minimum":1,"maximum":1000000},"message":{"type":"string","minLength":10,"maxLength":4000},"sourcePage":{"type":"string","maxLength":500}},"additionalProperties":false}}},"paths":{"/api/v1/products":{"get":{"summary":"List and search products"}},"/api/v1/products/{slug}":{"get":{"summary":"Get full product data"}},"/api/v1/events":{"post":{"summary":"Ingest an allow-listed automation event","security":[{"automationBearer":[]}]}},"/api/v1/rfqs":{"post":{"summary":"Submit an anonymous or authenticated wholesale RFQ","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":180}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WholesaleRfqRequest"}}}},"responses":{"200":{"description":"Idempotent retry returned"},"201":{"description":"RFQ accepted and lead.created event queued"},"429":{"description":"Hourly IP or email submission limit reached"}}}},"/api/v1/automation/webhooks/dispatch":{"post":{"summary":"Claim and deliver due signed webhook queue items","security":[{"automationBearer":[]}],"responses":{"200":{"description":"Dispatch counters"},"503":{"description":"Signing or automation secret is not configured"}}}},"/api/v1/admin/webhooks":{"get":{"summary":"List webhook endpoints and delivery counters","security":[{"cookieSession":[]}]},"post":{"summary":"Create an active signed webhook endpoint","security":[{"cookieSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointRequest"}}}}}},"/api/v1/admin/commission-settings":{"get":{"summary":"Read the effective three-level commission policy","security":[{"cookieSession":[]}]},"patch":{"summary":"Optimistically update rates for future commission freezes","security":[{"cookieSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionPolicyRequest"}}}},"responses":{"200":{"description":"Policy saved and audit event queued"},"409":{"description":"Another administrator changed the policy"},"422":{"description":"Invalid rate limits or ordering"}}}},"/api/v1/admin/feature-settings":{"get":{"summary":"Read independent payment and distributor-growth switches","security":[{"cookieSession":[]}]},"patch":{"summary":"Optimistically update platform feature switches","description":"Changes take effect immediately for new writes. Historical orders, commissions, wallets and audit records are preserved.","security":[{"cookieSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureSettingsRequest"}}}},"responses":{"200":{"description":"Switches saved and audit event queued"},"409":{"description":"Another administrator changed the switches"},"422":{"description":"Invalid flags or version"}}}},"/api/v1/admin/webhooks/{id}":{"post":{"summary":"Test, pause or activate a webhook endpoint","security":[{"cookieSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"delete":{"summary":"Delete an endpoint and its delivery history","security":[{"cookieSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/v1/admin/rfqs/{id}":{"post":{"summary":"Optimistically update an RFQ workflow status","security":[{"cookieSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/v1/admin/market-research":{"get":{"summary":"Read recent Serper-backed market research","security":[{"cookieSession":[]},{"automationBearer":[]}]},"post":{"summary":"Research a country market with six-hour paid-query caching","security":[{"cookieSession":[]},{"automationBearer":[]}]}},"/api/v1/auth/verification-code":{"post":{"summary":"Send a rate-limited 6-digit buyer registration email code"}},"/api/v1/auth/register":{"post":{"summary":"Register a verified buyer account and optional invitation relationship"}},"/api/v1/auth/login":{"post":{"summary":"Create an HttpOnly account session"}},"/api/v1/auth/logout":{"post":{"summary":"Revoke the current account session","security":[{"cookieSession":[]}]}},"/api/v1/cart":{"get":{"summary":"Read the authenticated server-side cart","security":[{"cookieSession":[]}]},"post":{"summary":"Add or replace a cart quantity with server-side MOQ and stock validation","security":[{"cookieSession":[]}]}},"/api/v1/checkout":{"post":{"summary":"Create an authenticated order from the cart and atomically reserve inventory","security":[{"cookieSession":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":180}}],"responses":{"200":{"description":"Idempotent retry returned"},"201":{"description":"Order created"},"409":{"description":"Cart or inventory conflict"}}}},"/api/v1/account/payment-proof":{"post":{"summary":"Upload a private buyer payment receipt image or PDF","security":[{"cookieSession":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["orderId","file"],"properties":{"orderId":{"type":"string"},"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Private media URL created"},"422":{"description":"Unsupported type or file larger than 8MB"}}}},"/api/v1/account/orders/{id}/payment-submissions":{"post":{"summary":"Submit an idempotent payment reference and proof for human review","security":[{"cookieSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":180}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentSubmissionRequest"}}}},"responses":{"200":{"description":"Idempotent retry returned"},"201":{"description":"Payment proof queued for review"},"409":{"description":"Another proof is already under review or the order is not payable"}}}},"/api/v1/admin/orders/{id}/payment-review":{"post":{"summary":"Approve or reject payment proof with optimistic concurrency","description":"Approval atomically marks the order paid, freezes the three-level commission snapshot and records payment audit events in one D1 batch.","security":[{"cookieSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentReviewRequest"}}}},"responses":{"200":{"description":"Review committed"},"409":{"description":"Submission changed, order changed, or commission invariant rejected the batch"},"422":{"description":"Invalid action, version or review note"}}}},"/api/v1/account/withdrawals":{"post":{"summary":"Reserve wallet funds and create an encrypted distributor withdrawal request","security":[{"cookieSession":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":180}}],"responses":{"201":{"description":"Withdrawal created and funds reserved"},"409":{"description":"Insufficient or changed balance"}}}},"/api/v1/account/distributor-application":{"post":{"summary":"Submit or resubmit the authenticated buyer's distributor application","security":[{"cookieSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DistributorApplicationRequest"}}}},"responses":{"200":{"description":"Idempotent pending application returned"},"201":{"description":"Application submitted"},"409":{"description":"Distributor account is already active"}}}},"/api/v1/orders":{"post":{"summary":"Create an idempotent order and atomically reserve stock","operationId":"createOrder","security":[{"distributionBearer":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":180}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderRequest"}}}},"responses":{"200":{"description":"Previous order returned for an idempotent retry"},"201":{"description":"Order created and all stock reserved"},"409":{"description":"Stock, price, MOQ or idempotency conflict; batch rolled back"}}}},"/api/v1/orders/{id}/pay":{"post":{"summary":"Mark an order paid and freeze three-level commissions","operationId":"markOrderPaid","security":[{"distributionBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmReceiptRequest"}}}},"responses":{"200":{"description":"Payment state and commission freeze committed"}}}},"/api/v1/orders/{id}/ship":{"post":{"summary":"Move a paid order with prepared commissions to shipped","operationId":"markOrderShipped","security":[{"distributionBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmReceiptRequest"}}}},"responses":{"200":{"description":"Order shipped or previous result returned"}}}},"/api/v1/orders/{id}/cancel":{"post":{"summary":"Cancel an unshipped order and atomically release stock and frozen commissions","operationId":"cancelOrder","security":[{"distributionBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmReceiptRequest"}}}},"responses":{"200":{"description":"Order cancelled or previous cancellation returned"},"409":{"description":"Order was shipped/settled or release batch failed and rolled back"}}}},"/api/v1/orders/{id}/confirm-receipt":{"post":{"summary":"Confirm receipt and atomically settle three-level commissions","operationId":"confirmOrderReceipt","security":[{"distributionBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmReceiptRequest"}}}},"responses":{"200":{"description":"Receipt confirmed or an idempotent previous result returned"},"401":{"description":"Invalid service token"},"409":{"description":"Order or wallet state conflict; D1 batch was rolled back"}}}}}}