{"openapi":"3.0.3","info":{"title":"lma39ol Merchant Trust API","version":"1.0.0","description":"Ratings, verified review invitations, trust badges, and billing for merchants integrating lma39ol into their own storefronts."},"servers":[{"url":"http://localhost:3001"}],"components":{"securitySchemes":{"apiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"A merchant API key (prefixed `lma_`), issued via POST /merchants/api-keys from an authenticated dashboard session."}},"schemas":{"RatingScores":{"type":"object","properties":{"responsiveness":{"type":"integer","minimum":0,"maximum":5,"description":"How quickly the seller responded to inquiries."},"communicationQuality":{"type":"integer","minimum":0,"maximum":5},"problemResolution":{"type":"integer","minimum":0,"maximum":5},"productDescription":{"type":"integer","minimum":0,"maximum":5,"description":"Was the product as described."},"productQuality":{"type":"integer","minimum":0,"maximum":5},"deliveryTime":{"type":"integer","minimum":0,"maximum":5},"packaging":{"type":"integer","minimum":0,"maximum":5},"shippingCost":{"type":"integer","minimum":0,"maximum":5},"deliveryCondition":{"type":"integer","minimum":0,"maximum":5}}}}},"security":[{"apiKeyAuth":[]}],"paths":{"/ratings":{"post":{"summary":"Submit a rating about a buyer","description":"Authenticated as a merchant, this always creates a private buyer-risk rating (not a public merchant score) — merchants cannot self-review. To collect a public, buyer-authored review instead, use the review-invitations flow below.","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["orderReference"],"properties":{"orderReference":{"type":"string"},"orderValue":{"type":"number"},"responsiveness":{"type":"integer","minimum":0,"maximum":5,"description":"How quickly the seller responded to inquiries."},"communicationQuality":{"type":"integer","minimum":0,"maximum":5},"problemResolution":{"type":"integer","minimum":0,"maximum":5},"productDescription":{"type":"integer","minimum":0,"maximum":5,"description":"Was the product as described."},"productQuality":{"type":"integer","minimum":0,"maximum":5},"deliveryTime":{"type":"integer","minimum":0,"maximum":5},"packaging":{"type":"integer","minimum":0,"maximum":5},"shippingCost":{"type":"integer","minimum":0,"maximum":5},"deliveryCondition":{"type":"integer","minimum":0,"maximum":5},"comment":{"type":"string"}}}}}},"responses":{"201":{"description":"Rating created."},"400":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"403":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"429":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}},"get":{"summary":"List ratings","security":[{"apiKeyAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Paginated ratings."},"429":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}},"/ratings/buyer-risk":{"get":{"summary":"Private buyer-reliability risk summary","description":"Cancellation rate, return rate, and punctuality-derived risk banding (low/medium/high) for a buyer — for the merchant's own risk screening, never shown publicly.","security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Risk summary."}}}},"/ratings/{ratingId}/reply":{"patch":{"summary":"Reply to a review","security":[{"apiKeyAuth":[]}],"parameters":[{"name":"ratingId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Reply saved."},"403":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}},"/review-invitations":{"post":{"summary":"Create a one-time review invitation (QR code)","description":"Issues a one-time token for a delivered order; print the returned QR code on a receipt or parcel insert so the buyer can scan it later to leave a verified, order-linked public review.","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["orderReference","buyer"],"properties":{"orderReference":{"type":"string"},"buyer":{"type":"object","required":["firstName","lastName"],"properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"}}},"orderValue":{"type":"number"},"currency":{"type":"string","default":"MAD"},"expiresInDays":{"type":"integer","minimum":1,"maximum":90,"default":14}}}}}},"responses":{"201":{"description":"Invitation created, including `reviewUrl` and a printable `qrCodeDataUrl`."},"400":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"409":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}},"get":{"summary":"List review invitations","security":[{"apiKeyAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}}],"responses":{"200":{"description":"Paginated invitations."}}}},"/public/review-invitations/{token}":{"get":{"summary":"Read an invitation by its one-time token (buyer-facing, no auth)","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Privacy-safe invitation preview."},"404":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"409":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"410":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}},"/public/review-invitations/{token}/review":{"post":{"summary":"Submit the review that redeems an invitation (buyer-facing, no auth)","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"responsiveness":{"type":"integer","minimum":0,"maximum":5,"description":"How quickly the seller responded to inquiries."},"communicationQuality":{"type":"integer","minimum":0,"maximum":5},"problemResolution":{"type":"integer","minimum":0,"maximum":5},"productDescription":{"type":"integer","minimum":0,"maximum":5,"description":"Was the product as described."},"productQuality":{"type":"integer","minimum":0,"maximum":5},"deliveryTime":{"type":"integer","minimum":0,"maximum":5},"packaging":{"type":"integer","minimum":0,"maximum":5},"shippingCost":{"type":"integer","minimum":0,"maximum":5},"deliveryCondition":{"type":"integer","minimum":0,"maximum":5},"comment":{"type":"string"}}}}}},"responses":{"201":{"description":"Review published; the invitation is consumed and cannot be reused."},"400":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"409":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}},"410":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}},"/trust/merchants/{merchantId}":{"get":{"summary":"Public trust badge (embeddable on a storefront, no auth)","security":[],"parameters":[{"name":"merchantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Aggregated public trust score and dimension breakdown."},"404":{"description":"Request rejected.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"errorCode":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}},"/payments/subscription":{"get":{"summary":"Get the merchant's current billing plan and subscription status","security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Subscription status."}}}},"/public/payments/plans":{"get":{"summary":"List available billing plans (public pricing catalog, no auth)","security":[],"responses":{"200":{"description":"Plan catalog."}}}}}}