Loading...
A webhook is a message from us that notifies a merchant’s system that a particular event has occurred.
There are two types of webhooks that can be sent from our system: a POST webhook that contains data in the payload body of a message and a GET webhook that contains data in the query string of the URL being notified.
This guide focuses on how to validate both of these types of webhooks to ensure the message came from our API.
The below webhook is a HTTP POST request and the message content is in the body of the webhook. The signature is in the header field X-GP-Signature.
X-GP-Signature.app_key (Click here to learn about app_key).app_key.X-GP-Signature value from the header. If it’s the same, the message came from us. If they do not match, the message did not come our system.X-GP-Signature = "ee16e2d14fb2969565499c172522e69955945a544751a5fa9e5fc775b3141785612c223ed77c2ff4cc367ead60f816c4fec6e16dc35564882d9aa695a3d0a907";
body = '{"id":"TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181","time_created":"2024-07-03T15:23:51.342Z","type":"SALE","status":"CAPTURED","channel":"CNP","capture_mode":"AUTO","amount":"1005","currency":"EUR","country":"DE","merchant_id":"MER_f414851d386a4e1f9fa4beb56c5e38b9","merchant_name":"Global Payments Test Merchant Mason","account_id":"TRA_4d49f5d4e1b84ea4a28c8902a8538375","account_name":"79810948","reference":"44819181","payment_method":{"result":"00","message":"SUCCEEDED","entry_mode":"ECOM","apm":{"provider":"testpay","wait_notification":"","fund_status":"NOT_EXPECTED","payment_description":"546CCB7","confirmed_accountholder":"","account_number":"","iban":"","bank_identifier_code":"","bank_name":"","bank_address":"","optional_redirect":""}},"batch_id":"","action":{"id":"ACT_Jm6BviEawzx7XgbQZUh0dbfBettgQ5","type":"STATUS_NOTIFICATION","time_created":"2024-07-03T15:24:52.217Z","result_code":"SUCCESS","app_id":"a5f0OOTJdAChObGXIqi8I5eGq6i6sLlJ","app_name":"sean_sandbox_app"}}';
app_key = "WinZP9PgPfVZuTi4";
stringToHash = body + app_key;
stringToHash = '{"id":"TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181","time_created":"2024-07-03T15:23:51.342Z","type":"SALE","status":"CAPTURED","channel":"CNP","capture_mode":"AUTO","amount":"1005","currency":"EUR","country":"DE","merchant_id":"MER_f414851d386a4e1f9fa4beb56c5e38b9","merchant_name":"Global Payments Test Merchant Mason","account_id":"TRA_4d49f5d4e1b84ea4a28c8902a8538375","account_name":"79810948","reference":"44819181","payment_method":{"result":"00","message":"SUCCEEDED","entry_mode":"ECOM","apm":{"provider":"testpay","wait_notification":"","fund_status":"NOT_EXPECTED","payment_description":"546CCB7","confirmed_accountholder":"","account_number":"","iban":"","bank_identifier_code":"","bank_name":"","bank_address":"","optional_redirect":""}},"batch_id":"","action":{"id":"ACT_Jm6BviEawzx7XgbQZUh0dbfBettgQ5","type":"STATUS_NOTIFICATION","time_created":"2024-07-03T15:24:52.217Z","result_code":"SUCCESS","app_id":"a5f0OOTJdAChObGXIqi8I5eGq6i6sLlJ","app_name":"sean_sandbox_app"}}WinZP9PgPfVZuTi4';
hashedString = SHA512(stringToHash);
hashedString = 'ee16e2d14fb2969565499c172522e69955945a544751a5fa9e5fc775b3141785612c223ed77c2ff4cc367ead60f816c4fec6e16dc35564882d9aa695a3d0a907'
IF X-GP-Signature == hashedString { All Good }
IF X-GP-Signature != hashedString { Issue }The below webhook is a HTTP GET request and the message content is in the URL’s query string. The signature is in the first query string field, X-GP-Signature.
https://www.example.com/?X-GP-Signature=8174e708320993a2083d82c097cbb148f1dcf381fb33ca85495fdc672c219e52d0ba19dab2f15460b00f80727fc952ad23cf9390b1af49227d8f6acd81205c14&id=TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181&status=PENDING&reference=44819181&payment_method.result=01&payment_method.message=PENDING&provider=testpay&apm.wait_notification=&apm.optional_redirect=&apm.fund_status=NOT_EXPECTED&apm.payment_description=546CCB7&apm.confirmed_accountholder=&apm.account_number=&country=DE&apm.bank.iban=&apm.bank.identifier_code=&apm.bank.name=&apm.bank.code=&action.id=ACT_UWGHF3hQxRmfe9im2W7AmSLUdXB1Rb&action.type=RETURN_NOTIFICATION&action.time_created=2024-07-03T15%3A24%3A23.402ZX-GP-Signature query string field. It will be the first parameter in the query string.X-GP-Signature value.app_key (Click here to learn about app_key).app_key.X-GP-Signature value from the query string field. If it’s the same, the message came from us. If they do not match, the message did not come from our system.fullURL = ‘https://www.example.com/?X-GP-Signature=8174e708320993a2083d82c097cbb148f1dcf381fb33ca85495fdc672c219e52d0ba19dab2f15460b00f80727fc952ad23cf9390b1af49227d8f6acd81205c14&id=TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181&status=PENDING&reference=44819181&payment_method.result=01&payment_method.message=PENDING&provider=testpay&apm.wait_notification=&apm.optional_redirect=&apm.fund_status=NOT_EXPECTED&apm.payment_description=546CCB7&apm.confirmed_accountholder=&apm.account_number=&country=DE&apm.bank.iban=&apm.bank.identifier_code=&apm.bank.name=&apm.bank.code=&action.id=ACT_UWGHF3hQxRmfe9im2W7AmSLUdXB1Rb&action.type=RETURN_NOTIFICATION&action.time_created=2024-07-03T15%3A24%3A23.402Z”;
X-GP-Signature = "8174e708320993a2083d82c097cbb148f1dcf381fb33ca85495fdc672c219e52d0ba19dab2f15460b00f80727fc952ad23cf9390b1af49227d8f6acd81205c14";
remainingQueryStringToHash = “id=TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181&status=PENDING&reference=44819181&payment_method.result=01&payment_method.message=PENDING&provider=testpay&apm.wait_notification=&apm.optional_redirect=&apm.fund_status=NOT_EXPECTED&apm.payment_description=546CCB7&apm.confirmed_accountholder=&apm.account_number=&country=DE&apm.bank.iban=&apm.bank.identifier_code=&apm.bank.name=&apm.bank.code=&action.id=ACT_UWGHF3hQxRmfe9im2W7AmSLUdXB1Rb&action.type=RETURN_NOTIFICATION&action.time_created=2024-07-03T15%3A24%3A23.402Z”;
appKey = "WinZP9PgPfVZuTi4";
stringToHash = body + app_key;
stringToHash = 'id=TRN_wRWA1rOQeVRDUOafRmirrpYPURPODJ_44819181&status=PENDING&reference=44819181&payment_method.result=01&payment_method.message=PENDING&provider=testpay&apm.wait_notification=&apm.optional_redirect=&apm.fund_status=NOT_EXPECTED&apm.payment_description=546CCB7&apm.confirmed_accountholder=&apm.account_number=&country=DE&apm.bank.iban=&apm.bank.identifier_code=&apm.bank.name=&apm.bank.code=&action.id=ACT_UWGHF3hQxRmfe9im2W7AmSLUdXB1Rb&action.type=RETURN_NOTIFICATION&action.time_created=2024-07-03T15%3A24%3A23.402ZWinZP9PgPfVZuTi4';
hashedString = SHA512(stringToHash);
hashedString = '8174e708320993a2083d82c097cbb148f1dcf381fb33ca85495fdc672c219e52d0ba19dab2f15460b00f80727fc952ad23cf9390b1af49227d8f6acd81205c14'
IF X-GP-Signature == hashedString { All Good }
IF X-GP-Signature != hashedString { Issue }