REST API Documentation
Base URL: https://api.jwi.id/api
Generated at 2026-04-08 10:48:08
Bearer token (JWT)
Authorization: Bearer {token}
Token didapat dari endpoint login/register dan digunakan di endpoint yang memakai middleware auth:api. Untuk endpoint billing non-login gunakan header X-MYWIFI-KEY.
API Key: API key dikelola admin. Hubungi admin untuk mendapatkan atau mengaktifkan key.
- Gunakan header
Accept: application/jsonuntuk mendapatkan versi JSON. - Tambahkan header Authorization untuk semua endpoint yang membutuhkan autentikasi.
- Path pada tabel sudah termasuk prefix
/api.
Auth
10 endpointshttps://api.jwi.id/api/auth/register
No auth
Registrasi user baru sekaligus mengembalikan token login.
| Field | Type | Required | Note |
|---|---|---|---|
name |
string | required | Max 255 |
email |
required | Unik di tabel user | |
password |
string | required | Min 6, sertakan password_confirmation |
phone |
integer | required | Digit saja, 8-15 digit |
phonecode |
integer | required | Digit saja, 1-5 digit |
address |
string | optional | |
gender |
string | optional | Male atau Female |
image |
string | optional | Path gambar, default default1.jpg |
| Status | Description |
|---|---|
| 201 | Token bearer + data user yang baru dibuat. |
| 422 | Validasi gagal. |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600,
"data": {
"uid": "2f0d1e6b-1234-4c9f-bc36-6e5d4fabc001",
"name": "John Doe",
"email": "john@example.com",
"phone": 628123456789,
"phonecode": 62,
"address": "Jl. Merdeka 123",
"image": "default1.jpg",
"is_active": true,
"gender": "Male",
"role_name": "Customer"
}
}
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Email sudah terdaftar."
]
}
}
https://api.jwi.id/api/customer/profile-photo
Auth required
Upload foto profil (disimpan di folder CI3: assets/images/profile).
| Field | Type | Required | Note |
|---|---|---|---|
photo |
file | required | image jpg/jpeg/png/gif, max 2MB |
| Status | Description |
|---|---|
| 201 | Foto berhasil diupload. |
| 401 | Unauthenticated. |
| 422 | Validasi gagal. |
{
"status": "success",
"message": "Foto profil berhasil diunggah.",
"filename": "uuid.jpg",
"url": "https://api.jwi.id/api/assets/images/profile/uuid.jpg"
}
https://api.jwi.id/api/auth/login
No auth
Login menggunakan email atau no_services dan password.
| Field | Type | Required | Note |
|---|---|---|---|
identifier |
string | required | Email atau nomor layanan |
password |
string | required |
| Status | Description |
|---|---|
| 200 | Token bearer + data user. |
| 422 | Email atau password salah. |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600,
"data": {
"uid": "2f0d1e6b-1234-4c9f-bc36-6e5d4fabc001",
"name": "John Doe",
"email": "john@example.com",
"phone": 628123456789,
"phonecode": 62,
"address": "Jl. Merdeka 123",
"image": "default1.jpg",
"is_active": true,
"gender": "Male",
"role_name": "Customer"
}
}
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Email atau password tidak sesuai."
]
}
}
https://api.jwi.id/api/auth/forgot-password
No auth
Membuat OTP reset password menggunakan no_services pelanggan.
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | required | ID pelanggan/no_services |
| Status | Description |
|---|---|
| 200 | OTP dibuat dan disimpan di tabel user_token. |
| 404 | Data pelanggan tidak ditemukan. |
{
"status": "success",
"message": "Kode OTP berhasil dibuat.",
"destination": "628123456789",
"otp": "123456"
}
{
"status": "not_found",
"message": "Data pelanggan tidak ditemukan."
}
https://api.jwi.id/api/auth/verify-otp
No auth
Verifikasi kode OTP reset password.
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | required | ID pelanggan/no_services |
otp |
string | required | Kode OTP yang diterima (berlaku 5 menit) |
| Status | Description |
|---|---|
| 200 | OTP valid dan dihapus dari tabel user_token. |
| 404 | Data pelanggan tidak ditemukan. |
| 422 | OTP tidak valid atau nomor tujuan tidak tersedia. |
{
"status": "success",
"message": "Kode OTP valid."
}
{
"status": "failed",
"message": "Kode OTP tidak valid atau sudah digunakan."
}
https://api.jwi.id/api/auth/reset-password
No auth
Reset password menggunakan OTP yang valid.
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | required | ID pelanggan/no_services |
otp |
string | required | Kode OTP yang diterima (berlaku 5 menit) |
password |
string | required | Min 6 |
password_confirmation |
string | required | Sama dengan password |
| Status | Description |
|---|---|
| 200 | Password berhasil direset. |
| 404 | Data pelanggan atau user tidak ditemukan. |
| 422 | OTP tidak valid atau nomor tujuan tidak tersedia. |
{
"status": "success",
"message": "Password berhasil direset."
}
{
"status": "failed",
"message": "Kode OTP tidak valid atau sudah digunakan."
}
https://api.jwi.id/api/auth/me
Auth required
Mengambil profil user yang sedang login.
{
"uid": "2f0d1e6b-1234-4c9f-bc36-6e5d4fabc001",
"name": "John Doe",
"email": "john@example.com",
"phone": 628123456789,
"phonecode": 62,
"address": "Jl. Merdeka 123",
"image": "default1.jpg",
"is_active": true,
"gender": "Male",
"role_name": "Customer"
}
{
"message": "Unauthenticated."
}
https://api.jwi.id/api/auth/logout
Auth required
Logout dan mencabut token aktif.
{
"message": "Berhasil logout."
}
{
"message": "Unauthenticated."
}
https://api.jwi.id/api/auth/refresh
Auth required
Mendapatkan token baru dari token lama.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600,
"data": {
"uid": "2f0d1e6b-1234-4c9f-bc36-6e5d4fabc001",
"name": "John Doe",
"email": "john@example.com",
"phone": 628123456789,
"phonecode": 62,
"address": "Jl. Merdeka 123",
"image": "default1.jpg",
"is_active": true,
"gender": "Male",
"role_name": "Customer"
}
}
{
"message": "Unauthenticated."
}
https://api.jwi.id/api/auth/change-password
Auth required
Mengubah password user.
| Field | Type | Required | Note |
|---|---|---|---|
current_password |
string | required | |
password |
string | required | Min 6, sertakan password_confirmation |
| Status | Description |
|---|---|
| 200 | Password diperbarui. |
| 422 | Password lama salah atau validasi gagal. |
{
"message": "Password berhasil diperbarui."
}
{
"message": "The given data was invalid.",
"errors": {
"current_password": [
"Password lama tidak sesuai."
]
}
}
Region
1 endpointshttps://api.jwi.id/api/region
No auth
Daftar region (data dari tabel company).
| Status | Description |
|---|---|
| 200 | Daftar region ditemukan. |
{
"status": "success",
"message": "Data perusahaan ditemukan.",
"data": [
{
"id": 1,
"name": "Region Jakarta"
}
]
}
Package
1 endpointshttps://api.jwi.id/api/package
No auth
Daftar paket aktif dan public berdasarkan company_id (category berisi data package_category).
| Field | Type | Required | Note |
|---|---|---|---|
company_id |
integer | required |
| Status | Description |
|---|---|
| 200 | Data paket ditemukan. |
| 422 | Validasi gagal. |
{
"status": "success",
"message": "Data paket ditemukan.",
"data": [
{
"id": 12,
"name": "Home 50 Mbps",
"price": 300000,
"description": "Unlimited broadband",
"category_id": 3,
"category": {
"id": 3,
"name": "Internet"
},
"public": 1,
"is_active": 1,
"company_id": 1
}
]
}
{
"message": "The given data was invalid.",
"errors": {
"company_id": [
"The company id field is required."
]
}
}
Customer
8 endpointshttps://api.jwi.id/api/customer
Auth required
Detail pelanggan beserta layanan aktif.
| Status | Description |
|---|---|
| 200 | Data pelanggan ditemukan. |
| 404 | Pelanggan belum terdaftar. |
{
"status": "success",
"message": "Data pelanggan ditemukan.",
"customer": {
"uid": "cst-001",
"name": "John Doe",
"email": "john@example.com",
"phone": 628123456789,
"no_services": "ISP00123",
"address": "Jl. Fiber No. 1",
"address_verified_date": "2023-01-12",
"register_date": "2023-01-10",
"activation_date": "2023-01-11",
"email_verified_date": "2023-01-12",
"id_card_verified_date": null,
"id_type_id": 1,
"id_type": "Identity Card (KTP)",
"id_number": "3201010101010001",
"status": "active",
"service": {
"qty": 1,
"price": 300000,
"total": 300000,
"package": {
"name": "Home 50 Mbps",
"description": "Unlimited broadband"
}
}
}
}
{
"status": "not_subscribed",
"message": "Pengguna belum memiliki data pelanggan terdaftar."
}
https://api.jwi.id/api/customer
Auth required
Mendaftarkan user login ke tabel customer dan membuat layanan awal.
| Field | Type | Required | Note |
|---|---|---|---|
package_id |
integer | required | |
company_id |
integer | required | |
id_type_id |
integer | required | |
id_number |
string | required | Max 20 |
latitude |
numeric | optional | |
longitude |
numeric | optional |
| Status | Description |
|---|---|
| 201 | Pelanggan berhasil dibuat. |
| 409 | Pelanggan sudah terdaftar. |
| 404 | Paket tidak ditemukan. |
| 422 | Validasi gagal. |
{
"status": "success",
"message": "Pelanggan berhasil dibuat.",
"customer": {
"no_services": "1700000000",
"name": "John Doe",
"email": "john@example.com"
}
}
{
"status": "already_subscribed",
"message": "Pengguna sudah terdaftar sebagai pelanggan.",
"no_services": "1700000000"
}
{
"status": "not_found",
"message": "Paket layanan tidak ditemukan."
}
https://api.jwi.id/api/customer/id-types
Auth required
Daftar tipe identitas (KTP/Passport/SIM, dsb) untuk diisi pelanggan.
| Status | Description |
|---|---|
| 200 | Daftar tipe identitas tersedia. |
{
"status": "success",
"message": "Identification types retrieved.",
"id_types": [
{
"id": 1,
"name": "Identity Card (KTP)"
},
{
"id": 2,
"name": "Passport"
},
{
"id": 3,
"name": "Driving License (SIM)"
}
]
}
{
"message": "Unauthenticated."
}
https://api.jwi.id/api/customer/change-id-card
Auth required
Memperbarui tipe identitas dan nomor identitas pelanggan.
| Field | Type | Required | Note |
|---|---|---|---|
id_type_id |
integer | required | exists:m_id_card,id |
id_number |
string | required | Max 20 characters |
| Status | Description |
|---|---|
| 200 | Data identitas berhasil diperbarui. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
| 422 | Validasi gagal. |
| 403 | Identitas sudah diverifikasi, hubungi admin. |
{
"status": "success",
"message": "Identification updated.",
"customer": {
"id_type_id": 1,
"id_type": "Identity Card (KTP)",
"id_number": "3201010101010001"
}
}
{
"status": "forbidden",
"message": "Data identitas sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
{
"message": "The given data was invalid.",
"errors": {
"id_type_id": [
"The selected id type id is invalid."
]
}
}
https://api.jwi.id/api/customer/email
Auth required
Memperbarui email pelanggan (mengubah email di tabel customer dan user).
| Field | Type | Required | Note |
|---|---|---|---|
email |
required | Unique di tabel user dan customer |
| Status | Description |
|---|---|
| 200 | Email berhasil diperbarui. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
| 422 | Validasi gagal (email sudah dipakai). |
| 403 | Email sudah diverifikasi, hubungi admin. |
{
"status": "success",
"message": "Email berhasil diperbarui.",
"customer": {
"email": "new@example.com"
}
}
{
"status": "forbidden",
"message": "Email sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Email sudah digunakan."
]
}
}
https://api.jwi.id/api/customer/address
Auth required
Memperbarui alamat pelanggan.
| Field | Type | Required | Note |
|---|---|---|---|
address |
string | required | Max 255 characters |
| Status | Description |
|---|---|
| 200 | Alamat berhasil diperbarui. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
| 422 | Validasi gagal. |
| 403 | Alamat sudah diverifikasi, hubungi admin. |
{
"status": "success",
"message": "Alamat berhasil diperbarui.",
"customer": {
"address": "Jl. Baru No. 99"
}
}
{
"status": "forbidden",
"message": "Alamat sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
https://api.jwi.id/api/customer/phone
Auth required
Memperbarui nomor telepon pelanggan (phonecode dan nomor WA).
| Field | Type | Required | Note |
|---|---|---|---|
phonecode |
integer | required | Digit saja, 1-5 digit. Jika diisi 08 akan otomatis menjadi 62 |
phone |
integer | required | Digit saja, 8-15 digit |
| Status | Description |
|---|---|
| 200 | Nomor telepon berhasil diperbarui. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
| 422 | Validasi gagal. |
{
"status": "success",
"message": "Nomor telepon berhasil diperbarui.",
"customer": {
"phonecode": 62,
"phone": 8123456789
}
}
{
"message": "The given data was invalid.",
"errors": {
"phone": [
"The phone field is required."
]
}
}
https://api.jwi.id/api/customer/network-status
Auth required
Ambil status koneksi Mikrotik berdasarkan no_services. Hanya mengembalikan status koneksi (online/offline/isolir) dengan info IP & uptime.
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | required | ID pelanggan/no_services |
| Status | Description |
|---|---|
| 200 | Status berhasil diambil. |
| 401 | Unauthenticated. |
| 404 | Pelanggan atau router tidak ditemukan / user belum ada di Mikrotik. |
| 503 | Router tidak bisa dihubungi. |
| 403 | No layanan tidak sesuai akun login. |
| 409 | User belum disinkronkan ke Mikrotik. |
| 422 | Validasi input gagal. |
| 500 | Error internal (contoh library Mikrotik tidak ditemukan). |
{
"status": "success",
"message": "Status pelanggan berhasil diambil.",
"data": {
"no_services": "ISP00123",
"name": "John Doe",
"mode": "PPPOE",
"router": {
"alias": "RT-01"
},
"customer": {
"user_mikrotik": "john_pppoe",
"user_profile": "REG50M"
},
"connection": {
"status": "online",
"is_online": true,
"ip_address": "10.10.10.2",
"uptime": {
"raw": "1d2h3m4s",
"seconds": 93784,
"human": "1d 2h 3m 4s"
},
"notes": []
},
"usage": null,
"session": null
}
}
{
"status": "not_found_on_router",
"message": "User tidak ditemukan di Mikrotik (PPP Secret). Silakan sinkronisasi."
}
{
"status": "not_synced",
"message": "User belum disinkronkan ke Mikrotik."
}
{
"status": "unreachable",
"message": "Gagal terhubung ke router Mikrotik."
}
Helpdesk
5 endpointshttps://api.jwi.id/api/help
Auth required
Daftar tiket bantuan pelanggan.
| Field | Type | Required | Note |
|---|---|---|---|
status |
string | optional | Pisahkan koma, default pending,process. Gunakan all untuk tanpa filter. |
year |
integer | optional | Default tahun berjalan. |
{
"status": "success",
"message": "Data bantuan ditemukan.",
"customer": {
"name": "John Doe",
"no_services": "ISP00123",
"email": "john@example.com"
},
"data": [
{
"id": 1,
"no_ticket": "240101001",
"no_services": "ISP00123",
"description": "Internet down sejak pagi.",
"status": "pending",
"date_help": "2024-01-01",
"created_at": "2024-01-01 10:00:00",
"help_type": {
"name": "Gangguan koneksi"
},
"help_solution": {
"name": "Restart modem"
}
}
]
}
{
"status": "not_subscribed",
"message": "Pengguna belum memiliki data pelanggan terdaftar."
}
https://api.jwi.id/api/help/options
Auth required
Pilihan tipe bantuan dan solusi.
{
"status": "success",
"message": "Daftar tipe dan solusi bantuan.",
"help_types": [
{
"id": 1,
"name": "Gangguan koneksi"
}
],
"help_solutions": [
{
"id": 1,
"name": "Restart modem",
"solution": "Silakan matikan lalu nyalakan router.",
"help_id": 1
}
]
}
https://api.jwi.id/api/help
Auth required
Membuat tiket bantuan baru.
| Field | Type | Required | Note |
|---|---|---|---|
help_type |
integer | required | exists:help_type,help_id |
help_solution |
integer | required | exists:help_solution,hs_id |
description |
string | required |
| Status | Description |
|---|---|
| 201 | Tiket berhasil dibuat. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
| 422 | Validasi gagal. |
{
"status": "success",
"message": "Tiket bantuan berhasil dibuat.",
"data": {
"id": 2,
"no_ticket": "240101002",
"help_type": {
"name": "Gangguan koneksi"
},
"help_solution": {
"name": "Restart modem"
},
"description": "Internet sering putus-putus.",
"status": "pending",
"date_help": "2024-01-01"
}
}
{
"status": "not_subscribed",
"message": "Pengguna belum memiliki data pelanggan terdaftar."
}
https://api.jwi.id/api/help/timeline
Auth required
Timeline tiket bantuan tertentu.
| Field | Type | Required | Note |
|---|---|---|---|
id |
integer | optional | Wajib isi id atau no_ticket |
no_ticket |
string | optional |
| Status | Description |
|---|---|
| 200 | Timeline ditemukan. |
| 401 | Unauthenticated. |
| 404 | Tiket tidak ditemukan. |
| 422 | Parameter id/no_ticket wajib ada salah satu. |
{
"status": "success",
"message": "Timeline tiket bantuan ditemukan.",
"ticket": {
"id": 1,
"no_ticket": "240101001"
},
"data": [
{
"remark": "Tiket dibuat oleh pelanggan.",
"status": "pending",
"teknisi": "John Doe",
"updated_at": "2024-01-01 10:00:00"
},
{
"remark": "Teknisi sedang menuju lokasi.",
"status": "process",
"teknisi": "Admin Helpdesk",
"updated_at": "2024-01-01 11:30:00"
}
]
}
{
"status": "not_found",
"message": "Tiket bantuan tidak ditemukan untuk pelanggan ini."
}
https://api.jwi.id/api/help/close
Auth required
Menutup tiket bantuan.
| Field | Type | Required | Note |
|---|---|---|---|
id |
integer | optional | |
no_ticket |
string | optional | |
remark |
string | required |
| Status | Description |
|---|---|
| 200 | Tiket ditutup. |
| 401 | Unauthenticated. |
| 404 | Tiket tidak ditemukan. |
| 422 | Parameter id/no_ticket wajib ada salah satu. |
{
"status": "success",
"message": "Tiket bantuan telah ditutup.",
"ticket": {
"id": 1,
"no_ticket": "240101001"
},
"timeline": {
"remark": "Tiket ditutup oleh pelanggan.",
"status": "closed",
"teknisi": "John Doe",
"action": "by customer",
"updated_at": "2024-01-01 12:00:00"
}
}
{
"status": "not_found",
"message": "Tiket bantuan tidak ditemukan untuk pelanggan ini."
}
Invoice
1 endpointshttps://api.jwi.id/api/invoice
Auth required
Daftar tagihan pelanggan.
| Field | Type | Required | Note |
|---|---|---|---|
status |
string | optional | Isi all untuk semua status. |
month |
integer | optional | |
year |
integer | optional |
| Status | Description |
|---|---|
| 200 | Data tagihan ditemukan. |
| 401 | Unauthenticated. |
| 404 | Pelanggan belum terdaftar. |
{
"status": "success",
"message": "Data tagihan ditemukan.",
"customer": {
"name": "John Doe",
"no_services": "ISP00123",
"email": "john@example.com"
},
"data": [
{
"invoice": "INV-2401-001",
"month": 1,
"year": 2024,
"status": "unpaid",
"due_date": "2024-01-10",
"amount": 350000,
"tax": 0,
"discount": 0,
"period": "January 2024",
"payment_codes": {
"va_bni": "999001ISP00123",
"alfamart": "ALFAISP00123",
"indomaret": "INDOISP00123"
},
"details": [
{
"name": "Paket Internet 50 Mbps",
"price": 300000,
"qty": 1,
"disc": 0,
"total": 300000
},
{
"name": "PPN",
"price": 50000,
"qty": 1,
"disc": 0,
"total": 50000
}
]
}
]
}
{
"status": "not_subscribed",
"message": "Pengguna belum memiliki data pelanggan terdaftar."
}
Notification (Auth User)
4 endpointshttps://api.jwi.id/api/notification
Auth required
Daftar notifikasi milik user login (JWT), termasuk ringkasan status delivery per device/token. Data otomatis difilter berdasarkan user/token yang terkait.
| Field | Type | Required | Note |
|---|---|---|---|
per_page |
integer | optional | Default 20, max 100 |
type |
string | optional | Filter jenis notifikasi, contoh: fcm_invoice_paid |
status |
string | optional | Filter delivery status: pending | sent | failed |
| Status | Description |
|---|---|
| 200 | Daftar notifikasi berhasil diambil. |
| 401 | Unauthenticated. |
{
"status": "success",
"message": "Daftar notifikasi berhasil diambil.",
"data": [
{
"id": 12,
"title": "Tagihan Terbit",
"body": "Tagihan INV-2401-001 periode January 2024 sudah terbit.",
"type": "fcm_invoice_created",
"reference_type": "invoice",
"reference_id": 2401001,
"data_payload": "{\"payload\":{\"no_services\":\"ISP00123\",\"title\":\"Tagihan Terbit\",\"body\":\"Tagihan INV-2401-001 periode January 2024 sudah terbit.\"}}",
"created_at": "2026-03-06 10:15:12",
"updated_at": "2026-03-06 10:15:12",
"summary": {
"total": 2,
"sent": 1,
"failed": 1,
"pending": 0,
"last_sent_at": "2026-03-06 10:15:13"
},
"deliveries": [
{
"id": 55,
"fcm_token_id": 7,
"token": "fcm_token_abc...",
"status": "sent",
"response": "{\"name\":\"projects/x/messages/abc\"}",
"error_message": null,
"sent_at": "2026-03-06 10:15:13",
"created_at": "2026-03-06 10:15:12",
"updated_at": "2026-03-06 10:15:13"
},
{
"id": 56,
"fcm_token_id": 8,
"token": "fcm_token_xyz...",
"status": "failed",
"response": "{\"error\":\"Requested entity was not found.\"}",
"error_message": "Requested entity was not found.",
"sent_at": null,
"created_at": "2026-03-06 10:15:12",
"updated_at": "2026-03-06 10:15:13"
}
]
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 1,
"last_page": 1
},
"filters": {
"type": null,
"status": null
}
}
{
"message": "Unauthenticated."
}
https://api.jwi.id/api/notification/token
Auth required
Register / update token FCM perangkat milik user login.
| Field | Type | Required | Note |
|---|---|---|---|
token |
string | required | |
platform |
string | optional | android | ios | web |
device_name |
string | optional | |
app_version |
string | optional |
| Status | Description |
|---|---|
| 200 | Token notifikasi berhasil disimpan. |
| 401 | Unauthenticated. |
| 422 | Validasi input token gagal. |
https://api.jwi.id/api/notification/token
Auth required
Nonaktifkan token FCM perangkat milik user login.
| Field | Type | Required | Note |
|---|---|---|---|
token |
string | required |
| Status | Description |
|---|---|
| 200 | Token dinonaktifkan / sudah tidak aktif (idempotent). |
| 401 | Unauthenticated. |
| 422 | Validasi input token gagal. |
https://api.jwi.id/api/notification/test
Auth required
Kirim test push ke semua token aktif milik user login.
| Field | Type | Required | Note |
|---|---|---|---|
title |
string | optional | |
body |
string | optional | |
data |
object | optional |
| Status | Description |
|---|---|
| 200 | Pengiriman test notifikasi selesai. |
| 401 | Unauthenticated. |
| 404 | Belum ada token perangkat terdaftar. |
| 422 | Validasi input/Firebase runtime error. |
| 500 | Gagal mengirim notifikasi Firebase (internal). |
Billing (API Key)
3 endpointshttps://api.jwi.id/api/billing/detail
No auth
Ambil data tagihan berdasarkan nomor layanan atau nomor invoice. Mendukung filter opsional status/periode, termasuk pesan spesifik untuk no_services salah/tidak terdaftar/lunas.
| Name | Required | Note |
|---|---|---|
X-MYWIFI-KEY |
required | API key dari tabel keys |
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | optional | Wajib jika invoice tidak dikirim. Format: huruf/angka/_/- (1-40 karakter). |
invoice |
string | optional | Bisa satu atau beberapa invoice dipisah koma. |
status |
string | optional | SUDAH BAYAR / BELUM BAYAR / paid / unpaid / all |
month |
integer | optional | 1-12 |
year |
integer | optional | contoh 2026 |
curl -X GET "https://api.jwi.id/api/billing/detail?no_services=28900001&status=BELUM%20BAYAR&month=2&year=2026" -H "X-MYWIFI-KEY: YOUR_KEY"
| Status | Description |
|---|---|
| 200 | Data tagihan ditemukan. |
| 400 | API key tidak dikirim, atau no_services/invoice tidak dikirim. |
| 403 | API key atau IP tidak diizinkan. |
| 404 | no_services tidak terdaftar, belum punya tagihan periode tersebut, invoice tidak ditemukan, atau hasil filter kosong (dengan error_code). |
| 422 | Format no_services tidak valid, atau nilai status/month/year tidak valid (dengan error_code). |
{
"status": true,
"data": [
{
"invoice": 230130001,
"month": 1,
"year": 2023,
"period": "January 2023",
"name": "John Doe",
"no_services": "ISP00123",
"amount": 277500,
"status": "BELUM BAYAR",
"due_date": "2023-01-10",
"isolir_date": "2023-01-20",
"payment_date": null,
"detail": [
{
"price": 250000,
"qty": 1,
"disc": 0,
"total": 250000,
"name": "Internet 50 Mbps",
"category": "Internet",
"remark": "-"
},
{
"price": 27500,
"qty": 1,
"disc": 0,
"total": 27500,
"name": "PPN",
"category": "Tax",
"remark": "-"
}
]
}
]
}
{
"status": false,
"error_code": "NO_SERVICES_NOT_REGISTERED",
"message": "Nomor layanan 99999999 tidak terdaftar. Periksa kembali no_services."
}
{
"status": false,
"error_code": "ALL_BILLS_PAID",
"message": "Semua tagihan pelanggan sudah lunas pada periode yang diminta."
}
{
"status": false,
"error_code": "INVALID_NO_SERVICES_FORMAT",
"message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
https://api.jwi.id/api/billing/unpaid
No auth
Ambil tagihan berdasarkan nomor layanan dengan default status BELUM BAYAR. Mendukung override filter status/periode dan menampilkan alasan spesifik jika data kosong.
| Name | Required | Note |
|---|---|---|
X-MYWIFI-KEY |
required | API key dari tabel keys |
| Field | Type | Required | Note |
|---|---|---|---|
no_services |
string | required | Format: huruf/angka/_/- (1-40 karakter). |
status |
string | optional | Default BELUM BAYAR. Opsi: SUDAH BAYAR / BELUM BAYAR / paid / unpaid / all |
month |
integer | optional | 1-12 |
year |
integer | optional | contoh 2026 |
curl -X GET "https://api.jwi.id/api/billing/unpaid?no_services=28900001&month=2&year=2026" -H "X-MYWIFI-KEY: YOUR_KEY"
| Status | Description |
|---|---|
| 200 | Data tagihan ditemukan. |
| 400 | API key tidak dikirim. |
| 403 | API key atau IP tidak diizinkan. |
| 404 | no_services tidak terdaftar, belum punya tagihan periode tersebut, atau semua tagihan sudah lunas (dengan error_code). |
| 422 | Format no_services tidak valid, atau nilai status/month/year tidak valid (dengan error_code). |
{
"status": true,
"data": [
{
"invoice": 230130001,
"month": 1,
"year": 2023,
"period": "January 2023",
"name": "John Doe",
"no_services": "ISP00123",
"amount": 277500,
"status": "BELUM BAYAR",
"due_date": "2023-01-10",
"isolir_date": "2023-01-20",
"payment_date": null,
"detail": [
{
"price": 250000,
"qty": 1,
"disc": 0,
"total": 250000,
"name": "Internet 50 Mbps",
"category": "Internet",
"remark": "-"
},
{
"price": 27500,
"qty": 1,
"disc": 0,
"total": 27500,
"name": "PPN",
"category": "Tax",
"remark": "-"
}
]
}
]
}
{
"status": false,
"error_code": "ALL_BILLS_PAID",
"message": "Semua tagihan pelanggan sudah lunas pada periode yang diminta."
}
{
"status": false,
"error_code": "NO_BILLS_IN_PERIOD",
"message": "Pelanggan belum memiliki tagihan pada periode yang diminta."
}
{
"status": false,
"error_code": "INVALID_NO_SERVICES_FORMAT",
"message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
https://api.jwi.id/api/billing/mark-as-paid
No auth
Set status tagihan menjadi SUDAH BAYAR berdasarkan invoice + no_services + reference_no, dengan validasi spesifik relasi invoice dan nomor layanan.
| Name | Required | Note |
|---|---|---|
X-MYWIFI-KEY |
required | API key dari tabel keys |
| Field | Type | Required | Note |
|---|---|---|---|
invoice |
string | required | |
no_services |
string | required | Format: huruf/angka/_/- (1-40 karakter). |
reference_no |
string | required | Nomor referensi dari payment |
curl -X POST "https://api.jwi.id/api/billing/mark-as-paid" -H "X-MYWIFI-KEY: YOUR_KEY" -H "Content-Type: application/json" -d '{"invoice":"230130001","no_services":"28900001","reference_no":"REF123456"}'
| Status | Description |
|---|---|
| 200 | Status diperbarui. |
| 400 | API key tidak dikirim. |
| 403 | API key atau IP tidak diizinkan. |
| 404 | no_services tidak terdaftar, invoice tidak ditemukan, atau invoice tidak terhubung dengan no_services (dengan error_code). |
| 409 | Invoice sudah dibayar sebelumnya. |
| 422 | Validasi gagal (invoice/no_services/reference_no wajib) atau format no_services tidak valid (dengan error_code). |
{
"status": true,
"message": "Tagihan berhasil diperbarui menjadi sudah dibayar"
}
{
"status": false,
"error_code": "INVOICE_SERVICE_MISMATCH",
"message": "Invoice ditemukan, tetapi tidak terhubung dengan nomor layanan 28900001."
}
{
"status": false,
"error_code": "INVOICE_ALREADY_PAID",
"message": "Invoice 230130001 sudah dibayar sebelumnya."
}
{
"status": false,
"error_code": "INVALID_NO_SERVICES_FORMAT",
"message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
Notification (API Key)
2 endpointshttps://api.jwi.id/api/notification/test-push
No auth
Endpoint testing Firebase push untuk admin/integrasi. Default dry_run=true (hanya validasi target token). Ubah dry_run=false untuk mengirim notifikasi sungguhan. Token selalu diambil otomatis dari database fcm_tokens berdasarkan no_services/email.
| Name | Required | Note |
|---|---|---|
X-MYWIFI-KEY |
required | API key dari tabel keys |
| Field | Type | Required | Note |
|---|---|---|---|
title |
string | optional | Default: Test Notifikasi Firebase |
body |
string | optional | |
no_services |
string | optional | |
email |
string | optional | |
data |
object | optional | |
dry_run |
boolean | optional | Default true |
curl -X POST "https://api.jwi.id/api/notification/test-push" -H "X-MYWIFI-KEY: YOUR_KEY" -H "Content-Type: application/json" -d '{"no_services":"28900001","title":"Test Notif","body":"Ini test dari REST API","dry_run":true}'
| Status | Description |
|---|---|
| 200 | Dry run sukses atau pengiriman test selesai. |
| 400 | API key tidak dikirim. |
| 403 | API key atau IP tidak diizinkan. |
| 404 | Target token tidak ditemukan. |
| 422 | Validasi input/Firebase runtime error. |
| 500 | Gagal mengirim notifikasi Firebase (internal). |
{
"status": "success",
"message": "Dry run berhasil. Target token ditemukan dan siap dikirim.",
"dry_run": true,
"resolved": {
"no_services": "28900001",
"email": null,
"matched_tokens": 2
},
"payload_preview": {
"title": "Test Notif",
"body": "Ini test dari REST API",
"data": {
"source": "ci3"
}
}
}
{
"status": "success",
"message": "Test push notifikasi selesai.",
"dry_run": false,
"summary": {
"target": 2,
"success": 2,
"failed": 0,
"invalid_tokens": 0
}
}
https://api.jwi.id/api/notification/push
No auth
Kirim push notifikasi produksi ke target token berdasarkan no_services/email/tokens.
| Name | Required | Note |
|---|---|---|
X-MYWIFI-KEY |
required | API key dari tabel keys |
| Field | Type | Required | Note |
|---|---|---|---|
title |
string | required | |
body |
string | required | |
no_services |
string | optional | |
email |
string | optional | |
tokens |
array[string] | optional | |
data |
object | optional |
curl -X POST "https://api.jwi.id/api/notification/push" -H "X-MYWIFI-KEY: YOUR_KEY" -H "Content-Type: application/json" -d '{"no_services":"28900001","title":"Pembayaran Berhasil","body":"Tagihan INV-001 sudah dibayar","data":{"type":"invoice_paid"}}'
| Status | Description |
|---|---|
| 200 | Pengiriman notifikasi selesai. |
| 400 | API key tidak dikirim. |
| 403 | API key atau IP tidak diizinkan. |
| 404 | Target token tidak ditemukan. |
| 422 | Validasi input/Firebase runtime error. |
| 500 | Gagal mengirim notifikasi Firebase (internal). |
Response Codes
11 status codes| Status | Description |
|---|---|
| 200 | Request berhasil diproses. |
| 201 | Data berhasil dibuat/upload. |
| 400 | Request tidak valid di level middleware (contoh: API key tidak dikirim). |
| 401 | Token auth tidak valid/expired atau user belum login. |
| 403 | Akses ditolak (contoh: API key invalid atau IP tidak diizinkan). |
| 404 | Data/target tidak ditemukan. |
| 409 | Konflik state data (contoh: sudah dibayar/sudah tersubscribe). |
| 422 | Validasi input gagal atau request business rule tidak terpenuhi. |
| 500 | Terjadi error internal server. |
| 502 | Dependency upstream gagal (contoh: vendor WhatsApp gagal kirim). |
| 503 | Service dependency tidak tersedia/unreachable. |