Webhooks/Callbacks

Webhook Authenticity Verification

You can verify the Message Authentication Code (MAC) of a given callback using the HMAC SHA-512 algorithm. The MAC ensures data integrity and authenticity by enabling the recipient to verify that the message has not been altered.

Header key: nmac Message Value: payReference (data["payReference"])

Sample Header

{
 "nmac": "6377f9fae71eedb408f45b5fb2f70e5cdab8f415f993707aeb0e2f2484238f65fe788084b4c354fcf0b7113aa380b7f6fb9e024dc5c0f32b745bc3198350cbb9",
 "Content-Type": "application/json"
}

Method to Calculate HMAC SHA-512

Here is the method to compute the HMAC SHA-512, as provided:

Java Version

public static String calculateHMACSHA512(String payReferenceString, String secretKey) {
    try {
        String algorithm = "HmacSHA512";
        Mac mac = Mac.getInstance(algorithm);
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
        mac.init(secretKeySpec);

        byte[] rawHmac = mac.doFinal(payReferenceString.getBytes());
        return bytesToHex(rawHmac);
    } catch (NoSuchAlgorithmException | InvalidKeyException ex) {
        System.out.println("Error Calculating SHA512 Mac");
    }
    return null;
}

private static String bytesToHex(byte[] bytes) {
    StringBuilder hexString = new StringBuilder();
    for (byte b : bytes) {
        String hex = Integer.toHexString(0xff & b);
        if (hex.length() == 1) hexString.append('0');
        hexString.append(hex);
    }
    return hexString.toString();
}

PHP Version

function calculateHMACSHA512(string $payReferenceString, string $secretKey): ?string {
    try {
        $hash = hash_hmac('sha512', $payReferenceString, $secretKey, true);
        return bin2hex($hash);
    } catch (Exception $ex) {
        error_log("Error Calculating SHA512 HMAC: " . $ex->getMessage());
        return null;
    }
}


// Example Use:

$key = "SK-l1vE-jhlajtbhttyytyhaho9883lta";
$payReferenceString = "PYDN-20250133222543502154838751243";

$hmac = calculateHMACSHA512($payReferenceString, $key);
echo "HMAC-SHA512: " . $hmac . PHP_EOL;

Javascript Version

const crypto = require('crypto');

function calculateHMACSHA512(payReferenceString, secretKey) {
    try {
        const hmac = crypto.createHmac('sha512', secretKey);
        hmac.update(payReferenceString);
        return hmac.digest('hex');
    } catch (error) {
        console.error("Error Calculating SHA512 HMAC", error);
        return null;
    }
}

Verification Logic

  1. Compute the MAC: Use the provided calculateHMACSHA512 method to compute the MAC for the given message and secret key.

  2. Compare MACs: Compare the computed MAC with the providedMac in a time-constant manner to prevent timing attacks.

All our Webhook/Callback are sent via HTTP Method to the specified url provided by Merchant.

Payout Webhook Event Types

transfer.success
transfer.failed
transfer.reversal
transfer.wallet.credit
transfer.wallet.debit

Payins Webhook Events

success
failed
charge.success
charge.failed
fixed.payment.success
fixed.payment.failed

Sample Webhook Responses

PAYIN WEBHOOK PAYLOAD 

SUCCESSFUL BANK TRANSFER  (DYNAMIC ACCOUNT)

{
  "event": "success",
  "data": {
    "accountNumber": "4570888889",
    "amount": 400,
    "amountPaid": 400,
    "channel": "BANKTRANSFER",
    "currency": "NGN",
    "customerEmail": "[email protected]",
    "customerName": "Daniel Joe",
    "sessionId": "10000425090098505125073703528",
    "fee": 50,
    "feeRatio": 1,
    "feeType": "Ratio",
    "stampDutyFee": 0,
    "appliedStampDutyFee": false,
    "payReference": "PYDN-20250019238832347115824786432",
    "created": "2025-01-07 18:12:34",
    "paymentCompletionDate": "2025-01-07 18:15:45",
    "paymentStartDate": "2025-01-07 18:12:34",
    "paymentStatus": "SUCCESSFUL",
    "reference": "4c6e83ae-4a91-4d45-bbc7-59e7c912f4f5",
    "vat": 0,
    "responseCode": "00",
    "narration": "Sample Narration",
    "payer": {
      "sourceAccountName": "SAM PAYER",
      "sourceAccountNumber": "8334497001"
    }
  }
}



SUCCESSFUL BANK TRANSFER  (FIXED ACCOUNT)

{
  "event": "fixed.payment.success",
  "data": {
    "accountReference": "19f3af87-8c91-4883-a3c8-04e8f522ca28",
    "accountNumber": "0083004524",
    "amount": 151200,
    "amountPaid": 151150,
    "channel": "BANKTRANSFER",
    "currency": "NGN",
    "customerEmail": "[email protected]",
    "customerName": "Sample CustomerName",
    "sessionId": "MI1849540961234",
    "fee": 3249.73,
    "feeRatio": 2,
    "feeType": "Ratio",
    "stampDutyFee": 50,
    "appliedStampDutyFee": false,
    "payReference": "PYDN-202501072099999514140085",
    "created": "2025-01-07 20:22:03",
    "paymentCompletionDate": "2025-01-07 20:22:03",
    "paymentStartDate": "2025-01-07 20:22:03",
    "paymentStatus": "SUCCESSFUL",
    "reference": "PYDN-202501072099999514140085",
    "vat": 0,
    "responseCode": "00",
    "fixedAccountNumber": "1183004511",
    "narration": "Transfer Narration",
    "payer": {
      "sourceBankName": "OPAY",
      "sourceAccountName": "SAMPLE OPAY CUSTOMER",
      "sourceAccountNumber": "****2866"
    }
  }
}

SUCCESSFUL CARD PAYIN

{
  "event": "success",
  "data": {
    "amount": 420,
    "amountPaid": 420,
    "channel": "CARD",
    "currency": "NGN",
    "customerEmail": "[email protected]",
    "customerName": "John Joe",
    "sessionId": "500720102499",
    "fee": 6.32,
    "feeRatio": 1.4,
    "feeType": "Ratio",
    "stampDutyFee": 0,
    "appliedStampDutyFee": false,
    "payReference": "PYDCRD-2020014787128341837",
    "created": "2025-01-07 21:20:06",
    "paymentCompletionDate": "2025-01-07 21:21:05",
    "paymentStartDate": "2025-01-07 21:20:01",
    "paymentStatus": "SUCCESSFUL",
    "reference": "56bcab3a-f30e-4",
    "vat": 0,
    "responseCode": "00",
    "narration": "",
    "payer": {
      "sourceAccountName": "Sam Joe"
    }
  }
}








PAYOUT WEBHOOK PAYLOAD 


SUCCESSFUL PAYOUT 
{
  "event": "transfer.success",
  "data": {
    "id": "d3792d15-82b0-43ef-af32-5de5ef0c60a1",
    "transactionAmount": 26250,
    "transactionFee": 500,
    "transactionReference": "PYDPYT-0112202419563400003748598",
    "responseCode": "00",
    "sessionId": "09028624120118588872826970586",
    "responseMessage": "Approved or completed successfully",
    "reference": "56274935607",
    "currencyCode": "NGN",
    "narration": "November pay",
    "senderAccountNumber": "6010336866",
    "senderAccountName": "Sample Merchant",
    "senderBank": "SAFE HAVEN MFB",
    "senderBankCode": "090286",
    "beneficiaryAccountName": "SAMPLE RECEIVER",
    "beneficiaryAccountNumber": "8130024726",
    "beneficiaryBank": "Opay",
    "beneficiaryBankCode": "100004",
    "transactionStatus": "SUCCESSFUL",
    "transactionStatusVerified": "true",
    "lastTransactionRequeryTimestamp": "2024-12-01 19:56:42",
    "created": "2024-12-01 19:56:34"
  }
}


FAILED PAYOUT


{
  "event": "transfer.failed",
  "data": {
    "id": "eed7eadb-406b-48b-ca603b9ce675",
    "transactionAmount": 1012,
    "transactionFee": 50,
    "transactionReference": "PYDPYT-07012025202247199945449",
    "responseCode": "81",
    "responseMessage": "Transaction Failed",
    "reference": "250108777662261900",
    "currencyCode": "NGN",
    "narration": "fees",
    "senderAccountNumber": "0034521179",
    "senderAccountName": "SAMPLE MERCHANT",
    "senderBank": "VFD Bank",
    "senderBankCode": "100033",
    "beneficiaryAccountName": "SAMPLE RECEIVER",
    "beneficiaryAccountNumber": "9126491726",
    "beneficiaryBank": "NGN",
    "beneficiaryBankCode": "090405",
    "transactionStatus": "FAILED",
    "transactionStatusVerified": "true",
    "lastTransactionRequeryTimestamp": "2025-01-07 20:22:53",
    "created": "2025-01-07 20:22:47"
  }
}




SUCCESSFUL POS TERMINAL WEBHOOK

{
    "event": "success",
    "data": {
        "accountNumber": "4565721625",
        "terminalId": "2100KJIL",
        "amount": 100.0,
        "amountPaid": 100.0,
        "channel": "POS",
        "currency": "NGN",
        "customerName": "MasterCard 2100KJIL",
        "sessionId": "1700074004691",
        "fee": 8.6,
        "feeRatio": 1.5,
        "feeType": "Ratio",
        "stampDutyFee": 0,
        "appliedStampDutyFee": false,
        "payReference": "PYDPOS-202502281000000241444522",
        "created": "2025-02-28 11:54:17",
        "paymentCompletionDate": "2025-02-28 11:54:17",
        "paymentStartDate": "2025-02-28 11:54:17",
        "paymentStatus": "SUCCESSFUL",
        "reference": "1700074004691",
        "vat": 0.0,
        "responseCode": "00",
        "narration": ""
    }
}


{
    "event": "failed",
    "data": {
        "accountNumber": "4565721625",
        "terminalId": "2100KJIL",
        "amount": 100.0,
        "amountPaid": 0.0,
        "channel": "POS",
        "currency": "NGN",
        "customerName": "MasterCard 2100KJIL",
        "sessionId": "1700074004691",
        "fee": 8.6,
        "feeRatio": 1.5,
        "feeType": "Ratio",
        "stampDutyFee": 0,
        "appliedStampDutyFee": false,
        "payReference": "PYDPOS-202502281000000241444522",
        "created": "2025-02-28 11:54:17",
        "paymentCompletionDate": "2025-02-28 11:54:17",
        "paymentStartDate": "2025-02-28 11:54:17",
        "paymentStatus": "SUCCESSFUL",
        "reference": "1700074004691",
        "vat": 0.0,
        "responseCode": "01",
        "narration": ""
    }
}



Last updated