openapi: 3.0.3
info:
  title: Boostigo Likee API
  version: "1.0.0"
  description: |
    Integrate Likee diamond recharge with a simple REST API.
    Flow: Identify user → confirm → Recharge → save order_id → receive webhook → verify order.
    Public URLs are stable (no /v1). `success: true` on recharge means the request was accepted; read `status`.
  contact: { name: Boostigo Developers, url: https://developers.boostigo.io }
servers:
  - url: https://api.boostigo.io
security:
  - bearerAuth: []
tags:
  - { name: Likee, description: Identify and recharge Likee accounts }
  - { name: Orders, description: Order status and details }
paths:
  /likee/user/{likee_id}:
    get:
      tags: [Likee]
      summary: Identify Likee user
      operationId: identifyLikeeUser
      parameters:
        - { name: likee_id, in: path, required: true, schema: { type: string, example: "1137852558" } }
      responses:
        "200":
          description: User found
          headers: { $ref: "#/components/headers/RateLimit" }
          content:
            application/json:
              schema: { $ref: "#/components/schemas/IdentifyResponse" }
              example: { success: true, data: { platform: likee, user: { likee_id: "1137852558", likee_uid: "1278112264", nickname: "yehya", avatar: "https://img.like.video/...", country: "LB" } } }
        "401": { $ref: "#/components/responses/InvalidApiKey" }
        "403": { $ref: "#/components/responses/Forbidden" }
        "404": { $ref: "#/components/responses/UserNotFound" }
        "422": { description: Invalid Likee ID, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: INVALID_LIKEE_ID, message: Invalid Likee ID. } } } } }
        "429": { $ref: "#/components/responses/RateLimited" }
        "503": { $ref: "#/components/responses/ServiceUnavailable" }
  /likee/recharge:
    post:
      tags: [Likee]
      summary: Create a Likee recharge order
      operationId: createLikeeRecharge
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/RechargeRequest" }
            example: { likee_id: "1137852558", likee_uid: "1278112264", diamond: 5000, amount: "95.00", request_id: "ORDER-CLIENT-10001" }
      responses:
        "201":
          description: Order accepted (status processing)
          headers: { $ref: "#/components/headers/RateLimit" }
          content: { application/json: { schema: { $ref: "#/components/schemas/OrderResponse" }, example: { success: true, data: { order_id: BST-LKE-8F72A19X, request_id: ORDER-CLIENT-10001, platform: likee, likee_id: "1137852558", likee_uid: "1278112264", diamond: 5000, amount: "95.00", currency: USD, status: processing, created_at: "2026-09-07T12:30:00Z", updated_at: "2026-09-07T12:30:00Z" } } } }
        "200":
          description: Duplicate request_id — existing order returned
          content: { application/json: { schema: { $ref: "#/components/schemas/OrderResponse" }, example: { success: true, data: { order_id: BST-LKE-8F72A19X, request_id: ORDER-CLIENT-10001, platform: likee, likee_id: "1137852558", likee_uid: "1278112264", diamond: 5000, amount: "95.00", currency: USD, status: processing, duplicate: true, created_at: "2026-09-07T12:30:00Z", updated_at: "2026-09-07T12:30:03Z" } } } }
        "400": { description: Invalid JSON, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" } } } }
        "401": { $ref: "#/components/responses/InvalidApiKey" }
        "402": { description: Insufficient API key balance, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: INSUFFICIENT_BALANCE, message: Insufficient API key balance. } } } } }
        "403": { $ref: "#/components/responses/Forbidden" }
        "404": { $ref: "#/components/responses/UserNotFound" }
        "422":
          description: Validation error (INVALID_LIKEE_ID, LIKEE_UID_MISMATCH, INVALID_DIAMOND_AMOUNT, AMOUNT_MISMATCH, INVALID_REQUEST_ID)
          content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: AMOUNT_MISMATCH, message: The supplied amount does not match the configured recharge amount. } } } }
        "429": { $ref: "#/components/responses/RateLimited" }
        "503": { $ref: "#/components/responses/ServiceUnavailable" }
  /orders/{order_id}:
    get:
      tags: [Orders]
      summary: Get order
      operationId: getOrder
      parameters:
        - { name: order_id, in: path, required: true, schema: { type: string, example: BST-LKE-8F72A19X } }
      responses:
        "200":
          description: Order
          headers: { $ref: "#/components/headers/RateLimit" }
          content: { application/json: { schema: { $ref: "#/components/schemas/OrderResponse" }, example: { success: true, data: { order_id: BST-LKE-8F72A19X, request_id: ORDER-CLIENT-10001, platform: likee, likee_id: "1137852558", likee_uid: "1278112264", diamond: 5000, amount: "95.00", currency: USD, status: success, created_at: "2026-09-07T12:30:00Z", updated_at: "2026-09-07T12:30:09Z", completed_at: "2026-09-07T12:30:09Z" } } } }
        "401": { $ref: "#/components/responses/InvalidApiKey" }
        "403": { $ref: "#/components/responses/Forbidden" }
        "404": { description: Order not found, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: ORDER_NOT_FOUND, message: Order was not found. } } } } }
        "429": { $ref: "#/components/responses/RateLimited" }
components:
  securitySchemes:
    bearerAuth: { type: http, scheme: bearer, description: "Authorization: Bearer YOUR_API_KEY" }
  headers:
    RateLimit:
      description: Rate limit headers
      schema: { type: string }
  responses:
    InvalidApiKey: { description: Invalid API key, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: INVALID_API_KEY, message: Invalid API key. } } } } }
    Forbidden: { description: API_KEY_DISABLED, STORE_DISABLED, PLATFORM_NOT_ENABLED or IP_NOT_ALLOWED, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: API_KEY_DISABLED, message: This API key is disabled. } } } } }
    UserNotFound: { description: Likee user not found, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: USER_NOT_FOUND, message: Likee user was not found. } } } } }
    RateLimited: { description: Too many requests, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: RATE_LIMIT_EXCEEDED, message: Too many requests. } } } } }
    ServiceUnavailable: { description: Likee service temporarily unavailable, content: { application/json: { schema: { $ref: "#/components/schemas/ErrorResponse" }, example: { success: false, error: { code: SERVICE_UNAVAILABLE, message: Likee service is temporarily unavailable. } } } } }
  schemas:
    ErrorResponse:
      type: object
      required: [success, error]
      properties:
        success: { type: boolean, enum: [false] }
        error:
          type: object
          required: [code, message]
          properties:
            code: { type: string, enum: [INVALID_API_KEY, API_KEY_DISABLED, STORE_DISABLED, PLATFORM_NOT_ENABLED, IP_NOT_ALLOWED, INVALID_LIKEE_ID, USER_NOT_FOUND, LIKEE_UID_MISMATCH, INVALID_DIAMOND_AMOUNT, AMOUNT_MISMATCH, INVALID_REQUEST_ID, DUPLICATE_REQUEST, INSUFFICIENT_BALANCE, ORDER_NOT_FOUND, RECHARGE_FAILED, RATE_LIMIT_EXCEEDED, SERVICE_UNAVAILABLE, INTERNAL_ERROR, INVALID_JSON, METHOD_NOT_ALLOWED, NOT_FOUND] }
            message: { type: string }
    LikeeUser:
      type: object
      required: [likee_id, likee_uid, nickname]
      properties:
        likee_id: { type: string }
        likee_uid: { type: string }
        nickname: { type: string }
        avatar: { type: string, nullable: true, format: uri }
        country: { type: string, nullable: true }
    IdentifyResponse:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data:
          type: object
          properties:
            platform: { type: string, enum: [likee] }
            user: { $ref: "#/components/schemas/LikeeUser" }
    RechargeRequest:
      type: object
      required: [likee_id, likee_uid, diamond, amount, request_id]
      properties:
        likee_id: { type: string, description: Public Likee ID }
        likee_uid: { type: string, description: UID returned by Identify }
        diamond: { type: integer, minimum: 1, description: Must be a configured amount }
        amount: { type: string, pattern: "^\\d+(\\.\\d{1,2})?$", description: Configured selling price for this key, e.g. "95.00" }
        request_id: { type: string, minLength: 1, maxLength: 100, pattern: "^[A-Za-z0-9_.:-]+$", description: Your unique reference (idempotency key) }
    Order:
      type: object
      required: [order_id, request_id, platform, likee_id, likee_uid, diamond, amount, currency, status, created_at]
      properties:
        order_id: { type: string, example: BST-LKE-8F72A19X }
        request_id: { type: string }
        platform: { type: string, enum: [likee] }
        likee_id: { type: string }
        likee_uid: { type: string }
        diamond: { type: integer }
        amount: { type: string, example: "95.00" }
        currency: { type: string, enum: [USD] }
        status: { $ref: "#/components/schemas/OrderStatus" }
        duplicate: { type: boolean, description: Present and true when an existing order was returned for a repeated request_id }
        error:
          type: object
          description: Present when status is failed
          properties: { code: { type: string, example: RECHARGE_FAILED }, message: { type: string } }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
        completed_at: { type: string, format: date-time }
    OrderStatus:
      type: string
      enum: [pending, processing, success, failed, cancelled, delayed]
      description: pending=created not started · processing=in progress · success=delivered · failed=permanently failed (refunded) · cancelled=cancelled (refunded) · delayed=temporarily delayed, still processing
    OrderResponse:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/Order" }
    WebhookEvent:
      type: object
      description: Body of webhook POSTs. Headers X-Boostigo-Event, X-Boostigo-Delivery, X-Boostigo-Timestamp, X-Boostigo-Signature (sha256=HMAC_SHA256(secret, timestamp + "." + raw_body)).
      properties:
        event: { type: string, enum: [order.processing, order.success, order.failed, order.cancelled, order.delayed] }
        data: { $ref: "#/components/schemas/Order" }
