1. HMAC-SHA512

This is the default method. Each event payload is signed using HMAC-SHA512 with your provided signing_key. The signature is sent in the xpay-signature header.

private boolean verifySignature(String incomingSignature, String payload, String secret) throws Exception {
        Mac sha512Hmac = Mac.getInstance("HmacSHA512");
        SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA512");
        sha512Hmac.init(keySpec);
        byte[] macData = sha512Hmac.doFinal(payload.getBytes("UTF-8"));
        incomingSignature.equals(Base64.getEncoder().encodeToString(macData));
    }

2. ECDSA

xPay supports ECDSA signature verification for webhooks. The signature is sent in the xpay-private-signature header, and the public key is provided below.

xPay Webhook Public Key

This is the public key used for webhook signature verification. The key below is base64 encoded. You can use this key to verify ECDSA signatures from xPay webhooks.

MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw==
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class WebhookVerifier {
    public static boolean verifySignature(String publicKeyBase64, String signatureBase64, String payload) throws Exception {
        byte[] publicBytes = Base64.getDecoder().decode(publicKeyBase64);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA");
        ecdsaVerify.initVerify(pubKey);
        ecdsaVerify.update(payload.getBytes("UTF-8"));

        byte[] signatureBytes = Base64.getDecoder().decode(signatureBase64);
        return ecdsaVerify.verify(signatureBytes);
    }

    public static void main(String[] args) throws Exception {
        String publicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw==";
        String signature = "MEUCIQDncKxd1HEthoRD/+kX2Kw0ZKRbaewtX9IfvW5vE/MPMwIgZ/BLckOaRkHqP3mtIX4DQRRKLXvmt9mmWG3mKMNUZPI=";
        String payload = "{\"eventId\":\"whe_g00AGgDy9KeiTPj6\",...}";

        boolean isValid = verifySignature(publicKey, signature, payload);
        System.out.println("Signature valid: " + isValid);
    }
}


Sample Payload Header

{
  "xpay-signature" : "s3z2v3ZGwMvDwiQ+9PpAT3WuSYU+PeSZJqvdzZXPmifAh3sT+s502PgJJx9NV4KQaScEaquTEuHJ30v17hK5GA==",
  "xpay-private-signature" : "MEYCIQD+649oWWsMkVbTcOsfkxKvxsnbAPbeq0QHptC2i1dFuwIhALN5GHEliiv+MT3/5a2ye8Wbud5rFNDRIMz6ExgWAaYg",
  ...
}