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:

  1. API-Key: Kunci publik yang digunakan untuk identifikasi.
  2. 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)

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)

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)

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