H2H

Callback

Notifikasi otomatis ke server kamu saat transaksi berstatus final, supaya tidak perlu cek status terus-menerus.

Cara mengaktifkan

  1. Isi Callback URL (opsional, harus http atau https ke alamat publik) di Atur Koneksi > Host to Host > Payload URL.
  2. Ambil Callback Secret di Kredensial H2H (butuh OTP email) untuk memverifikasi signature.
Callback URL boleh dikosongkan. Kalau kosong, cek hasil lewat Cek status.

Yang dikirim

Method POST dengan body JSON saat status final (sukses atau gagal):

{
  "merchant_id": "ACN12345",
  "ref_id": "TRX-0001",
  "product": "Tsel6",
  "target": "08123456789",
  "status": "sukses",
  "sn": "1234567890",
  "message": "Transaksi Sukses",
  "price": 6150
}
FieldKeterangan
ref_idref_id transaksi dari sistem kamu.
statussukses atau gagal.
snSerial number atau bukti transaksi (jika ada).
messagePesan dari provider.
priceHarga yang dipotong dari Saldo Merchant.

Verifikasi signature

Header X-Signature berisi HMAC-SHA256(body_mentah, callback_secret) dalam heksadesimal. Hitung ulang di server kamu dan bandingkan. Kalau tidak sama, tolak.

<?php
$body = file_get_contents('php://input');            // body mentah
$sig  = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$calc = hash_hmac('sha256', $body, 'CALLBACK_SECRET');

if (!hash_equals($calc, $sig)) {
    http_response_code(401);
    exit;
}
$data = json_decode($body, true);
// proses sekali per ref_id (idempoten), lalu balas:
header('Content-Type: application/json');
echo json_encode(['status' => 'ok']);
const crypto = require("crypto");
app.post("/callback", express.raw({ type: "*/*" }), (req, res) => {
  const calc = crypto.createHmac("sha256", process.env.CALLBACK_SECRET)
                     .update(req.body).digest("hex");
  if (calc !== req.get("X-Signature")) return res.sendStatus(401);
  const data = JSON.parse(req.body.toString());
  // proses sekali per ref_id
  res.json({ status: "ok" });
});
import hmac, hashlib, os
from flask import Flask, request, jsonify, abort
app = Flask(__name__)

@app.post("/callback")
def callback():
    body = request.get_data()
    calc = hmac.new(os.environ["CALLBACK_SECRET"].encode(), body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(calc, request.headers.get("X-Signature", "")):
        abort(401)
    data = request.get_json()
    # proses sekali per ref_id
    return jsonify(status="ok")

Anti replay (disarankan): callback juga membawa X-Timestamp (detik Unix) dan X-Signature-V2 = HMAC-SHA256(X-Timestamp + "." + body_mentah, callback_secret).

Aturan callback

  • Balas HTTP 2xx berformat JSON, contoh {"status":"ok"}. Batas tunggu 8 detik.
  • Selain itu dianggap gagal dan dikirim ulang oleh sistem selama 24 jam.
  • Callback bisa terkirim lebih dari sekali. Proses sekali saja per ref_id.
  • Hitung signature dari body mentah, bukan hasil decode ulang JSON.
  • Gunakan HTTPS untuk Callback URL.