Webhooks (Fireblocks, Xendit, Duitku, Micro-Queuing)
Dokumen ini menjelaskan endpoint callback dari layanan eksternal (payment/custody/reporting). Semua route webhook berada di routes/api.php.
Daftar route webhook
Semua route berikut berada di middleware leader.only kecuali disebutkan lain:
| Method | Path | Controller@method | Middleware |
|---|---|---|---|
| POST | /api/webhook/fireblock | WebhookController@fireblock | leader.only |
| POST | /api/webhook/fireblock-v2 | WebhookController@fireblockV2 | leader.only |
| POST | /api/webhook/binance | WebhookController@binance | leader.only |
| POST | /api/webhook/duitku-deposit | WebhookController@duitkuDeposit | leader.only |
| POST | /api/webhook/duitku/inquiry | WebhookController@duitkuInquiry | leader.only |
| POST | /api/webhook/duitku/notify | WebhookController@duitkuNotify | leader.only |
| POST | /api/webhook/xendit/handle-created-va | WebhookXenditController@handleCreatedVA | leader.only |
| POST | /api/webhook/xendit/handle-deposit-paid | WebhookXenditController@handleDepositPaid | leader.only |
| POST | /api/webhook/xendit/handle-deposit-paid-qris | WebhookXenditController@handleDepositPaidQris | leader.only |
| POST | /api/webhook/xendit/handle-withdrawal | WebhookXenditController@handleWithdrawal | leader.only |
| POST | /api/webhook/micro-queuing/report | WebhookMicroQueuingController@handleReport | leader.only |
Fireblocks webhook
1) POST /api/webhook/fireblock
- Controller:
App\Http\Controllers\Api\WebhookController@fireblock - Validasi keamanan:
- signature webhook Fireblocks (
validateFireblocksWebhook) - gagal verifikasi →
401 UnauthorizedviasendError
- signature webhook Fireblocks (
Payload penting yang dipakai
- top-level:
type,data data.*:assetId,status,destinationAddress,destinationTag,txHash,externalTxId,amount,assetType,note
Alur utama
- Abaikan event untuk default address dan gas tank autofuel.
- Mapping symbol khusus:
HOT1 -> HOTMATIC -> POLTRX_USDT_S2UZ -> USDT
- Withdrawal path:
externalTxId+ statusCOMPLETED→withdrawalSuccess(...)externalTxId+ statusFAILED→withdrawalFailed(...)
- Deposit path:
- cari
UserCoinAddressviadestinationAddress/legacy_address/destinationTag - create
UserDepositsaat status allowed + adatxHash - saat status
COMPLETED:- update deposit status
- tambah saldo user (
addUserBalance) - trigger Elliptic + notifikasi admin
- cari
Response
- Umumnya
200 OK(sendResponse(null, "OK")) walau event di-skip. - Kasus tertentu bisa
400jika data tidak valid/aksi gagal.
2) POST /api/webhook/fireblock-v2
- Controller:
WebhookController@fireblockV2 - V2 memakai struktur notifikasi Push API V2:
- top-level:
id,eventType,resourceId,createdAt,workspaceId,data
- top-level:
- Event diproses hanya jika
eventTypetermasuk:transaction.createdtransaction.status.updatedtransaction.approval_status.updated
- Alur withdrawal/deposit secara bisnis mirip v1, dengan logging lebih detail.
Binance webhook
POST /api/webhook/binance
- Controller:
WebhookController@binance - Endpoint ini memproses event user-data-stream Binance (mis. update order/execution report).
- Di controller ada konstanta event:
executionReportrefreshWebsocketheartbeat
- Tujuan utamanya sinkronisasi status order/trade internal (
t_order,trades, lock balance, dll.) saat event Binance masuk.
Payload Binance bervariasi per event type; untuk integrasi produksi, gunakan payload resmi Binance user data stream + pastikan field signature/timestamp sesuai validasi controller.
Xendit webhooks
Controller: App\Http\Controllers\Api\WebhookXenditController
Validasi keamanan
- Header:
X-CALLBACK-TOKEN - Deposit menggunakan token env:
XENDIT_WEBHOOK_VERIFICATION_TOKEN
- Withdrawal menggunakan token env:
XENDIT_WD_WEBHOOK_VERIFICATION_TOKEN
Jika token tidak cocok, request dianggap invalid.
1) handle-created-va
- Path:
/api/webhook/xendit/handle-created-va - Mencari
UserVaberdasarkanidcallback virtual account. - Update status VA.
- Response sukses:
{
"response_code": 200,
"response_message": "success receive data",
"response_data": null
}
2) handle-deposit-paid
- Path:
/api/webhook/xendit/handle-deposit-paid - Payload penting:
id,owner_id,payment_id,bank_code,amount,account_number, dll. - Proses:
- validasi user dari account number
- create
CashDeposit - tambah IDR available balance (dikurangi fee VA)
- kirim notifikasi user/admin
- report KKI
3) handle-deposit-paid-qris
- Path:
/api/webhook/xendit/handle-deposit-paid-qris - Payload penting:
- top-level:
id,event,amount,status - nested:
qr_code.*,payment_details.*
- top-level:
- Proses:
- create
CashDeposittipe online - update
QrisPayment - tambah IDR balance (dikurangi fee QRIS)
- report KKI QRIS
- create
4) handle-withdrawal
- Path:
/api/webhook/xendit/handle-withdrawal - Payload penting:
data.metadata.request_id,data.metadata.user_id,data.status - Proses:
- cari
UserWithdrawalbyrequest_id - jika status callback
SUCCEEDED:- update status withdrawal jadi success
- kurangi
locked_balanceuser - kirim notifikasi + email sukses
- cari
- Response sukses:
response_code=200,response_message="success receive data"
Duitku webhooks
Controller: App\Http\Controllers\Api\WebhookController
1) POST /api/webhook/duitku-deposit
- Payload penting:
merchantCode,amount,merchantOrderId,publisherOrderId,signature - Validasi signature:
md5(merchantCode + amount + merchantOrderId + DUITKU_MERCHANT_API_KEY)
- Jika valid:
- update IDR balance
- update
CashDepositstatus success + publisher order id - kirim notifikasi admin
2) POST /api/webhook/duitku/inquiry
- Payload penting:
action,merchantCode,bin,vaNo,session,signature - Validasi signature dengan merchant key.
- Jika valid:
- cek user dan fixed VA prefix
- simpan mapping redis
merchantOrderId -> user_id + va - return response format Duitku inquiry (
statusCode,statusMessage, dll.)
3) POST /api/webhook/duitku/notify
- Payload penting:
merchantCode,amount,merchantOrderId,productDetail,resultCode,signature - Validasi signature.
- Jika
resultCode == "00":- tambah IDR balance (setelah biaya)
- create record cash deposit
- hapus redis mapping inquiry
Micro-Queuing callback
POST /api/webhook/micro-queuing/report
- Controller:
WebhookMicroQueuingController@handleReport - Auth:
- Bearer token harus cocok
MICRO_QUEUE_AUTH client_secretharus cocok salah satu:MICRO_QUEUE_CLIENT_SECRET_KKIMICRO_QUEUE_CLIENT_SECRET_ICCMICRO_QUEUE_CLIENT_SECRET_CFX
- Bearer token harus cocok
Payload penting
| Field | Fungsi |
|---|---|
request_id | id request report di DB |
client_secret | menentukan jenis report (KKI/ICC/CFX) |
api_response | response JSON dari queue processor |
Proses
- Parse
api_response, ambilresponseMessage/message. - Update status report (
SUCCESS/FAILED) pada tabel terkait (KkiReport,ICCReport,CFXReport).
Response
- sukses callback: HTTP 200 +
response_message: "callback success" - data/auth tidak valid: HTTP 400 + error message sesuai cabang logic.