Webhook Events
Our system provides the ability to receive real-time updates by sending event notifications to registered webhooks.
About webhook
You can contact us to provide your Webhook endpoint
to receive event notifications. Currently, we only support creating one webhook endpoint. The webhook endpoint only supports the HTTPS
protocol, and the request method is POST
.
Event formats
Once your webhook is set up successfully, it will be notified of new events as they occur. These payloads are JSON formatted with the following general structure:
{
"event_id": "",
"event_identifier": "",
"data": {...},
}
Webhook retry
You need to respond with our standard HTTP status codes 200 or 201 within 30 seconds. If you do not respond in a timely manner or if the status code is abnormal, the system will attempt to resend the webhook, with retry delays of 10s, 30s, 60s, 120s, 300s, and 600s.
Webhook verification
In order to verify that the webhook events are indeed sent by DogPay
, the payload of each webhook event is signed using the HTTP header wh-signature
. This signature is based on a SHA-512 hash-based message authentication code (HMAC), using your ApiKey as the key and the JSON payload (i.e., the request body) as the message.
Code example
package com.example.dogpay2;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class DogPayWebhookVerifier {
private static String bytesToHex(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("Input byte array cannot be null");
}
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();
}
public static boolean verifySignature(String apiKey, String payload, String whSignature) {
try {
// Initializing a Mac Instance with the HMAC-SHA512 Algorithm
Mac hmacSha512 = Mac.getInstance("HmacSHA512");
SecretKeySpec secretKeySpec = new SecretKeySpec(apiKey.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
hmacSha512.init(secretKeySpec);
// Compute HMAC signatures
byte[] computedHash = hmacSha512.doFinal(payload.getBytes(StandardCharsets.UTF_8));
String computedSignature = bytesToHex(computedHash);
return computedSignature.equals(whSignature);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
String apiKey = "{{apiKey}}";
String payload = "{"
+ "\"event_id\":\"997daf9b-4162-4864-914c-960ff6cc16ad\","
+ "\"event_identifier\":\"card.transaction\","
+ "\"data\":{"
+ "\"id\":\"043fe653-e916-4989-a044-c8404cc4730c\","
+ "\"cardId\":\"9afe2c3c-306c-492f-aa99-6ce6574440bd\","
+ "\"cardChannel\":\"c_002_budget\","
+ "\"accountId\":\"1bd30ef3-0f13-468c-a9b7-61b141a02864\","
+ "\"orderNum\":\"202503101055594738096\","
+ "\"transactionId\":null,"
+ "\"currency\":\"USD\","
+ "\"fee\":\"0.65000000\","
+ "\"amount\":\"10.00000000\","
+ "\"type\":\"consumption\","
+ "\"status\":\"pending\","
+ "\"createAt\":\"2025-03-10T02:55:59.470Z\","
+ "\"transactionAt\":\"2025-03-10T02:55:59.474Z\","
+ "\"completeAt\":\"2025-03-10T02:55:59.474Z\","
+ "\"detail\":\"WECHAT*TENCENT ShenZhen CN\","
+ "\"sourceId\":\"a435-2ad446944ebe-bf04-5c86-6c3e-5d51\","
+ "\"tradeTag\":null,"
+ "\"account\":null,"
+ "\"card\":null,"
+ "\"reasonCode\":0,"
+ "\"mcc\":\"123456\""
+ "}"
+ "}";
String whSignature = "example_wh_signature";
boolean isValid = verifySignature(apiKey, payload, whSignature);
if (isValid) {
System.out.println("Success");
} else {
System.out.println("Failed");
}
}
}
Updated 3 months ago