Buat dan Validasi Signature
Safe Acceptance API menggunakan komunikasi klien ke server dan bukan server ke server. Untuk menjaga keamanan transaksi, pengguna diharapkan membuat signature dan validasi pesan untuk menjaga keaslian pesan atau transaksi yang berjalan.
API menggunakan signature sebagai validator untuk request dan respon yang sesuai. signature dibuat dari body request dan respon dengan melakukan hashing dengan kunci rahasia bersama yang hanya diketahui oleh merchant dan Xendit.
Jika Anda melakukan verifikasi signature dalam tanggapan Xendit dan tidak cocok dengan body request Anda, kemungkinan respon tersebut telah dirusak dan berpotensi terkena penipuan. Respon harus ditolak dalam situasi itu.
Secara singkat, langkah-langkah yang diperlukan adalah sebagai berikut:
- Membuat shared secret dari secret API key Anda
- Membuat representasi string dari body request transaksi Anda
- Tanda tangani (signing) string dengan shared secret Anda
- Tambahkan signature dan signed_fields ke body request yang akan di-POST ke API safe acceptance
Di bawah ini adalah penjelasan secara detil pada setiap langkahnya.
1. Membuat shared secret dari secret API key Anda
Untuk membuat shared secret, gunakan secret API key apa pun dengan akses write yang dihasilkan dari Dasbor Xendit dan hash dengan sha256.
hash('sha256', 'put_your_Xendit_secret_API_key_here');
const sharedSecret = crypto.createHash('sha256')
.update('put_your_Xendit_secret_API_key_here')
.digest('hex');
String sha256hex = Hashing.sha256()
.hashString('put_your_Xendit_secret_API_key_here', StandardCharsets.UTF_8)
.toString();
Java dengan Apache Commons Codecs
String sha256hex = DigestUtils.sha256Hex('put_your_Xendit_secret_API_key_here');
Semua hal di atas harus menghasilkan string hex yang akan menjadi shared secret Anda yang digunakan untuk menandatangani transaksi, yang akan terlihat seperti ini 57425b47283422a8b0dd567374dd179232daca1da7f9cd21732b429d69b00f89
2. Membuat representasi string dari body request pada transaksi Anda
Saat membuat signature, buat string "name: value" yang dipisahkan koma dari body request POST yang disertakan dalam bidang signed_field_names
.
Urutan parameter dalam string sangat penting untuk proses pembuatan signature.
Untuk contoh permintaan safe acceptance seperti di bawah ini:
{
"amount": 10000,
"authorization": "Basic eG5kX3B1YmxpY19wcm9kdWN0aW9uX2NoQXBYaUVlVjVVbkdkZm9GUm1vdHk6",
"reference_id": "test-transaction",
"request_timestamp": "2020-01-01T00:00:00.000Z",
"return_url": "https://merchant.com/checkout/completed",
"signed_field_names": "amount,authorization,return_url,reference_id,signed_field_names,transaction_timestamp"
}
INFO
Anda perlu melakukan hash pada otorisasi Anda ke format base64
String yang akan dilakukan tanda tangan amount=10000,authorization=Basic eG5kX3B1YmxpY19wcm9kdWN0aW9uX2NoQXBYaUVlVjVVbkdkZm9GUm1vdHk6,redirect_url=https://merchant.com/checkout/completed,reference_id=test-transaction,signed_field_names=amount,authorization,redirect_url,reference_id,signed_field_names,request_timestamp=2020-01-01T00:00:00.000Z
3. Tanda tangani string dengan shared secret Anda
Pembuatan signature harus dibuat menggunakan HMAC dengan algoritme SHA256 dan secret API key yang dibuat di atas. String yang akan ditandatangani harus dalam urutan yang sama persis dengan nilai string signed_field_names
.
hash_hmac('sha256', string_to_sign, shared_secret, false)
const signature = crypto.createHmac('sha256', shared_secret)
.update(string_to_sign)
.digest('hex');
String signature = Hashing.hmacSha256(shared_secret)
.newHasher()
.putString(string_to_sign, UTF_8)
.hash()
.toString();
Java dengan Apache Commons Codecs
HmacUtils hm256 = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, shared_secret);
String signature = hm256.hmacHex(string_to_sign);
4. Tambahkan Signature dan signed_fields ke formulir yang akan di-POST ke API Safe Acceptance
Pengujian
Contoh berikut mengasumsikan bahwa secret API key adalah xnd_production_vkeTQhp5itRjUrGresYdi0t0kkY
.
Mengirimkan request pembuatan signature
Contohnya parameter berikut:
{
"amount": 10000,
"authorization": "Basic eG5kX3B1YmxpY19wcm9kdWN0aW9uX2NoQXBYaUVlVjVVbkdkZm9GUm1vdHk6",
"reference_id": "test-transaction",
"request_timestamp": "1610678291403",
"redirect_url": "https://merchant.com/checkout/completed",
"signed_field_names": "amount,authorization,redirect_url,reference_id,signed_field_names,transaction_timestamp"
}
Hasil pembuatan signature Anda akan terlihat seperti ini: 847988a920b31da8c1f124a1930569b6444cf70abb34e8c22620d069ccc367fe
Validasi signature respon
Anda akan memvalidasi parameter signature
menggunakan shared secret yang hanya diketahui oleh Anda dan Xendit.
Contohnya parameter berikut:
{
"created": "2019-07-15T15:54:52.141Z",
"business_id": "5d08a4nfea3b620019cfa213c",
"authorized_amount": 1200000,
"reference_id": "TVLK-123456",
"merchant_reference_code": "5d1ec8f4a3bcd10019a7e2de",
"masked_card_number": "400000XXXXXX0002",
"charge_type": "MULTI_USE_TOKEN",
"card_brand": "VISA",
"card_type": "CREDIT",
"status": "CAPTURED",
"bank_reconciliation_id": "5622988916826241203012",
"eci": "05",
"capture_amount": "1200000",
"currency": "IDR",
"id": "5d1eca0ca3bcd10019a7e2ee",
"authorized_amount": "1200000",
"merchant_id": "00080091009103589348501",
"mid_label": "xendit_ctv_agg",
"descriptor": "MERCHANT*EXPERIENCE",
"signed_field_names": "created,business_id,authorized_amount,reference_id,merchant_reference_code,masked_card_number,charge_type,card_brand,card_type,status,bank_reconciliation_id,eci,capture_amount,currency,id,authorized_amount,merchant_id,mid_label,descriptor",
"signature": "df212f41629f11d50128f2742963e103a52db30f4da9948b38318edfbf0ab470"
}
Hasil validasi signature Anda harus memeriksa apakah isi respon cocok dengan signature ini: df212f41629f11d50128f2742963e103a52db30f4da9948b38318edfbf0ab470
Perhatikan bahwa Anda juga harus memeriksa apakah stempel waktu created
dari respon berada dalam kisaran yang wajar dari stempel waktu tempat sistem Anda menerima respon.
Jika waktu ketika sistem Anda menerimanya jauh lebih lambat dari stempel waktu transaksi respon, ini mungkin berarti bahwa pihak ketiga mencegat respon Xendit dan mengirimi Anda respon mereka sendiri, yang merupakan risiko keamanan.
Xendit merekomendasikan rentang <5 menit perbedaan antara stempel waktu respon dan waktu aktual di mana sistem Anda menerimanya.
Last Updated on 2023-05-20