Authentication - SNAP
Tentang Authentication - SNAP
NICEPAY menerapkan dua mekanisme keamanan autentikasi pada seluruh API SNAP dengan mengacu pada standar internasional yang berlaku, yakni:
- Access Token, untuk memastikan pemanggil API telah terautentikasi dan berwenang.
- Signature, untuk memastikan keaslian pengirim dan bahwa isi request tidak berubah selama proses komunikasi API.
Tahapan implementasi dari kedua autentikasi standar tersebut akan dijelaskan secara rinci pada halaman ini; mulai dari cara mendapatkan Access Token, sampai pada proses pembuatan Signature untuk menjalankan proses transaksi dengan NICEPAY.
Informasi Penting
Komponen | Fungsi | Dibuat oleh |
|---|---|---|
Client ID / X-CLIENT-KEY | Identitas milik Merchant yang diberikan oleh NICEPAY | NICEPAY |
Access Token | Otorisasi untuk mengakses NICEPAY protected resources. Berlaku selama 15 menit. | NICEPAY (Merchant perlu melakukan request terlebih dahulu). |
Signature (X-SIGNATURE) | Memastikan integritas data dan non-repudiation terjaga saat proses komunikasi dengan API sedang berlangsung. | Merchant |
Alur
- Merchant membuat Signature terlebih dahulu. Lalu, melakukan request Access Token.
- NICEPAY melakukan verifikasi Signature, kemudian melakukan return accessToken.
- Merchant menggunakan accessToken (Bearer) pada request API SNAP berikutnya; seperti pada pembayaran, periksa status transaksi, dan refund.
- Jika Access Token yang digunakan telah kedaluwarsa, Merchant perlu mengajukan kembali Access Token yang baru.
Persiapan Integrasi
Sebelum memulai tahap berikutnya, mohon pastikan Merchant sudah memiliki beberapa hal berikut.
- Client ID dari NICEPAY. Value ini akan dipakai sebagai header di parameter X-CLIENT-KEY.
- Pasangan kunci RSA (Private Key dan Public Key). Private Key hanya disimpan oleh Merchant, sedangkan Public Key didaftarkan kepada NICEPAY.
- Waktu server yang akurat (sinkron NTP), karena X-TIMESTAMP akan ikut divalidasi.
Jangan pernah mengirim, menyimpan di repository, atau pun menaruh Private Key di aplikasi Anda (browser maupun aplikasi mobile).
Seluruh pembuatan Signature harus dilakukan pada server milik Merchant.
NICEPAY Base URL
NICEPAY menyediakan dua environment yang bisa diakses oleh Merchant, yaitu Sandbox/Development dan Production. Semua request yang dilakukan harus menggunakan HTTPS dengan menambahkan path endpoint setelah base URL dimasukkan. Pastikan Client ID dan Key yang Merchant gunakan sesuai dengan environment yang dituju.
Environment | Protocol | Current NICEPAY Base URL | New NICEPAY Base URL |
|---|---|---|---|
Development | HTTPS | https://dev.nicepay.co.id/ | https://dev-services.nicepay.co.id/ |
Production | HTTPS | https://www.nicepay.co.id/ | https://services.nicepay.co.id/ |
Mohon segera lakukan perubahan NICEPAY Base URL menjadi URL terbaru sebelum tanggal 25 Desember 2026.
Kredensial untuk Testing
Apabila ingin melakukan uji coba API SNAP NICEPAY terlebih dahulu sebelum memulai proses integrasi, silakan gunakan kredensial di bawah ini dengan menggunakan clientID IONPAYTEST.
Kredensial sandbox ini dipakai bersama dan private key-nya bersifat publik. Mohon hanya digunakan pada Environment Development.
Jangan pernah digunakan pada environment Production bahkan sebagai key pair sendiri.
Kredensial | Fungsi | Dipakai pada | Asal | Contoh Kredensial Testing di Development |
|---|---|---|---|---|
Client ID | Identitas Merchant. Dikirim sebagai X-CLIENT-KEY (Access Token) dan X-PARTNER-ID (service request). | Semua request. | Diberikan oleh NICEPAY. | IONPAYTEST |
Channel ID | Identitas channel Merchant, yaitu Client ID ditambah 01. | Header CHANNEL-ID pada service request. | Dibentuk dari Client ID. | IONPAYTEST01 |
Client Secret * | Kunci HMAC-SHA512 untuk Symmetric Signature. | Service request (Registration, Check Status, Cancel, dan lainnya). | Diberikan NICEPAY dan tersedia field Client Secret di Merchant Back Office . Silakan lihat Credential Management | |
Private Key (RSA 2048) | Menandatangani Asymmetric Signature. | Request Access Token. | Dibuat dan disimpan sendiri oleh Merchant. | Silakan lihat halaman bagian Signature untuk mengetahui cara membuat Private Key. |
Public Key (RSA 2048) * | Melakukan verifikasi Asymmetric Signature. | Didaftarkan ke NICEPAY. | Dibuat bersama Private Key, lalu ditempel Merchant dengan value Merchant Public Key yang ada pada Merchant Back Office -Credential Management dalam format PEM. | Silakan daftarkan Public Key Merchant dengan menghubungi tim Integrasi NICEPAY melalui [email protected] |
Public Key NICEPAY * | Melakukan verifikasi Signature pada notifikasi dari NICEPAY. | Diperlukan pada saat Merchant melakukan integrasi API Notifikasi SNAP dengan NICEPAY. | Diberikan oleh NICEPAY melalui email atau bisa dicek pada field NICEPAY Public Key di Merchant Back Office -Credential Management. | |
Access Token | Otorisasi service request, berlaku selama 15 menit. | Header Authorization. | Hasil request dari Access Token. | - |
Berikut ini merupakan dua parameter wajib lain yang dibuat oleh sistem Merchant pada setiap request, bukan diberikan oleh NICEPAY.
- X-TIMESTAMP: waktu saat Merchant melakukan request dalam format ISO-8601, zona waktu GMT+7.
- X-EXTERNAL-ID: nomor referensi unik untuk setiap request transaksi.
Untuk transaksi yang memerlukan notifikasi, seperti Virtual Account, siapkan juga Notification URL milik Merchant. URL ini dikirim sebagai dbProcessUrl saat menggunakan Registration API.
Cara Memakai Kredensial Sandbox
- Simpan private key sandbox yang diberikan oleh tim NICEPAY, lalu buat Asymmetric Signature dengan IONPAYTEST sebagai Client ID. Contoh lengkap ada pada bagian Contoh Demo (Asymmetric).
- Hit Request Access Token ke endpoint Development.
- Setelah Access Token didapatkan, buat Symmetric Signature dengan Client Secret yang diberikan oleh NICEPAY dan taruh value Access Token pada header Authorization.
- Gunakan NICEPAY Public Key untuk melakukan validasi notifikasi yang dikirim NICEPAY.
Access Token API
Access Token adalah string value autentikasi yang diberikan oleh NICEPAY ke Merchant untuk mengakses API, seperti pada pembayaran, cek status transaksi, atau pengembalian dana.
Request Access Token
Service Code | 73 |
|---|---|
API Endpoint | |
HTTP Method | POST |
Description | Request Token for Authentication |
Content-type | application/json |
Header
Request Access Token Header
Nama Parameter Header | Tipe | Atribut | Konten |
|---|---|---|---|
Content-Type | String | Mandatory | Application/json |
X-TIMESTAMP | String | Mandatory | Waktu request dengan format ISO-8601 beserta zona waktu YYYY-MM-DDTHH:MM:SS (2022-03-21T10:11:40+07:00) |
X-CLIENT KEY | String | Mandatory | Nilai Client ID ini disediakan oleh NICEPAY. Pastikan untuk menggunakan nilai tersebut dengan benar. (X-CLIENT KEY = CLIENT_ID) |
X-SIGNATURE | String | Mandatory | Dibuat oleh Merchant menggunakan algoritma Asymmetric Signature SHA256withRSA. (Private_Key, stringToSign) stringToSign = client ID + “|” + X-TIMESTAMP Lihat bagian Signature berikut. |
Body
Request Access Token Parameter
Parameter | Tipe | Kebutuhan | Deskripsi |
|---|---|---|---|
grantType | String | Mandatory | Harap hanya masukkan nilai berikut “client_credentials” |
additionalInfo | Object | Optional | Informasi tambahan. Boleh dikirim sebagai objek kosong {} |
Response Access Token Parameter
Parameter BI | Parameter NICEPAY | Tipe | Ukuran | Kebutuhan | Deskripsi |
|---|---|---|---|---|---|
responseCode | responseCd | String | | Optional | Kode error yang mengindikasikan jenis error yang dikembalikan dalam respons API |
responseMessage | responseMsg | String | | Optional | Response Message Memberikan informasi tambahan secara terperinci mengenai respons API |
accessToken | | String | 2048 | Mandatory | Sebuah string yang mewakili otorisasi dikeluarkan oleh NICEPAY untuk Merchant, sehingga dapat digunakan untuk mengakses API transaksi. |
tokenType | | String | | Mandatory | Selalu bernilai Bearer. |
expiresIn | | String | | Mandatory | Masa berlaku token dalam detik: 900 (15 menit). |
Sample Parameter
curl --location 'https://dev-services.nicepay.co.id/nicepay/v1.0/access-token/b2b' \
--header 'Content-Type: application/json' \
--header 'X-CLIENT-KEY: IONPAYTEST' \
--header 'X-TIMESTAMP: 2024-12-31T10:11:40+07:00' \
--header 'X-SIGNATURE: DZ9iZR6xtWoFwFaARgo9h6mDgckZpPRLQjMTAlGqrYrJ4xah/deCsxe159H7sf9i2clJeGrsoq5ZDe4tzM+IRQhcxY47K3mYcbnPFGdP5maCC/tCCi63TScB0XUpJzpuPc4TM3G+2uIo816VcoKTXxR5v188m5yGDsGmfW4urddjI1Xor9lZdXP1c6fMH19psMN0g137GCD4tOdjeKW/gGpbvjMi0HQu9PjaJtoFxGmypdxayXfUU3VxWtSWf6AZ88UQ++iOBXfAQIX5Vtt6+fKh/1DOCEcZFe87Em1437VZcTET5dOuEXeQ+ow2PT/Or9iey0M8qQzk3Y6oWJg/sw==' \
--data '{
"grantType": "client_credentials",
"additionalInfo": {}
}'
Cara Menggunakan Access Token
Sertakan token pada header Authorization di setiap request API SNAP berikutnya.
Expiry Date and Requesting New Access Token
- Token berlaku selama 900 detik (15 menit) sejak diterbitkan.
- Tidak ada refresh token. Setelah kedaluwarsa, mohon minta token baru melalui endpoint yang sama.
- Simpan token di memori atau cache server Merchant, lalu pakai ulang sampai mendekati waktu kedaluwarsa. Mohon untuk tidak meminta token baru pada setiap transaksi apabila token expiry time masih aktif.
- Jika sebuah request transaksi ditolak karena token tidak valid atau kedaluwarsa, silakan melakukan request token baru, lalu ulangi request transaksi tersebut satu kali.
API SNAP Service Code
Berikut ini merupakan daftar Service Code terkait layanan yang dapat digunakan Merchant setelah mendapatkan Access Token dari NICEPAY.
Metode | Service Code | API Reference |
|---|---|---|
Virtual Account | 27 | |
Virtual Account | 26 | |
Virtual Account | 31 | |
E-Wallet | 73 | |
E-Wallet | 54 | |
E-Wallet | 55 | |
E-Wallet | 58 | |
QRIS | 47 | |
QRIS | 51 | |
QRIS | 78 | |
Payout | 00 | |
Payout | 11 |
Error API yang Sering Ditemui (Access Token)
Berikut ini merupakan penyebab umum kegagalan yang sering terjadi pada saat melakukan request token. Kunjungi halaman General Response Code and Message - API SNAP untuk informasi lebih lengkap.
Case | Yang perlu diperiksa |
|---|---|
Signature tidak valid | Format stringToSign, Private Key yang dipakai, dan encoding Base64. |
Client ID tidak dikenali | Nilai X-CLIENT-KEY dan environment (Development/Sandbox atau Production). |
Format X-TIMESTAMP salah | Format ISO-8601 dengan zona waktu, misalnya +07:00. |
Field wajib kosong | Header X-TIMESTAMP, X-CLIENT-KEY, X-SIGNATURE, dan grantType. |
grantType salah | Harus diisi dengan value "client_credentials". |
Signature
Signature (X-SIGNATURE) adalah digital sign pada setiap request di API SNAP. Signature ini memberikan tiga jaminan keamanan, mencakup:
- Integritas Data. Memastikan data permintaan tidak diubah selama proses pengiriman tanpa terdeteksi oleh sistem. Jika terdapat perubahan pada data, tanda tangan digital tidak lagi valid sehingga permintaan akan ditolak.
- Non-Repudiation. Memastikan pengirim tidak dapat menyangkal permintaan yang telah ditandatangani menggunakan Private Key miliknya, karena tanda tangan tersebut hanya dapat dibuat oleh pihak yang memiliki Private Key yang sesuai. Mekanisme ini berlaku untuk tanda tangan dengan Asymmetric Signature.
- Perlindungan Replay. Mencegah permintaan lama yang telah dicegat untuk dikirim ulang dan diproses kembali sebagai permintaan yang valid. Hal ini dilakukan dengan menyertakan X-TIMESTAMP dalam data yang ditandatangani, sehingga validitas waktu permintaan dapat diverifikasi.
Standar SNAP dari Bank Indonesia menggunakan dua jenis Signature bergantung pada API yang dipanggil.
Jenis | Dipakai untuk | Algoritma | Kunci |
|---|---|---|---|
Asymmetric | Request Access Token. | SHA256withRSA | Private Key Merchant |
Symmetric | Request layanan (transaksi). | HMAC-SHA512 | Client Secret |
Create Key Pair for Asymmetric Signature A (Private Key dan Public Key)
Asymmetric Signature menggunakan sepasang kunci RSA yang terdiri dari dua jenis kunci:
- Private Key: Digunakan oleh Merchant untuk menandatangani API request. Kunci ini wajib dijaga kerahasiaannya dan tidak boleh dibagikan kepada pihak lain.
- Public Key: Diberikan kepada NICEPAY untuk keperluan proses verifikasi Signature.
Kedua kunci tersebut wajib menggunakan panjang kunci RSA 2048-bit.
Contoh di bawah ini menggunakan OpenSSL.
1. Buat Private Key.
File private_key.pem berformat PKCS#8 (diawali -----BEGIN PRIVATE KEY-----), yang bisa langsung dipakai di Java dan Node.js.
2. Buat Public Key dari Private Key.
File public_key.pem diawali dengan -----BEGIN PUBLIC KEY-----.
3. Serahkan Public Key ke NICEPAY.
Kirim hanya public_key.pem ke NICEPAY. Pastikan Merchant mendaftarkan Public Key untuk environment yang dipakai (Development/Sandbox atau Production). Gunakan format PEM, yaitu isi public_key.pem lengkap dengan baris -----BEGIN PUBLIC KEY----- dan -----END PUBLIC KEY-----. Tempel hanya Public Key. Jangan pernah menempelkan Private Key di field mana pun.
4. Simpan private key dengan aman
Simpan private_key.pem di server Merchant dengan akses terbatas, misalnya di secret manager atau variabel lingkungan yang terlindungi. Jika Private Key bocor, buat key pair baru dan daftarkan Public Key yang baru ke NICEPAY.
5. Uji pembuatan signature (opsional)
Merchant bisa mencoba membuat Signature dari terminal untuk membandingkan hasilnya dengan kode yang telah dimiliki.
Catatan format: Jika Private Key Merchant diawali dengan -----BEGIN RSA PRIVATE KEY----- (PKCS#1), ubah ke PKCS#8 menjadi openssl pkcs8 -topk8 -nocrypt -in private_key.pem -out private_key_pkcs8.pem karena Java umumnya membutuhkan format PKCS#8.
Command ini menghasilkan nilai X-SIGNATURE untuk stringToSign tersebut.
Signature untuk Access Token (Asymmetric)
1. Siapkan stringToSign.
Contoh:
Nilai X-TIMESTAMP pada stringToSign harus identik dengan yang dikirim di Header.
2. Tandatangani dengan SHA256withRSA.
Gunakan algoritma SHA256withRSA dengan Private Key Merchant untuk menandatangani stringToSign.
3. Encode dengan Base64.
Hasil signature (byte) di-encode ke Base64.
4. Kirim sebagai Header.
Masukkan hasilnya ke Header X-SIGNATURE.
Sample Code
String stringToSign = clientId + "|" + timestamp;
java.security.Signature signer = java.security.Signature.getInstance("SHA256withRSA");
signer.initSign(privateKey); // java.security.PrivateKey
signer.update(stringToSign.getBytes(java.nio.charset.StandardCharsets.UTF_8));
String xSignature = java.util.Base64.getEncoder().encodeToString(signer.sign());Contoh Demo (Asymmetric)
Gunakan data demo berikut untuk berlatih dan membandingkan hasil kode Merchant.
Key pair di bawah dibuat khusus untuk demo. Jangan pernah digunakan pada Development/Sandbox atau Production.
Data input
stringToSign
Private Key demo (simpan sebagai ionpaytest_sandbox_private_key.pem)
Public Key demo (simpan sebagai ionpaytest_sandbox_public_key.pem)
Hasil: X-SIGNATURE
Karena SHA256withRSA (PKCS#1 v1.5) menghasilkan nilai Signature yang sama untuk input dan key yang sama, pengujian yang dilakukan oleh Merchant seharusnya menghasilkan Signature yang identik dengan contoh di atas. Merchant juga dapat melakukan verifikasi melalui terminal:
Client Secret (Symmetric Key)
Berbeda dengan RSA Key Pair, kunci untuk Symmetric Signature tidak dibuat sendiri oleh Merchant. Kunci tersebut merupakan Client Secret yang diterbitkan oleh NICEPAY dan digunakan sebagai key untuk algoritma HMAC-SHA512. NICEPAY memakai key yang sama untuk melakukan verifikasi terhadap Signature yang dihasilkan Merchant.
| Asymmetric (Access Token) | Symmetric (Request Layanan) |
|---|---|---|
Kunci | Private Key RSA | Client Secret |
Dibuat oleh | Merchant | NICEPAY |
Yang diberikan ke NICEPAY | Public Key | Tidak ada, key tidak boleh dikirim kepada pihak manapun |
Disimpan oleh | Merchant (Private Key) | Merchant dan NICEPAY |
Panduan Pengelolaan Client Secret:
- Simpan Client Secret di server Merchant menggunakan secret manager atau environment variables yang terlindungi.
- Jangan menyimpan Client Secret di dalam source code, repository, atau aplikasi disisi klien, termasuk browser dan aplikasi mobile.
- Jangan menyertakan Client Secret dalam request, log, maupun pesan atau komunikasi kepada pihak mana pun, termasuk Tim NICEPAY.
- Gunakan Client Secret yang sesuai dengan environment, baik Development/Sandbox maupun Production.
- Jika Client Secret terindikasi bocor atau terekspos, segera hubungi tim NICEPAY untuk meminta penerbitan Client Secret baru.
Signature untuk Request Layanan Transaksi (Symmetric)
Setelah memperoleh Access Token, Merchant dapat mengajukan request layanan transaksi SNAP NICEPAY (misalnya registrasi transaksi, pembayaran, periksa status, dan pengembalian dana). Setiap request wajib ditandatangani menggunakan Symmetric Signature.
Berikut adalah header yang wajib disertakan dalam request :
Nama Header | Kebutuhan | Deskripsi |
|---|---|---|
Content-Type | Mandatory | application/json |
Authorization | Mandatory | Bearer {accessToken} |
X-TIMESTAMP | Mandatory | Waktu request, format ISO-8601 dalam zona waktu GMT+7 (Jakarta). Contoh: 2024-12-31T10:11:40+07:00 |
X-SIGNATURE | Mandatory | Symmetric Signature yang dibuat Merchant, dengan rumus di bawah. |
X-PARTNER-ID | Mandatory | Client ID dari NICEPAY. Maksimal 20 karakter. |
X-EXTERNAL-ID | Mandatory | Nomor referensi unik untuk setiap request. Maksimal 40 karakter. |
CHANNEL-ID | Mandatory | "Client ID" ditambah "01". Contoh: IONPAYTEST + 01 menjadi IONPAYTEST01 Maksimal 20 karakter. |
1. Hitung hash body
Minify body request dengan hapus spasi dan garis baris baru di luar nilai string, hitung SHA-256, lalu ubah ke heksadesimal huruf kecil.
2. Susun stringToSign
EndpointUrl merujuk pada nilai API Endpoint yang tercantum pada setiap halaman dokumentasi API. Sertakan query string jika tersedia, tetapi tidak termasuk domain..
Contoh: /api/v1.0/transfer-va/create-va untuk Registration - API Virtual Account SNAP.
3. Sign dengan HMAC-SHA512
Sample Code
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
// requestBody = body JSON yang sudah di-minify, sama persis dengan yang dikirim
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hash = sha256.digest(requestBody.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hash) {
hex.append(String.format("%02x", b)); // huruf kecil
}
String bodyHash = hex.toString();
String stringToSign = httpMethod + ":" + endpointUrl + ":" + accessToken
+ ":" + bodyHash + ":" + timestamp;
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA512"));
String xSignature = Base64.getEncoder()
.encodeToString(mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));Body yang di-hash harus sama persis dengan body yang dikirim. Jika library yang dipakai Merchant untuk mengirim request rupanya mengubah urutan atau format JSON setelah Signature dibuat, maka proses verifikasi akan gagal.
Contoh Demo (Symmetric)
Contoh berikut ini menggunakan Registration - API Virtual Account SNAP (Service Code 27, Bank BMRI), dengan Client Secret dan Access Token demo. Jangan memakai nilai demo ini untuk request sungguhan pada environment Development maupun Production.
Data input
Request body (sudah di-minify)
1. bodyHash
2. stringToSign
3. Hasil: X-SIGNATURE
4. Sertakan Signature dalam Request
Signature yang telah dihasilkan wajib disertakan pada header X-SIGNATURE, bersama dengan header wajib lainnya sebagaimana tercantum pada tabel di atas.
Catatan Penting:
- Request body yang dikirim melalui --data-raw harus sama persis dengan request body yang digunakan untuk menghasilkan SHA-256 hash. Perbedaan sekecil apa pun pada format, spasi, baris baru, maupun nilai dapat menyebabkan Signature tidak valid.
- Contoh di atas menggunakan Access Token dan Signature demo sehingga request tidak akan berhasil apabila dikirimkan secara langsung.
- Sebelum melakukan pengujian, ganti seluruh nilai demo dengan Access Token, Client Secret, dan Merchant Client ID yang sesuai dengan environment yang digunakan.
Selain itu, Merchant juga dapat membandingkan hasil yang diperoleh dengan output dari command terminal berikut:
Kesalahan Umum pada Pembuatan Signature
Case | Penyebab yang sering terjadi |
|---|---|
Signature ditolak meskipun kode terlihat benar. | Nilai X-TIMESTAMP pada stringToSign berbeda dengan yang dikirim di Header. |
Signature ditolak hanya pada sebagian request. | Body berubah setelah di-hash (spasi, urutan field, encoding). |
Signature ditolak di semua request. | Private Key tidak cocok dengan Public Key yang terdaftar di NICEPAY. |
Signature ditolak saat pindah environment. | Memakai Client ID atau kunci dari satu environment di environment lain. |
Muncul karakter aneh pada Signature. | Lupa melakukan encode Base64 atau ada baris baru yang ikut terbawa. |