The signature
Both kinds of notification use the same algorithm and the same secret. Only the input string differs.
Algorithm
signature = urlencode( base64( sha256( DATA + HashKey ) ) )
HashKey is the hash key of your program. It is a shared secret: it is
never transmitted in the notification, it is only appended to the data before hashing. If you do not
know your program hash key, ask your account manager. Note that this is a different key from the one
used to sign requests you send to us.
The SHA-256 must be taken over the raw binary digest, then base64 encoded, then
URL encoded. Hashing to a hex string first and base64ing that is the single most common
implementation mistake, and it produces a value that never matches.
Per-request notifications: DATA is the values, concatenated
DATA is the value of every field in the notification, in the documented order,
concatenated together. Field names are not included. There is no separator between the values, and
no & or = characters. The values are taken in their
URL-encoded form, exactly as they appear on the wire, so do not decode them before
hashing. The signature field itself is excluded, as are any fields documented as
excluded for that event.
Example - payout notification
DATA = wireId + orderID + accountId + beneficiaryId + payoutAccountId + wireStatus
+ transferAmount + transferCurrency + paymentScheme
+ payoutAccountName + payoutAccountNickname + payoutAccountFirst
+ payoutAccountLast + payoutAccountCompanyName
+ beneficiaryName + beneficiaryNickname + beneficiaryFirst
+ beneficiaryLast + beneficiaryCompanyName
See Payout Notification for the full field
list and an example payload.
Program notifications: DATA is the whole body
DATA is the complete request body exactly as received, with the trailing
&signature=... parameter removed. Field names, = and
& separators are all included, because the body is template-defined and has no
fixed field list to concatenate. Do not parse, reorder, decode or re-encode the body before
hashing: take the raw bytes, cut off the signature parameter, and hash what is left.
Example - program notification
Received body:
event=balance_request_timed_out&request_id=84213&result_code=889&amount=250.00&signature=Ax7v...%3D
DATA = event=balance_request_timed_out&request_id=84213&result_code=889&amount=250.00
The signature is always the last parameter in the body, so cutting at the last occurrence
of &signature= is the reliable way to split it.