Dokumentasi API Merchant untuk Gateway Pembayaran
1. Pendahuluan
Dokumen ini menjelaskan spesifikasi teknis API yang harus disediakan oleh setiap Merchant (misalnya: SIMAK, SPMB) agar dapat terhubung dengan Gateway Pembayaran universitas.
Gateway Pembayaran bertindak sebagai proxy yang aman. Gateway akan menerima permintaan dari bank (BSI), memvalidasinya, dan meneruskannya ke API merchant yang sesuai.
2. Autentikasi
Setiap merchant memiliki dua kunci rahasia yang tersimpan di gateway:
API-Key: Kunci publik yang digunakan untuk identifikasi.Secret-Key: Kunci rahasia pribadi yang digunakan untuk memverifikasi keaslian (integritas) data pembayaran.
Setiap permintaan yang masuk dari gateway ke API merchant Anda akan menyertakan dua (2) HTTP Header khusus untuk autentikasi:
Header Deskripsi
X-API-Key Berisi API-Key unik milik
merchant. API Anda wajib
memeriksa apakah key ini valid.
X-Gateway-Signature (Hanya untuk Payment & Reversal)
Berisi signature HMAC-SHA256 dari
body permintaan. API Anda
wajib memvalidasi signature
ini.
Validasi X-Gateway-Signature (Wajib untuk Payment/Reversal)
Untuk memastikan bahwa permintaan notifikasi pembayaran/reversal
benar-benar berasal dari gateway dan datanya tidak diubah, Anda
wajib memvalidasi X-Gateway-Signature.
Signature ini dibuat menggunakan Secret-Key merchant Anda dengan
algoritma HMAC-SHA256 terhadap seluruh body JSON mentah dari
permintaan.
Contoh Validasi di Django/Python:
``` python
Di dalam views.py merchant Anda (misal: SIMAK)
import hmac import hashlib import json from django.http import JsonResponse
Ini harus disimpan di settings.py Anda, jangan di-hardcode!
YOUR_MERCHANT_SECRET_KEY = "xxxxxxxx-rahasia-anda-xxxxxxxx" YOUR_MERCHANT_API_KEY = "apikey-anda-yang-didapat-dari-gateway"
def validate_gateway_signature(request): """ Fungsi untuk memvalidasi header X-Gateway-Signature. Mengembalikan True jika valid, False jika tidak. """ try: # 1. Ambil signature dari header signature_from_header = request.headers.get('X-Gateway-Signature') if not signature_from_header: return False
# 2. Buat signature tandingan di sisi Anda
# PENTING: Gunakan request.body (dalam bentuk bytes mentah)
raw_body = request.body
digest = hmac.new(
YOUR_MERCHANT_SECRET_KEY.encode('utf-8'),
msg=raw_body,
digestmod=hashlib.sha256
).hexdigest()
# 3. Bandingkan keduanya dengan aman
return hmac.compare_digest(digest, signature_from_header)
except Exception as e:
print(f"Error validasi signature: {e}")
return False
def my_payment_notification_view(request): # 1. Validasi API Key api_key = request.headers.get('X-API-Key') if api_key != YOUR_MERCHANT_API_KEY: return JsonResponse({'code': '98', 'message': 'Invalid API Key'}, status=401)
# 2. Validasi Signature
if not validate_gateway_signature(request):
return JsonResponse({'code': '98', 'message': 'Invalid Signature'}, status=401)
# 3. Jika lolos, proses data
try:
data = json.loads(request.body)
# ... Lakukan logika bisnis Anda di sini ...
# (Contoh: tandai tagihan sebagai lunas)
# 4. Kirim respon sukses
return JsonResponse({
"code": "00",
"message": "Pembayaran Sukses"
})
except json.JSONDecodeError:
return JsonResponse({'code': '30', 'message': 'Invalid JSON format'}, status=400)
except Exception as e:
# Tangani error bisnis Anda
return JsonResponse({'code': '99', 'message': f'Internal Error: {e}'}, status=500)
3. Spesifikasi Endpoint API
API merchant Anda harus menyediakan 3 (tiga) endpoint. URL untuk endpoint ini akan Anda berikan kepada admin gateway untuk dikonfigurasi.
A. Endpoint Inquiry (Validasi Tagihan)
- URL:
[inquiry_url](Dikonfigurasi di gateway) - Method:
POST - Tujuan: Untuk mengecek status tagihan berdasarkan nomor pembayaran.
- Header Request dari Gateway:
X-API-Key: [API-Key Anda]
Request Body (JSON)
Gateway akan meneruskan JSON mentah yang diterima dari BSI. API Anda hanya perlu membaca field nomorPembayaran.
json
{
"action": "inquiry",
"nomorPembayaran": "881231914363",
"waktuTransaksi": "20241030143000",
"idTransaksi": "BSI123456789",
"kodeChannel": "TELLER",
"kodeTerminal": "T1"
}
Response Body (JSON)
API Anda wajib merespon dengan format JSON berikut.
Jika Sukses (Tagihan Ditemukan & Belum Lunas): Respon Anda wajib
menyertakan code: "00".
json
{
"code": "00",
"message": "Tagihan Ditemukan",
"nomorPembayaran": "881231914363",
"idTagihan": "REG-2023-001",
"nama": "BUDI SANTOSO",
"totalNominal": "1500000",
"detailTagihan": [
{
"namaTagihan": "Uang Pendaftaran",
"nominal": "1500000"
}
]
}
Jika Gagal (Tagihan Tidak Ditemukan): Gunakan code: "14".
json
{
"code": "14",
"message": "Tagihan tidak ditemukan",
"nomorPembayaran": "881231914363"
}
Jika Gagal (Tagihan Sudah Lunas):\
Gunakan code: "13".
json
{
"code": "13",
"message": "Tagihan sudah lunas",
"nomorPembayaran": "881231914363"
}
B. Endpoint Payment (Notifikasi Pembayaran)
- URL:
[payment_url](Dikonfigurasi di gateway) - Method:
POST - Tujuan: Menerima konfirmasi bahwa tagihan telah dibayar. API Anda wajib memvalidasi signature dan menandai tagihan sebagai LUNAS.
- Header Request dari Gateway:
X-API-Key: [API-Key Anda]X-Gateway-Signature: [HMAC-SHA256 Signature]
Request Body (JSON)
Gateway akan mengirimkan JSON yang sudah disederhanakan yang berisi detail pembayaran.
json
{
"action": "payment",
"nomor_pembayaran": "881231914363",
"total_nominal": "1500000",
"nomor_jurnal": "BSI-JURNAL-98765",
"waktu_transaksi_bank": "20241030143500",
"id_transaksi_bank": "BSI123456999",
"kode_channel": "MBANKING"
}
Response Body (JSON)
Jika Sukses (Pembayaran berhasil dicatat):
Respon Anda wajib menyertakan code: "00".
json
{
"code": "00",
"message": "Pembayaran Sukses Dicatat",
"nomorPembayaran": "881231914363",
"idTagihan": "REG-2023-001",
"nomorJurnalMerchant": "INV-12345"
}
C. Endpoint Reversal (Notifikasi Pembatalan)
- URL:
[reversal_url](Dikonfigurasi di gateway) - Method:
POST - Tujuan: Menerima notifikasi bahwa pembayaran sebelumnya dibatalkan oleh bank. API Anda wajib memvalidasi signature dan membatalkan status LUNAS pada tagihan.
- Header Request dari Gateway:
X-API-Key: [API-Key Anda]X-Gateway-Signature: [HMAC-SHA256 Signature]
Request Body (JSON)
Format body sama persis dengan Payment, namun nilai field action
adalah "reversal".
json
{
"action": "reversal",
"nomor_pembayaran": "881231914363",
"total_nominal": "1500000",
"nomor_jurnal": "BSI-JURNAL-98765",
"waktu_transaksi_bank": "20241030144000",
"id_transaksi_bank": "BSI123456999-REV",
"kode_channel": "MBANKING"
}
Response Body (JSON)
Jika Sukses (Pembatalan berhasil dicatat): Respon Anda wajib
menyertakan code: "00".
json
{
"code": "00",
"message": "Reversal Sukses Dicatat",
"nomorPembayaran": "881231914363"
}
4. Daftar Kode Respon (Response Codes)
API merchant Anda wajib menggunakan kode-kode berikut dalam respon JSON-nya.
Kode Keterangan Kapan Digunakan?
00 Sukses Inquiry berhasil,
Payment/Reversal
berhasil dicatat.
13 Tagihan Sudah Lunas Saat Inquiry, jika
tagihan sudah dibayar
sebelumnya.
14 Tagihan Tidak Saat Inquiry, jika
Ditemukan nomorPembayaran tidak
ada di sistem.
30 Format Salah Jika JSON yang diterima
merchant tidak valid.
98 Autentikasi Gagal Jika X-API-Key atau
X-Gateway-Signature
tidak valid.
99 General Error Error internal di sisi
merchant (Error
database, dll).