API v1.9.0

Kanan Bayar API

Dokumentasi integrasi external lengkap dengan parameter, contoh request, dan contoh response. Semua nominal memakai Rupiah sebagai integer, bukan sen/minor unit.

Mulai dari sini

Base URL & Authentication

Base URLhttps://bayar.kanan.id/api/v1Seluruh endpoint di bawah relatif terhadap base URL ini.
API Merchant IDmer_xxxxxxxxxGunakan ID dari GET /merchants. Jangan gunakan GoBiz Merchant ID G....

Header autentikasi

Authorization: Bearer kb_live_xxxxxxxxxxxxxxxxx
Accept: application/json
Content-Type: application/json

Fallback jika reverse proxy menghapus Authorization: X-API-Key: kb_live_xxxxxxxxx.

Baru di v1.9.0

Produk, Varian, Outlet, Customer & POS

API key dapat diberi scope granular untuk sinkronisasi katalog dan pembuatan transaksi POS. Harga item selalu dihitung ulang oleh server dari katalog aktif.

MethodEndpointScopeFungsi
GET / POST/productsproducts:read/writeList / tambah produk; GET menyertakan varian.
POST/products/{prd_id}products:writeUbah produk/status.
POST/products/{prd_id}/variantsproducts:writeTambah varian SKU/barcode/harga/stok.
POST/variants/{var_id}products:writeUbah varian/status.
GET / POST/outletsoutlets:read/writeList / tambah outlet.
POST/outlets/{out_id}outlets:writeUbah outlet/status.
GET / POST/customerscustomers:read/writeList / tambah customer.
POST/customers/{cus_id}customers:writeUbah customer/status.
POST/pos/paymentspos:createBuat payment POS dari produk/varian.

Request POS

POST /pos/payments
Authorization: Bearer kb_live_xxx
Idempotency-Key: POS-EXT-000123

{
  "merchant_id":"mer_xxx",
  "outlet_id":"out_xxx",
  "customer_id":"cus_xxx",
  "items":[
    {"product_id":"prd_xxx","variant_id":"var_xxx","qty":2},
    {"product_id":"prd_yyy","qty":1}
  ],
  "discount_type":"percent",
  "discount_value":10
}

Aturan penting

IdempotentKirim Idempotency-Key atau order_id untuk retry yang aman.
Varianvariant_id wajib bila produk memiliki varian.
Server authoritativeClient tidak menentukan harga final; server memvalidasi produk, outlet, stok, harga dan diskon.
GET/pingPublic

Ping / Health Check

Memastikan domain, SSL, rewrite, PHP dan routing API dapat diakses dari luar.

Parameter

Tidak ada parameter.

Request

curl -sS https://bayar.kanan.id/api/v1/ping

Response 200

{
  "success": true,
  "data": {
    "service": "Kanan Bayar API",
    "version": "1.9.0",
    "status": "ok",
    "time": "2026-10-05T13:30:00+07:00",
    "request_id": "req_c8f1..."
  }
}
GET/account/usageaccount:read

Paket & Kuota Akun

Parameter

Tidak ada parameter.

Request

curl -sS 'https://bayar.kanan.id/api/v1/account/usage' \
  -H 'Authorization: Bearer kb_live_xxx'

Response 200

{
  "success": true,
  "data": {
    "plan": {"code":"pro","name":"Pro","price_monthly":299000},
    "usage": {
      "merchants": {"used":1,"limit":10},
      "transactions": {"used":84,"limit":10000},
      "api_requests": {"used":1472,"limit":100000}
    },
    "reset_at": "2026-11-01T00:00:00+07:00"
  }
}
GET/account/api-usageaccount:read

Statistik Penggunaan API

ParameterLokasiWajibContohKeterangan
daysqueryTidak307–90 hari. Default 30.

Request

GET /account/api-usage?days=30

Response 200

{
  "success": true,
  "data": {
    "days": 30,
    "daily": [{"day":"2026-10-05","requests":128,"errors":2,"avg_ms":94}],
    "routes": [{"route":"/api/v1/payments","method":"POST","requests":48,"errors":1,"avg_ms":132}]
  }
}
GET/merchantsmerchants:read

Daftar Merchant

Gunakan nilai data[].id sebagai merchant_id untuk QRIS dan payment.

Parameter

Tidak ada parameter.

Request

GET /merchants

Response 200

{
  "success": true,
  "data": [
    {
      "id": "mer_3Q0K7Pz7c8xA2F5mS7pLVA",
      "name": "DeltaNet",
      "status": "active",
      "token_status": "valid",
      "last_token_check_at": "2026-10-05 13:25:12",
      "connected_at": "2026-10-05 09:18:44",
      "last_sync_at": "2026-10-05 13:29:41"
    }
  ]
}
GET/transactionstransactions:read

Mutasi Masuk

ParameterLokasiWajibContohKeterangan
merchantqueryTidakmer_...Filter merchant.
fromqueryTidak2026-10-01Format YYYY-MM-DD.
toqueryTidak2026-10-05Maksimum rentang 31 hari.
pagequeryTidak1Default 1.
per_pagequeryTidak501–100, default 50.

Request

GET /transactions?merchant=mer_3Q0K7Pz7c8xA2F5mS7pLVA&from=2026-10-01&to=2026-10-05&page=1&per_page=50

Response 200

{
  "success": true,
  "data": [{
    "transaction_id": "01a109ba-9428-7000-a121-5e997b3e4331",
    "order_id": "QRIS-0220261005014305QykVUCzAuaID",
    "merchant": {"id":"mer_3Q0K7Pz7c8xA2F5mS7pLVA","name":"DeltaNet"},
    "amount": 10000,
    "status": "settlement",
    "issuer": "BCA",
    "transaction_time": "2026-10-05T08:43:05+07:00"
  }],
  "meta": {"page":1,"per_page":50,"total":1,"pages":1}
}
POST/qrisqris:create

Buat QRIS Langsung

Membuat QRIS tanpa hosted payment/invoice. Nilai amount adalah Rupiah, contoh 12000 = Rp12.000.

ParameterTipeWajibContohKeterangan
merchant_idstringYamer_...ID public dari endpoint merchants.
amountintegerYa12000Nominal Rupiah.

Request JSON

{
  "merchant_id": "mer_3Q0K7Pz7c8xA2F5mS7pLVA",
  "amount": 12000
}

Response 201

{
  "success": true,
  "data": {
    "qris_id": "qris_xxx",
    "trx_id": "trx_xxx",
    "qris_code": "00020101021226...6304ABCD",
    "amount": 12000,
    "expires_at": "2026-10-05T13:36:00+07:00"
  }
}
GET/paymentspayments:read

Daftar / Cari Payment

ParameterWajibContohKeterangan
order_idTidakORDER-20261005-0001Cari berdasarkan order ID.
external_idTidakINV-CLIENT-001ID dari sistem eksternal.
statusTidakpaidpending|paid|expired|cancelled.
merchantTidakmer_...Filter merchant.
pageTidak1Default 1.
per_pageTidak501–100.

Request

GET /payments?status=paid&merchant=mer_3Q0K7Pz7c8xA2F5mS7pLVA&page=1

Response 200

{
  "success": true,
  "data": [{
    "id": "pay_58I_RSoy3OofBIh0pCbBig",
    "reference_id": "KB-261005-E6CC1A7CDF",
    "order_id": "ORDER-20261005-0001",
    "external_id": "INV-CLIENT-001",
    "amount": 12000,
    "status": "paid",
    "payment_url": "https://bayar.kanan.id/bayar/pay_58I_RSoy3OofBIh0pCbBig",
    "invoice": {"id":"inv_xxx","number":"INV-2610-000004","url":"https://bayar.kanan.id/invoice/inv_xxx"},
    "expires_at": "2026-10-05T10:52:24+07:00",
    "paid_at": "2026-10-05T10:49:31+07:00",
    "created_at": "2026-10-05T10:47:24+07:00"
  }],
  "meta": {"page":1,"per_page":50,"total":1,"pages":1}
}
GET/payments/{id}payments:read

Detail Payment

ParameterLokasiWajibContoh
idpathYapay_58I_RSoy3OofBIh0pCbBig

Request

GET /payments/pay_58I_RSoy3OofBIh0pCbBig

Response 200

{
  "success": true,
  "data": {
    "id":"pay_58I_RSoy3OofBIh0pCbBig",
    "reference_id":"KB-261005-E6CC1A7CDF",
    "order_id":"ORDER-20261005-0001",
    "external_id":"INV-CLIENT-001",
    "amount":12000,
    "status":"paid",
    "payment_url":"https://bayar.kanan.id/bayar/pay_58I_RSoy3OofBIh0pCbBig",
    "invoice":{"id":"inv_xxx","number":"INV-2610-000004","url":"https://bayar.kanan.id/invoice/inv_xxx"},
    "expires_at":"2026-10-05T13:40:00+07:00",
    "paid_at":"2026-10-05T13:37:21+07:00"
  }
}
POST/payments/{id}/checkpayments:check

Cek Status Payment

Membaca status lokal terbaru sekaligus memprioritaskan centralized mutation worker. Request ini tidak memanggil GoPay langsung; status dapat tetap pending sampai worker menemukan mutasi yang cocok. Untuk production, utamakan webhook/callback.

ParameterLokasiWajibContoh
idpathYapay_58I_RSoy3OofBIh0pCbBig

Request

POST /payments/pay_58I_RSoy3OofBIh0pCbBig/check

Response 200

{
  "success": true,
  "data": {
    "id":"pay_58I_RSoy3OofBIh0pCbBig",
    "amount":12000,
    "status":"paid",
    "paid_at":"2026-10-05T13:37:21+07:00",
    "check": {"status":"paid"}
  }
}
GET/invoicespayments:read

Daftar Invoice

ParameterWajibContohKeterangan
statusTidakpaidunpaid|paid|expired|cancelled.
order_idTidakORDER-20261005-0001Filter berdasarkan order ID.
merchantTidakmer_...Filter merchant.
pageTidak1Halaman.
per_pageTidak501–100.

Request

GET /invoices?status=paid&merchant=mer_3Q0K7Pz7c8xA2F5mS7pLVA&page=1

Response 200

{
  "success": true,
  "data": [{
    "id":"inv_xxx",
    "number":"INV-2610-000004",
    "order_id":"ORDER-20261005-0001",
    "reference_id":"KB-261005-E6CC1A7CDF",
    "merchant":{"id":"mer_3Q0K7Pz7c8xA2F5mS7pLVA","name":"DeltaNet"},
    "payment_id":"pay_58I_RSoy3OofBIh0pCbBig",
    "status":"paid",
    "total":12000,
    "issue_date":"2026-10-05",
    "due_at":"2026-10-05T13:40:00+07:00",
    "paid_at":"2026-10-05T13:37:21+07:00",
    "url":"https://bayar.kanan.id/invoice/inv_xxx",
    "pdf_url":"https://bayar.kanan.id/invoice/inv_xxx/pdf"
  }],
  "meta":{"page":1,"per_page":50,"total":1,"pages":1}
}
GET/invoices/{id}payments:read

Detail Invoice

Parameter

idpathWajibinv_xxx

Request

GET /invoices/inv_xxx

Response 200

{
  "success": true,
  "data": {
    "id":"inv_xxx",
    "number":"INV-2610-000004",
    "status":"paid",
    "total":12000,
    "payment_id":"pay_58I_RSoy3OofBIh0pCbBig",
    "description":"Internet Oktober",
    "items":[] ,
    "url":"https://bayar.kanan.id/invoice/inv_xxx",
    "pdf_url":"https://bayar.kanan.id/invoice/inv_xxx/pdf"
  }
}
GET/reconciliationtransactions:read

Reconciliation

ParameterWajibContohKeterangan
merchantYamer_...Merchant public ID.
fromTidak2026-10-01Awal periode.
toTidak2026-10-31Akhir periode, maksimum 366 hari.

Request

GET /reconciliation?merchant=mer_3Q0K7Pz7c8xA2F5mS7pLVA&from=2026-10-01&to=2026-10-31

Response 200

{
  "success": true,
  "data": {
    "merchant":{"id":"mer_3Q0K7Pz7c8xA2F5mS7pLVA","name":"DeltaNet"},
    "period":{"from":"2026-10-01","to":"2026-10-31"},
    "gross":447000,
    "matched_amount":420000,
    "unmatched_payment_amount":12000,
    "unmatched_transaction_amount":15000,
    "matched_count":18,
    "unmatched_payment_count":1,
    "unmatched_transaction_count":2
  }
}
ERR4xx / 5xxSemua endpoint

Format Error

Contoh 422

{
  "success": false,
  "error": {
    "code": "validation_error",
    "message": "merchant_id dan amount wajib diisi.",
    "request_id": "req_c8f1..."
  }
}

Status yang umum

400 JSON/request tidak valid401 API key salah/tidak ada403 scope tidak cukup404 resource tidak ditemukan409 idempotency conflict422 parameter tidak valid429 rate limit/kuota503 gateway belum tersedia
HOOKpayment.paidWebhook

Contoh Webhook Payment Paid

Headers

X-Kanan-Event: payment.paid
X-Kanan-Delivery: whd_xxx
X-Kanan-Signature: sha256=<hex-hmac>
Content-Type: application/json

Contoh body

{
  "id": "pay_58I_RSoy3OofBIh0pCbBig",
  "reference_id": "KB-261005-E6CC1A7CDF",
  "order_id": "ORDER-20261005-0001",
  "external_id": "INV-CLIENT-001",
  "amount": 12000,
  "status": "paid",
  "paid_at": "2026-10-05T13:37:21+07:00",
  "transaction": {
    "transaction_id": "01a109ba-9428-7000-a121-5e997b3e4331",
    "amount": 12000,
    "issuer": "BCA"
  },
  "match_source": "worker_reconciliation"
}

Verifikasi X-Kanan-Signature menggunakan HMAC SHA-256 terhadap raw request body, lalu bandingkan dengan hash_equals.

Tes setelah deploy

KANAN_BAYAR_API_KEY='kb_live_...' bash scripts/api_external_test.sh

Smoke test memeriksa HTTPS/routing, CORS preflight, Bearer auth, dan fallback X-API-Key tanpa membuat transaksi.