Lewati ke konten

Signature Verification

Digunakan oleh: BCA, BRI, Mandiri, BNI, CIMB, Nobu, AstraPay, ShopeePay

{HTTP_METHOD}:{RELATIVE_PATH}:{ACCESS_TOKEN}:{SHA256_HEX(REQUEST_BODY)}:{TIMESTAMP}
POST:/bca/v1.0/balance-inquiry:eyJhbGciOi...:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:2026-07-01T10:30:00+07:00
function signTransaction(method, path, token, body, timestamp, clientSecret) {
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const stringToSign = `${method}:${path}:${token}:${bodyHash}:${timestamp}`;
return crypto
.createHmac('sha512', clientSecret)
.update(stringToSign)
.digest('base64');
}

Digunakan oleh: BNC, DANA (untuk beberapa service)

function signRSA(method, path, token, body, timestamp, privateKey) {
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const stringToSign = `${method}:${path}:${token}:${bodyHash}:${timestamp}`;
return crypto
.sign('sha256', Buffer.from(stringToSign), privateKey)
.toString('base64');
}

OVO menggunakan hex encoding alih-alih base64:

function signOVO(method, path, token, body, timestamp, privateKey) {
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const stringToSign = `${method}:${path}:${token}:${bodyHash}:${timestamp}`;
return crypto
.sign('sha256', Buffer.from(stringToSign), privateKey)
.toString('hex'); // ← HEX, bukan base64
}

Server menandatangani webhook dengan RSA private key. Verifikasi menggunakan webhook public key:

function verifyWebhook(stringToSign, signatureB64, publicKeyPem) {
const signature = Buffer.from(signatureB64, 'base64');
return crypto.verify('sha256', Buffer.from(stringToSign), publicKeyPem, signature);
}