Mulai
Base URL environment ini:
http://epayment.dev.unja.ac.id/api/v1Seluruh request API memakai header:
Accept: application/json
Content-Type: application/json
Authorization: Bearer <access-token>Tidak tersedia fitur “Try it” pada halaman ini. Operasi API dapat mengubah data keuangan.
Autentikasi
Token memakai OAuth2 Client Credentials. Credential diberikan admin dan bukan credential login pengguna.
Meminta access token.
Request token
curl -X POST 'http://epayment.dev.unja.ac.id/oauth/token' \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client-id>' \
--data-urlencode 'client_secret=<client-secret>'Response token
{
"token_type": "Bearer",
"expires_in": 1800,
"access_token": "<access-token>"
}- Tidak ada refresh token.
- Cache token di backend dan minta token baru sebelum kedaluwarsa.
- Client nonaktif, dicabut, atau kedaluwarsa ditolak.
Format error
| Status | Arti |
|---|---|
| 400 | Request OAuth atau format request tidak valid. |
| 401 | Credential atau Bearer token tidak valid. |
| 403 | Token valid, tetapi aplikasi tidak memiliki scope endpoint. |
| 404 | Data tidak ditemukan atau bukan milik client pada resource billing. |
| 409 | Konflik state, referensi, data terpakai, atau konfirmasi pembayaran berbeda sudah ada. |
| 422 | Validasi payload gagal. |
| 429 | Rate limit terlampaui. |
{
"message": "The given data was invalid.",
"errors": {
"field": ["Pesan validasi."]
}
}Biaya
GET memerlukan master:read. POST, PUT, PATCH, dan DELETE memerlukan master:write.
Master kelompok biaya. Akses baca dan perubahan dipisahkan berdasarkan scope aplikasi.
Daftar paginated biaya aktif. Filter: search, per_page (1–100, default 15).
Membuat biaya. Response 201.
Mengambil satu biaya berdasarkan ID.
Mengganti seluruh field input.
Memperbarui field yang dikirim.
Menghapus biaya yang belum dipakai. Menghasilkan 409 bila direferensikan jenis tagihan atau hak akses pengguna.
Payload create/update
{
"nama_biaya": "Biaya Laboratorium",
"id_akun": null,
"ganjil": 1,
"genap": 1,
"pendek": 0,
"status": true
}Response create/detail
{
"data": {
"id_biaya": 18,
"id_akun": null,
"nama_biaya": "Biaya Laboratorium",
"ganjil": 1,
"genap": 1,
"pendek": 0,
"status": true,
"update_date": "2026-11-04T10:00:00.000000Z"
}
}| Field | Aturan |
|---|---|
id_akun | Opsional; boleh null. Jika diisi, harus tersedia pada master akun. |
nama_biaya | Wajib, maksimal 30 karakter. Kombinasi nama dan ganjil harus unik. |
ganjil, genap, pendek | Wajib untuk POST/PUT, integer 32-bit. |
status | Wajib, boolean. Hanya biaya aktif yang tersedia untuk transaksi baru. |
Jenis tagihan
Master jenis tagihan yang terhubung ke biaya. GET memerlukan master:read; operasi perubahan memerlukan master:write.
Filter: search, id_biaya, tahun_akademik, aktif, per_page.
Membuat jenis tagihan. id_jenis ditentukan pemanggil dan harus unik.
Mengambil detail beserta relasi biaya.
Mengganti field input selain id_jenis.
Memperbarui field yang dikirim. id_jenis tidak dapat diubah.
Menonaktifkan jenis tagihan dengan aktif=false; tidak menghapus histori.
Payload create
{
"id_jenis": 20261001,
"id_biaya": 1,
"tahun_akademik": "20261",
"keterangan": "Tagihan Semester Ganjil 2026/2027",
"aktif": true
}Response create/detail
{
"data": {
"id_jenis": 20261001,
"id_biaya": 1,
"tahun_akademik": "20261",
"keterangan": "Tagihan Semester Ganjil 2026/2027",
"aktif": true,
"biaya": {
"id_biaya": 1,
"nama_biaya": "Uang Kuliah"
}
}
}tahun_akademik wajib lima digit. keterangan maksimal 100 karakter.
Tagihan langsung
Flow sederhana untuk membuat tagihan dengan nominal final tanpa item billing. Create dan perubahan masa pembayaran memerlukan tagihan:write.
Inquiry exact berdasarkan ID tagihan. Memerlukan tagihan:read dan mengembalikan status BELUM_DIBUKA, BELUM_DIBAYAR, KEDALUWARSA, atau DIBAYAR.
Menyimpan satu konfirmasi pembayaran. Memerlukan pembayaran:write. Nominal mengikuti nilai bank dan tidak wajib sama dengan nominal tagihan.
{
"bank_ref": "TRX-20261109-001",
"nominal": "750000.00",
"denda": "0.00",
"waktu_bayar": "2026-11-09T10:30:00+07:00",
"teller_id": "TELLER-01",
"channel": "MOBILE_BANKING"
}bank diambil dari kode aplikasi terautentikasi dan tidak diterima dari payload. Retry payload sama aman dan mengembalikan data existing. Payload berbeda untuk ID tagihan yang sudah dikonfirmasi menghasilkan 409.Membuat tagihan pada jenis aktif. Kombinasi id_jenis + identitas_pengguna harus belum ada.
curl -X POST 'http://epayment.dev.unja.ac.id/api/v1/tagihan' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-token>' \
-d '{
"id_jenis": 20261001,
"identitas_pengguna": "A001",
"nama_pengguna": "Pengguna Contoh",
"nominal": 1500000,
"denda": 0,
"waktu_open": "2026-11-04T08:00:00+07:00",
"waktu_close": "2026-12-04T23:59:59+07:00",
"email_pengguna": "contoh@example.com",
"telepon_pengguna": "081234567890"
}'Response create/update masa pembayaran
{
"data": {
"id_tagihan": "20261001123456",
"id_jenis": 20261001,
"identitas_pengguna": "A001",
"nama_pengguna": "Pengguna Contoh",
"nominal": "1500000.00",
"denda": "0.00",
"waktu_open": "2026-11-04 08:00:00",
"waktu_close": "2026-12-04 23:59:59"
}
}| Field | Aturan |
|---|---|
identitas_pengguna, nama_pengguna | Wajib, maksimal 60 karakter. |
nominal | Wajib, 0–9.999.999.999.999,99; maksimal dua desimal. |
denda | Opsional, 0–99.999.999,99. |
waktu_open, waktu_close | Wajib; waktu tutup tidak boleh sebelum waktu buka. |
email_pengguna, telepon_pengguna | Opsional; email maksimal 100 dan telepon maksimal 15 karakter. |
Mengubah waktu buka dan tutup. Tagihan lunas ditolak dengan 409.
{
"waktu_open": "2026-11-04T08:00:00+07:00",
"waktu_close": "2027-01-04T23:59:59+07:00"
}expire_date_va tidak berubah, serta tidak ada panggilan perpanjangan ke bank.Billing berbasis item
Read memerlukan billings:read; create/update/recalculate memerlukan billings:write; issue dan cancel memakai scope masing-masing.
Flow draft untuk menghitung detail dari rubrik/tarif atau input manual, lalu menerbitkannya menjadi tagihan. Setiap billing hanya dapat diakses client pembuatnya.
Membuat draft. Retry dengan external_reference dan payload sama mengembalikan data existing; payload berbeda menghasilkan 409.
Mengambil billing milik client beserta item.
Mengganti header dan seluruh item selama status masih DRAFT. external_reference tidak dapat diubah.
Menghitung ulang harga MASTER dan validasi jenis detail RUBRIK tanpa mengubah harga detail MANUAL.
Menerbitkan draft menjadi tagihan. Semua detail harus memakai id_jenis billing. Aksi idempotent bila sudah ISSUED.
Membatalkan billing yang masih DRAFT.
Payload create/update billing
{
"external_reference": "INV-2026-0001",
"nama_billing": "Tagihan Laboratorium",
"id_jenis": 20261001,
"identitas_pengguna": "A001",
"nama_pengguna": "Pengguna Contoh",
"email_pengguna": "contoh@example.com",
"telepon_pengguna": "081234567890",
"waktu_open": "2026-11-04T08:00:00+07:00",
"waktu_close": "2026-12-04T23:59:59+07:00",
"denda": 0,
"items": [
{
"line_reference": "ITEM-1",
"detail_source": "RUBRIK",
"id_rubrik_tarif": 101,
"id_tarif": 501,
"pricing_source": "MASTER",
"qty": 1,
"harga_satuan": null,
"diskon": 0
},
{
"line_reference": "ITEM-2",
"detail_source": "MANUAL",
"id_rubrik_tarif": null,
"id_tarif": null,
"pricing_source": "EXTERNAL",
"kode_item": "LAYANAN-TAMBAHAN",
"nama_item": "Layanan tambahan",
"satuan": "paket",
"qty": 1,
"harga_satuan": 50000,
"diskon": 0
}
]
}Response billing
{
"data": {
"uuid": "<billing-uuid>",
"external_reference": "INV-2026-0001",
"status": "DRAFT",
"nominal": "1500000.00",
"id_jenis": 20261001,
"id_tagihan": null,
"ready_to_issue": true,
"issues": [],
"items": [
{
"line_reference": "ITEM-1",
"detail_source": "RUBRIK",
"pricing_source": "MASTER",
"qty": "1.000",
"harga_satuan": "1500000.00",
"diskon": "0.00",
"subtotal": "1500000.00"
}
]
}
}Aturan item
| Field | Aturan |
|---|---|
id_jenis | Wajib, aktif, dan menjadi jenis untuk seluruh detail billing. |
line_reference | Wajib, unik dalam satu billing, maksimal 100 karakter. |
detail_source | RUBRIK atau MANUAL. Bila tidak dikirim, diinferensikan dari keberadaan id_rubrik_tarif. |
id_rubrik_tarif | Wajib untuk RUBRIK dan harus resolve ke id_jenis billing; harus kosong untuk MANUAL. |
pricing_source | MASTER atau EXTERNAL. Detail MANUAL wajib EXTERNAL. |
id_tarif | Wajib untuk harga MASTER dan harus kosong untuk EXTERNAL atau detail MANUAL. |
nama_item | Wajib untuk MANUAL; kode_item dan satuan opsional. |
harga_satuan | Opsional untuk MASTER; wajib untuk EXTERNAL. |
qty | Lebih dari 0, maksimal tiga desimal. |
diskon | Tidak boleh negatif atau melebihi subtotal sebelum diskon. |
Status billing
| Status | Makna | Aksi |
|---|---|---|
DRAFT | Billing belum diterbitkan. | Dapat update, recalculate, issue, atau cancel. |
ISSUED | Billing sudah menjadi tagihan dan memiliki id_tagihan. | Read; issue ulang aman dan mengembalikan data existing. |
CANCELLED | Draft dibatalkan. | Read saja. |
Batasan penting
- Setiap client OAuth hanya dapat memakai endpoint sesuai scope pada profil aplikasinya.
- Token valid tanpa scope yang diperlukan menghasilkan
403. - Resource billing dibatasi ke client pembuat; akses lintas client menghasilkan
404. - Rate limit awal: token 20 request/menit/IP, API 120 request/menit/IP dan 60 request/menit/client setelah autentikasi.
- Tagihan langsung tidak menyimpan pemilik API. Lindungi credential dan terbitkan hanya untuk backend tepercaya.
- Response pagination memakai struktur paginator Laravel:
data,current_page,per_page,total, dan URL halaman. - Tanggal disimpan dalam zona waktu aplikasi
Asia/Jakarta. Kirim offset eksplisit untuk menghindari ambiguitas.