TransFluo X-SIGNATURE HMAC


Context

In the process of verifying payments, TransFluo implements a notification mechanism that consists in contacting the partner on a Webhook, in order to send him the information of a payment whose status has changed. For security purposes, an HMAC token has been implemented in the header of this notification to allow verification on the partner's side.

The purpose of this turorial is to describe the process for verifying the HMAC token.

Before proceeding to go, you need to retrieve your Secret Key in your merchant account:

  • Go to www.TransFluo.com/login and log in with your access details
  • Then click on the "View API" button
  • You will find your Secret Key there

Scenario

scenario-hmac

The server executes a POST request on your notification url containing :

  • Headers:

    • X-SIGNATURE : An HMAC token to allow verification on the partner's side.
  • Form values:

    • cpm_merchant_id: the merchant_id variable you sent at initialization
    • cpm_trans_id: the transaction_id variable that you sent at initialization
    • cpm_trans_date: the date and time of the transaction
    • cpm_amount: the amount
    • signature : A token. It is different from the generated token
    • payment_method : the payment method
    • cel_customer: the number used to make the payment
    • cpm_reason : the status of the transaction. If there is an error, you have the reason for the failure

Step to Understand how to receive response sent to your webhook

Step 1

The response is encrypted by concatenation of the information received in the body of the request. Thus, you must use the same signature to be able to decrypt the json response:

 
    $webhook_payload = [
        "status" => 'SUCCES',
        "amount" => '500',
        "customer" => '67XXXXXXX',
        "order_id" => 'SHOP123-20250911-0001',
        "reference_id" => 'avf45jhn454frr5vfvf1f4dgfgf1fg1',
        "merchant_name" => transfluo_51210320122,
        "reason" => 'THE_REASON_IF_THE_TRANSACTION_FAILS',
        "timestamp" => date("c"),
    ];

    $payload_json = json_encode($webhook_payload, JSON_UNESCAPED_UNICODE);

    $signature = hash_hmac("sha256", $payload_json, $merchant_secret_key);

    $ch = curl_init($webhook_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_json);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json; charset=UTF-8',
        "X-Mya-Signature: $signature"
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $webhook_response = curl_exec($ch);
    curl_close($ch);

 


How your webhook should correctly receive the response



    $payload = file_get_contents('php://input');
    $data = json_decode($payload, true);
    file_put_contents($logFile, "Raw payload (truncated 1k chars): " . substr($payload, 0, 1000) . "\n", FILE_APPEND);

    if (!$data) {
        file_put_contents($logFile, "❌ Invalid JSON received\n", FILE_APPEND);
        http_response_code(400);
        echo json_encode(["status" => "error", "reason" => "Invalid JSON"]);
        return;
    }

    $signature = $_SERVER['HTTP_X_MYA_SIGNATURE'] ?? '';
    $order_id = $data['order_id'] ?? '';
    if (!$order_id) {
        file_put_contents($logFile, "❌ Missing order_id in payload\n", FILE_APPEND);
        http_response_code(400);
        echo json_encode(["status" => "error", "reason" => "Missing order_id"]);
        return;
    }

    $merchant_secret_key = 'YOUR_SECRET_KEY';

    // Verify HMAC safely
    $check = hash_hmac('sha256', $payload, $merchant_secret_key);
    if (!hash_equals((string)$check, (string)$signature)) {
        file_put_contents($logFile, "❌ Invalid HMAC signature\n", FILE_APPEND);
        http_response_code(403);
        echo json_encode(["status" => "error", "reason" => "Invalid signature"]);
        return;
    }
    file_put_contents($logFile, "✅ Signature verified\n", FILE_APPEND);

    

Step 2

Create the signature following the HMAC technique by applying the SHA256 algorithm with the secret key (which will be communicated to you).


Example with php

$signature = hash_hmac("sha256", $payload_json, $merchant_secret_key);