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
Compute the MAC: Use the provided
calculateHMACSHA512
method to compute the MAC for the given message and secret key.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": "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": ""
}
}
Last updated