REST API Documentation

Base URL: https://api.jwi.id/api

Generated at 2026-04-08 10:48:08

Version 1
Authentication

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.

Tips
  • Gunakan header Accept: application/json untuk mendapatkan versi JSON.
  • Tambahkan header Authorization untuk semua endpoint yang membutuhkan autentikasi.
  • Path pada tabel sudah termasuk prefix /api.
Auth
10 endpoints
POST https://api.jwi.id/api/auth/register No auth

Registrasi user baru sekaligus mengembalikan token login.

Body
Field Type Required Note
name string required Max 255
email 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
Responses
Status Description
201 Token bearer + data user yang baru dibuat.
422 Validasi gagal.
Sample responses
201 Created 201
{
    "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"
    }
}
422 Validation error 422
{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "Email sudah terdaftar."
        ]
    }
}
POST https://api.jwi.id/api/customer/profile-photo Auth required

Upload foto profil (disimpan di folder CI3: assets/images/profile).

Body
Field Type Required Note
photo file required image jpg/jpeg/png/gif, max 2MB
Responses
Status Description
201 Foto berhasil diupload.
401 Unauthenticated.
422 Validasi gagal.
Sample responses
201 Created 201
{
    "status": "success",
    "message": "Foto profil berhasil diunggah.",
    "filename": "uuid.jpg",
    "url": "https://api.jwi.id/api/assets/images/profile/uuid.jpg"
}
POST https://api.jwi.id/api/auth/login No auth

Login menggunakan email atau no_services dan password.

Body
Field Type Required Note
identifier string required Email atau nomor layanan
password string required
Responses
Status Description
200 Token bearer + data user.
422 Email atau password salah.
Sample responses
200 OK 200
{
    "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"
    }
}
422 Login gagal 422
{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "Email atau password tidak sesuai."
        ]
    }
}
POST https://api.jwi.id/api/auth/forgot-password No auth

Membuat OTP reset password menggunakan no_services pelanggan.

Body
Field Type Required Note
no_services string required ID pelanggan/no_services
Responses
Status Description
200 OTP dibuat dan disimpan di tabel user_token.
404 Data pelanggan tidak ditemukan.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Kode OTP berhasil dibuat.",
    "destination": "628123456789",
    "otp": "123456"
}
404 Tidak ditemukan 404
{
    "status": "not_found",
    "message": "Data pelanggan tidak ditemukan."
}
POST https://api.jwi.id/api/auth/verify-otp No auth

Verifikasi kode OTP reset password.

Body
Field Type Required Note
no_services string required ID pelanggan/no_services
otp string required Kode OTP yang diterima (berlaku 5 menit)
Responses
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.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Kode OTP valid."
}
422 OTP tidak valid 422
{
    "status": "failed",
    "message": "Kode OTP tidak valid atau sudah digunakan."
}
POST https://api.jwi.id/api/auth/reset-password No auth

Reset password menggunakan OTP yang valid.

Body
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
Responses
Status Description
200 Password berhasil direset.
404 Data pelanggan atau user tidak ditemukan.
422 OTP tidak valid atau nomor tujuan tidak tersedia.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Password berhasil direset."
}
422 OTP tidak valid 422
{
    "status": "failed",
    "message": "Kode OTP tidak valid atau sudah digunakan."
}
GET https://api.jwi.id/api/auth/me Auth required

Mengambil profil user yang sedang login.

Sample responses
200 OK 200
{
    "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"
}
401 Unauthenticated 401
{
    "message": "Unauthenticated."
}
POST https://api.jwi.id/api/auth/logout Auth required

Logout dan mencabut token aktif.

Sample responses
200 OK 200
{
    "message": "Berhasil logout."
}
401 Unauthenticated 401
{
    "message": "Unauthenticated."
}
POST https://api.jwi.id/api/auth/refresh Auth required

Mendapatkan token baru dari token lama.

Sample responses
200 OK 200
{
    "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"
    }
}
401 Unauthenticated 401
{
    "message": "Unauthenticated."
}
POST https://api.jwi.id/api/auth/change-password Auth required

Mengubah password user.

Body
Field Type Required Note
current_password string required
password string required Min 6, sertakan password_confirmation
Responses
Status Description
200 Password diperbarui.
422 Password lama salah atau validasi gagal.
Sample responses
200 OK 200
{
    "message": "Password berhasil diperbarui."
}
422 Password lama salah 422
{
    "message": "The given data was invalid.",
    "errors": {
        "current_password": [
            "Password lama tidak sesuai."
        ]
    }
}
Region
1 endpoints
GET https://api.jwi.id/api/region No auth

Daftar region (data dari tabel company).

Responses
Status Description
200 Daftar region ditemukan.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Data perusahaan ditemukan.",
    "data": [
        {
            "id": 1,
            "name": "Region Jakarta"
        }
    ]
}
Package
1 endpoints
POST https://api.jwi.id/api/package No auth

Daftar paket aktif dan public berdasarkan company_id (category berisi data package_category).

Body
Field Type Required Note
company_id integer required
Responses
Status Description
200 Data paket ditemukan.
422 Validasi gagal.
Sample responses
200 OK 200
{
    "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
        }
    ]
}
422 Validation error 422
{
    "message": "The given data was invalid.",
    "errors": {
        "company_id": [
            "The company id field is required."
        ]
    }
}
Customer
8 endpoints
GET https://api.jwi.id/api/customer Auth required

Detail pelanggan beserta layanan aktif.

Responses
Status Description
200 Data pelanggan ditemukan.
404 Pelanggan belum terdaftar.
Sample responses
200 OK 200
{
    "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"
            }
        }
    }
}
404 Not subscribed 404
{
    "status": "not_subscribed",
    "message": "Pengguna belum memiliki data pelanggan terdaftar."
}
POST https://api.jwi.id/api/customer Auth required

Mendaftarkan user login ke tabel customer dan membuat layanan awal.

Body
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
Responses
Status Description
201 Pelanggan berhasil dibuat.
409 Pelanggan sudah terdaftar.
404 Paket tidak ditemukan.
422 Validasi gagal.
Sample responses
201 Created 201
{
    "status": "success",
    "message": "Pelanggan berhasil dibuat.",
    "customer": {
        "no_services": "1700000000",
        "name": "John Doe",
        "email": "john@example.com"
    }
}
409 Already subscribed 409
{
    "status": "already_subscribed",
    "message": "Pengguna sudah terdaftar sebagai pelanggan.",
    "no_services": "1700000000"
}
404 Package not found 404
{
    "status": "not_found",
    "message": "Paket layanan tidak ditemukan."
}
GET https://api.jwi.id/api/customer/id-types Auth required

Daftar tipe identitas (KTP/Passport/SIM, dsb) untuk diisi pelanggan.

Responses
Status Description
200 Daftar tipe identitas tersedia.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Identification types retrieved.",
    "id_types": [
        {
            "id": 1,
            "name": "Identity Card (KTP)"
        },
        {
            "id": 2,
            "name": "Passport"
        },
        {
            "id": 3,
            "name": "Driving License (SIM)"
        }
    ]
}
401 Unauthenticated 401
{
    "message": "Unauthenticated."
}
PUT https://api.jwi.id/api/customer/change-id-card Auth required

Memperbarui tipe identitas dan nomor identitas pelanggan.

Body
Field Type Required Note
id_type_id integer required exists:m_id_card,id
id_number string required Max 20 characters
Responses
Status Description
200 Data identitas berhasil diperbarui.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
422 Validasi gagal.
403 Identitas sudah diverifikasi, hubungi admin.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Identification updated.",
    "customer": {
        "id_type_id": 1,
        "id_type": "Identity Card (KTP)",
        "id_number": "3201010101010001"
    }
}
403 Verified 403
{
    "status": "forbidden",
    "message": "Data identitas sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
422 Validation error 422
{
    "message": "The given data was invalid.",
    "errors": {
        "id_type_id": [
            "The selected id type id is invalid."
        ]
    }
}
PUT https://api.jwi.id/api/customer/email Auth required

Memperbarui email pelanggan (mengubah email di tabel customer dan user).

Body
Field Type Required Note
email email required Unique di tabel user dan customer
Responses
Status Description
200 Email berhasil diperbarui.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
422 Validasi gagal (email sudah dipakai).
403 Email sudah diverifikasi, hubungi admin.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Email berhasil diperbarui.",
    "customer": {
        "email": "new@example.com"
    }
}
403 Verified 403
{
    "status": "forbidden",
    "message": "Email sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
422 Validation error 422
{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "Email sudah digunakan."
        ]
    }
}
PUT https://api.jwi.id/api/customer/address Auth required

Memperbarui alamat pelanggan.

Body
Field Type Required Note
address string required Max 255 characters
Responses
Status Description
200 Alamat berhasil diperbarui.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
422 Validasi gagal.
403 Alamat sudah diverifikasi, hubungi admin.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Alamat berhasil diperbarui.",
    "customer": {
        "address": "Jl. Baru No. 99"
    }
}
403 Verified 403
{
    "status": "forbidden",
    "message": "Alamat sudah diverifikasi. Silakan hubungi admin untuk perubahan."
}
PUT https://api.jwi.id/api/customer/phone Auth required

Memperbarui nomor telepon pelanggan (phonecode dan nomor WA).

Body
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
Responses
Status Description
200 Nomor telepon berhasil diperbarui.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
422 Validasi gagal.
Sample responses
200 OK 200
{
    "status": "success",
    "message": "Nomor telepon berhasil diperbarui.",
    "customer": {
        "phonecode": 62,
        "phone": 8123456789
    }
}
422 Validation error 422
{
    "message": "The given data was invalid.",
    "errors": {
        "phone": [
            "The phone field is required."
        ]
    }
}
POST 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.

Body
Field Type Required Note
no_services string required ID pelanggan/no_services
Responses
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).
Sample responses
200 OK 200
{
    "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
    }
}
404 Not found on router 404
{
    "status": "not_found_on_router",
    "message": "User tidak ditemukan di Mikrotik (PPP Secret). Silakan sinkronisasi."
}
409 Not synced 409
{
    "status": "not_synced",
    "message": "User belum disinkronkan ke Mikrotik."
}
503 Unreachable 503
{
    "status": "unreachable",
    "message": "Gagal terhubung ke router Mikrotik."
}
Helpdesk
5 endpoints
GET https://api.jwi.id/api/help Auth required

Daftar tiket bantuan pelanggan.

Query Params
Field Type Required Note
status string optional Pisahkan koma, default pending,process. Gunakan all untuk tanpa filter.
year integer optional Default tahun berjalan.
Sample responses
200 OK 200
{
    "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"
            }
        }
    ]
}
404 Not subscribed 404
{
    "status": "not_subscribed",
    "message": "Pengguna belum memiliki data pelanggan terdaftar."
}
GET https://api.jwi.id/api/help/options Auth required

Pilihan tipe bantuan dan solusi.

Sample responses
200 OK 200
{
    "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
        }
    ]
}
POST https://api.jwi.id/api/help Auth required

Membuat tiket bantuan baru.

Body
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
Responses
Status Description
201 Tiket berhasil dibuat.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
422 Validasi gagal.
Sample responses
201 Created 201
{
    "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"
    }
}
404 Not subscribed 404
{
    "status": "not_subscribed",
    "message": "Pengguna belum memiliki data pelanggan terdaftar."
}
GET https://api.jwi.id/api/help/timeline Auth required

Timeline tiket bantuan tertentu.

Query Params
Field Type Required Note
id integer optional Wajib isi id atau no_ticket
no_ticket string optional
Responses
Status Description
200 Timeline ditemukan.
401 Unauthenticated.
404 Tiket tidak ditemukan.
422 Parameter id/no_ticket wajib ada salah satu.
Sample responses
200 OK 200
{
    "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"
        }
    ]
}
404 Not found 404
{
    "status": "not_found",
    "message": "Tiket bantuan tidak ditemukan untuk pelanggan ini."
}
POST https://api.jwi.id/api/help/close Auth required

Menutup tiket bantuan.

Body
Field Type Required Note
id integer optional
no_ticket string optional
remark string required
Responses
Status Description
200 Tiket ditutup.
401 Unauthenticated.
404 Tiket tidak ditemukan.
422 Parameter id/no_ticket wajib ada salah satu.
Sample responses
200 OK 200
{
    "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"
    }
}
404 Not found 404
{
    "status": "not_found",
    "message": "Tiket bantuan tidak ditemukan untuk pelanggan ini."
}
Invoice
1 endpoints
GET https://api.jwi.id/api/invoice Auth required

Daftar tagihan pelanggan.

Query Params
Field Type Required Note
status string optional Isi all untuk semua status.
month integer optional
year integer optional
Responses
Status Description
200 Data tagihan ditemukan.
401 Unauthenticated.
404 Pelanggan belum terdaftar.
Sample responses
200 OK 200
{
    "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
                }
            ]
        }
    ]
}
404 Not subscribed 404
{
    "status": "not_subscribed",
    "message": "Pengguna belum memiliki data pelanggan terdaftar."
}
Notification (Auth User)
4 endpoints
GET https://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.

Query Params
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
Responses
Status Description
200 Daftar notifikasi berhasil diambil.
401 Unauthenticated.
Sample responses
200 OK 200
{
    "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
    }
}
401 Unauthorized 401
{
    "message": "Unauthenticated."
}
POST https://api.jwi.id/api/notification/token Auth required

Register / update token FCM perangkat milik user login.

Body
Field Type Required Note
token string required
platform string optional android | ios | web
device_name string optional
app_version string optional
Responses
Status Description
200 Token notifikasi berhasil disimpan.
401 Unauthenticated.
422 Validasi input token gagal.
DELETE https://api.jwi.id/api/notification/token Auth required

Nonaktifkan token FCM perangkat milik user login.

Body
Field Type Required Note
token string required
Responses
Status Description
200 Token dinonaktifkan / sudah tidak aktif (idempotent).
401 Unauthenticated.
422 Validasi input token gagal.
POST https://api.jwi.id/api/notification/test Auth required

Kirim test push ke semua token aktif milik user login.

Body
Field Type Required Note
title string optional
body string optional
data object optional
Responses
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 endpoints
GET https://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.

Headers
Name Required Note
X-MYWIFI-KEY required API key dari tabel keys
Query Params
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
Sample CURL
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"
Responses
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).
Sample responses
200 OK 200
{
    "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": "-"
                }
            ]
        }
    ]
}
404 No Services Not Registered 404
{
    "status": false,
    "error_code": "NO_SERVICES_NOT_REGISTERED",
    "message": "Nomor layanan 99999999 tidak terdaftar. Periksa kembali no_services."
}
404 Customer Paid Off 404
{
    "status": false,
    "error_code": "ALL_BILLS_PAID",
    "message": "Semua tagihan pelanggan sudah lunas pada periode yang diminta."
}
422 Invalid no_services Format 422
{
    "status": false,
    "error_code": "INVALID_NO_SERVICES_FORMAT",
    "message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
GET 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.

Headers
Name Required Note
X-MYWIFI-KEY required API key dari tabel keys
Query Params
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
Sample CURL
curl -X GET "https://api.jwi.id/api/billing/unpaid?no_services=28900001&month=2&year=2026" -H "X-MYWIFI-KEY: YOUR_KEY"
Responses
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).
Sample responses
200 OK 200
{
    "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": "-"
                }
            ]
        }
    ]
}
404 Customer Paid Off 404
{
    "status": false,
    "error_code": "ALL_BILLS_PAID",
    "message": "Semua tagihan pelanggan sudah lunas pada periode yang diminta."
}
404 No Bill In Period 404
{
    "status": false,
    "error_code": "NO_BILLS_IN_PERIOD",
    "message": "Pelanggan belum memiliki tagihan pada periode yang diminta."
}
422 Invalid no_services Format 422
{
    "status": false,
    "error_code": "INVALID_NO_SERVICES_FORMAT",
    "message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
POST 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.

Headers
Name Required Note
X-MYWIFI-KEY required API key dari tabel keys
Body
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
Sample CURL
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"}'
Responses
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).
Sample responses
200 OK 200
{
    "status": true,
    "message": "Tagihan berhasil diperbarui menjadi sudah dibayar"
}
404 Invoice Mismatch 404
{
    "status": false,
    "error_code": "INVOICE_SERVICE_MISMATCH",
    "message": "Invoice ditemukan, tetapi tidak terhubung dengan nomor layanan 28900001."
}
409 Conflict 409
{
    "status": false,
    "error_code": "INVOICE_ALREADY_PAID",
    "message": "Invoice 230130001 sudah dibayar sebelumnya."
}
422 Invalid no_services Format 422
{
    "status": false,
    "error_code": "INVALID_NO_SERVICES_FORMAT",
    "message": "Format no_services tidak valid. Gunakan kombinasi huruf/angka yang benar."
}
Notification (API Key)
2 endpoints
POST https://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.

Headers
Name Required Note
X-MYWIFI-KEY required API key dari tabel keys
Body
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
Sample CURL
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}'
Responses
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).
Sample responses
200 Dry Run 200
{
    "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"
        }
    }
}
200 Send Real Push 200
{
    "status": "success",
    "message": "Test push notifikasi selesai.",
    "dry_run": false,
    "summary": {
        "target": 2,
        "success": 2,
        "failed": 0,
        "invalid_tokens": 0
    }
}
POST https://api.jwi.id/api/notification/push No auth

Kirim push notifikasi produksi ke target token berdasarkan no_services/email/tokens.

Headers
Name Required Note
X-MYWIFI-KEY required API key dari tabel keys
Body
Field Type Required Note
title string required
body string required
no_services string optional
email string optional
tokens array[string] optional
data object optional
Sample CURL
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"}}'
Responses
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
General Meaning
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.