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:

  1. How to calculate the signature of the received callback.
  2. 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.

Enter your OPay Secret Key
Enter OPay Callback 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();
                                      }
                        
                

See Also

User Profile 12 messages

James Jones
Application Developer
Recent Notifications
Another purpose persuade Due in 2 Days
+28%
Would be to people Due in 2 Days
+50%
-27%
The best product Due in 2 Days
+8%