Payment Gateway

Hash-Based Signature

Signature adalah kode unik yang digunakan untuk menjaga keamanan dan keaslian data saat terjadi transaksi. Signature dibuat menggunakan algoritma kriptografi seperti RSA dan SHA-256. Setiap menerima request, Espay akan melakukan validasi terhadap signature yang diterimanya, untuk memastikan data transaksi berasal dari Anda dan tidak diubah saat proses transmissi.
Format Parameter

Setiap layanan Espay memiliki format parameter yang berbeda-beda dalam pembuatan signature-nya. Berikut ini format kombinasi parameter beserta layanannya:

Layanan Pesan Gabungan Parameter
Virtual Account (Send Invoice)
Kunjungi layanan di sini.
Request
signature key + rq_uuid + rq_datetime + order_id + amount + ccy + comm_code + SENDINVOICE
Inquiry Transaction
Kunjungi layanan di sini.
Request
signature key + rq_datetime + order_id + INQUIRY
Response
signature key + rq_uuid + rs_datetime + order_id + error_code + INQUIRY-RS
Payment Notification
Kunjungi layanan di sini.
Request
signature key + rq_datetime + order_id + PAYMENTREPORT
Response
signature key + rq_uuid + rs_datetime + error_code + PAYMENTREPORT-RS
Check Payment Status
Kunjungi layanan di sini.
Request
signature key + rq_datetime + order_id + CHECKSTATUS
Expire Transaction
Kunjungi layanan di sini.

Request

signature key + rq_datetime + order_id + EXPIRETRANSACTION
Credit Card - Tokenization
Kunjungi layanan di sini.
Request
signature key + comm_code + trx_id + amount
Credit Card - Capture
Kunjungi layanan di sini.
Request
signature key + comm_code + trx_id + amount
Credit Card - Void
Kunjungi layanan di sini.
Request
signature key + comm_code + trx_id
Credit Card - Refund
Kunjungi layanan di sini.
Request
signature key + comm_code + trx_id + amount
Push To Pay / QRIS / Linkage
Kunjungi layanan di sini.
Request
rq_uuid + comm_code + product_code + order_id + amount + signature key + PUSHTOPAY
Settlement Notification
Kunjungi layanan di sini.
Request
rq_uuid + rq_datetime + sender_id + receiver_id
Payment Link
Kunjungi layanan di sini.
Request
comm_code + orderid + amount + key + datetime + password
Komponen Signature
Komponen Keterangan
amount
Total pembayaran.
ccy
Kode mata uang transaksi.

Value:
  • Rupiah: IDR
comm_code
Merchant code yang diberikan oleh tim Espay.

Contoh:
SGWYESSISHOP
error_code
Kode error.

Contoh:
0000
Key
API Key yang diberikan oleh tim Espay.
order_id / orderid
Kode unik untuk mengidentifikasi pesanan / penagihan / faktur.

Contoh:
Nomor transaksi, invoice id, dll.
rq_uuid
Request identifier. ID unik yang digunakan untuk mengidentifikasi pesan.
rq_datetime / datetime
Tanggal dan waktu request transaksi.

Contoh:
2024-01-01 14:39:11
rs_datetime
Tanggal dan waktu response transaksi.

Contoh:
2024-01-01 14:39:11
signature key
Signature yang diberikan oleh tim Espay.

Contoh:
s8qndd0ghZdrl04r

Format Hash-Based Signature

Dalam Hash-Based Signature ini, ada 3 jenis format signature yang harus Anda sesuaikan dengan penggunaannya:

  1. Format Signature Universal 
  2. Format Signature Payment Link
  3. Format Signature Settlement Notification

Tabel berikut menjelaskan perbedaan format signature yang digunakan pada masing-masing layanan:

Karakteristik Format Signature
Universal
Format Signature
Payment Link
Format Signature Settlement Notification
Cakupan Layanan
Digunakan untuk semua layanan yang terdaftar di tabel Format Kombinasi Parameter, selain Payment Link dan Settlement Notification.
Khusus untuk layanan Payment Link.
Khusus untuk layanan Settlement Notification.
Pemisah Antar Field
Menggunakan ## sebagai pemisah antar field.
Menggunakan ## sebagai pemisah antar field.
Tidak menggunakan pemisah ##.
Konversi Uppercase
Format kombinasi parameter wajib dikonversi ke uppercase.
Format kombinasi tidak perlu dikonversi menggunakan uppercase.
Format kombinasi tidak perlu dikonversi menggunakan uppercase.
Algoritma Hash
SHA-256
SHA-256.
MD-5 dan SHA-1.
Contoh Gabungan Parameter
##signaturekey##rq_uuid##rq_datetime##order_id##amount##ccy##comm_code##SENDINVOICE##
##comm_code##orderid##amount##key##datetime##password##
rq_uuid+rq_datetime+sender_id+receiver_id

Format Signature Universal

Format Signature Universal digunakan untuk seluruh layanan yang tercantum pada tabel Format Kombinasi Parameter, kecuali Payment Link dan Settlement Notification. Pada format ini, setiap parameter digabungkan menggunakan pemisah ##, kemudian dikonversi ke huruf besar (uppercase) sebelum diproses menggunakan algoritma SHA-256.

Langkah-Langkah Generate Signature

Berikut ini langkah-langkah untuk membuat signature berdasarkan kebutuhan layanan yang digunakan dengan contoh layanan Virtual Account (Send Invoice):

  1. Gabungkan kombinasi signature yang sudah ditentukan oleh Espay menggunakan "##".
Format kombinasi
##SignatureKey##rq_uuid##rq_datetime##order_id##amount##ccy##comm_code##SENDINVOICE##
##cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504##rfbd39734-ed32-490d-98c4-e91bcd91037a##2024-01-01 14:39:11##ORDER001##100000##IDR##SGWDIGALLERY##SENDINVOICE##
  1. Ubah kombinasi yang sudah disatukan pada langkah 1, menjadi Uppercase.
Format sebelum uppercase
##cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504##rfbd39734-ed32-490d-98c4-e91bcd91037a##2024-01-01 14:39:11##ORDER001##100000##IDR##SGWDIGALLERY##SENDINVOICE##
Format setelah uppercase
##CC256D3A2D7687E6F4E1F4217C534BC6B18F66E3552AA9D312F5F4808130504##RFBD39734-ED32-490D-98C4-E91BCD91037A##2024-01-01 14:39:11##ORDER001##100000##IDR##SGWDIGALLERY##SENDINVOICE##
  1. Ubah format menggunakan hash dengan algoritma SHA-256.
Format sebelum hash SHA-256
##CC256D3A2D7687E6F4E1F4217C534BC6B18F66E3552AA9D312F5F4808130504##RFBD39734-ED32-490D-98C4-E91BCD91037A##2024-01-01 14:39:11##ORDER001##100000##IDR##SGWDIGALLERY##SENDINVOICE##
Format setelah hash SHA-256
b474188c95439412262f5808473caa8c12676acf4381842ff43b1b4a22493808
Contoh Kode


Generate Signature Universal Virtual Account (Send Invoice)

$signatureKey = 'cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504';
$rq_uuid      = 'rfbd39734-ed32-490d-98c4-e91bcd91037a';
$rq_datetime  = '2024-01-01 14:39:11';
$order_id     = 'ORDER001';
$amount       = '100000';
$ccy          = 'IDR';
$comm_code    = 'SGWYESSISHOP';
$action       = 'SENDINVOICE';
                                  
$raw_string = strtoupper("##{$signatureKey}##{$rq_uuid}##{$rq_datetime}##{$order_id}##{$amount}##{$ccy}##{$comm_code}##{$action}##");

$signature = hash('sha256', $raw_string);
         
echo "Raw String: " . $raw_string . PHP_EOL;
echo "Signature : " . $signature;
                
              


Generate Signature Universal Virtual Account (Send Invoice)

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class UniversalSignatureGenerator {

    public static void main(String[] args) {
        String signatureKey = "cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504";
        String rq_uuid      = "rfbd39734-ed32-490d-98c4-e91bcd91037a";
        String rq_datetime  = "2024-01-01 14:39:11";
        String order_id     = "ORDER001";
        String amount       = "100000";
        String ccy          = "IDR";
        String comm_code    = "SGWYESSISHOP";
        String action       = "SENDINVOICE";

        // Buat raw string dan ubah ke uppercase
        String rawString = String.format("##%s##%s##%s##%s##%s##%s##%s##%s##",
                signatureKey, rq_uuid, rq_datetime, order_id, amount, ccy, comm_code, action
        ).toUpperCase();

        try {
          // Hash menggunakan SHA-256
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(rawString.getBytes(StandardCharsets.UTF_8));

            // Konversi hasil hash ke hex string
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                hexString.append(String.format("%02x", b));
            }

            // Output hasil
            System.out.println("Raw String: " + rawString);
            System.out.println("Signature : " + hexString.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
                
              


Generate Signature Universal Virtual Account (Send Invoice)

const crypto = require('crypto');

const signatureKey = 'cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504';
const rq_uuid      = 'rfbd39734-ed32-490d-98c4-e91bcd91037a';
const rq_datetime  = '2024-01-01 14:39:11';
const order_id     = 'ORDER001';
const amount       = '100000';
const ccy          = 'IDR';
const comm_code    = 'SGWYESSISHOP';
const action       = 'SENDINVOICE';

// Gabungkan dan ubah ke UPPERCASE
const rawString = `##${signatureKey}##${rq_uuid}##${rq_datetime}##${order_id}##${amount}##${ccy}##${comm_code}##${action}##`.toUpperCase();

// Buat SHA-256 hash
const signature = crypto.createHash('sha256').update(rawString).digest('hex');

// Output
console.log("Raw String :", rawString);
console.log("Signature  :", signature);
                
              

Format Signature Payment Link digunakan khusus untuk layanan Payment Link. Pada format ini, parameter digabungkan menggunakan pemisah ## tanpa perlu dikonversi ke huruf besar (uppercase). Signature kemudian diproses menggunakan algoritma SHA-256.

Langkah-Langkah Generate Signature

Berikut ini langkah-langkah untuk membuat signature berdasarkan kebutuhan layanan Payment Link:

  1. Gabungkan kombinasi signature yang sudah ditentukan oleh Espay menggunakan "##".
Format kombinasi
##comm_code##orderid##amount##key##datetime##password##
##ESPAYCOMMCODE##ORDER001-JKT-2020##200000.00##rwjfiwhrwrwhugdsdfyfyd##2020-08-08 09:17:45##P@ssw0rd!##
  1. Ubah format menggunakan hash dengan algoritma SHA-256.
Format sebelum hash SHA-256
##ESPAYCOMMCODE##ORDER001-JKT-2020##200000.00## rwjfiwhrwrwhugdsdfyfyd##2020-08-08 09:17:45##P@ssw0rd!##
Format setelah hash SHA-256
b958d232cb4b5aad3ee37f44ebc89f149083cdd5f8ae100fa0d96776bcae718d
Contoh Kode


Generate Signature Payment Link

$comm_code = 'SGWYESSISHOP';
$order_id  = 'ORDER001';
$amount    = '200000.00';
$key       = 'rwjfiwhrwrwhugdsdfyfyd';
$datetime  = '2020-08-08 09:17:45';
$password  = 'P@ssw0rd!';

$raw_string = ("##{$comm_code}##{$order_id}##{$amount}##{$key}##{$datetime}##{$password}##");

$signature = hash('sha256', $raw_string);

echo "Raw String : $raw_string\n";
echo "Signature  : $signature\n";
                
              


Generate Signature Payment Link

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class SettlementSignatureExample {
    public static void main(String[] args) {
        String comm_code = "SGWYESSISHOP";
        String order_id  = "ORDER001";
        String amount    = "200000.00";
        String key       = "rwjfiwhrwrwhugdsdfyfyd";
        String datetime  = "2020-08-08 09:17:45";
        String password  = "P@ssw0rd!";

        // Buat raw string dan ubah ke upper
        String rawString = String.format("##%s##%s##%s##%s##%s##%s##",
                comm_code, order_id, amount, key, datetime, password
        );

        try {
            // Hash menggunakan SHA-256
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(rawString.getBytes(StandardCharsets.UTF_8));

            // Konversi hasil hash ke hex string
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                hexString.append(String.format("%02x", b));
            }

            // Output
            System.out.println("Raw String : " + rawString);
            System.out.println("Signature  : " + hexString.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
                
              


Generate Signature Payment Link

const crypto = require('crypto');

const comm_code = 'SGWYESSISHOP';
const order_id  = 'ORDER001';
const amount    = '200000.00';
const key       = 'rwjfiwhrwrwhugdsdfyfyd';
const datetime  = '2020-08-08 09:17:45';
const password  = 'P@ssw0rd!';

// Buat raw string seperti PHP
const rawString = `##${comm_code}##${order_id}##${amount}##${key}##${datetime}##${password}##`;

// Buat hash SHA256
const signature = crypto.createHash('sha256').update(rawString).digest('hex');

// Output
console.log("Raw String :", rawString);
console.log("Signature  :", signature);
                
              

Format Signature Settlement Notification

Format Signature Settlement Notification digunakan khusus untuk layanan Settlement Notification. Pada format ini, parameter digabungkan tanpa menggunakan pemisah ## dan tidak perlu dikonversi ke huruf besar (uppercase). Proses pembentukan signature dilakukan menggunakan algoritma MD5 dan SHA-1.

Langkah-Langkah Generate Signature

Berikut ini langkah untuk pembuatan signature khusus layanan Settlement Notification:

  1. Gabungkan kombinasi signature yang sudah ditentukan oleh Espay.
rq_uuid : cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504
rq_datetime: 2024-01-01 14:39:11
sender_id: GOWORLDPG
receiver_id: SGWYESSISHOP
Gabungan Parameter
rq_uuid + rq_datetime + sender_id + receiver_id
Format kombinasi
cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f48081305042024-01-01 14:39:11GOWORLDPGSGWYESSISHOP
  1. Lakukan hash dengan MD-5.
Format sebelum hash MD-5
cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f48081305042024-01-01 14:39:11GOWORLDPGSGWYESSISHOP

Format setelah hash MD-5

cc29f34e06e17749b0b82e9bf8c4229a
  1. Lakukan SHA-1 pada hasil MD-5.
Format sebelum SHA-1
cc29f34e06e17749b0b82e9bf8c4229a
Format setelah SHA-1
591e6edde42e0d63705ccca9d7ff077392aa7f03
Contoh Kode


Generate Signature untuk Settlement Notification

$rq_uuid      = "cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504";
$rq_datetime  = "2024-01-01 14:39:11";
$sender_id    = "GOWORLDPG";
$receiver_id  = "SGWYESSISHOP";

$raw_string = $rq_uuid . $rq_datetime . $sender_id . $receiver_id;

$md5_hash = md5($raw_string);
$final_signature = sha1($md5_hash);

echo $final_signature;
                
              


Generate Signature untuk Settlement Notification

import java.nio.charset.StandardCharsets;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class DualHashSignature {

    public static void main(String[] args) {
        String rq_uuid     = "cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504";
        String rq_datetime = "2024-01-01 14:39:11";
        String sender_id   = "GOWORLDPG";
        String receiver_id = "SGWYESSISHOP";

        // Gabungkan string seperti PHP
        String rawString = rq_uuid + rq_datetime + sender_id + receiver_id;

        try {
            // Step 1: MD5 hash
            String md5Hash = hashString(rawString, "MD5");

            // Step 2: SHA1 hash dari hasil MD5
            String finalSignature = hashString(md5Hash, "SHA-1");

            // Output hasil
            System.out.println("Raw String       : " + rawString);
            System.out.println("MD5 Hash         : " + md5Hash);
            System.out.println("Final Signature  : " + finalSignature);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String hashString(String input, String algorithm) throws Exception {
        MessageDigest digest = MessageDigest.getInstance(algorithm);
        byte[] hashedBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        for (byte b : hashedBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
                
              


Generate Signature untuk Settlement Notification

const crypto = require('crypto');

const rq_uuid     = "cc256d3a2d7687e6f4e1f4217c534bc6b18f66e3552aa9d312f5f4808130504";
const rq_datetime = "2024-01-01 14:39:11";
const sender_id   = "GOWORLDPG";
const receiver_id = "SGWYESSISHOP";

// Gabungkan raw string
const rawString = rq_uuid + rq_datetime + sender_id + receiver_id;

// Hash MD5
const md5Hash = crypto.createHash('md5').update(rawString).digest('hex');

// Hash SHA1 dari MD5
const finalSignature = crypto.createHash('sha1').update(md5Hash).digest('hex');

// Output
console.log("Raw String     :", rawString);
console.log("MD5 Hash       :", md5Hash);
console.log("Final Signature:", finalSignature);
                
              

Try It!

Anda bisa coba masukkan data sesuai dengan input yang telah disediakan. Setelah itu Anda submit dan lihat hasilnya!

Request
Value
Request

FAQ

Hash-Based Signature digunakan untuk memastikan keaslian dan integritas data pada request yang dikirim ke Espay dengan cara melakukan hashing terhadap parameter tertentu menggunakan signature key dari Espay.

Metode ini diperlukan untuk:
  1. Memastikan permintaan benar-benar dikirim oleh merchant yang valid.
  2. Mencegah perubahan data selama proses pengiriman.
  3. Mengamankan transaksi dari penyalahgunaan.
Hash-Based Signature bekerja dengan cara:
  • Menggabungkan parameter tertentu sesuai ketentuan.
  • Melakukan proses hashing menggunakan algoritma yang sudah tentukan.
  • Mengirimkan hasil hash sebagai signature pada permintaan.
Espay akan melakukan proses yang sama untuk memverifikasi apakah signature yang dikirim sesuai dengan data permintaan.
Perbedaan utama terletak pada mekanisme keamanan yang digunakan:

Hash-Based Signature
  • Menggunakan signature key yang sama antara Anda dan Espay untuk membuat dan memverifikasinya.
  • Digunakan pada layanan non-SNAP.

Signature Asymmetric
  • Menggunakan private key untuk generate signature dan public key untuk melakukan validasi.
  • Digunakan pada layanan SNAP.
Error “Credential is not Valid” terjadi karena value signature yang Anda kirim tidak sesuai dengan spesifikasi Espay atau tidak cocok dengan permintaan yang diterima sistem.

Jika terjadi error Invalid Signature, Anda dapat melakukan pengecekan mandiri dengan langkah berikut:

  1. Pastikan data yang digunakan untuk membuat signature sama persis dengan data yang dikirim pada request (tidak ada perbedaan nilai atau format).
  2. Periksa format parameter, terutama Timestamp, urutan dan penulisan parameter.
  3. Pastikan tidak ada perbedaan format data, seperti spasi, perubahan huruf besar-kecil, atau perubahan nilai saat request dikirim.
  4. Gunakan fitur Try It yang tersedia di dokumentasi Espay untuk membandingkan hasil signature yang di-generate dengan signature yang dikirim.

Jika hasil signature sudah sesuai dengan fitur Try It namun permintaan masih ditolak, silakan menghubungi tim teknis Espay untuk pengecekan lebih lanjut.

Setiap layanan memiliki format signature yang berbeda. Pastikan format signature yang digunakan sesuai dengan jenis layanan dan flow yang digunakan. Silakan mengacu ke tabel format signature pada dokumentasi Hash-Based Signature Espay di sini.
Scroll to Top