1

Ringkasan & Prasyarat

Webhook lokasi memungkinkan SmartGate mengirim notifikasi otomatis dan real-time ke server HR/payroll milik perusahaan Anda setiap kali ada peristiwa tertentu: penghuni memperbarui foto swafoto, atau penghuni melakukan presensi masuk/keluar gerbang. Server Anda menerima data ini sebagai HTTP POST berformat JSON, tanpa perlu polling data secara berkala ke SmartGate.

๐Ÿ›ก๏ธ
Peran Admin Lokasi
Hanya pengguna dengan role: admin dan status keanggotaan aktif pada lokasi tersebut yang dapat melihat dan mengubah konfigurasi webhook.
๐Ÿ’Ž
Subskripsi Premium Aktif
Fitur webhook khusus untuk lokasi dengan tier langganan Premium yang berstatus aktif. Lokasi dengan tier Free akan diarahkan ke halaman ajakan upgrade.
๐ŸŒ
Endpoint Publik Siap Menerima
Server tujuan harus memiliki URL https:// yang dapat diakses dari internet dan mampu menerima body application/json lewat method POST.
2

Cara Membuka Menu Konfigurasi Webhook

Menu ini tersedia di dalam layar Detail Lokasi, diakses lewat halaman Profil:

Langkah 2.1

Buka Profil โ†’ Pilih Lokasi

Masuk ke tab Profil, gulir ke bagian Lokasi Saya, lalu ketuk salah satu lokasi tempat Anda menjadi admin untuk masuk ke layar Detail Lokasi.

Screenshot Profil - Lokasi Saya
๐Ÿ‘ค
Screenshot: Profil โ†’ Lokasi Saya
web-info/assets/screenshots/webhook-pilih-lokasi.jpeg
1080 x 2400 px
Langkah 2.2

Buka Menu Titik Tiga โ†’ Konfigurasi Webhook

Pada layar Detail Lokasi, ketuk ikon titik tiga (โ‹ฎ) di pojok kanan atas foto sampul lokasi, lalu pilih Konfigurasi Webhook dari daftar menu yang muncul.

๐Ÿ’ก Menu ini hanya tampil untuk admin lokasi. Jika tidak muncul, periksa peran keanggotaan Anda pada lokasi tersebut.
Screenshot Menu Titik Tiga Detail Lokasi
โ‹ฎ
Screenshot: Menu Detail Lokasi
web-info/assets/screenshots/webhook-menu-detail-lokasi.jpeg
1080 x 2400 px
3

Mengisi Form Konfigurasi

Layar Konfigurasi Webhook terdiri dari beberapa bagian. Isi masing-masing sesuai kebutuhan integrasi dengan sistem HR/payroll Anda:

Langkah 3.1

Status Webhook

Sakelar di bagian paling atas menentukan apakah pengiriman webhook aktif. Saat nonaktif, konfigurasi tetap tersimpan tetapi tidak ada event yang dikirim ke server Anda โ€” berguna untuk menonaktifkan sementara tanpa kehilangan pengaturan.

Screenshot Status Webhook
๐Ÿ”˜
Screenshot: Sakelar Status Webhook
web-info/assets/screenshots/webhook-status.jpeg
1080 x 2400 px
Langkah 3.2

URL Webhook (Endpoint)

Masukkan URL lengkap server tujuan, contoh https://api.perusahaan.com/v1/webhook. URL wajib diawali http:// atau https:// โ€” gunakan https:// untuk keamanan data di jalur pengiriman.

Screenshot URL Webhook
๐Ÿ”—
Screenshot: Kolom URL Webhook
web-info/assets/screenshots/webhook-endpoint.jpeg
1080 x 2400 px
Langkah 3.3

Autentikasi Server Pihak Ketiga

Pilih tipe autentikasi (HMAC Signature, Bearer Token, Basic Auth, atau Custom Header) lalu isi Token / Secret Key. Khusus tipe Custom Header, isi juga Nama Header yang diinginkan (mis. X-Api-Key). Detail cara kerja tiap tipe ada di bagian 4.

๐Ÿ’ก Saat mengedit konfigurasi yang sudah ada, kosongkan kolom Token / Secret Key jika ingin tetap memakai secret lama โ€” isi hanya jika ingin menggantinya.
Screenshot Autentikasi Webhook
๐Ÿ”
Screenshot: Tipe Autentikasi & Token
web-info/assets/screenshots/webhook-autentikasi.jpeg
1080 x 2400 px
Langkah 3.4

Event yang Di-subscribe

Centang event yang ingin dikirim ke server Anda. Minimal satu event harus dipilih:

  • Pembaruan Foto Penghuni โ€” picture.updated
  • Presensi Masuk Gerbang โ€” presence.checkin
  • Presensi Keluar Gerbang โ€” presence.checkout
Screenshot Event Webhook
โ˜‘๏ธ
Screenshot: Daftar Event Webhook
web-info/assets/screenshots/webhook-events.jpeg
1080 x 2400 px
Kolom di Layar Parameter API Keterangan
Status Webhook is_active true/false. Wajib diisi saat menyimpan.
URL Webhook endpoint_url Wajib diisi, harus diawali http:// atau https://.
Tipe Autentikasi auth_type Salah satu dari hmac, bearer, basic, custom.
Token / Secret Key auth_token Wajib diisi saat konfigurasi pertama kali dibuat. Boleh dikosongkan saat edit untuk mempertahankan secret lama.
Nama Header Baru custom_header_name Hanya muncul & wajib diisi jika Tipe Autentikasi = custom. Nama HTTP header yang akan dikirim ke server Anda (mis. X-Api-Key) โ€” hanya huruf, angka, dan karakter - _ . ~ dst (tanpa spasi), maksimal 100 karakter.
Event yang Di-subscribe events Array berisi minimal 1 dari picture.updated, presence.checkin, presence.checkout.

Setelah semua kolom terisi, ketuk Simpan Konfigurasi. Jika ini pengisian pertama kali untuk lokasi tersebut, kolom Token / Secret Key wajib diisi.

4

Autentikasi & Keamanan Payload

SmartGate melampirkan header autentikasi pada setiap request webhook berdasarkan tipe yang dipilih. Server tujuan perlu memverifikasi header ini agar hanya menerima request yang sah dari SmartGate:

Tipe (auth_type) Header yang Dikirim Cara Kerja
Direkomendasikan
hmac
X-Signature: <hex> Signature dihitung dengan HMAC-SHA256(body_json, secret), hasil dalam format hexadecimal huruf kecil. Server Anda menghitung ulang HMAC dari raw body yang diterima dengan secret yang sama, lalu membandingkannya dengan header ini.
Umum
bearer
Authorization: Bearer <secret> Secret dikirim apa adanya sebagai bearer token pada header Authorization.
Perhatian
basic
Authorization: Basic <secret> Secret dikirim apa adanya setelah kata Basic โ€” tidak di-encode Base64 secara otomatis oleh sistem. Lihat catatan di bawah.
Baru
custom
<nama_header>: <secret> Nama header bebas sesuai isian Nama Header (custom_header_name), nilainya dari Token / Secret Key apa adanya. Cocok jika server Anda mengharuskan nama header spesifik di luar 3 tipe di atas (mis. X-Api-Key, X-Webhook-Token).
โš ๏ธ Catatan penting untuk tipe Basic Auth: berbeda dari standar HTTP Basic Auth pada umumnya (yang mengharapkan nilai base64(user:password)), SmartGate mengirim isi kolom Token / Secret Key langsung tanpa proses encoding tambahan. Jika server tujuan Anda mengharapkan format Basic Auth standar, hitung dan masukkan sendiri hasil base64(user:password) ke dalam kolom Token / Secret Key.

Jika kolom Token / Secret Key dibiarkan kosong (belum pernah diisi sama sekali), request webhook dikirim tanpa header autentikasi apa pun.

5

Uji Coba (Test) Webhook

Setelah konfigurasi disimpan, bagian Uji Coba Webhook muncul di bagian bawah layar untuk mengirim payload contoh langsung ke URL webhook tersimpan, tanpa perlu menunggu event sungguhan terjadi.

Langkah 5.1

Pilih Event Pengujian & Kirim

Pilih salah satu event pada dropdown Event Pengujian (ping, presence.checkin, presence.checkout, atau picture.updated), lalu ketuk tombol Uji Coba.

๐Ÿ’ก Tombol ini hanya aktif setelah konfigurasi webhook tersimpan (URL endpoint tidak kosong).
Screenshot Uji Coba Webhook
๐Ÿ“ก
Screenshot: Uji Coba & Hasil Pengujian
web-info/assets/screenshots/webhook-uji-coba.jpeg
1080 x 2400 px

Hasil pengujian ditampilkan dalam sebuah kartu berisi:

  • Status โ€” "Pengujian Berhasil" (hijau) jika server tujuan membalas HTTP 2xx, atau "Pengujian Gagal" (merah) jika sebaliknya atau koneksi gagal.
  • HTTP Status dan Waktu Respons (ms) dari server tujuan.
  • Request Payload โ€” isi JSON persis yang dikirim SmartGate.
  • Response Body โ€” isi balasan dari server tujuan, atau pesan error jika gagal terhubung.
6

Format Data yang Dikirim Webhook

Semua request webhook dikirim sebagai POST dengan header Content-Type: application/json. Setiap payload selalu memuat field dasar event, timestamp (format ISO-8601 UTC), dan location_id, ditambah field spesifik sesuai jenis event di bawah ini.

6.1 Test Ping โ€” LocationWebhookService.testWebhook

Dipicu manual dari tombol Uji Coba (lihat bagian 5). Semua payload uji coba โ€” apa pun event yang dipilih โ€” selalu memuat flag "is_test": true dan field message, dengan data contoh (dummy). Ini adalah penanda utama untuk membedakan pengiriman uji coba dari data sungguhan pada sistem Anda.

POST {endpoint_url} event: "ping" (default)
{
  "event": "ping",
  "timestamp": "2026-08-12T09:15:32Z",
  "location_id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "is_test": true,
  "message": "Ping test payload from SmartGate Webhook Dispatcher"
}
POST {endpoint_url} event: "picture.updated" (uji coba)
{
  "event": "picture.updated",
  "timestamp": "2026-08-12T09:15:32Z",
  "location_id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "is_test": true,
  "message": "Ping test payload from SmartGate Webhook Dispatcher",
  "user_id": "64a1f2e3d4c5b6a7f8e9d0c1",
  "user_name": "Test Resident",
  "phone": "08123456789",
  "user_code": "USR-99999",
  "photo_url": "https://api.smartgate.id/internal/photos/64a1f2e3d4c5b6a7f8e9d0c1?token=test",
  "approval_token": "apv_test_token",
  "approval_endpoint": "https://api.smartgate.id/v1/webhooks/photo-approval/64a1f2e3d4c5b6a7f8e9d0c1/apv_test_token"
}
POST {endpoint_url} event: "presence.checkin" / "presence.checkout" (uji coba)
{
  "event": "presence.checkin",
  "timestamp": "2026-08-12T09:15:32Z",
  "location_id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "is_test": true,
  "message": "Ping test payload from SmartGate Webhook Dispatcher",
  "gate_id": "gate-test",
  "gate_name": "Gerbang Utama Uji Coba",
  "user": {
    "id": "64a1f2e3d4c5b6a7f8e9d0c1",
    "name": "Test Resident",
    "role": "penghuni",
    "unit_no": "Blok A-12"
  },
  "verification_tier": "verified",
  "latitude": -6.2,
  "longitude": 106.816666
}

6.2 Perubahan Foto โ€” PhotoProcessingService.notifyHrForAllLocations

Dikirim otomatis setelah seorang penghuni berhasil mengunggah/memperbarui foto swafoto master, ke setiap lokasi aktif milik penghuni tersebut yang men-subscribe event picture.updated. Tidak seperti payload uji coba, payload sungguhan tidak memuat field is_test maupun message.

POST {endpoint_url} event: "picture.updated"
{
  "event": "picture.updated",
  "timestamp": "2026-08-12T09:15:32Z",
  "location_id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "user_id": "66a9b8c7d6e5f4a3b2c1d0e9",
  "user_name": "Budi Santoso",
  "phone": "081234567890",
  "user_code": "USR-00123",
  "userCode": "USR-00123",
  "photo_url": "https://api.smartgate.id/api/internal/photos/66a9b8c7d6e5f4a3b2c1d0e9?token=9f3c1a7e...b21a",
  "approval_token": "9f3c1a7e...b21a",
  "approval_endpoint": "https://api.smartgate.id/api/v1/webhooks/photo-approval/66a9b8c7d6e5f4a3b2c1d0e9/9f3c1a7e...b21a"
}

userCode (camelCase) adalah duplikat dari user_code yang dipertahankan untuk kompatibilitas sistem lama โ€” nilainya selalu identik.

Alur persetujuan foto (opsional): jika sistem HR Anda perlu menyetujui/menolak foto sebelum dianggap resmi, unduh gambar dari photo_url (URL ini sudah memuat token akses sekali pakai di query ?token=), lalu kirim keputusan ke approval_endpoint yang disertakan pada payload yang sama:

POST / PUT {approval_endpoint} dikirim oleh server Anda ke SmartGate
{
  "status": "approved",
  "token": "9f3c1a7e...b21a"
}

status harus "approved" atau "rejected"; token harus sama persis dengan approval_token yang diterima pada payload. Setiap kali foto diperbarui, token baru dibuat dan menggantikan token sebelumnya, sehingga token lama otomatis tidak berlaku lagi.

6.3 Presensi Masuk/Keluar โ€” CheckInOutService.callHrLogPresence

Dikirim secara sinkron tepat setelah presensi masuk/keluar gerbang berhasil dicatat (dan verifikasi wajah cocok), ke lokasi terkait jika event presence.checkin/presence.checkout di-subscribe.

POST {endpoint_url} event: "presence.checkin" | "presence.checkout"
{
  "event": "presence.checkin",
  "timestamp": "2026-08-12T08:02:11Z",
  "location_id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "gate_id": "66f2b3c4d5e6f7a8b9c0d1e2",
  "gate_name": "Gerbang Utama",
  "user": {
    "id": "66a9b8c7d6e5f4a3b2c1d0e9",
    "name": "Budi Santoso",
    "role": "penghuni",
    "unit_no": "Blok A-12"
  },
  "verification_tier": "verified",
  "latitude": -6.200123,
  "longitude": 106.816456
}

Kontrak respons yang wajib dipenuhi server Anda: berbeda dari dua event lain, hasil balasan server tujuan untuk event presensi dibaca dan disimpan kembali oleh SmartGate ke dalam riwayat aktivitas penghuni. Balas dengan salah satu bentuk berikut:

200 OK respons sukses dari server Anda
{
  "success": true,
  "data": {
    "checkIn": 1755000131000,
    "checkOut": null,
    "presenceDay": "2026-08-12",
    "hrEmployeeId": 4021,
    "attendanceStatus": "ON_TIME"
  }
}
200 OK respons gagal dari server Anda
{
  "success": false,
  "message": "Karyawan tidak ditemukan di sistem HR"
}
๐Ÿ’ก Webhook presensi bersifat notifikasi tambahan, bukan syarat presensi. Jika server Anda gagal dihubungi, timeout, atau membalas format yang tidak sesuai, presensi penghuni tetap tercatat sukses di SmartGate โ€” hanya data attendance yang ditandai error: true.
7

Pertanyaan Umum & Solusi Kendala (FAQ)

Kenapa menu "Konfigurasi Webhook" tidak muncul di Detail Lokasi?
Menu ini hanya tampil untuk pengguna dengan peran admin aktif pada lokasi tersebut. Pastikan akun Anda memiliki role admin, bukan penghuni/satpam.
Kenapa saat membuka layar webhook muncul pesan "Subskripsi Premium Dibutuhkan"?
Fitur webhook khusus untuk lokasi dengan tier langganan Premium yang aktif. Hubungi admin pusat/pengelola untuk meng-upgrade paket lokasi Anda.
Uji coba webhook selalu gagal padahal URL sudah benar, kenapa?
Periksa HTTP Status dan Response Body/pesan error pada kartu hasil pengujian. Penyebab umum: server tujuan menolak Content-Type application/json, firewall/whitelist IP memblokir server SmartGate, atau header autentikasi tidak sesuai ekspektasi server Anda (lihat bagian 4, terutama catatan Basic Auth).
Bagaimana cara mengganti Token/Secret Key tanpa mengubah pengaturan lain?
Buka kembali layar Konfigurasi Webhook, isi ulang kolom Token / Secret Key dengan nilai baru, lalu ketuk Simpan Konfigurasi. Kolom lain (URL, tipe autentikasi, event) tetap seperti semula jika tidak diubah.
Apa bedanya payload uji coba dengan payload event sungguhan?
Payload uji coba (dari tombol Uji Coba) selalu berisi data contoh/dummy dan menyertakan field "is_test": true serta message. Payload event sungguhan (foto/presensi asli) tidak pernah menyertakan kedua field tersebut.