Notifications
This page outlines the Notifications Service, which sends you updates for fraud screen transactions.
Overview
Fraud Prevention API Notifications is a solution that lets you integrate with Fraud Prevention more closely than ever. When changes occur that can impact your business, Fraud Prevention will push details of the change directly to your systems via standard POST messages. With our push notifications you can remain informed, simplify operations, and ensure your business is protected from fraud.
We currently support notifications for both order purchase and account screen events. So, if an analyst specialist has reviewed the transaction, you'll be notified immediately with the resolution and reccomended actions.
Message schema and details
This section will delve into the architectural makeup of our messages which consists of two primary parts: the Envelope and the Notification Payload. The Envelope incorporates the notification metadata, while the Notification Payload contains the intricate details of the notification. Let's explore these components in detail.
Envelope object schema
Field | Type | Possible values | Nullable | Sample | Description |
---|---|---|---|---|---|
event_name | String | MERCHANTSHIELD_FRAUD | false | MERCHANTSHIELD_FRAUD | Event name, always will be MERCHANTSHIELD_FRAUD . |
creation_time | String | Data time (UTC) | false | 2024-01-18T10:29:20.484649887Z | Time notification event created. |
notification_id | String | GUID | false | d72ac517-f0a7-4a65-8547-250cf81ce440 | Unique notification id. |
payload | Payload | Payload object | false | Actual notification payload. See Payload object schema description below. |
Payload object schema
Field | Type | Possible values | Nullable | Sample | Description |
---|---|---|---|---|---|
risk_id | String | GUID | false | fdeaf9dc-ac79-4c2f-a148-0e722374aef1 | Risk transactions unique identifier. |
entity_type | String | BookingFraud , Account | false | BookingFraud | Entity type. |
entity_id | String | GUID | false | be8076bc-d17c-45fa-84e6-0fe6a609f3ac | The Reference ID of the affected screen booking or account takeover transactions. |
decision | String | PASS, FAIL | true | PASS | Decision made by the Analyst specialist after reviewing the transaction. |
decision_date_time | String | Data time (UTC) | false | 2024-03-07T22:28:33.552Z | Analyst decision date and time in UTC format. |
recommended_actions | Array of Strings | for BookingFraud entity type: RELEASE , CANCEL_FULL_REFUND , CANCEL_NO_REFUND <hr> for Account entity type: TERMINATE_ACTIVE_SESSIONS , HARD_PASSWORD_RESET | could be empty | ["CANCEL_FULL_REFUND"] | List of recommended remediation actions. |
partner_account_id | String | GUID | false | ff1fddb1-29ac-41a1-8c0b-6db5932c913d | Your partner account Id. |
Each message is an HTTPS POST request with a JSON message body.
Example of BookingFraud update
{
"event_name": "MERCHANTSHIELD_FRAUD",
"creation_time": "2024-01-18T10:29:20.484649887Z",
"notification_id": "0597ae4c-b6d2-4d47-ba58-36534e04f1cf",
"payload": {
"risk_id": "9beabb6d-77b9-474e-852a-3cb9fedabb3a",
"entity_type": "BookingFraud",
"entity_id": "1e5092ad-4440-40cf-9a14-0bf76ced339c",
"decision_date_time": "2024-03-07T22:28:33.552Z",
"decision": "PASS",
"recommended_actions": [
"RELEASE"
],
"partner_account_id": "972edd1c-b50f-4d7e-b5bb-05212aa20d03"
}
}
Example of Account Takeover update
{
"event_name": "MERCHANTSHIELD_FRAUD",
"creation_time": "2024-01-18T10:29:20.484649887Z",
"notification_id": "c9235ccb-8716-4ac3-a3ad-ef96042aa32a",
"payload": {
"risk_id": "d2f0d5ab-cda1-484e-9507-e0fcf81960dc",
"entity_type": "Account",
"entity_id": "13538ba1-df41-446c-8266-4f325e4ef264",
"decision_date_time": "2024-03-07T22:28:33.552Z",
"decision": "PASS",
"recommended_actions": [],
"partner_account_id": "34f8df88-26f3-48f2-a81b-12fae9306192"
}
}
Integration
Receiving a message
To start receiving notifications, you will need to stand up an endpoint that can accept a POST message that will be pushed to your endpoint. The endpoint should:
- Be publicly accessible.
- Have HTTPS and TLS 1.2 or above enabled.
- Configure a valid TLS certificate, which is trusted by most modern applications (a self-signed certificate might not be trusted).
Work with your Fraud Prevention Integration Consultant to get set up and provide them with:
- The URL for your endpoint to handle messages.
We are working to provide you with self-service tools to test your integration. Until then, your Integration Consultant can help you make test bookings to confirm that you're receiving notifications for the offline events you subscribed to.
Important configuration notes
- Fraud Prevention uses cloud-based servers - ensure your listener endpoints are configured to receive notification pushes from different potential IP addresses.
- If you wish to change your endpoint URL, you must keep the original URL live until we validate your new URL for receiving notification pushes. Contact your Fraud Prevention representative before making such changes.
- Only one URL may be used for notifications.
Handling a message
Recognize the importance of prompt action. Carefully review the details of the callback request, make sure you are processing all combinations of entitties, decisions and recommended remediation actions.
Undeliverable messages
If we encounter difficulties in delivering a message to your endpoint, we have established a protocol to automatically attempt redelivery. This will occur five times with an exponential backoff, initiating after a delay of 5 seconds.
Validation
To validate the event, you will need to compare the signature SHA512 hash in the header with one that you generate using your API key, shared secret, and the timestamp in the request header.
Make sure to validate that api-key
header is actually a API key you were provided while Fraud Prevention onboarding process.
Protecting your shared secret
The shared secret provided to you is critical to the security of your request data – treat it like a password. Never include the raw value in any publicly accessible site or app code. You will be provided with a shared secret and an API key when you are approved to integrate Fraud Prevention.
Callback request header structure
Header name | Sample value |
---|---|
x-eg-notification-signature | Sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
x-eg-notification-timestamp | 13536472536 |
api-key | c05b7b59-0a29-4cb1-9b09-d36954c9a605 |
Validating hash against signature steps
Prepare the
signed_payload
string:- The signed_payload string is created by concatenating:
- The timestamp as a string from
x-eg-notification-timestamp
header - The
.
character. - The actual JSON payload (i.e., the request body)
- The timestamp as a string from
- The signed_payload string is created by concatenating:
Determine the expected signature:
- Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the
signed_payload
string as the message.
- Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the
Compare the signatures: Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within tolerance.
Example on Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class TestApplication {
public static final String HMAC_SHA_256 = "HmacSHA256";
public static void main(String[] args){
// extracted data from the notification request payload
// x-eg-notification-timestamp: 1634021234
String eg_timestamp_header_value = "timestamp_header_value";
// x-eg-notification-signature: SHA256=signature_header_value
String eg_signature_header_value = "signature_header_value";
// api-key: api_key_to_validate
String api_key_header_value = "api_key_to_validate";
// json payload
String json_payload = "json_payload";
// your api key
String api_key = "your_api_key";
// signing secret from the secret store
String your_endpoints_signing_secret = "your_endpoints_signing_secret";
if (!api_key.equals(api_key_header_value)) {
throw new RuntimeException("Failure! Api key does not match expected value!");
}
try {
// Prepare the `signed_payload` string
String signed_payload = eg_timestamp_header_value + "." + json_payload;
// Determine the expected signature
String expected_signature = generate_hmac(signed_payload,
your_endpoints_signing_secret);
if (!eg_signature_header_value.equals(expected_signature)) {
throw new RuntimeException("Failure! Signature does not match expected value!");
}
System.out.println("Success! The generated signature matches the expected value.");
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
System.err.println("Error generating HMAC: " + e.getMessage());
}
}
/**
* Generates a hashed message authentication code using the HMAC-SHA256 algorithm.
* This method may throw an Exception when the HMAC-SHA256 algorithm is not supported
* or the secret key is invalid.
*
* @param message The message to be encoded
* @param secret The secret key
* @return The Base64 encoded HMAC
*/
public static String generate_hmac(String message, String secret)
throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256_hmac = Mac.getInstance(HMAC_SHA_256);
SecretKeySpec secret_key_spec = new SecretKeySpec(secret.getBytes(), HMAC_SHA_256);
sha256_hmac.init(secret_key_spec);
byte[] hmac = sha256_hmac.doFinal(message.getBytes());
return Base64.getEncoder().encodeToString(hmac);
}
}