Logo Universitas Jambi ePayment Universitas JambiDokumentasi integrasi aplikasi

Dokumentasi API

Referensi autentikasi, master biaya, jenis tagihan, tagihan langsung, dan billing berbasis item.

Versi v1Format JSONOAuth2 Client CredentialsZona waktu Asia/Jakarta

Mulai

Base URL environment ini:

http://epayment.dev.unja.ac.id/api/v1
Keamanan: gunakan HTTPS di production. Simpan Client ID, Client Secret, dan access token hanya di backend atau secret manager. Jangan taruh credential di browser, aplikasi mobile, URL, log, atau repositori.

Seluruh 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.

POST/oauth/token

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

StatusArti
400Request OAuth atau format request tidak valid.
401Credential atau Bearer token tidak valid.
403Token valid, tetapi aplikasi tidak memiliki scope endpoint.
404Data tidak ditemukan atau bukan milik client pada resource billing.
409Konflik state, referensi, data terpakai, atau konfirmasi pembayaran berbeda sudah ada.
422Validasi payload gagal.
429Rate 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.

GET/api/v1/biaya

Daftar paginated biaya aktif. Filter: search, per_page (1–100, default 15).

POST/api/v1/biaya

Membuat biaya. Response 201.

GET/api/v1/biaya/{biaya}

Mengambil satu biaya berdasarkan ID.

PUT/api/v1/biaya/{biaya}

Mengganti seluruh field input.

PATCH/api/v1/biaya/{biaya}

Memperbarui field yang dikirim.

DELETE/api/v1/biaya/{biaya}

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"
  }
}
FieldAturan
id_akunOpsional; boleh null. Jika diisi, harus tersedia pada master akun.
nama_biayaWajib, maksimal 30 karakter. Kombinasi nama dan ganjil harus unik.
ganjil, genap, pendekWajib untuk POST/PUT, integer 32-bit.
statusWajib, 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.

GET/api/v1/jenis-tagihan

Filter: search, id_biaya, tahun_akademik, aktif, per_page.

POST/api/v1/jenis-tagihan

Membuat jenis tagihan. id_jenis ditentukan pemanggil dan harus unik.

GET/api/v1/jenis-tagihan/{jenisTagihan}

Mengambil detail beserta relasi biaya.

PUT/api/v1/jenis-tagihan/{jenisTagihan}

Mengganti field input selain id_jenis.

PATCH/api/v1/jenis-tagihan/{jenisTagihan}

Memperbarui field yang dikirim. id_jenis tidak dapat diubah.

DELETE/api/v1/jenis-tagihan/{jenisTagihan}

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.

GET/api/v1/tagihan/{tagihan}

Inquiry exact berdasarkan ID tagihan. Memerlukan tagihan:read dan mengembalikan status BELUM_DIBUKA, BELUM_DIBAYAR, KEDALUWARSA, atau DIBAYAR.

POST/api/v1/tagihan/{tagihan}/konfirmasi

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"
}
Nilai 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.
POST/api/v1/tagihan

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"
  }
}
FieldAturan
identitas_pengguna, nama_penggunaWajib, maksimal 60 karakter.
nominalWajib, 0–9.999.999.999.999,99; maksimal dua desimal.
dendaOpsional, 0–99.999.999,99.
waktu_open, waktu_closeWajib; waktu tutup tidak boleh sebelum waktu buka.
email_pengguna, telepon_penggunaOpsional; email maksimal 100 dan telepon maksimal 15 karakter.
PATCH/api/v1/tagihan/{tagihan}/masa-pembayaran

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"
}
Mengubah masa pembayaran mengikuti perilaku web: data VA dan 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.

POST/api/v1/billings

Membuat draft. Retry dengan external_reference dan payload sama mengembalikan data existing; payload berbeda menghasilkan 409.

GET/api/v1/billings/{billing-uuid}

Mengambil billing milik client beserta item.

PUT/api/v1/billings/{billing-uuid}

Mengganti header dan seluruh item selama status masih DRAFT. external_reference tidak dapat diubah.

POST/api/v1/billings/{billing-uuid}/recalculate

Menghitung ulang harga MASTER dan validasi jenis detail RUBRIK tanpa mengubah harga detail MANUAL.

POST/api/v1/billings/{billing-uuid}/issue

Menerbitkan draft menjadi tagihan. Semua detail harus memakai id_jenis billing. Aksi idempotent bila sudah ISSUED.

POST/api/v1/billings/{billing-uuid}/cancel

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

FieldAturan
id_jenisWajib, aktif, dan menjadi jenis untuk seluruh detail billing.
line_referenceWajib, unik dalam satu billing, maksimal 100 karakter.
detail_sourceRUBRIK atau MANUAL. Bila tidak dikirim, diinferensikan dari keberadaan id_rubrik_tarif.
id_rubrik_tarifWajib untuk RUBRIK dan harus resolve ke id_jenis billing; harus kosong untuk MANUAL.
pricing_sourceMASTER atau EXTERNAL. Detail MANUAL wajib EXTERNAL.
id_tarifWajib untuk harga MASTER dan harus kosong untuk EXTERNAL atau detail MANUAL.
nama_itemWajib untuk MANUAL; kode_item dan satuan opsional.
harga_satuanOpsional untuk MASTER; wajib untuk EXTERNAL.
qtyLebih dari 0, maksimal tiga desimal.
diskonTidak boleh negatif atau melebihi subtotal sebelum diskon.

Status billing

StatusMaknaAksi
DRAFTBilling belum diterbitkan.Dapat update, recalculate, issue, atau cancel.
ISSUEDBilling sudah menjadi tagihan dan memiliki id_tagihan.Read; issue ulang aman dan mengembalikan data existing.
CANCELLEDDraft 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.