195 lines
4.7 KiB
Markdown
195 lines
4.7 KiB
Markdown
# API Contract Draft - QRIS Soundbox Platform v1
|
|
|
|
## 1. Prinsip API
|
|
- gunakan HTTPS
|
|
- semua endpoint device memakai auth khusus device
|
|
- semua endpoint admin/merchant memakai RBAC
|
|
- endpoint create yang sensitif wajib support idempotency key
|
|
- response harus punya request_id / trace_id
|
|
|
|
## 2. Admin / Merchant APIs
|
|
|
|
### Merchant
|
|
- `POST /admin/merchants`
|
|
- `GET /admin/merchants`
|
|
- `GET /admin/merchants/{merchantId}`
|
|
- `PATCH /admin/merchants/{merchantId}`
|
|
- `POST /admin/merchants/{merchantId}/approve`
|
|
- `POST /admin/merchants/{merchantId}/reject`
|
|
|
|
#### Create Merchant
|
|
- `POST /admin/merchants`
|
|
|
|
Request body:
|
|
```json
|
|
{
|
|
"legal_name": "Toko Indo",
|
|
"brand_name": "Toko Indo",
|
|
"settlement_account_reference": "bank:9876543210",
|
|
"settlement_account_type": "merchant_bank_account",
|
|
"payout_mode": "merchant_direct",
|
|
"fee_profile_id": "fee_basic"
|
|
}
|
|
```
|
|
|
|
`payout_mode`:
|
|
- `merchant_direct` (default): payout mengikuti rekening/referensi milik merchant.
|
|
- `manual`: payout dilakukan manual/offline oleh tim operasi.
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"data": {
|
|
"id": "m_123",
|
|
"merchant_code": "m_123abc",
|
|
"legal_name": "Toko Indo",
|
|
"brand_name": "Toko Indo",
|
|
"settlement_account_reference": "bank:9876543210",
|
|
"settlement_account_type": "merchant_bank_account",
|
|
"payout_mode": "merchant_direct"
|
|
},
|
|
"request_id": "req_001",
|
|
"timestamp": "2026-05-24T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
Catatan penting:
|
|
- Pada fase awal, settlement tidak ditarik ke rekening perusahaan.
|
|
- Pencairan merchant dilakukan via `payout_account_reference` milik merchant.
|
|
- Untuk merchant yang belum punya integrasi payout otomatis, gunakan `payout_mode: manual`.
|
|
|
|
### Outlet
|
|
- `POST /admin/merchants/{merchantId}/outlets`
|
|
- `GET /admin/outlets`
|
|
- `GET /admin/outlets/{outletId}`
|
|
- `PATCH /admin/outlets/{outletId}`
|
|
|
|
### Terminal
|
|
- `POST /admin/outlets/{outletId}/terminals`
|
|
- `GET /admin/terminals`
|
|
- `GET /admin/terminals/{terminalId}`
|
|
- `PATCH /admin/terminals/{terminalId}`
|
|
|
|
### Device / TMS
|
|
- `POST /admin/devices`
|
|
- `GET /admin/devices`
|
|
- `GET /admin/devices/{deviceId}`
|
|
- `PATCH /admin/devices/{deviceId}`
|
|
- `POST /admin/devices/{deviceId}/bind`
|
|
- `POST /admin/devices/{deviceId}/unbind`
|
|
- `POST /admin/devices/{deviceId}/commands`
|
|
- `GET /admin/devices/{deviceId}/commands`
|
|
- `GET /admin/devices/{deviceId}/commands/{commandId}`
|
|
- `GET /admin/devices/{deviceId}/heartbeats`
|
|
- `GET /admin/devices/{deviceId}/notifications`
|
|
- `POST /admin/seed`
|
|
|
|
### Transactions
|
|
- `GET /admin/transactions`
|
|
- `GET /admin/transactions/{transactionId}`
|
|
- `POST /admin/transactions/{transactionId}/retry-notification`
|
|
|
|
### Settlements
|
|
- `GET /admin/settlements`
|
|
- `GET /admin/settlements/{settlementId}`
|
|
- `POST /admin/settlements/run`
|
|
- `POST /admin/settlements/{settlementId}/retry-payout`
|
|
- Catatan: endpoint ini dipakai untuk batch/reconciliation status; eksekusi payout dilakukan sesuai konfigurasi `payout_mode` merchant.
|
|
|
|
## 3. Device APIs
|
|
|
|
### Provisioning
|
|
- `POST /device/provision/activate`
|
|
- `POST /device/provision/refresh-credential`
|
|
|
|
### Heartbeat
|
|
- `POST /device/heartbeat`
|
|
|
|
Sample request:
|
|
```json
|
|
{
|
|
"device_id": "sbx_001",
|
|
"timestamp": "2026-05-23T10:00:00Z",
|
|
"firmware_version": "1.0.3",
|
|
"network_strength": 78,
|
|
"battery_level": 92,
|
|
"state": "idle"
|
|
}
|
|
```
|
|
|
|
### Config
|
|
- `GET /device/config`
|
|
- `POST /device/config/ack`
|
|
- `POST /device/commands/ack`
|
|
|
|
### Device command payload ack
|
|
Device mengirim:
|
|
```json
|
|
{
|
|
"device_id": "sbx_001",
|
|
"command_id": "cmd_123",
|
|
"status": "delivered",
|
|
"reason": "ok",
|
|
"result_payload": {
|
|
"payment_result": "ok"
|
|
}
|
|
}
|
|
```
|
|
`status` untuk ACK: `delivered` | `failed` | `timeout`.
|
|
|
|
### Dynamic QR create
|
|
- `POST /device/transactions/dynamic-qr`
|
|
|
|
Headers:
|
|
- `Authorization: Bearer <device-token>`
|
|
- `Idempotency-Key: <uuid>`
|
|
|
|
Request:
|
|
```json
|
|
{
|
|
"device_id": "sbx_001",
|
|
"terminal_id": "term_001",
|
|
"amount": 50000,
|
|
"currency": "IDR",
|
|
"request_id": "req_123"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"request_id": "req_123",
|
|
"transaction_id": "tx_123",
|
|
"qr_type": "dynamic",
|
|
"qr_payload": "000201010212...",
|
|
"expires_at": "2026-05-23T10:05:00Z",
|
|
"status": "awaiting_payment"
|
|
}
|
|
```
|
|
|
|
## 4. Merchant Portal APIs
|
|
- `GET /merchant/me`
|
|
- `GET /merchant/dashboard/summary`
|
|
- `GET /merchant/transactions`
|
|
- `GET /merchant/transactions/{transactionId}`
|
|
- `GET /merchant/settlements`
|
|
- `GET /merchant/settlements/{settlementId}`
|
|
- `GET /merchant/devices`
|
|
- `GET /merchant/outlets`
|
|
|
|
## 5. Webhook Receiver
|
|
- `POST /integrations/qris/callback`
|
|
- `POST /integrations/bank/payout-callback`
|
|
|
|
## 6. Catatan Error Model
|
|
Gunakan error code yang konsisten, misalnya:
|
|
- `DEVICE_UNAUTHORIZED`
|
|
- `DEVICE_NOT_BOUND`
|
|
- `DEVICE_CAPABILITY_NOT_SUPPORTED`
|
|
- `INVALID_AMOUNT`
|
|
- `DUPLICATE_REQUEST`
|
|
- `PARTNER_TIMEOUT`
|
|
- `TRANSACTION_NOT_FOUND`
|
|
- `SETTLEMENT_NOT_ELIGIBLE`
|
|
- `MERCHANT_PAYOUT_NOT_CONFIGURED`
|