OPay Callback Notification Signature
Whenever the status of any of your transaction has been updated, e.g. a reference code payment has been paid, OPay
will keep you informed at your designated callBackUrl
. Since anyone can get hold of your
endpoint and attempt to send you phony event objects for malicious purposes
(e.g. to see if they can mark their subscription to your product as renewed just in case
you aren't running any verifications on the transaction reference),
it is important to verify that callbacks originate from OPay.
You can do any or both of the below to verify callbacks from OPay:
- Watch the IPs and accept callbacks only from our IPs.
- Validate the Signature as described in the section that follows.
In this page, you will learn:
- How to calculate the signature of the received callback.
- How to validate OPay callback signature.
Callback Signature Calculator
-HMac-SHA3-512 signature of the callback payload
Valid callbacks are raised with sha512
value, which is essentially a HMAC-SHA3-512 signature of the callback payload signed using your Secret Key.
The following section helps you generate a signature from the HMAC computation of the private key and payload.
Callback Signature Validation
-HMac-SHA3-512 signature of the callback payload
Valid callbacks are raised with sha512 value, which is essentially a HMac-SHA3-512 signature of the callback payload. Yes, signed using your Secret Key.
-Example signature payload params:
There are two values for Refunded, when payload.refunded is true, it is t, otherwise it is f.
{
"payload": {
"amount": "30000",
"channel": "Web",
"country": "EG",
"currency": "EGP",
"displayedFailure": "",
"fee": "1500",
"feeCurrency": "EGP",
"instrumentType": "BankCard",
"reference": "test0816_1639568742",
"refunded": false,
"status": "SUCCESS",
"timestamp": "2021-12-15T11:46:26Z",
"token": "211215140485151728",
"transactionId": "211215140485151728",
"updated_at": "2021-12-15T11:46:26Z"
},
"sha512": "91036c7cc6274b4ec2b2c3e4dc5b0f0ef9817978dfd5e379a9a57414061c4f090ae36771f532099f9c72b3b73fd6ebb0c7c9d052b5a19d9c940ea0f101e86b67",
"type": "transaction-status"
}
-Code Example:
package com.opay.sdk.utils;
import com.opay.sdk.exception.OPaySignException;
import com.opay.sdk.model.TopupStatusNotifyPayload;
import com.opay.sdk.model.TransactionStatusNotifyPayload;
/**
* Verification signature tools
*
* @author wanjun.an
* @since 1.0
*/
public class SignatureUtils {
public static boolean verifyTransactionSignature(TransactionStatusNotifyPayload payload, String secretKey) throws OPaySignException {
String format = "{Amount:\"%s\",Currency:\"%s\",Reference:\"%s\",Refunded:%s,Status:\"%s\",Timestamp:\"%s\",Token:\"%s\",TransactionID:\"%s\"}";
String signString = String.format(format,
payload.getAmount(),
payload.getCurrency(),
payload.getReference(),
true == payload.getRefunded() ? "t" : "f",
payload.getStatus(),
payload.getTimestamp(),
payload.getToken() == null && payload.getToken().length() == 0 ? "" : payload.getToken(),
payload.getTransactionId()
);
String sign = HmacUtils.buildHmacSha3_512(signString, secretKey);
if (payload.getSignature().equalsIgnoreCase(sign)) {
return true;
}
throw new OPaySignException();
}
public static boolean verifyTopupSignature(TopupStatusNotifyPayload payload, String secretKey) throws OPaySignException {
String format = "{orderNo:\"%s\",merchantOrderNo:\"%s\",merchantId:\"%s\",orderAmount:\"%s\",serviceType:\"%s\",orderStatus:\"%s\"}";
String signString = String.format(format,
payload.getOrderNo(),
payload.getMerchantOrderNo(),
payload.getMerchantId(),
payload.getOrderAmount(),
payload.getServiceType(),
payload.getOrderStatus()
);
String sign = HmacUtils.buildHmacSha3_512(signString, secretKey);
if (payload.getSignature().equalsIgnoreCase(sign)) {
return true;
}
throw new OPaySignException();
}