{
  "openapi": "3.0.3",
  "info": {
    "title": "SoraPay API",
    "version": "1.0.0",
    "description": "API SoraPay — agregator QRIS dinamis model akun pusat. Semua error berbentuk {\"error\": \"kode\"}. Nominal selalu rupiah bulat (integer)."
  },
  "servers": [
    {
      "url": "https://api.sorapay.biz.id"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerJWT": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    }
  },
  "paths": {
    "/healthz": {
      "get": {
        "summary": "Status kesehatan layanan",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/register": {
      "post": {
        "summary": "Daftar akun merchant baru (wajib verifikasi email)",
        "security": [],
        "responses": {
          "201": {
            "description": "Akun dibuat: {merchant, api_key (sekali tampil), pending_token}. pending_token adalah JWT ber-purpose pending_verification (24 jam, BUKAN token sesi) untuk GET /v1/auth/verification-status dan POST /v1/auth/complete-registration."
          },
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/login": {
      "post": {
        "summary": "Masuk; respons bisa {token,merchant} atau {totp_required,ticket}",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/login/totp": {
      "post": {
        "summary": "Selesaikan login dengan kode TOTP (langkah kedua)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/forgot-password": {
      "post": {
        "summary": "Minta email reset kata sandi (respons selalu generik)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/reset-password": {
      "post": {
        "summary": "Reset kata sandi dengan token dari email",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/reset-password/check": {
      "post": {
        "summary": "Periksa token reset tanpa mengonsumsinya",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/verify-email": {
      "post": {
        "summary": "Verifikasi email pendaftaran dengan token",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/resend-verification": {
      "post": {
        "summary": "Kirim ulang email verifikasi",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/verification-status": {
      "get": {
        "summary": "Status verifikasi pendaftaran (Bearer pending_token dari register)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "{email_verified, account_status: unverified|pending_review|active|disabled} milik token tertunda itu sendiri"
          },
          "401": {
            "description": "Token tertunda tidak sah/kedaluwarsa/dicabut (unauthorized | token_revoked)"
          },
          "429": {
            "description": "Terlalu banyak permintaan (too_many_attempts)"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/auth/complete-registration": {
      "post": {
        "summary": "Selesaikan pendaftaran menjadi sesi penuh (Bearer pending_token, sekali pakai)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "Sama seperti login: {token, merchant} — atau {totp_required, ticket} bila akun memakai TOTP (lanjutkan di /v1/auth/login/totp). Pertukaran sukses menaikkan token_version: pending_token mati seketika."
          },
          "401": {
            "description": "Token tertunda tidak sah/kedaluwarsa/dicabut (unauthorized | token_revoked)"
          },
          "403": {
            "description": "Gerbang akun, kode sama seperti login (email_not_verified | account_pending_review | account_disabled)"
          },
          "429": {
            "description": "Terlalu banyak permintaan (too_many_attempts)"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/public/payments/{public_id}": {
      "get": {
        "summary": "Detail pembayaran publik untuk halaman bayar",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "public_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/public/payments/{public_id}/claim": {
      "post": {
        "summary": "Kirim klaim bukti bayar (multipart: note wajib, image opsional <=5MB png/jpeg/webp)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "public_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Profil merchant pemanggil",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/profile": {
      "put": {
        "summary": "Ubah profil (store_name, whatsapp)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/password": {
      "put": {
        "summary": "Ubah kata sandi",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/payout": {
      "put": {
        "summary": "Ubah tujuan penarikan (bank)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/webhook": {
      "put": {
        "summary": "Ubah webhook_url",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/webhook/rotate-secret": {
      "post": {
        "summary": "Rotasi webhook_secret",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/webhook/test": {
      "post": {
        "summary": "Kirim webhook tes ke webhook_url merchant (delivery antre)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/api-key/rotate": {
      "post": {
        "summary": "Rotasi API key (key baru tampil sekali)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/balance": {
      "get": {
        "summary": "Saldo, tertahan, dan tersedia",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/ledger": {
      "get": {
        "summary": "Mutasi ledger dengan saldo berjalan; query: page,page_size,kind,from,to",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/payments": {
      "post": {
        "summary": "Buat pembayaran dari panel",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      },
      "get": {
        "summary": "Daftar pembayaran milik sendiri; query: q,status,from,to,page,page_size -> {payments,total,page,page_size}",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/payments/{id}": {
      "get": {
        "summary": "Detail satu pembayaran milik sendiri (id = public_id atau numerik); 404 bila bukan miliknya",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/payments/export": {
      "get": {
        "summary": "Ekspor CSV pembayaran milik sendiri (filter sama seperti daftar)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/withdrawals": {
      "post": {
        "summary": "Ajukan penarikan",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      },
      "get": {
        "summary": "Daftar penarikan milik sendiri",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/withdrawals/{id}/cancel": {
      "post": {
        "summary": "Batalkan penarikan milik sendiri yang masih requested",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/totp/enroll": {
      "post": {
        "summary": "Mulai pendaftaran TOTP (2FA)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/totp/enable": {
      "post": {
        "summary": "Aktifkan TOTP dengan kode konfirmasi",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/totp/disable": {
      "post": {
        "summary": "Nonaktifkan TOTP",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/delete-request": {
      "post": {
        "summary": "Ajukan penghapusan akun",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/announcements": {
      "get": {
        "summary": "Pengumuman aktif untuk merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/subscription": {
      "get": {
        "summary": "Status langganan merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/claims": {
      "get": {
        "summary": "Klaim bukti bayar pada pembayaran milik sendiri; query: status",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/claims/{id}/approve": {
      "post": {
        "summary": "Setujui klaim (menyelesaikan pembayaran lewat settlement)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/claims/{id}/reject": {
      "post": {
        "summary": "Tolak klaim (note wajib)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/claims/{id}/image": {
      "get": {
        "summary": "Unduh gambar bukti klaim milik sendiri",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/payments": {
      "post": {
        "summary": "Buat pembayaran lewat API key",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "api-key"
        ]
      }
    },
    "/v1/payments/{public_id}": {
      "get": {
        "summary": "Detail pembayaran lewat API key",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "public_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "api-key"
        ]
      }
    },
    "/v1/admin/stats": {
      "get": {
        "summary": "Statistik ringkas operator",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants": {
      "get": {
        "summary": "Daftar merchant + saldo",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}": {
      "get": {
        "summary": "Detail satu merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      },
      "patch": {
        "summary": "Ubah data merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/status": {
      "patch": {
        "summary": "Ubah status merchant (active/disabled)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/approve": {
      "post": {
        "summary": "Setujui merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/reject": {
      "post": {
        "summary": "Tolak merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/reset-password": {
      "post": {
        "summary": "Reset kata sandi merchant oleh admin",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/revoke-sessions": {
      "post": {
        "summary": "Cabut semua sesi merchant",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/adjustments": {
      "post": {
        "summary": "Penyesuaian saldo manual (ledger)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/view-as": {
      "post": {
        "summary": "Masuk sebagai merchant (view-as)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/merchants/{id}/role": {
      "patch": {
        "summary": "Ubah role merchant/admin",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/admins": {
      "post": {
        "summary": "Buat akun admin baru",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments": {
      "get": {
        "summary": "Daftar semua pembayaran; filter status,merchant_id",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/{id}": {
      "get": {
        "summary": "Detail pembayaran: payment+merchant+ledger+webhook deliveries+klaim",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/{id}/cancel": {
      "post": {
        "summary": "Batalkan pembayaran pending",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/{id}/refund": {
      "post": {
        "summary": "Refund pembayaran lunas",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/{id}/settle": {
      "post": {
        "summary": "Selesaikan pembayaran secara manual",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/{id}/check": {
      "post": {
        "summary": "Periksa ulang status pembayaran ke konektor",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/payments/stale": {
      "get": {
        "summary": "Pembayaran pending yang macet/stale",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/withdrawals": {
      "get": {
        "summary": "Daftar penarikan; filter status",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/withdrawals/{id}": {
      "patch": {
        "summary": "Proses penarikan (processing/paid/rejected)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/webhooks": {
      "get": {
        "summary": "Daftar antrean webhook deliveries",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/webhooks/{id}/requeue": {
      "post": {
        "summary": "Antrekan ulang satu webhook delivery",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/connector/status": {
      "get": {
        "summary": "Status konektor Akun Pusat & sesi",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/connector/login/request-otp": {
      "post": {
        "summary": "Minta OTP login Akun Pusat",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/connector/login/verify": {
      "post": {
        "summary": "Verifikasi OTP login Akun Pusat",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/connector/qris": {
      "post": {
        "summary": "Pasang template QRIS statis Akun Pusat",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/settings": {
      "get": {
        "summary": "Baca pengaturan aplikasi",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      },
      "put": {
        "summary": "Simpan pengaturan aplikasi",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/badges": {
      "get": {
        "summary": "Jumlah item menunggu tindakan admin",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/announcements": {
      "get": {
        "summary": "Daftar pengumuman",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      },
      "post": {
        "summary": "Buat pengumuman",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/announcements/{id}": {
      "patch": {
        "summary": "Ubah pengumuman",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      },
      "delete": {
        "summary": "Hapus pengumuman",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/audit-logs": {
      "get": {
        "summary": "Log audit aksi admin",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/security/logins": {
      "get": {
        "summary": "Riwayat percobaan login",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/deletion-requests": {
      "get": {
        "summary": "Daftar permintaan hapus akun",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/deletion-requests/{id}/process": {
      "post": {
        "summary": "Proses permintaan hapus akun",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/claims": {
      "get": {
        "summary": "Semua klaim bukti bayar; query: status",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/claims/{id}/approve": {
      "post": {
        "summary": "Setujui klaim (menyelesaikan pembayaran)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/claims/{id}/reject": {
      "post": {
        "summary": "Tolak klaim (note wajib)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/claims/{id}/image": {
      "get": {
        "summary": "Unduh gambar bukti klaim",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/exports/payments": {
      "get": {
        "summary": "Ekspor CSV semua pembayaran; filter status,merchant_id,from,to",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/exports/merchants": {
      "get": {
        "summary": "Ekspor CSV semua merchant + saldo",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/exports/withdrawals": {
      "get": {
        "summary": "Ekspor CSV penarikan; filter status",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/v1/admin/exports/fee-report": {
      "get": {
        "summary": "Ekspor CSV laporan fee per hari; query: from,to",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "admin"
        ]
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "Dokumen OpenAPI ini",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "publik"
        ]
      }
    },
    "/v1/me/notifications": {
      "get": {
        "summary": "Daftar notifikasi panel penjual (terbaru dulu) + jumlah belum dibaca",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Tidak terautentikasi"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/notifications/read-all": {
      "post": {
        "summary": "Tandai semua notifikasi milik penjual sudah dibaca",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Tidak terautentikasi"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    },
    "/v1/me/notifications/{id}/read": {
      "post": {
        "summary": "Tandai satu notifikasi sudah dibaca (hanya milik sendiri; milik orang lain 404)",
        "security": [
          {
            "bearerJWT": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Permintaan tidak valid ({error: kode})"
          },
          "401": {
            "description": "Tidak terautentikasi"
          },
          "404": {
            "description": "Tidak ditemukan"
          }
        },
        "tags": [
          "merchant"
        ]
      }
    }
  }
}
