# Webhooks/Callbacks

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"])\ <br>

```json
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

```java
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&#x20;

```php
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

```javascript
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**

```bash
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

<pre class="language-json"><code class="lang-json">PAYIN WEBHOOK PAYLOAD 

<strong>SUCCESSFUL BANK TRANSFER  (DYNAMIC ACCOUNT)
</strong>
{
  "event": "success",
  "data": {
    "accountNumber": "4570888889",
    "amount": 400,
    "amountPaid": 400,
    "channel": "BANKTRANSFER",
    "currency": "NGN",
    "customerEmail": "daniel@example.com",
    "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@gmail.com",
    "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": "john@example.com",
    "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": ""
    }
}




</code></pre>
