openapi: 3.0.3
info:
  title: eSIM Dealer Open API
  version: 1.0.0
  description: |
    经销商 Open API。AppKey 绑定租户，无需 shopId；下单使用 BALANCE 钱包。

    **鉴权**：见文档「鉴权与签名」。Header：`RT-AccessCode`、`RT-RequestID`、`RT-Timestamp`、`X-Signature`。

    **响应**：`{ "code": "000000", "message": "success", "data": ... }`

servers:
  - url: https://api.example.com
    description: 生产环境（由平台提供实际域名）

tags:
  - name: System
    description: 系统与连通性
  - name: Package
    description: 可售套餐查询
  - name: Order
    description: 下单、查单、退款
  - name: Profile
    description: eSIM Profile 管理与用量
  - name: Account
    description: BALANCE 钱包余额与充值
  - name: Webhook
    description: 订单事件回调配置
  - name: Region
    description: 支持的国家/地区

paths:
  /open-api/v1/health:
    post:
      tags: [System]
      summary: 连通性检查
      operationId: health
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
            example: {}
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultHealth'

  /open-api/v1/package/list:
    post:
      tags: [Package]
      summary: 套餐列表
      operationId: listPackages
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PackageListRequest'
            example:
              pageNum: 1
              pageSize: 20
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultPackagePage'

  /open-api/v1/esim/order:
    post:
      tags: [Order]
      summary: 下单
      operationId: createOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
            example:
              transactionId: TX202506180001
              packageCode: PKG-US-1GB-7D
              quantity: 1
              notifyEmail: api@example.com
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultOrder'

  /open-api/v1/esim/query:
    post:
      tags: [Order]
      summary: 查单
      operationId: queryOrder
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueryOrderRequest'
            example:
              transactionId: TX202506180001
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultOrderDetail'

  /open-api/v1/esim/refund:
    post:
      tags: [Order]
      summary: 订单退款
      operationId: refundOrder
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefundRequest'
            example:
              orderNo: ORD202506180001
              remark: customer request
            examples:
              fullRefund:
                summary: 整单退款
                value:
                  orderNo: ORD202506180001
                  remark: customer request
              partialByItem:
                summary: 按子项部分退
                value:
                  orderNo: ORD202506180001
                  remark: partial item refund
                  items:
                    - itemNo: ITEM202506180001-1
              partialByProfile:
                summary: 按 Profile 部分退
                value:
                  orderNo: ORD202506180001
                  remark: partial profile refund
                  items:
                    - itemNo: ITEM202506180001-1
                      profileTokens:
                        - "8901234567890123456"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultRefund'

  /open-api/v1/esim/profile/list:
    post:
      tags: [Profile]
      summary: Profile 列表
      operationId: listProfiles
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileListRequest'
            example:
              pageNum: 1
              pageSize: 20
              orderNo: ORD202506180001
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultProfilePage'

  /open-api/v1/esim/profile/cancel:
    post:
      tags: [Profile]
      summary: 取消 Profile
      operationId: cancelProfile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileKeyRequest'
            example:
              iccid: "8900000000000000000"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultProfileAction'

  /open-api/v1/esim/profile/revoke:
    post:
      tags: [Profile]
      summary: 撤销 Profile
      operationId: revokeProfile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileKeyRequest'
            example:
              iccid: "8900000000000000000"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultProfileAction'

  /open-api/v1/esim/profile/suspend:
    post:
      tags: [Profile]
      summary: 暂停 Profile
      description: 部分套餐不支持，返回业务错误
      operationId: suspendProfile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileKeyRequest'
            example:
              iccid: "8900000000000000000"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultProfileAction'

  /open-api/v1/esim/profile/unsuspend:
    post:
      tags: [Profile]
      summary: 恢复 Profile
      operationId: unsuspendProfile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileKeyRequest'
            example:
              iccid: "8900000000000000000"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultProfileAction'

  /open-api/v1/esim/profile/usage:
    post:
      tags: [Profile]
      summary: 用量查询
      operationId: queryUsage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileKeyRequest'
            example:
              iccid: "8900000000000000000"
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultUsage'

  /open-api/v1/account/balance:
    post:
      tags: [Account]
      summary: 余额查询
      operationId: queryBalance
      requestBody:
        content:
          application/json:
            schema:
              type: object
            example: {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultBalance'

  /open-api/v1/account/topup:
    post:
      tags: [Account]
      summary: 提交充值申请
      description: 线下转账凭证，平台审核后入账
      operationId: submitTopUp
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TopUpRequest'
            example:
              transactionId: TOPUP202506180001
              amount: 100.00
              currency: USD
              voucherUrl: https://example.com/voucher/abc.jpg
              remark: wire transfer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultTopUp'

  /open-api/v1/webhook/set:
    post:
      tags: [Webhook]
      summary: 设置回调 URL
      operationId: setWebhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookSetRequest'
            example:
              callbackUrl: https://example.com/openapi/webhook
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultWebhook'

  /open-api/v1/webhook/query:
    post:
      tags: [Webhook]
      summary: 查询回调 URL
      operationId: queryWebhook
      requestBody:
        content:
          application/json:
            schema:
              type: object
            example: {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultWebhook'

  /open-api/v1/region/list:
    post:
      tags: [Region]
      summary: 支持的国家/地区
      operationId: listRegions
      requestBody:
        content:
          application/json:
            schema:
              type: object
            example: {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenApiResultRegionList'

components:
  schemas:
    OpenApiResultHealth:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data:
              type: object
              description: 连通性检查结果
              properties:
                status:
                  type: string
                  example: UP
                  description: 服务状态，固定返回 UP
                tenantId:
                  type: string
                  description: 当前 AppKey 绑定的租户 ID
                clientName:
                  type: string
                  description: API 凭证名称（平台开通时配置）

    OpenApiResultBase:
      type: object
      description: 统一响应包装
      properties:
        code:
          type: string
          example: '000000'
          description: 业务码，000000 表示成功；鉴权/业务错误见文档「错误码」
        message:
          type: string
          example: success
          description: 结果说明，失败时为错误描述

    MoneyAmount:
      type: string
      description: 金额，JSON 中为字符串两位小数
      example: '1.60'

    SnowflakeId:
      oneOf:
        - type: integer
          format: int64
        - type: string
      description: 64 位主键 ID；超过 JS Number 安全整数范围时序列化为 string
      example: '2072635013959573507'

    NullableString:
      type: string
      nullable: true

    PackageListRequest:
      type: object
      description: 套餐列表查询
      properties:
        pageNum:
          type: integer
          default: 1
          minimum: 1
          description: 页码，从 1 开始
        pageSize:
          type: integer
          default: 50
          maximum: 200
          description: 每页条数，默认 50，最大 200
        packageCode:
          type: string
          description: 可选，按套餐编码精确筛选

    CreateOrderRequest:
      type: object
      description: 创建 eSIM 订单（BALANCE 钱包扣款）
      required: [transactionId, packageCode, quantity, notifyEmail]
      example:
        transactionId: TX202506180001
        packageCode: PKG-US-1GB-7D
        quantity: 1
        notifyEmail: api@example.com
      properties:
        transactionId:
          type: string
          maxLength: 64
          description: 外部幂等单号，同一租户下不可重复
        packageCode:
          type: string
          description: 套餐编码，来自 package/list
        quantity:
          type: integer
          minimum: 1
          maximum: 500
          description: 购买数量（每张 eSIM 一条 Profile）
        notifyEmail:
          type: string
          format: email
          description: 订单通知邮箱
        estimatedUseTime:
          type: string
          format: date
          description: 预计出行日 yyyy-MM-dd；estimatedUseTimeRequired=true 的套餐必填

    QueryOrderRequest:
      type: object
      description: 查单；orderNo 与 transactionId 至少填一项
      properties:
        orderNo:
          type: string
          description: 平台订单号
        transactionId:
          type: string
          description: 下单时传入的幂等单号

    RefundRequest:
      type: object
      description: 订单退款；整单或按子项/Profile 部分退
      example:
        orderNo: ORD202506180001
        remark: customer request
        items:
          - itemNo: ITEM202506180001-1
            profileTokens:
              - "8901234567890123456"
      properties:
        orderNo:
          type: string
          description: 平台订单号（与 transactionId 二选一或同时传）
        transactionId:
          type: string
          description: 外部幂等单号
        remark:
          type: string
          description: 退款备注，写入订单日志
        items:
          type: array
          description: 部分退款时指定子项；空则按整单规则处理
          items:
            $ref: '#/components/schemas/RefundItemRequest'

    RefundItemRequest:
      type: object
      description: 按订单子项退款
      properties:
        itemNo:
          type: string
          description: 子项编号，来自查单 items[].itemNo
        profileTokens:
          type: array
          items: { type: string }
          description: iccid 或 esimTranNo 列表；空则退该子项下全部 Profile

    ProfileListRequest:
      type: object
      description: Profile 分页查询，支持多条件组合
      properties:
        pageNum:
          type: integer
          description: 页码，默认 1
        pageSize:
          type: integer
          description: 每页条数，默认 50
        orderNo:
          type: string
          description: 按平台订单号筛选
        transactionId:
          type: string
          description: 按外部幂等单号筛选
        iccid:
          type: string
          description: 按 ICCID 精确筛选
        esimTranNo:
          type: string
          description: 按 eSIM 交易号精确筛选

    ProfileKeyRequest:
      type: object
      description: Profile 操作定位；profileId、iccid、esimTranNo 至少填一项
      properties:
        profileId:
          $ref: '#/components/schemas/SnowflakeId'
          description: Profile 主键 ID
        iccid:
          type: string
          description: SIM 卡 ICCID
        esimTranNo:
          type: string
          description: eSIM 交易号 / 安装标识

    TopUpRequest:
      type: object
      description: 线下充值申请，平台审核后入账 BALANCE 钱包
      required: [transactionId, amount, voucherUrl]
      properties:
        transactionId:
          type: string
          description: 外部幂等单号
        amount:
          $ref: '#/components/schemas/MoneyAmount'
          description: 充值金额
        currency:
          type: string
          default: USD
          description: 币种，默认 USD
        voucherUrl:
          type: string
          description: 转账凭证图片 URL（可访问的公网地址）
        remark:
          type: string
          description: 备注说明

    WebhookSetRequest:
      type: object
      description: 设置订单事件回调地址
      required: [callbackUrl]
      properties:
        callbackUrl:
          type: string
          format: uri
          description: HTTPS 回调 URL，接收 ORDER_PAID / DELIVERY_UPDATED / REFUND_COMPLETED（对外仅 3 种 eventType；多种履约变更聚合为 DELIVERY_UPDATED，详见文档 Webhook 章节）

    PackageVo:
      type: object
      description: 可售 eSIM 套餐
      properties:
        packageCode:
          type: string
          description: 套餐编码，下单时使用
        packageName:
          type: string
          description: 套餐名称
        subName:
          type: string
          description: 副标题
        description:
          type: string
          description: 套餐描述
        coverUrl:
          type: string
          description: 封面图 URL
        platformPackageName:
          type: string
          description: 平台原始套餐名称
        price:
          $ref: '#/components/schemas/MoneyAmount'
          description: 结算价
        retailPrice:
          $ref: '#/components/schemas/MoneyAmount'
          description: 建议零售价
        currency:
          type: string
          description: 价格币种，如 USD
        planMode:
          type: string
          description: 套餐模式，如 TOTAL（总量）/ DAILY（日包）
        validDays:
          type: integer
          format: int64
          description: 激活后有效天数
        unusedValidDays:
          type: integer
          format: int64
          description: 未激活失效天数
        totalVolumeBytes:
          type: integer
          format: int64
          description: 总流量（字节）；日包为每日高速流量上限
        dailyHighSpeedBytes:
          type: integer
          format: int64
          description: 日包每日高速流量（字节）
        isUnlimitedTotal:
          type: integer
          description: 是否无限流量套餐：0 否 1 是
        throttleKbps:
          type: integer
          description: 达量后限速（Kbps），0 表示不限速或未配置
        countryCodes:
          type: string
          description: 覆盖国家 ISO3166-1 alpha-2，逗号分隔
        networkSpeed:
          type: string
          description: 网络制式快照，如 4G/5G
        ipExport:
          type: string
          description: 流量出口国家/地区
        isRegional:
          type: integer
          description: 是否区域类套餐：0 单国 1 区域
        speedLimitRule:
          type: string
          description: 限速规则说明（人类可读）
        estimatedUseTimeRequired:
          type: boolean
          description: 下单是否必须填写 estimatedUseTime
        estimatedUseTimeGapHours:
          type: integer
          description: 预计出行日距今天最小间隔（小时）
        bizType:
          type: integer
          description: 业务类型，与 product_type 字典一致
        isRechargeable:
          type: integer
          description: 是否可复充：0 否 1 是
        rechargeableSeriesId:
          type: string
          description: 可复充关联系列 ID
        rechargeableSeriesName:
          type: string
          description: 可复充关联系列名称
        product:
          $ref: '#/components/schemas/PackageProductVo'
        coverage:
          type: array
          description: 覆盖明细
          items: { $ref: '#/components/schemas/CoverageVo' }

    PackageProductVo:
      type: object
      description: 套餐所属产品（系列 / SPU）
      properties:
        productCode:
          type: string
          description: 产品编码
        productName:
          type: string
          description: 产品名称
        coverUrl:
          type: string
          description: 产品封面图 URL
        countryCodes:
          type: string
          description: 覆盖国家 ISO2 快照，逗号分隔
        networkSpeed:
          type: string
          description: 网络制式
        coverage:
          type: array
          description: 产品级覆盖明细
          items: { $ref: '#/components/schemas/CoverageVo' }

    CoverageVo:
      type: object
      description: 覆盖国家及运营商
      properties:
        countryCode:
          type: string
          description: ISO3166-1 alpha-2 国家码
        countryName:
          type: string
          description: 国家中文名
        countryNameEn:
          type: string
          description: 国家英文名
        flagEmoji:
          type: string
          description: 国旗 Emoji
        apn:
          type: string
          description: 默认 APN
        operators:
          type: array
          description: 当地运营商列表
          items:
            $ref: '#/components/schemas/OperatorVo'

    OperatorVo:
      type: object
      description: 覆盖国家下的运营商
      properties:
        operatorName:
          type: string
          description: 运营商名称
        networkType:
          type: string
          description: 网络类型，如 4G / 5G

    PageMeta:
      type: object
      description: 分页元数据
      properties:
        total:
          type: integer
          description: 总记录数
        pageNum:
          type: integer
          description: 当前页码
        pageSize:
          type: integer
          description: 每页条数

    OpenApiResultPackagePage:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data:
              allOf:
                - $ref: '#/components/schemas/PageMeta'
                - type: object
                  description: 分页套餐列表
                  properties:
                    list:
                      type: array
                      description: 当前页套餐列表
                      items: { $ref: '#/components/schemas/PackageVo' }

    OrderVo:
      type: object
      description: 下单结果
      properties:
        orderNo:
          type: string
          description: 平台订单号
        transactionId:
          type: string
          description: 外部幂等单号
        status:
          type: string
          enum: [PAID, PENDING]
          description: 订单状态摘要；PAID=已扣款，PENDING=待支付/处理中
        totalAmount:
          $ref: '#/components/schemas/MoneyAmount'
          description: 订单总金额
        currency:
          type: string
          description: 币种

    OpenApiResultOrder:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/OrderVo'

    OrderDetailVo:
      type: object
      description: 订单详情
      properties:
        orderId:
          $ref: '#/components/schemas/SnowflakeId'
          description: 订单主键 ID
        orderNo:
          type: string
          description: 平台订单号
        transactionId:
          type: string
          description: 外部幂等单号
        orderSource:
          type: string
          description: 订单来源，Open API 订单为 OPEN_API
        payStatus:
          type: string
          description: 支付状态：PENDING / PAID / FAILED / REFUNDED
        deliveryStatus:
          type: string
          description: 发货状态：PENDING / PARTIAL / DELIVERED / FAILED
        orderStatus:
          type: string
          description: 订单状态：UNPAID / PAID / FULFILLING / COMPLETED / CANCELLED / REFUNDING / REFUNDED / FAILED
        totalAmount:
          $ref: '#/components/schemas/MoneyAmount'
          description: 订单总金额
        currency:
          type: string
          description: 币种
        payTime:
          type: string
          format: date-time
          nullable: true
          description: 支付完成时间（UTC ISO8601）；未支付时为 null
        items:
          type: array
          description: 订单子项列表
          items: { $ref: '#/components/schemas/OrderItemVo' }

    OrderItemVo:
      type: object
      description: 订单子项（一个套餐一行）
      properties:
        itemNo:
          type: string
          description: 子项编号
        packageCode:
          type: string
          description: 套餐编码
        packageName:
          type: string
          description: 套餐名称
        quantity:
          type: integer
          description: 购买数量
        itemStatus:
          type: string
          description: 子项状态：PENDING / DELIVERED / ACTIVATING / ACTIVATED / FAILED / REFUNDED
        iccid:
          $ref: '#/components/schemas/NullableString'
          description: 首张卡 ICCID 摘要；未发货时为 null
        qrCodeUrl:
          $ref: '#/components/schemas/NullableString'
          description: eSIM 安装二维码 URL；未发货时为 null
        activationCode:
          $ref: '#/components/schemas/NullableString'
          description: SM-DP+ 激活码；未发货时为 null
        profiles:
          type: array
          description: 每张 eSIM 卡明细（quantity>1 时多条）
          items:
            $ref: '#/components/schemas/ProfileVo'

    OpenApiResultOrderDetail:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/OrderDetailVo' }

    RefundVo:
      type: object
      description: 退款结果
      properties:
        orderNo:
          type: string
          description: 平台订单号
        transactionId:
          type: string
          description: 外部幂等单号
        status:
          type: string
          enum: [REFUNDED, REFUNDING]
          description: REFUNDED=已入账；REFUNDING=退款处理中
        refundAmount:
          $ref: '#/components/schemas/MoneyAmount'
          description: 本次或累计退款金额
        currency:
          type: string
          description: 币种
        items:
          type: array
          description: 各子项退款状态
          items:
            $ref: '#/components/schemas/RefundItemResultVo'

    RefundItemResultVo:
      type: object
      description: 子项退款结果
      properties:
        itemNo:
          type: string
          description: 子项编号
        refundStatus:
          type: string
          enum: [PENDING, COMPLETED]
          description: PENDING=处理中；COMPLETED=已完成

    OpenApiResultRefund:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/RefundVo' }

    ProfileVo:
      type: object
      description: eSIM Profile（单张卡）
      properties:
        profileId:
          $ref: '#/components/schemas/SnowflakeId'
          description: Profile 主键 ID
        orderNo:
          type: string
          description: 所属平台订单号
        transactionId:
          type: string
          description: 所属外部幂等单号
        itemNo:
          type: string
          description: 所属订单子项编号
        packageCode:
          type: string
          description: 套餐编码
        packageName:
          type: string
          description: 套餐名称
        iccid:
          type: string
          description: SIM 卡 ICCID
        esimTranNo:
          type: string
          description: eSIM 交易号
        esimStatus:
          type: string
          description: >-
            供应商 eSIM 状态原文（如 NEW / GOT_RESOURCE / IN_USE 等，因渠道而异）。
            Webhook 中与上次快照对比变化时 changeHints 含 ESIM_STATUS_CHANGED
        smdpStatus:
          type: string
          description: SM-DP+ 安装过程状态（因渠道而异）；变化时 changeHints 含 SMDP_STATUS_CHANGED
        cancelled:
          type: boolean
          description: 是否已取消/撤销；由 false→true 时 changeHints 含 PROFILE_CANCELLED
        qrCodeUrl:
          type: string
          description: 安装二维码 URL；首次出现时 changeHints 含 QR_CODE_READY
        activationCode:
          type: string
          description: SM-DP+ 激活码；首次出现时 changeHints 含 ACTIVATION_CODE_READY
        apn:
          type: string
          description: 默认 APN
        activated:
          type: boolean
          description: 是否已激活（安装/开始使用）
        lifecycleStatus:
          type: string
          enum: [PENDING, DELIVERED, ACTIVATING, ACTIVATED, CANCELLED]
          description: >-
            平台归一化 Profile 生命周期；变化时 changeHints 含 PROFILE_LIFECYCLE_CHANGED。
            PENDING=待发码；DELIVERED=已发码；ACTIVATING=安装/激活中；ACTIVATED=已激活；CANCELLED=已取消
        planUseStatus:
          type: string
          enum: [STARTED, ENDED]
          description: 套餐使用状态；变为 STARTED/ENDED 时 changeHints 含 PLAN_USE_STARTED / PLAN_USE_ENDED
        planUseStartTime:
          type: string
          description: 套餐使用开始时间（ISO8601）
        planUseEndTime:
          type: string
          description: 套餐使用结束时间（ISO8601）
        profileStatus:
          type: integer
          description: 供应商 Profile 状态码（整数，因渠道而异）
        dataUsageBytes:
          type: integer
          format: int64
          description: 已用流量（字节，Webhook 缓存值）；变化时 changeHints 含 USAGE_UPDATED
        totalDataBytes:
          type: integer
          format: int64
          description: 总流量（字节）
        remainDataBytes:
          type: integer
          format: int64
          description: 剩余流量（字节）

    OpenApiResultProfilePage:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data:
              allOf:
                - $ref: '#/components/schemas/PageMeta'
                - type: object
                  properties:
                    list:
                      type: array
                      description: Profile 列表
                      items: { $ref: '#/components/schemas/ProfileVo' }

    ProfileActionVo:
      type: object
      description: Profile 操作结果（取消/撤销/暂停/恢复）
      properties:
        profileId:
          $ref: '#/components/schemas/SnowflakeId'
          description: Profile 主键 ID
        iccid:
          type: string
          description: SIM 卡 ICCID
        esimTranNo:
          type: string
          description: eSIM 交易号
        status:
          type: string
          description: 操作后 Profile 状态
        asyncStatus:
          type: string
          enum: [PENDING, COMPLETED]
          description: 异步操作状态；PENDING 表示仍在处理中

    OpenApiResultProfileAction:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/ProfileActionVo' }

    UsageVo:
      type: object
      description: Profile 实时用量
      properties:
        profileId:
          $ref: '#/components/schemas/SnowflakeId'
          description: Profile 主键 ID
        iccid:
          type: string
          description: SIM 卡 ICCID
        esimTranNo:
          type: string
          description: eSIM 交易号
        dataUsageBytes:
          type: integer
          format: int64
          description: 已用流量（字节）
        totalDataBytes:
          type: integer
          format: int64
          description: 套餐总流量（字节）
        usagePercent:
          $ref: '#/components/schemas/MoneyAmount'
          description: 使用百分比 0–100
        noUsageRecord:
          type: boolean
          description: true 表示暂无用量记录（未激活或未上报）

    OpenApiResultUsage:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/UsageVo' }

    BalanceVo:
      type: object
      description: BALANCE 钱包余额
      properties:
        currency:
          type: string
          description: 币种
        availableBalance:
          $ref: '#/components/schemas/MoneyAmount'
          description: 可用余额
        frozenBalance:
          $ref: '#/components/schemas/MoneyAmount'
          description: 冻结金额（下单预占等）

    OpenApiResultBalance:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/BalanceVo' }

    TopUpVo:
      type: object
      description: 充值申请结果
      properties:
        applyId:
          $ref: '#/components/schemas/SnowflakeId'
          description: 充值申请主键 ID
        requestNo:
          type: string
          description: 平台申请单号
        transactionId:
          type: string
          description: 外部幂等单号
        status:
          type: string
          enum: [PENDING, APPROVED, REJECTED]
          description: PENDING=待审核；APPROVED=已通过；REJECTED=已拒绝

    OpenApiResultTopUp:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/TopUpVo' }

    WebhookVo:
      type: object
      description: 当前配置的回调地址
      properties:
        callbackUrl:
          type: string
          description: HTTPS 回调 URL

    OpenApiResultWebhook:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data: { $ref: '#/components/schemas/WebhookVo' }

    RegionVo:
      type: object
      description: 支持的国家/地区
      properties:
        countryCode:
          type: string
          description: ISO3166-1 alpha-2 国家码
        countryName:
          type: string
          description: 国家中文名
        countryNameEn:
          type: string
          description: 国家英文名
        flagEmoji:
          type: string
          description: 国旗 Emoji

    OpenApiResultRegionList:
      allOf:
        - $ref: '#/components/schemas/OpenApiResultBase'
        - type: object
          properties:
            data:
              type: array
              description: 国家/地区列表
              items: { $ref: '#/components/schemas/RegionVo' }

    WebhookCallbackPayload:
      type: object
      description: 出站 Webhook POST Body
      properties:
        eventType:
          type: string
          enum: [ORDER_PAID, DELIVERY_UPDATED, REFUND_COMPLETED]
          description: >-
            事件类型（对外仅 3 种）。ORDER_PAID=已支付；DELIVERY_UPDATED=发货/Profile 变更（含 iccid 就绪、安装状态、
            套餐启停、流量/有效期告警等，均聚合为此类型）；REFUND_COMPLETED=退款入账完成
        transactionId:
          type: string
          description: 外部幂等单号
        orderNo:
          type: string
          description: 平台订单号
        orderId:
          $ref: '#/components/schemas/SnowflakeId'
          description: 订单主键 ID
        payStatus:
          type: string
          description: 支付状态：PENDING / PAID / FAILED / REFUNDED
        deliveryStatus:
          type: string
          enum: [PENDING, PARTIAL, DELIVERED, FAILED, UNKNOWN]
          description: 发货状态；变化时 changeHints 含 DELIVERY_STATUS_CHANGED
        orderStatus:
          type: string
          enum: [UNPAID, PAID, FULFILLING, COMPLETED, CANCELLED, REFUNDING, REFUNDED, FAILED, UNKNOWN]
          description: 订单状态；变化时 changeHints 含 ORDER_STATUS_CHANGED
        refundAmount:
          $ref: '#/components/schemas/MoneyAmount'
          description: 累计已退金额，REFUND_COMPLETED 事件时有值
        changeHints:
          type: array
          description: >-
            相对本订单同 eventType 上一次成功投递快照的变更摘要（平台计算）。
            DELIVERY_UPDATED 时用于识别本次推送含义；详见 Webhook 文档 changeHints 表
          items:
            type: string
            enum:
              - DELIVERY_STATUS_CHANGED
              - ORDER_STATUS_CHANGED
              - ITEM_STATUS_CHANGED
              - ICCID_READY
              - QR_CODE_READY
              - ACTIVATION_CODE_READY
              - PROFILE_LIFECYCLE_CHANGED
              - ESIM_STATUS_CHANGED
              - SMDP_STATUS_CHANGED
              - PLAN_USE_STARTED
              - PLAN_USE_ENDED
              - USAGE_UPDATED
              - PROFILE_CANCELLED
              - REFUND_AMOUNT_UPDATED
              - ORDER_SNAPSHOT_SYNC
              - ORDER_PAID
              - REFUND_COMPLETED
        currency:
          type: string
          description: 币种
        items:
          type: array
          description: 订单子项快照（含 Profile 摘要）
          items: { $ref: '#/components/schemas/OrderItemVo' }
