openapi: 3.0.3
info:
  title: ThunJai Express — Open API (ເອກະສານສຳລັບນັກພັດທະນາ)
  version: 1.0.0
  description: |-
    Open API ສຳລັບຄູ່ຮ່ວມງານ/ພາຍນອກຂອງ **ThunJai Express** (`server/api_open_ext`, ພອດເລີ່ມຕົ້ນ `8181`).

    ## ການຢືນຢັນຕົວຕົນ
    1. ເອີ້ນ `POST /auth/requestToken` ພ້ອມ `user`, `pwd` (= API key) ແລະ `sign` ເພື່ອຮັບ `access_token` (ແລະ `refresh_token`)
    2. ແນບໂທເຄັນໃນທຸກຄຳຮ້ອງຕໍ່ໄປຜ່ານ `Authorization: Bearer <access_token>`
    3. ເມື່ອໝົດອາຍຸ ໃຫ້ເອີ້ນ `POST /auth/refreshToken`

    **ປະເພດຜູ້ໃຊ້**
    - **ຜູ້ສົ່ງ (Sender)** — ຊື່ຜູ້ໃຊ້ເປັນເບີໂທລະສັບ (ຈາກ `db_sender`)
    - **ພະນັກງານ Drop-off** — ຊື່ຜູ້ໃຊ້ຂຶ້ນຕົ້ນດ້ວຍ `S.` ແລະ ມີ `@` (ຈາກ `db_user`); ການຕອບກັບໂທເຄັນຈະມີ `drop_off_ids` ຂອງຈຸດ Drop-off ທີ່ພະນັກງານດູແລ

    ### ລາຍເຊັນ (`sign`)
    `sign = HMAC_SHA256( querystring({ user, pwd }), key = api_key_secret )` → ສະຕຣິງ hex

    ## ຮູບແບບການຕອບກັບ (envelope)
    ທຸກ API ຈະຕອບກັບໃນຮູບແບບມາດຕະຖານ; ຟິລດ໌ **`data`** ຂອງແຕ່ລະ API ໄດ້ອະທິບາຍໄວ້ດ້ານລຸ່ມ
    ```json
    { "data": <payload|null>, "data_total": <number>, "success": true, "error": null }
    ```
    ເມື່ອເກີດຂໍ້ຜິດພາດ `success=false` ແລະ `error` ຈະມີຂໍ້ຄວາມ/ລະຫັດຜິດພາດ
servers:
  - url: https://{host}/api
    description: Production (behind reverse proxy)
    variables:
      host:
        default: open-api-doc.thunjaiexpress.com
tags:
  - name: Auth
    description: Token issue & refresh
    x-displayName: ການຢືນຢັນຕົວຕົນ
  - name: Master
    description: Reference / lookup data
    x-displayName: ຂໍ້ມູນອ້າງອີງ
  - name: Order
    description: Sender order operations
    x-displayName: ອໍເດີ້ (ຜູ້ສົ່ງ)
  - name: Pickup
    description: Sender pickup operations
    x-displayName: ການເຂົ້າຮັບເຄື່ອງ
  - name: User Address
    description: Sender address book
    x-displayName: ທີ່ຢູ່ຜູ້ໃຊ້
  - name: Drop-off — Profile
    description: Drop-off staff — responsible drop-offs
    x-displayName: Drop-off — ໂປຣໄຟລ໌
  - name: Drop-off — Bank Account
    description: Drop-off staff — bank account management
    x-displayName: Drop-off — ບັນຊີທະນາຄານ
  - name: Drop-off — Wallet
    description: Drop-off staff — wallet credit (deposit only)
    x-displayName: Drop-off — ກະເປົາເງິນ
  - name: Drop-off — Order
    description: Drop-off staff — order management
    x-displayName: Drop-off — ອໍເດີ້
security:
  - bearerAuth: []
paths:
  /auth/requestToken:
    post:
      tags:
        - Auth
      summary: ຂໍ access token
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user
                - pwd
                - sign
              properties:
                user:
                  type: string
                  description: Sender phone number, or drop-off staff username (S.…@owner)
                  example: '8562055512345'
                pwd:
                  type: string
                  description: The issued API key
                  example: a1b2c3…
                sign:
                  type: string
                  description: HMAC-SHA256 hex of querystring({user,pwd}) keyed by api_key_secret
      responses:
        '200':
          description: Token issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_Token'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /auth/refreshToken:
    post:
      tags:
        - Auth
      summary: ຕໍ່ອາຍຸ access token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - refresh_token
              properties:
                refresh_token:
                  type: string
                  description: The refresh_token returned by /auth/requestToken
      responses:
        '200':
          description: New token issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_Token'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /master/provinces:
    get:
      tags:
        - Master
      summary: ລາຍການແຂວງ
      responses:
        '200':
          description: Province list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_NamedList'
  /master/districts:
    get:
      tags:
        - Master
      summary: ລາຍການເມືອງຂອງແຂວງ
      parameters:
        - in: query
          name: province_id
          required: true
          schema:
            type: integer
          description: ລະຫັດແຂວງ
      responses:
        '200':
          description: District list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_NamedList'
        '400':
          $ref: '#/components/responses/ParamRequired'
  /master/villages:
    get:
      tags:
        - Master
      summary: ລາຍການບ້ານຂອງເມືອງ
      parameters:
        - in: query
          name: district_id
          required: true
          schema:
            type: integer
          description: ລະຫັດເມືອງ
      responses:
        '200':
          description: Village list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              description: Village (district-sub) id
                            name:
                              type: string
                              description: Localised village name (per Locale header)
                            post_code:
                              type: string
                              description: Postal code
        '400':
          $ref: '#/components/responses/ParamRequired'
  /master/deliveryTypes:
    get:
      tags:
        - Master
      summary: ລາຍການປະເພດການບໍລິການຈັດສົ່ງ
      responses:
        '200':
          description: Delivery types
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_NamedList'
  /master/packaging:
    get:
      tags:
        - Master
      summary: ລາຍການຫຸ້ມຫໍ່
      responses:
        '200':
          description: Packaging options
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              description: Packaging id
                            name:
                              type: string
                              description: Localised packaging name
                            width:
                              type: number
                              description: Width (cm)
                            long:
                              type: number
                              description: Length (cm)
                            height:
                              type: number
                              description: Height (cm)
  /order/service/checkServiceType:
    post:
      tags:
        - Order
      summary: ປະເພດການບໍລິການທີ່ໃຊ້ໄດ້ຕາມຕົ້ນທາງ/ປາຍທາງ
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Origin & destination address ids (province/district/district_sub).
      responses:
        '200':
          description: Available service types
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_NamedList'
  /order/service/estimatePrice:
    post:
      tags:
        - Order
      summary: ປະເມີນລາຄາຄ່າຈັດສົ່ງ
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Origin/destination + parcel weight & dimensions + service type.
      responses:
        '200':
          description: Estimated price
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          service_price:
                            type: number
                            description: Delivery service price (incl. VAT)
                          service_price_vat_amount:
                            type: number
                            description: VAT portion of the service price
                          service_price_out_vat:
                            type: number
                            description: Service price excluding VAT
                          weight:
                            type: number
                            description: Chargeable weight (kg)
                          fee_distance:
                            type: number
                            description: Distance-based fee component
                          total:
                            type: number
                            description: Total estimated charge
  /order/tracking:
    get:
      tags:
        - Order
      summary: ຕິດຕາມອໍເດີ້
      parameters:
        - in: query
          name: order_no
          required: true
          schema:
            type: string
          description: Order number to track
      responses:
        '200':
          description: Tracking detail (null if not found)
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/OrderTracking'
  /order/list:
    get:
      tags:
        - Order
      summary: ລາຍການອໍເດີ້ຂອງຜູ້ເອີ້ນ
      parameters:
        - in: query
          name: date_start
          schema:
            type: string
          description: ກັ່ນຕອງແຕ່ວັນທີ (YYYY-MM-DD)
        - in: query
          name: date_end
          schema:
            type: string
          description: ກັ່ນຕອງຮອດວັນທີ (YYYY-MM-DD)
        - in: query
          name: paging
          schema:
            type: integer
            default: 0
          description: ໜ້າເລີ່ມທີ່ 0 (20 ລາຍການຕໍ່ໜ້າ)
      responses:
        '200':
          description: Order list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_OrderList'
  /order/detail:
    get:
      tags:
        - Order
      summary: ລາຍລະອຽດອໍເດີ້ (ຂອງຜູ້ເອີ້ນ)
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: ລະຫັດອໍເດີ້
      responses:
        '200':
          description: ລາຍລະອຽດອໍເດີ້
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_OrderDetail'
  /order/create:
    put:
      tags:
        - Order
      summary: ສ້າງອໍເດີ້
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderCreate'
      responses:
        '200':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          order_id:
                            type: integer
                            description: Newly created order id
                          'no':
                            type: string
                            description: Generated order number
  /order/cancel:
    post:
      tags:
        - Order
      summary: ຍົກເລີກອໍເດີ້
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: ລະຫັດອໍເດີ້
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
  /order/delete:
    delete:
      tags:
        - Order
      summary: ລຶບອໍເດີ້ (ພາຍໃນເວລາທີ່ກຳນົດ)
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: ລະຫັດອໍເດີ້
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
  /order/label:
    get:
      tags:
        - Order
      summary: ຮັບລິ້ງໃບປະໜ້າສຳລັບພິມ
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: ລະຫັດອໍເດີ້
        - in: query
          name: locale
          schema:
            type: string
            enum:
              - la
              - th
              - en
              - cn
              - vn
          description: Label language
      responses:
        '200':
          description: Label link
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          url:
                            type: string
                            description: Printable label URL (PDF/HTML)
  /pickup/request:
    put:
      tags:
        - Pickup
      summary: ຂໍເຂົ້າຮັບເຄື່ອງສຳລັບອໍເດີ້
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Order id(s) + pickup address/time.
      responses:
        '200':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          pickup_id:
                            type: integer
                            description: Newly created pickup job id
                          'no':
                            type: string
                            description: Generated pickup number
  /pickup/list:
    get:
      tags:
        - Pickup
      summary: ລາຍການວຽກເຂົ້າຮັບເຄື່ອງ
      parameters:
        - in: query
          name: date_start
          schema:
            type: string
          description: ກັ່ນຕອງແຕ່ວັນທີ (YYYY-MM-DD)
        - in: query
          name: date_end
          schema:
            type: string
          description: ກັ່ນຕອງຮອດວັນທີ (YYYY-MM-DD)
      responses:
        '200':
          description: Pickup jobs
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        description: Pickup jobs
                        items:
                          $ref: '#/components/schemas/PickupListItem'
  /pickup/detail:
    get:
      tags:
        - Pickup
      summary: ລາຍລະອຽດວຽກເຂົ້າຮັບເຄື່ອງ
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: Pickup job id
      responses:
        '200':
          description: Pickup detail
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/PickupListItem'
  /user/address/types:
    get:
      tags:
        - User Address
      summary: ລາຍການປະເພດທີ່ຢູ່
      responses:
        '200':
          description: Address types
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_NamedList'
  /user/address/list:
    get:
      tags:
        - User Address
      summary: ລາຍການທີ່ຢູ່ຂອງຜູ້ເອີ້ນ
      responses:
        '200':
          description: Address list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        description: Saved addresses
                        items:
                          $ref: '#/components/schemas/UserAddressItem'
  /user/address/detail:
    get:
      tags:
        - User Address
      summary: ລາຍລະອຽດທີ່ຢູ່
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: Address id
        - in: query
          name: include_address_detail
          schema:
            type: boolean
          description: Include resolved province/district names
      responses:
        '200':
          description: ລາຍລະອຽດທີ່ຢູ່
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/UserAddressItem'
  /user/address/add:
    put:
      tags:
        - User Address
      summary: ເພີ່ມທີ່ຢູ່
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAddress'
      responses:
        '200':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          sender_addr_id:
                            type: integer
                            description: Newly created address id
  /user/address/update:
    post:
      tags:
        - User Address
      summary: ແກ້ໄຂທີ່ຢູ່
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - type: object
                  required:
                    - id
                  properties:
                    id:
                      type: integer
                      description: Address id to update
                - $ref: '#/components/schemas/UserAddress'
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
  /user/address/delete:
    delete:
      tags:
        - User Address
      summary: ລຶບທີ່ຢູ່
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: Address id
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
  /dropoff/list:
    get:
      tags:
        - Drop-off — Profile
      summary: ຈຸດ Drop-off ທີ່ພະນັກງານຄົນນີ້ດູແລ
      description: Active drop-offs linked to the authenticated staff (`db_user_drop_off`).
      responses:
        '200':
          description: Responsible drop-offs
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        description: Drop-offs the staff may act on
                        items:
                          $ref: '#/components/schemas/DropOffListItem'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/bankAccount:
    get:
      tags:
        - Drop-off — Bank Account
      summary: ເບິ່ງບັນຊີທະນາຄານຫຼ້າສຸດຂອງ Drop-off
      parameters:
        - $ref: '#/components/parameters/DropOffId'
      responses:
        '200':
          description: Bank account (null if none)
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/BankAccount'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      tags:
        - Drop-off — Bank Account
      summary: ສ້າງ/ແກ້ໄຂບັນຊີທະນາຄານຂອງ Drop-off (ກວດສອບໃໝ່ເມື່ອມີການປ່ຽນແປງ)
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - drop_off_id
                - bank_id
                - account_no
                - account_name
                - photo_book_bank
              properties:
                drop_off_id:
                  type: integer
                  description: Target drop-off (must be one you're responsible for)
                bank_id:
                  type: integer
                  description: Bank id (from master)
                account_no:
                  type: string
                  description: ເລກບັນຊີທະນາຄານ
                account_name:
                  type: string
                  description: Bank account holder name
                remark:
                  type: string
                  description: Optional remark
                drop_off_bank_account_id:
                  type: integer
                  description: Provide to update an existing account; omit to create
                photo_book_bank:
                  type: string
                  format: binary
                  description: Bank book photo (required)
      responses:
        '200':
          description: Saved
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          acc_id:
                            type: integer
                            description: Created/updated account id
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/bankAccount/status:
    get:
      tags:
        - Drop-off — Bank Account
      summary: ເບິ່ງສະຖານະການກວດສອບບັນຊີທະນາຄານຂອງ Drop-off
      parameters:
        - $ref: '#/components/parameters/DropOffId'
      responses:
        '200':
          description: Verification status (null if none)
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/BankAccountStatus'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/balance:
    get:
      tags:
        - Drop-off — Wallet
      summary: ຍອດເຄຣດິດຄົງເຫຼືອໃນກະເປົາເງິນ
      parameters:
        - $ref: '#/components/parameters/DropOffId'
      responses:
        '200':
          description: Balance
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/WalletBalance'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/companyAccounts:
    get:
      tags:
        - Drop-off — Wallet
      summary: ບັນຊີບໍລິສັດສຳລັບເຕີມເງິນ
      responses:
        '200':
          description: Company accounts
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        description: Company accounts that accept branch top-up
                        items:
                          $ref: '#/components/schemas/CompanyAccount'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/deposit/genQr:
    post:
      tags:
        - Drop-off — Wallet
      summary: ສ້າງ QR ສຳລັບເຕີມເງິນກະເປົາ
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - acc_id
                - drop_off_id
                - amount
              properties:
                acc_id:
                  type: integer
                  description: Company account id to receive the deposit
                drop_off_id:
                  type: integer
                  description: Drop-off being topped up
                amount:
                  type: number
                  description: ຈຳນວນເງິນທີ່ເຕີມ
      responses:
        '200':
          description: QR generated
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          qr_string:
                            type: string
                            description: EMVCo QR payload to render for the payer
                          ref_1:
                            type: string
                            description: Payment reference number
                          trx_id:
                            type: string
                            description: Transaction id — poll with /deposit/checkQr
                          minutes:
                            type: integer
                            description: QR validity window (minutes)
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/deposit/checkQr:
    post:
      tags:
        - Drop-off — Wallet
      summary: ກວດສອບວ່າຊຳລະ QR ເຕີມເງິນແລ້ວ ຫຼື ຍັງ
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - trx_id
              properties:
                trx_id:
                  type: integer
                  description: Transaction id from /deposit/genQr
      responses:
        '200':
          description: Paid status
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          is_paid:
                            type: boolean
                            description: True once the QR payment is confirmed
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/deposit/slip:
    post:
      tags:
        - Drop-off — Wallet
      summary: ແຈ້ງເຕີມເງິນດ້ວຍສລິບໂອນເງິນ
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - acc_id
                - drop_off_id
                - amount
                - transfer_date
                - transfer_time
                - reference_no
                - slip_image
              properties:
                acc_id:
                  type: integer
                  description: Company account the transfer was sent to
                drop_off_id:
                  type: integer
                  description: Drop-off being topped up
                amount:
                  type: number
                  description: ຈຳນວນເງິນທີ່ເຕີມ
                transfer_date:
                  type: string
                  description: Transfer date (DD/MM/YYYY)
                transfer_time:
                  type: string
                  description: Transfer time (HH:mm)
                reference_no:
                  type: string
                  description: Bank transfer reference
                slip_image:
                  type: string
                  format: binary
                  description: Transfer slip image
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/transactions:
    get:
      tags:
        - Drop-off — Wallet
      summary: ປະຫວັດທຸລະກຳກະເປົາເງິນ (ຕາມຊ່ວງວັນທີ)
      parameters:
        - $ref: '#/components/parameters/DropOffId'
        - in: query
          name: date_start
          schema:
            type: string
          description: ກັ່ນຕອງແຕ່ວັນທີ (DD/MM/YYYY)
        - in: query
          name: date_end
          schema:
            type: string
          description: ກັ່ນຕອງຮອດວັນທີ (DD/MM/YYYY)
        - in: query
          name: paging
          schema:
            type: integer
            default: 0
          description: ໜ້າເລີ່ມທີ່ 0 (20 ລາຍການຕໍ່ໜ້າ)
      responses:
        '200':
          description: Transaction history
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: array
                        description: Wallet transactions, newest first
                        items:
                          $ref: '#/components/schemas/WalletTransaction'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/wallet/summary:
    get:
      tags:
        - Drop-off — Wallet
      summary: ຍອດສະຫຼຸບກະເປົາເງິນ (ເຕີມ & ຊຳລະ) ຕາມຊ່ວງວັນທີ
      description: Returns `sum_deposit` and `sum_payment` only — withdraw totals are not exposed.
      parameters:
        - $ref: '#/components/parameters/DropOffId'
        - in: query
          name: date_start
          schema:
            type: string
          description: ກັ່ນຕອງແຕ່ວັນທີ (DD/MM/YYYY)
        - in: query
          name: date_end
          schema:
            type: string
          description: ກັ່ນຕອງຮອດວັນທີ (DD/MM/YYYY)
      responses:
        '200':
          description: Totals
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          sum_deposit:
                            type: number
                            description: ຍອດເຕີມເງິນລວມ (ອະນຸມັດ/ລໍຖ້າ) ໃນຊ່ວງເວລາ
                          sum_payment:
                            type: number
                            description: ຍອດໃຊ້ຈ່າຍ (ຊຳລະ) ລວມໃນຊ່ວງເວລາ
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/order/create:
    put:
      tags:
        - Drop-off — Order
      summary: ສ້າງອໍເດີ້ແທນຜູ້ສົ່ງທີ່ຈຸດ Drop-off
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - type: object
                  required:
                    - drop_off_id
                  properties:
                    drop_off_id:
                      type: integer
                      description: Drop-off receiving the parcel (must be one you're responsible for)
                - $ref: '#/components/schemas/OrderCreate'
      responses:
        '200':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          order_id:
                            type: integer
                            description: Newly created order id
                          'no':
                            type: string
                            description: Generated order number
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/order/list:
    get:
      tags:
        - Drop-off — Order
      summary: ລາຍການອໍເດີ້ທີ່ພະນັກງານຄົນນີ້ສ້າງ (ຕາມຊ່ວງວັນທີ)
      parameters:
        - in: query
          name: drop_off_id
          schema:
            type: integer
          description: Filter by drop-off
        - in: query
          name: order_no
          schema:
            type: string
          description: Search by order no / receiver / sender name
        - in: query
          name: status
          schema:
            type: integer
          description: Filter by order status
        - in: query
          name: date_start
          schema:
            type: string
          description: ກັ່ນຕອງແຕ່ວັນທີ (DD/MM/YYYY)
        - in: query
          name: date_end
          schema:
            type: string
          description: ກັ່ນຕອງຮອດວັນທີ (DD/MM/YYYY)
        - in: query
          name: paging
          schema:
            type: integer
            default: 0
          description: ໜ້າເລີ່ມທີ່ 0 (20 ລາຍການຕໍ່ໜ້າ)
      responses:
        '200':
          description: Order list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_OrderList'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/order/detail:
    get:
      tags:
        - Drop-off — Order
      summary: ລາຍລະອຽດອໍເດີ້
      parameters:
        - in: query
          name: id
          required: true
          schema:
            type: integer
          description: ລະຫັດອໍເດີ້
      responses:
        '200':
          description: ລາຍລະອຽດອໍເດີ້
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Env_OrderDetail'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /dropoff/order/cancel:
    post:
      tags:
        - Drop-off — Order
      summary: ຍົກເລີກ (ລຶບ) ອໍເດີ້ພາຍໃນເວລາທີ່ກຳນົດ
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - id
              properties:
                id:
                  type: integer
                  description: Order id to cancel
      responses:
        '200':
          $ref: '#/components/responses/OkNull'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: '`Authorization: Bearer <access_token>` from /auth/requestToken.'
  parameters:
    DropOffId:
      in: query
      name: drop_off_id
      required: true
      description: ລະຫັດຈຸດ Drop-off ທີ່ພະນັກງານທີ່ລັອກອິນດູແລ
      schema:
        type: integer
  responses:
    OkNull:
      description: Success (no payload — `data` is null)
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Envelope'
              - type: object
                properties:
                  data:
                    nullable: true
                    description: null on success
                    example: null
    Unauthorized:
      description: Missing/invalid token, or drop-off not permitted for this staff (HTTP 401)
    ParamRequired:
      description: A required parameter is missing (HTTP 400)
  schemas:
    Envelope:
      type: object
      properties:
        data:
          nullable: true
          description: Payload (object or array), or null
        data_total:
          type: integer
          description: Element count when data is an array/object; else 0
          example: 0
        success:
          type: boolean
          description: True on success, false on error
          example: true
        error:
          type: string
          nullable: true
          description: Error message/code when success=false (else null)
          example: null
    Env_Token:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/TokenResponse'
    Env_NamedList:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            data:
              type: array
              description: List of id/name lookup items
              items:
                type: object
                properties:
                  id:
                    type: integer
                    description: ລະຫັດລາຍການ
                  name:
                    type: string
                    description: ຊື່ຕາມພາສາ (ຕາມ Locale header)
    Env_OrderList:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            data:
              type: array
              description: Orders, newest first
              items:
                $ref: '#/components/schemas/OrderListItem'
    Env_OrderDetail:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/OrderDetail'
    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
          description: ໂທເຄັນສຳລັບ Authorization header
        refresh_token:
          type: string
          description: ໂທເຄັນສຳລັບຂໍ access_token ໃໝ່ຜ່ານ /auth/refreshToken
        drop_off_ids:
          type: array
          items:
            type: integer
          description: ມີສະເພາະພະນັກງານ Drop-off — ຈຸດ Drop-off ທີ່ເຮັດລາຍການໄດ້
    DropOffListItem:
      type: object
      properties:
        hub_id:
          type: integer
          description: Parent hub id of this drop-off
        drop_off_id:
          type: integer
          description: ລະຫັດ Drop-off (ໃຊ້ເປັນ drop_off_id ໃນການເອີ້ນອື່ນ)
        drop_off_name:
          type: string
          description: Drop-off name
        drop_off_desc:
          type: string
          description: 'Display label: [id] name'
    BankAccount:
      type: object
      nullable: true
      description: Latest bank account of the drop-off (null if none)
      properties:
        acc_id:
          type: integer
          description: Bank account id
        drop_off_id:
          type: integer
          description: Owning drop-off id
        bank_id:
          type: integer
          description: Bank id
        acc_no:
          type: string
          description: ເລກບັນຊີທະນາຄານ
        acc_name:
          type: string
          description: ຊື່ເຈົ້າຂອງບັນຊີ
        acc_status:
          type: integer
          description: Verification status — 0=wait, 1=approve, 2=reject, 3=disable
        acc_book_image:
          type: string
          description: Bank book image path
        acc_remark:
          type: string
          description: Remark
        request_time:
          type: string
          description: When the account was submitted for verification
        edit_time:
          type: string
          description: Last edit time
        bank_name:
          type: string
          description: (code) localised bank name
    BankAccountStatus:
      type: object
      nullable: true
      description: Verification status of the drop-off's latest bank account (null if none)
      properties:
        acc_status:
          type: integer
          description: 0=wait, 1=approve, 2=reject, 3=disable
        reject_remark:
          type: string
          nullable: true
          description: Reason if rejected
        disable_remark:
          type: string
          nullable: true
          description: Reason if disabled
        bank_name:
          type: string
          description: Localised bank name
    WalletBalance:
      type: object
      properties:
        balance:
          type: number
          description: ເຄຣດິດທີ່ໃຊ້ໄດ້ (ເຄຣດິດປັດຈຸບັນລົບຍອດຖອນທີ່ລໍຖ້າອະນຸມັດ)
        is_low:
          type: boolean
          description: True when balance is at/below the configured minimum-trigger setting
        is_exceed:
          type: boolean
          description: True when balance is <= 0
    CompanyAccount:
      type: object
      properties:
        acc_id:
          type: integer
          description: Company account id (pass as acc_id when depositing)
        bank_id:
          type: integer
          description: Bank id
        acc_no:
          type: string
          description: Company bank account number
        acc_name:
          type: string
          description: Company account name
        is_allow_qr:
          type: boolean
          description: Whether QR payment is enabled for this account
        bank_code:
          type: string
          description: Bank code
        bank_name:
          type: string
          description: Bank name (English)
        acc_desc:
          type: string
          description: 'Display label: (code) acc_no - acc_name'
        acc_desc_2:
          type: string
          nullable: true
          description: '''QR Code Payment'' when QR is allowed, else null'
    WalletTransaction:
      type: object
      properties:
        id:
          type: integer
          description: Transaction id
        type:
          type: integer
          description: 1=deposit, 2=withdraw, 3=usage (payment), 4=commission
        time:
          type: string
          description: Transaction time (DD/MM/YYYY HH:mm)
        'no':
          type: string
          description: Transaction number
        usage_type:
          type: string
          nullable: true
          description: 'For usage rows: ORDER | PICKUP'
        usage_id:
          type: integer
          nullable: true
          description: Linked order/pickup payment id
        usage_no:
          type: string
          nullable: true
          description: Linked order/pickup number
        amount:
          type: number
          description: ຈຳນວນເງິນຂອງທຸລະກຳ
        channel:
          type: integer
          description: 1=qr, 2=slip, 3=credit
        slip_image:
          type: string
          nullable: true
          description: Uploaded slip image path (slip deposits)
        slip_transfer_time:
          type: string
          nullable: true
          description: Slip transfer time
        slip_transfer_amount:
          type: number
          nullable: true
          description: Amount stated on the slip
        slip_transfer_ref:
          type: string
          nullable: true
          description: Slip transfer reference
        trx_id:
          type: integer
          nullable: true
          description: Payment-gateway transaction id (QR)
        trx_ref:
          type: string
          nullable: true
          description: Gateway reference
        trx_no:
          type: string
          nullable: true
          description: Gateway transaction number
        trx_time:
          type: string
          nullable: true
          description: Gateway confirmation time
        trx_amount:
          type: number
          nullable: true
          description: Gateway-confirmed amount
        detail:
          type: string
          nullable: true
          description: Human-readable detail
        remark:
          type: string
          nullable: true
          description: Remark
        verify_status:
          type: integer
          description: 0=wait, 1=pass/approve, 2=reject/fail
        verify_time:
          type: string
          nullable: true
          description: Verification time
        verify_by:
          type: string
          nullable: true
          description: Verifier username
        verify_remark:
          type: string
          nullable: true
          description: Verification remark
        status:
          type: boolean
          description: Row active flag
        add_time:
          type: string
          description: Created time
        add_by:
          type: string
          description: Creator username
        edit_time:
          type: string
          nullable: true
          description: Last edit time
        edit_by:
          type: string
          nullable: true
          description: Last editor username
        balance_after:
          type: number
          nullable: true
          description: Running balance after this transaction
    OrderStatusEvent:
      type: object
      description: One status-history entry
      properties:
        status:
          type: integer
          description: Status code — 0=new, 1=await pickup, 2=picked up, 3=in transit, 4=out for delivery, 5=cancelled, 6=returned, 9=at drop-off, 99=done
        status_time:
          type: string
          description: When the status occurred (DD/MM/YYYY HH:mm)
        detail:
          type: string
          nullable: true
          description: Status detail
        remark:
          type: string
          nullable: true
          description: Remark
    OrderListItem:
      type: object
      properties:
        id:
          type: integer
          description: ລະຫັດອໍເດີ້
        'no':
          type: string
          description: ເລກທີ່ອໍເດີ້
        sender_name:
          type: string
          description: ຊື່ຜູ້ສົ່ງ
        sender_address_id:
          type: integer
          description: Sender address id
        sender_addr:
          type: string
          description: Sender address line
        sender_addr_province:
          type: string
          description: Sender province (localised)
        sender_addr_district:
          type: string
          description: Sender district (localised)
        sender_addr_district_sub:
          type: string
          description: Sender village (localised)
        receiver_name:
          type: string
          description: ຊື່ຜູ້ຮັບ
        receiver_addr:
          type: string
          description: Receiver address line
        receiver_tel:
          type: string
          description: ເບີໂທຜູ້ຮັບ
        price_net_origin:
          type: number
          nullable: true
          description: Net amount collected at origin
        receiver_addr_province:
          type: string
          description: Receiver province (localised)
        receiver_addr_district:
          type: string
          description: Receiver district (localised)
        receiver_addr_district_sub:
          type: string
          description: Receiver village (localised)
        status:
          type: integer
          description: ລະຫັດສະຖານະອໍເດີ້ປັດຈຸບັນ
        add_time:
          type: string
          description: Created time (DD/MM/YYYY HH:mm)
        edit_time:
          type: string
          description: Last edit time
        cod:
          type: boolean
          description: ເປັນອໍເດີ້ COD ຫຼື ບໍ່
        sender_order_no:
          type: string
          nullable: true
          description: The partner's own reference number
        product_total:
          type: string
          description: count_SUMqty, e.g. '2_5' = 2 items, 5 pieces
        sum_paid_at_origin:
          type: number
          nullable: true
          description: Total already paid at origin
    OrderDetail:
      type: object
      properties:
        id:
          type: integer
          description: ລະຫັດອໍເດີ້
        'no':
          type: string
          description: ເລກທີ່ອໍເດີ້
        status:
          type: integer
          description: ລະຫັດສະຖານະອໍເດີ້ປັດຈຸບັນ
        sender_address_id:
          type: integer
          description: Sender address id
        sender_order_no:
          type: string
          nullable: true
          description: Partner's own reference number
        receiver_name:
          type: string
          description: ຊື່ຜູ້ຮັບ
        receiver_addr:
          type: string
          description: Receiver address line
        receiver_tel:
          type: string
          description: ເບີໂທຜູ້ຮັບ
        sender_addr_province:
          type: string
          description: Sender province (localised)
        sender_addr_district:
          type: string
          description: Sender district (localised)
        sender_addr_district_sub:
          type: string
          description: Sender village (localised)
        receiver_addr_province:
          type: string
          description: Receiver province (localised)
        receiver_addr_district:
          type: string
          description: Receiver district (localised)
        receiver_addr_district_sub:
          type: string
          description: Receiver village (localised)
        cod:
          type: boolean
          description: ເປັນອໍເດີ້ COD ຫຼື ບໍ່
        price_net_dest:
          type: number
          description: Net amount to collect at destination
        paid_total:
          type: number
          description: Total paid so far
        hub_src_id:
          type: integer
          nullable: true
          description: Source hub id
        hub_src_code:
          type: string
          nullable: true
          description: Source hub code
        hub_src_name:
          type: string
          nullable: true
          description: Source hub name
        hub_src_zone_name:
          type: string
          nullable: true
          description: Source hub zone name
        hub_dest_id:
          type: integer
          nullable: true
          description: Destination hub id
        hub_dest_code:
          type: string
          nullable: true
          description: Destination hub code
        hub_dest_name:
          type: string
          nullable: true
          description: Destination hub name
        hub_dest_zone_name:
          type: string
          nullable: true
          description: Destination hub zone name
        pickup_req_time:
          type: string
          nullable: true
          description: Pickup requested time
        pickup_pick_time:
          type: string
          nullable: true
          description: Picked-up time
        hub_src_in_time:
          type: string
          nullable: true
          description: Arrived at source hub
        hub_src_out_time:
          type: string
          nullable: true
          description: Left source hub
        dc_in_time:
          type: string
          nullable: true
          description: Arrived at distribution centre
        dc_out_time:
          type: string
          nullable: true
          description: Left distribution centre
        hub_dest_in_time:
          type: string
          nullable: true
          description: Arrived at destination hub
        hub_dest_out_time:
          type: string
          nullable: true
          description: Left destination hub
        on_delivery_time:
          type: string
          nullable: true
          description: Out for delivery time
        delivered_time:
          type: string
          nullable: true
          description: Delivered time
        cancel_time:
          type: string
          nullable: true
          description: Cancelled time
        product_list:
          type: array
          description: Order line items
          items:
            type: object
            properties:
              id:
                type: integer
                description: Order product id
              product_name:
                type: string
                description: Product name
              qty:
                type: integer
                description: Quantity
              weight:
                type: number
                description: Weight (kg)
              width:
                type: number
                description: Width (cm)
              long:
                type: number
                description: Length (cm)
              height:
                type: number
                description: Height (cm)
              service_price:
                type: number
                description: Computed delivery service price for the item
        note_list:
          type: array
          description: Order notes (to rider/hub/deliverer)
          items:
            type: object
            properties:
              type:
                type: string
                description: Note target — TO_RIDER | TO_HUB | TO_DELIVERER
              detail:
                type: string
                description: Note text
        status_list:
          type: array
          description: Status history
          items:
            $ref: '#/components/schemas/OrderStatusEvent'
        photo_list:
          type: array
          description: Proof/parcel photo URLs
          items:
            type: string
            description: Photo URL
        payment_list:
          type: array
          description: Payment records
          items:
            type: object
            properties:
              id:
                type: integer
                description: Payment id
              payment_amount:
                type: number
                description: Amount paid
              payment_at_type:
                type: integer
                description: 1=origin, 2=destination
              channel:
                type: integer
                description: 1=QR, 2=Cash
              verify_status:
                type: integer
                description: 0=wait, 1=approve, 2=reject
        failed_log_list:
          type: array
          description: Delivery-failure entries (if any)
          items:
            type: object
            description: A delivery-failure record
    OrderTracking:
      type: object
      nullable: true
      description: Public tracking view of an order (null if not found)
      properties:
        'no':
          type: string
          description: ເລກທີ່ອໍເດີ້
        receiver_name:
          type: string
          description: ຊື່ຜູ້ຮັບ
        receiver_addr:
          type: string
          description: Receiver address line
        receiver_tel:
          type: string
          description: ເບີໂທຜູ້ຮັບ
        receiver_addr_province:
          type: string
          description: Receiver province (localised)
        receiver_addr_district:
          type: string
          description: Receiver district (localised)
        receiver_addr_district_sub:
          type: string
          description: Receiver village (localised)
        status:
          type: integer
          description: ລະຫັດສະຖານະອໍເດີ້ປັດຈຸບັນ
        add_time:
          type: string
          description: Created time
        pickup_req_time:
          type: string
          nullable: true
          description: Pickup requested time
        pickup_pick_time:
          type: string
          nullable: true
          description: Picked-up time
        hub_src_in_time:
          type: string
          nullable: true
          description: Arrived at source hub
        hub_src_out_time:
          type: string
          nullable: true
          description: Left source hub
        dc_in_time:
          type: string
          nullable: true
          description: Arrived at distribution centre
        dc_out_time:
          type: string
          nullable: true
          description: Left distribution centre
        hub_dest_in_time:
          type: string
          nullable: true
          description: Arrived at destination hub
        hub_dest_out_time:
          type: string
          nullable: true
          description: Left destination hub
        on_delivery_time:
          type: string
          nullable: true
          description: Out for delivery time
        delivered_time:
          type: string
          nullable: true
          description: Delivered time
        cancel_time:
          type: string
          nullable: true
          description: Cancelled time
        cancel_remark:
          type: string
          nullable: true
          description: Cancellation reason
        delivery_level_code:
          type: string
          nullable: true
          description: Service level code
        delivery_level_label:
          type: string
          nullable: true
          description: Service level label
        delivery_level_pending_date:
          type: integer
          nullable: true
          description: Expected days to deliver for the service level
        status_list:
          type: array
          description: Status history
          items:
            $ref: '#/components/schemas/OrderStatusEvent'
        photo_list:
          type: array
          description: Photo URLs
          items:
            type: string
            description: Photo URL
    PickupListItem:
      type: object
      properties:
        pickup_id:
          type: integer
          description: Pickup job id
        'no':
          type: string
          description: Pickup number
        status:
          type: integer
          description: 0=await acceptance, 1=await go, 2=en route, 3=picked up, 4=failed
        sender_name:
          type: string
          description: ຊື່ຜູ້ສົ່ງ
        qty:
          type: integer
          description: Declared parcel quantity
        pkg_qty:
          type: integer
          description: Number of packages
        order_product_qty:
          type: integer
          description: Total product quantity across linked orders
        urgent_qty:
          type: integer
          description: Urgent item count
        sender_addr_province:
          type: string
          description: Pickup province (localised)
        sender_addr_district:
          type: string
          description: Pickup district (localised)
        sender_addr_district_sub:
          type: string
          description: Pickup village (localised)
        add_time:
          type: string
          description: Created time
        edit_time:
          type: string
          description: Last edit time
    UserAddressItem:
      type: object
      properties:
        sender_addr_id:
          type: integer
          description: Address id
        sender_addr_name:
          type: string
          description: Contact name at this address
        sender_addr_tel:
          type: string
          description: Contact phone
        sender_addr:
          type: string
          description: Address line
        sender_addr_province:
          type: integer
          description: ລະຫັດແຂວງ
        sender_addr_district:
          type: integer
          description: ລະຫັດເມືອງ
        sender_addr_district_sub:
          type: integer
          description: Village (district-sub) id
        province_name:
          type: string
          description: Province name (localised)
        district_name:
          type: string
          description: District name (localised)
        district_sub_name:
          type: string
          description: Village name (localised)
        sender_addr_postcode:
          type: string
          description: Postal code
        sender_addr_type_id:
          type: integer
          description: Address type — 0=other,1=home,2=building,3=warehouse,4=factory
        sender_addr_status:
          type: integer
          description: 1=active, 0=inactive
        sender_addr_is_default:
          type: boolean
          description: Whether this is the default address
        sender_addr_is_show:
          type: boolean
          description: Whether the address is shown to the user
        sender_addr_location:
          type: string
          description: Geo location as 'lat,lng'
    OrderCreate:
      type: object
      required:
        - sender_addr_id
        - service_type
        - product_list
      properties:
        sender_id:
          type: integer
          description: Sender id (resolved from the token for sender principals)
        sender_addr_id:
          type: integer
          description: Origin/sender address id
        service_type:
          type: integer
          description: Delivery service type id
        receive_id:
          type: integer
          description: Existing receiver/customer id (optional)
        receive_name:
          type: string
          description: ຊື່ຜູ້ຮັບ
        receive_phone_no:
          type: string
          description: ເບີໂທຜູ້ຮັບ
        receive_address:
          type: string
          description: Receiver address line
        receive_province:
          type: integer
          description: Receiver province id
        receive_district:
          type: integer
          description: Receiver district id
        receive_district_sub:
          type: integer
          description: Receiver village (district-sub) id
        sender_order_no:
          type: string
          description: Your own reference number
        note_rider:
          type: string
          description: Note to the pickup rider
        note_hub:
          type: string
          description: Note to the hub
        note_deliverer:
          type: string
          description: Note to the deliverer
        product_list:
          type: array
          description: Parcel line items
          items:
            type: object
            properties:
              product_name:
                type: string
                description: Product name
              qty:
                type: integer
                description: Quantity
              weight:
                type: number
                description: Weight (kg)
              width:
                type: number
                description: Width (cm)
              long:
                type: number
                description: Length (cm)
              height:
                type: number
                description: Height (cm)
              price:
                type: number
                description: Declared goods value
              is_cod:
                type: boolean
                description: Whether this item is COD
    UserAddress:
      type: object
      required:
        - type_id
        - name
        - tel
        - address
        - province_id
        - district_id
        - district_sub_id
      properties:
        type_id:
          type: integer
          description: Address type — 0=other,1=home,2=building,3=warehouse,4=factory
        name:
          type: string
          description: Contact name
        tel:
          type: string
          description: Contact phone
        address:
          type: string
          description: Address line
        province_id:
          type: integer
          description: ລະຫັດແຂວງ
        district_id:
          type: integer
          description: ລະຫັດເມືອງ
        district_sub_id:
          type: integer
          description: Village (district-sub) id
        post_code:
          type: string
          description: Postal code
        location:
          type: string
          description: Geo location as 'lat,lng'
        is_default:
          type: boolean
          description: Set as default address
