# Algoritma Tanda Tangan (Signature)

Setiap request API harus dilengkapi dengan signature untuk verifikasi keamanan dan keaslian request dari merchant.

## Cara Membuat Signature

Signature dibuat menggunakan algoritma **MD5** dengan langkah-langkah berikut:

### Langkah 1: Urutkan Parameter
Ambil semua parameter yang dikirim dan urutkan berdasarkan nama parameter secara alfabetik (ASCII order):

```php
ksort($data);
```

### Langkah 2: Buat String Signature
Gabungkan semua parameter (yang nilainya tidak kosong) dengan format `key=value&key=value&...`:

```
amount=50000&dateTime=2024-04-26 18:18:18&dstCode=PERMATA&email=user@domain.com&memberId=10085&name=John Doe&notifyUrl=http://example.com/callback&orderId=ORDER123&phone=08123456789
```

### Langkah 3: Tambahkan Secret Key
Tambahkan `key=` diikuti dengan merchant secret key di akhir string:

```
amount=50000&dateTime=2024-04-26 18:18:18&dstCode=PERMATA&email=user@domain.com&memberId=10085&name=John Doe&notifyUrl=http://example.com/callback&orderId=ORDER123&phone=08123456789&key=slrkogmvo13hb92d8i5111bxm8q8euc7
```

### Langkah 4: Hash dengan MD5
Hash string di atas menggunakan MD5 dan ubah hasil ke uppercase:

```php
$sign = strtoupper(md5($stringSignTemp));
```

**Hasil Contoh:**
```
7DFEC0884F2DD5661667AA8E8A91C695
```

## Parameter yang Tidak Diikutkan dalam Signature

Parameter berikut **TIDAK** dihitung dalam signature jika nilainya kosong:
- String kosong: `""`
- Angka nol: `0`
- String "0": `"0"`
- Null: `null`
- Boolean false: `false`

## Contoh Implementasi PHP

```php
private function generateSignature($data, $secretKey)
{
    // Urutkan parameter berdasarkan nama key
    ksort($data);
    
    // Buat string signature
    $stringSignTemp = "";
    foreach ($data as $key => $value) {
        // Lewati nilai kosong
        if (!empty($value)) {
            $stringSignTemp .= $key . "=" . $value . "&";
        }
    }
    
    // Tambahkan secret key
    $stringSignTemp .= "key=" . $secretKey;
    
    // Hash dengan MD5 dan ubah ke uppercase
    return strtoupper(md5($stringSignTemp));
}

// Penggunaan
$parameters = [
    "memberId" => "10085",
    "orderId" => "ORDER123",
    "amount" => 50000,
    "dstCode" => "PERMATA",
    "name" => "John Doe",
    "phone" => "08123456789",
    "email" => "user@domain.com",
    "dateTime" => "2024-04-26 18:18:18",
    "notifyUrl" => "http://example.com/callback"
];

$secretKey = "slrkogmvo13hb92d8i5111bxm8q8euc7";
$signature = $this->generateSignature($parameters, $secretKey);
// Output: 7DFEC0884F2DD5661667AA8E8A91C695
```

## Verifikasi Signature di Backend (Callback)

Ketika menerima callback dari sistem payment gateway, Anda harus memverifikasi signature:

```php
public function verifySignature($receivedData, $receivedSign, $secretKey)
{
    // Hapus parameter 'sign' dari data
    unset($receivedData['sign']);
    
    // Hitung signature dari data yang diterima
    $calculatedSign = $this->generateSignature($receivedData, $secretKey);
    
    // Bandingkan dengan signature yang diterima
    return strtoupper($receivedSign) === strtoupper($calculatedSign);
}
```

## Debugging Tips

Jika signature tidak cocok, periksa:
1. Apakah secret key benar? (case-sensitive)
2. Apakah parameter sudah diurutkan alfabetik?
3. Apakah ada parameter dengan nilai kosong yang tidak dihilangkan?
4. Apakah format string sudah benar (dengan `&` sebagai separator)?
5. Apakah hasil MD5 sudah diubah ke uppercase?

---

**Penting**: Jangan pernah meng-share secret key Anda kepada siapapun. Simpan dengan aman.
