API Docs v0.7.0
POST /auth/login Public

Owner login dengan identifier dan password

Autentikasi owner via identifier (email ATAU klay_id) + password. Akun harus sudah di-create oleh admin Skalar saat onboarding. Berhasil = access token di body, refresh token di httpOnly cookie. Response data hanya berisi access_token (tidak ada nested user object).

Request body

FieldTypeDescription
identifierrequired string Email atau klay_id owner.
passwordrequired string · password
{
  "identifier": "string",
  "password": "string"
}

Responses

200
Login berhasil
401
Email atau password salah
403
Akun ditemukan tapi business status SUSPENDED atau CHURNED
POST /auth/google/login Public

Owner login dengan Google OAuth (BELUM DIIMPLEMENTASI)

Handler saat ini mengembalikan 501 Not Implemented (auth/handler.go GoogleLogin). Google OAuth login belum di-wire. Entri 200/403 di bawah adalah kontrak yang dimaksudkan tapi belum dibangun: dipanggil NextAuth setelah Google OAuth berhasil, server verifikasi email terdaftar sebagai owner, lalu issue JWT Klay sendiri.

Request body

FieldTypeDescription
emailrequired string · email
namerequired string
{
  "email": "owner@klay.id",
  "name": "string"
}

Responses

200
[INTENDED, BELUM DIBANGUN] Login berhasil
403
[INTENDED, BELUM DIBANGUN] Email belum terdaftar sebagai owner
501
Google login belum diimplementasi (perilaku aktual server)
POST /auth/refresh Public

Refresh access token

Baca refresh token dari httpOnly cookie, issue access token baru.

Responses

200
Access token baru
FieldTypeDescription
success boolean
data object
error string
401
Refresh token tidak valid atau expired
POST /auth/logout 🔒 Auth required

Logout

Hapus refresh token dari httpOnly cookie.

Responses

200
Logout berhasil
401
GET /users/me 🔒 Auth required

Profil owner yang sedang login

Mengembalikan profil owner beserta data business yang terkait.

Responses

200
Profil berhasil diambil
FieldTypeDescription
success boolean
data object
error string
401
PATCH /users/me 🔒 Auth required

Update profil owner

Owner update nama atau phone. Tidak bisa ubah email (admin Skalar only).

Request body

FieldTypeDescription
full_name string
phone string
{
  "full_name": "string",
  "phone": "string"
}

Responses

200
Profil ter-update
FieldTypeDescription
success boolean
data object
error string
401
GET /business 🔒 Auth required

Detail business owner yang login

Responses

200
Data business
FieldTypeDescription
success boolean
data object
error string
401
PATCH /business 🔒 Auth required

Update info business (terbatas)

Owner hanya bisa ubah field display business. Field plan, features, max_operators, status, xendit_status — admin Skalar only.

Request body

FieldTypeDescription
business_name string
phone string
address string
city string
country string
qris_string string QRIS static payload merchant.
category string
{
  "business_name": "string",
  "phone": "string",
  "address": "string",
  "city": "string",
  "country": "string",
  "qris_string": "string",
  "category": "string"
}

Responses

200
Business ter-update
FieldTypeDescription
success boolean
data object
error string
401
403
GET /business/operators 🔒 Auth required

List operator business

Daftar operator + info kuota. qr_token tidak dikembalikan di list, hanya saat create dan regenerate.

Responses

200
List operator
FieldTypeDescription
success boolean
data object
error string
401
403
POST /business/operators 🔒 Auth required

Tambah operator baru

Owner-only. Cap divalidasi terhadap business.max_operators (default 3, admin update kalo beli add-on, -1 = unlimited). Body hanya berisi name; server generate operator_code (KL-XXXXX), PIN, dan qr_token. operator_code dan credential (qr_token/pin) dikembalikan di response create/regenerate ini saja (one-time).

Request body

FieldTypeDescription
namerequired string Satu-satunya field input. Server generate operator_code dan credential, dikembalikan di response.
{
  "name": "string"
}

Responses

201
Operator dibuat
FieldTypeDescription
success boolean
data object
error string
400
Input tidak valid
401
403
409
operator_code sudah dipakai atau slot penuh
GET /business/operators/{operator_id} 🔒 Auth required

Detail satu operator

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

200
Operator ditemukan
FieldTypeDescription
success boolean
data object
error string
401
403
404
PUT /business/operators/{operator_id} 🔒 Auth required

Update operator (partial)

Owner update name atau is_active. Reset password dan QR di endpoint terpisah.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Request body

FieldTypeDescription
name string
is_active boolean
{
  "name": "string",
  "is_active": true
}

Responses

200
Operator ter-update
FieldTypeDescription
success boolean
data object
error string
401
403
404
DELETE /business/operators/{operator_id} 🔒 Auth required

Hapus operator (soft delete)

Soft delete — deleted_at di-set, row tetap ada. operator_code TIDAK dibebaskan (tetap tersimpan di row, slot unique index terpakai). Operator tidak bisa login lagi. Slot operator aktif berkurang (COUNT is_active turun). Data historis tetap valid.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

200
Operator dihapus
401
403
404
POST /business/operators/{operator_id}/regenerate-qr 🔒 Auth required

Regenerate qr_token operator

Issue qr_token baru. QR lama tidak valid untuk login baru, tapi sesi JWT yang masih aktif tetap berlaku sampai access token expired.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

200
QR baru
FieldTypeDescription
success boolean
data object
error string
401
403
404
GET /business/operators/{operator_id}/qr 🔒 Auth required

Ambil operator_code + qr_token operator

UndocumentedPresent in user/routes.go, absent from prior contract.

Owner-only. Mengembalikan operator_code dan qr_token saat ini untuk re-render QR di dashboard tanpa regenerate.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

200
operator_code dan qr_token
FieldTypeDescription
success boolean
data object
error string
401
403
404
POST /business/operators/{operator_id}/rotate 🔒 Auth required

Rotate credential operator

UndocumentedPresent in user/routes.go, absent from prior contract.

Owner-only. Issue ulang qr_token dan PIN operator. Credential baru dikembalikan satu kali (one-time) di response ini.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

200
Credential operator ter-rotate
FieldTypeDescription
success boolean
data object
error string
401
403
404
POST /business/operators/{operator_id}/force-logout 🔒 Auth required

Paksa logout operator

UndocumentedPresent in user/routes.go, absent from prior contract.

Owner-only. Cabut sesi aktif operator (revoke refresh token). Mengembalikan 204 No Content saat sukses.

Parameters

NameIn · TypeDescription
operator_idrequired path · string

Responses

204
Sesi operator dicabut (no content)
401
403
404
POST /operator/auth/login Public

Operator login dengan credential

Endpoint public. identifier (email atau klay_id business) me-resolve business; operator dicari via operator_code + PIN.

Request body

FieldTypeDescription
identifierrequired string Email atau klay_id business (resolves business).
operator_coderequired string
pinrequired string · password Tepat 6 digit numerik (server: validate len=6,numeric).
{
  "identifier": "string",
  "operator_code": "string",
  "pin": "string"
}

Responses

200
Login berhasil
FieldTypeDescription
success boolean
data object
error string
400
Input tidak valid
401
Credential salah
403
Operator non-aktif atau business SUSPENDED/CHURNED
POST /operator/auth/login/qr Public

Operator login dengan QR scan

Endpoint public. qr_token statis, regenerate via owner.

Request body

FieldTypeDescription
qr_tokenrequired string
{
  "qr_token": "string"
}

Responses

200
Login berhasil
FieldTypeDescription
success boolean
data object
error string
400
401
qr_token tidak valid
403
Operator non-aktif atau business SUSPENDED/CHURNED
GET /operator/me 🔒 Auth required

Profil operator yang sedang login (PWA operator)

Responses

200
Profil operator
FieldTypeDescription
success boolean
data object
error string
401
GET /products 🔒 Auth required

List produk business

Owner & operator (RequireOperator) bisa GET. Handler hanya pakai business_id dari JWT; tidak ada query filter/sort/search yang diproses oleh server.

Responses

200
List produk (data dibungkus sebagai object { products: [...] })
FieldTypeDescription
success boolean
data object
error string
401
POST /products 🔒 Auth required

Tambah produk (owner only)

UndocumentedOwner-facing product CRUD exists at /products in routes.go; prior contract said admin-only.

RequireOwner. business_id diambil dari JWT, bukan body.

Request body

Responses

201
Produk dibuat
FieldTypeDescription
success boolean
data object
error string
400
Body invalid atau gagal validasi
401
403
GET /products/{product_id} 🔒 Auth required

Detail produk

Owner & operator (RequireOperator).

Parameters

NameIn · TypeDescription
product_idrequired path · string

Responses

200
Detail produk
FieldTypeDescription
success boolean
data object
error string
401
404
PATCH /products/{product_id} 🔒 Auth required

Update produk (owner only, partial)

UndocumentedOwner-facing product CRUD exists at /products in routes.go; prior contract said admin-only.

RequireOwner. Partial update — field yang tidak dikirim tidak berubah.

Parameters

NameIn · TypeDescription
product_idrequired path · string

Request body

Responses

200
Produk ter-update
FieldTypeDescription
success boolean
data object
error string
400
Body invalid atau product_id tidak valid
401
403
404
DELETE /products/{product_id} 🔒 Auth required

Hapus produk (owner only)

UndocumentedOwner-facing product CRUD exists at /products in routes.go; prior contract said admin-only.

RequireOwner.

Parameters

NameIn · TypeDescription
product_idrequired path · string

Responses

200
Produk dihapus. response.NoContent() mengembalikan HTTP 200 dengan body { success: true }, BUKAN 204 No Content.
FieldTypeDescription
success boolean
401
403
404
GET /orders 🔒 Auth required

List order milik operator yang login

order.ListMyOrders (RequireOperator). Hanya order milik operator dari JWT. Kalau dipanggil owner (operator_id kosong) mengembalikan array kosong. Response adalah array Transaction langsung di `data`, BUKAN object berpaginasi.

Responses

200
Array order milik operator (atau [] untuk owner)
FieldTypeDescription
success boolean
data array<object>
error string
401
POST /orders 🔒 Auth required

Buat order baru (status DRAFT)

order.CreateOrder (RequireOperator). Status awal DRAFT. Backend hitung total_amount dari items dan snapshot product_name + unit_price ke order_items. operator_id diambil dari JWT (nullable kalau owner).

Request body

FieldTypeDescription
itemsrequired array<object>
note string
{
  "items": [
    {
      "product_id": "string",
      "quantity": 0
    }
  ],
  "note": "string"
}

Responses

201
Order DRAFT dibuat (response.Created -> 201)
FieldTypeDescription
success boolean
data object
error string
400
Body invalid, items kosong, atau produk tidak ditemukan/unavailable (ErrEmptyItems / ErrProductNotFound dipetakan ke 400 BadRequest)
401
PATCH /orders/{order_id}/items 🔒 Auth required

Ganti items order DRAFT

order.UpdateItems (RequireOperator). Hanya valid saat status DRAFT.

Parameters

NameIn · TypeDescription
order_idrequired path · string

Request body

FieldTypeDescription
itemsrequired array<object>
note string
{
  "items": [
    {
      "product_id": "string",
      "quantity": 0
    }
  ],
  "note": "string"
}

Responses

200
Order diperbarui
FieldTypeDescription
success boolean
data object
error string
400
Body invalid / produk tidak ditemukan
401
404
409
Order tidak dalam status DRAFT (ErrNotDraft)
POST /orders/{order_id}/checkout/begin 🔒 Auth required

Mulai checkout (DRAFT -> PENDING)

order.BeginCheckout (RequireOperator). Stamp checkout_started_at dan pindah status ke PENDING. Tidak ada request body. Wajib dipanggil sebelum confirm — confirm tanpa begin menghasilkan ErrCheckoutNotStarted (400).

Parameters

NameIn · TypeDescription
order_idrequired path · string

Responses

200
Checkout dimulai, status PENDING
FieldTypeDescription
success boolean
data object
error string
401
404
409
Order tidak dalam status DRAFT (ErrNotDraft)
POST /orders/{order_id}/checkout/confirm 🔒 Auth required

Konfirmasi checkout (PENDING -> CONFIRMED)

order.ConfirmCheckout (RequireOperator). Body wajib `payment_method`. Server menolak kalau begin-checkout belum dipanggil (ErrCheckoutNotStarted) atau gesture terlalu cepat <800ms sejak checkout_started_at (ErrGestureTooFast). Stamp confirmed_at + confirmed_by (string), lalu trigger consumption_log dari product.recipe. Response menyertakan qris_string saat payment QRIS_STATIC.

Parameters

NameIn · TypeDescription
order_idrequired path · string

Request body

FieldTypeDescription
payment_methodrequired object
{
  "payment_method": null
}

Responses

200
Order CONFIRMED. data = Order + qris_string (nullable, hanya QRIS_STATIC).
FieldTypeDescription
success boolean
data object
error string
400
Body invalid atau checkout belum dimulai (ErrCheckoutNotStarted)
401
404
409
Order tidak PENDING (ErrNotPending) atau konfirmasi terlalu cepat <800ms (ErrGestureTooFast)
POST /orders/{order_id}/void 🔒 Auth required

Void order (operator)

order.VoidOrder (RequireOperator). Tidak ada request body. Mengembalikan response.NoContent = HTTP 200 dengan body {"success":true} (BUKAN 204).

Parameters

NameIn · TypeDescription
order_idrequired path · string

Responses

200
Order di-void. Body {"success":true} tanpa data.
FieldTypeDescription
success boolean
401
404
POST /transactions/{id}/void 🔒 Auth required

Void order (owner)

order.VoidOrderByOwner (RequireOwner). Write mutation di domain order tapi di-mount di path /transactions/{id}/void. Body wajib `void_reason`. Owner identity diambil dari user_id JWT. Mengembalikan response.NoContent = HTTP 200 dengan {"success":true} (BUKAN 204).

Parameters

NameIn · TypeDescription
idrequired path · string

Request body

FieldTypeDescription
void_reasonrequired string Wajib diisi untuk audit
{
  "void_reason": "string"
}

Responses

200
Order di-void. Body {"success":true} tanpa data.
FieldTypeDescription
success boolean
400
void_reason kosong / body invalid
401
403
404
GET /transactions 🔒 Auth required

List transaksi business (read-only log)

transaction.List (RequireOwner). Read-only history. status query menerima hanya DRAFT/CONFIRMED/VOIDED — PENDING ditolak 400 oleh validasi list-filter.

Parameters

NameIn · TypeDescription
start_date query · string Format YYYY-MM-DD
end_date query · string Format YYYY-MM-DD
status query · string Hanya DRAFT, CONFIRMED, VOIDED diterima. PENDING ditolak 400.
payment_method query · string
operator_id query · string
page query · integer
limit query · integer

Responses

200
List transaksi berpaginasi
FieldTypeDescription
success boolean
data object
error string
400
Filter invalid (mis. status=PENDING, payment_method/tanggal/page/limit salah)
401
403
GET /transactions/{transaction_id} 🔒 Auth required

Detail transaksi

transaction.GetByID (RequireOperator). Mengembalikan OrderWithItems (Transaction + items[]).

Parameters

NameIn · TypeDescription
transaction_idrequired path · string

Responses

200
Detail transaksi
FieldTypeDescription
success boolean
data object
error string
400
transaction_id tidak valid
401
403
404
GET /operator/transactions 🔒 Auth required

List transaksi milik operator yang login

transaction.OperatorList (RequireOperatorOnly). Operator-scoped — hanya transaksi operator dari JWT. Filter: start_date, end_date, page, limit (tidak ada filter status/payment_method/operator_id di endpoint ini).

Parameters

NameIn · TypeDescription
start_date query · string Format YYYY-MM-DD
end_date query · string Format YYYY-MM-DD
page query · integer
limit query · integer

Responses

200
List transaksi operator berpaginasi
FieldTypeDescription
success boolean
data object
error string
400
Filter invalid
401
GET /metrics/summary 🔒 Auth required

Ringkasan performa business

Aggregate untuk dashboard. Count hanya status CONFIRMED.

Parameters

NameIn · TypeDescription
period query · string

Responses

200
Summary
FieldTypeDescription
success boolean
data object
error string
401
403
GET /metrics/trend 🔒 Auth required

Tren transaksi harian

Parameters

NameIn · TypeDescription
start_date query · string
end_date query · string

Responses

200
Tren harian
FieldTypeDescription
success boolean
data array<object>
error string
401
403
GET /metrics/top-products 🔒 Auth required

Produk terlaris

Parameters

NameIn · TypeDescription
period query · string
limit query · integer

Responses

200
Top produk
FieldTypeDescription
success boolean
data array<object>
error string
401
403
GET /metrics/peak-hours 🔒 Auth required

Distribusi jam tersibuk

Parameters

NameIn · TypeDescription
period query · string

Responses

200
Peak hours
FieldTypeDescription
success boolean
data array<object>
error string
401
403
GET /metrics/overview 🔒 Auth required

Analytics overview untuk custom date range

Dipakai di page Analytics, mendukung custom timeframe dan period comparison.

Parameters

NameIn · TypeDescription
start_daterequired query · string
end_daterequired query · string
compare_with query · string

Responses

200
Analytics overview
FieldTypeDescription
success boolean
data object
error string
401
403
GET /metrics/reports/daily-sales 🔒 Auth required

Laporan penjualan harian

Aggregate transaksi CONFIRMED per hari pada tanggal tertentu.

Parameters

NameIn · TypeDescription
daterequired query · string

Responses

200
Laporan harian
FieldTypeDescription
success boolean
data object
error string
401
403
GET /metrics/reports/monthly-sales 🔒 Auth required

Laporan penjualan bulanan

Parameters

NameIn · TypeDescription
monthrequired query · string Format YYYY-MM

Responses

200
Laporan bulanan
FieldTypeDescription
success boolean
data object
error string
401
403
GET /metrics/reports/consumption 🔒 Auth required

Laporan pemakaian bahan baku

Aggregate dari consumption_log per ingredient untuk periode. Foundation buat owner restock decision dan AI insight downstream.

Parameters

NameIn · TypeDescription
start_daterequired query · string
end_daterequired query · string
ingredient query · string Filter per ingredient name (diabaikan server)

Responses

200
Laporan consumption
FieldTypeDescription
success boolean
data object
error string
401
403
POST /metrics/reports/export 🔒 Auth required

Export laporan ke PDF atau CSV

Generate file download. Server return URL temporary atau stream langsung. Type laporan dan periode di-passing via body.

Request body

FieldTypeDescription
typerequired string · enum
formatrequired string · enum
periodrequired object Shape tergantung type. Daily=date, monthly=month, consumption=start_date+end_date.
{
  "type": "daily_sales",
  "format": "pdf",
  "period": {}
}

Responses

200
File generated
FieldTypeDescription
success boolean
data object
error string
401
403
422
Type / format / period combination tidak valid
GET /metrics/insight 🔒 Auth required

List insight cards

Rule-based MVP. Schema sudah siap untuk model_version + confidence kalau nanti switch ke AI engine.

Responses

200
Insight cards
FieldTypeDescription
success boolean
data array<object>
error string
401
403
POST /admin/auth/login Public

Admin Skalar login

Request body

FieldTypeDescription
emailrequired string · email
passwordrequired string · password
{
  "email": "owner@klay.id",
  "password": "string"
}

Responses

200
Admin login berhasil
FieldTypeDescription
success boolean
data object
error string
401
Credential salah
POST /admin/auth/refresh Public

Refresh admin access token

Responses

200
Token baru
FieldTypeDescription
success boolean
data object
error string
401
POST /admin/auth/logout 🔒 Auth required

Admin logout

Responses

200
Logout berhasil
401
GET /admin/me 🔒 Auth required

Profil admin yang sedang login

Responses

200
Profil admin
FieldTypeDescription
success boolean
data object
error string
401
GET /admin/owners 🔒 Auth required

List semua owners (cross-merchant)

Admin view. handler.ListOwners — hanya menerima page dan limit. Filter status/plan/q tidak diproses server (admin/handler.go).

Parameters

NameIn · TypeDescription
page query · integer
limit query · integer

Responses

200
List owners berpaginasi
FieldTypeDescription
success boolean
data object
error string
401
403
POST /admin/owners 🔒 Auth required

Onboard merchant baru

Create Business + User owner sekaligus. Body matches admin/model.go CreateBusinessRequest. business_id digenerate server.

Request body

Responses

201
Owner berhasil di-onboard
FieldTypeDescription
success boolean
data object
error string
400
Input tidak valid
401
403
409
Email owner sudah dipakai
GET /admin/owners/{owner_id} 🔒 Auth required

Detail owner

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Responses

200
Detail owner
FieldTypeDescription
success boolean
data object
error string
401
403
404
PATCH /admin/owners/{owner_id} 🔒 Auth required

Update business info owner (admin-controlled fields)

Matches admin/model.go UpdateBusinessRequest. Field yang tidak dikirim tidak berubah. merchant_status enum: PENDING | REGISTERED | ACTIVE | SUSPENDED.

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Request body

Responses

200
Owner ter-update
FieldTypeDescription
success boolean
data object
error string
401
403
404
PATCH /admin/owners/{owner_id}/status 🔒 Auth required

Toggle aktif/suspend owner

handler.SetOwnerStatus — boolean toggle. enabled=true mengaktifkan, enabled=false mensuspend. Returns HTTP 200 { success: true } via response.NoContent().

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Request body

FieldTypeDescription
enabledrequired boolean true = aktifkan, false = suspend
{
  "enabled": true
}

Responses

200
Status ter-toggle. response.NoContent() returns HTTP 200 { success:true }.
400
401
404
POST /admin/owners/{owner_id}/credential 🔒 Auth required

Set credential login owner (email dan/atau password)

UndocumentedRoute present in admin/routes.go but absent from prior contract.

handler.SetOwnerCredential. email opsional (jika dikirim harus valid email). password wajib, min 6 karakter. Returns HTTP 200 { success:true } via response.NoContent().

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Request body

FieldTypeDescription
email string · email Opsional. Jika dikirim harus valid email format.
passwordrequired string · password Wajib, min 6 karakter.
{
  "email": "owner@klay.id",
  "password": "string"
}

Responses

200
Credential diperbarui. response.NoContent() returns HTTP 200 { success:true }.
400
401
404
GET /admin/owners/{owner_id}/products 🔒 Auth required

List produk milik business

handler.ListOwnerProducts. Response membungkus products di dalam object { products: [...] } (bukan array langsung).

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Responses

200
List produk
FieldTypeDescription
success boolean
data object
error string
401
403
404
POST /admin/owners/{owner_id}/products 🔒 Auth required

Tambah produk untuk business

handler.CreateProduct. Body matches admin/model.go AdminCreateProductRequest. business_id diambil dari path param, bukan body.

Parameters

NameIn · TypeDescription
owner_idrequired path · string

Request body

Responses

201
Produk dibuat
FieldTypeDescription
success boolean
data object
error string
400
Input tidak valid
401
403
GET /admin/products/{product_id} 🔒 Auth required

Detail produk (termasuk recipe)

handler.GetProduct. Returns AdminProductDetail yang menyertakan recipe array.

Parameters

NameIn · TypeDescription
product_idrequired path · string

Responses

200
Detail produk dengan recipe
FieldTypeDescription
success boolean
data object
error string
401
403
404
PATCH /admin/products/{product_id} 🔒 Auth required

Update produk (partial)

handler.UpdateProduct. Body matches admin/model.go AdminUpdateProductRequest. Semua field optional (pointer) — field tidak dikirim tidak berubah.

Parameters

NameIn · TypeDescription
product_idrequired path · string

Request body

Responses

200
Produk ter-update
FieldTypeDescription
success boolean
data object
error string
401
403
404
DELETE /admin/products/{product_id} 🔒 Auth required

Hapus produk

handler.DeleteProduct. Soft delete kalau produk sudah ada di transaksi historis. Returns HTTP 200 { success:true } via response.NoContent() (BUKAN 204).

Parameters

NameIn · TypeDescription
product_idrequired path · string

Responses

200
Produk dihapus
401
403
404
PUT /admin/products/{product_id}/recipe 🔒 Auth required

Replace recipe produk

handler.UpdateProductRecipe. Mengganti seluruh recipe array (bukan merge). Returns HTTP 200 { success:true } via response.NoContent() (BUKAN 204).

Parameters

NameIn · TypeDescription
product_idrequired path · string

Request body

FieldTypeDescription
reciperequired array<object> Array ingredient baru. Mengganti seluruh recipe yang ada.
{
  "recipe": [
    null
  ]
}

Responses

200
Recipe ter-update. response.NoContent() returns HTTP 200 { success:true }.
400
401
404
DELETE /admin/owners/{owner_id}/operators/{operator_id} 🔒 Auth required

Hapus operator atas permintaan merchant

handler.DeleteOperator. Admin hanya bisa REMOVE operator on request. Tidak ada request body — handler tidak membaca body (admin/handler.go). Returns HTTP 200 { success:true } via response.NoContent() (BUKAN 204).

Parameters

NameIn · TypeDescription
owner_idrequired path · string
operator_idrequired path · string

Responses

200
Operator dihapus. response.NoContent() returns HTTP 200 { success:true }.
401
403
404
GET /admin/transactions 🔒 Auth required

List transaksi cross-merchant

handler.ListTransactions. Filter yang diproses: status (string), business_id (uuid), start_date (YYYY-MM-DD, filter created_at >= start), end_date (YYYY-MM-DD, filter created_at < end+1day), page (default 1), limit (default 20, max 100).

Parameters

NameIn · TypeDescription
status query · string Filter status transaksi (string bebas, tidak divalidasi enum di handler).
business_id query · string Filter per business.
start_date query · string Format YYYY-MM-DD. created_at >= start_date.
end_date query · string Format YYYY-MM-DD. created_at < end_date + 1 hari.
page query · integer
limit query · integer

Responses

200
List transaksi cross-merchant berpaginasi
FieldTypeDescription
success boolean
data object
error string
401
403
POST /admin/transactions/{transaction_id}/void 🔒 Auth required

Void transaksi (admin)

handler.VoidTransaction. Tidak ada request body — handler tidak membaca body. Returns HTTP 200 { success:true } via response.NoContent() (BUKAN 204). 409 dikembalikan jika transaksi bukan status PENDING/CONFIRMED (tidak bisa di-void).

Parameters

NameIn · TypeDescription
transaction_idrequired path · string

Responses

200
Transaksi di-void. response.NoContent() returns HTTP 200 { success:true }.
401
403
404
409
Transaksi tidak bisa di-void (sudah VOIDED atau status tidak valid)