Request Signing
To guarantee the authenticity and origin of the requests, a digital signature of the request payload is required for certain Embedded Wallet API endpoints. The signature is calculated using HMAC-SHA256 and is provided in a HTTP request header Signature.
For more information regarding HMAC encryption and signatures check these resources:
Webhook signing
All wallet webhook requests made from Paysafe to Merchant contain a Signature header. Its purpose is to enable Merchant to verify the authenticity of the received data. The signature is calculated against the JSON request body.
HMAC secret key
The singing and signature verification requires the use of HMAC Secret Key that is exchanged between Merchant and Paysafe.
The secret key is 256 bytes long and is base64 encoded as text.A random key could be generated using openssl:
$ openssl rand 256 -base64
Example output:
dOTYlA1XIDJH867WhK8iWe54SONltkRZgNxejUoygtvwdUVxKKa+Mm57RXpH6pI7qh3gkKxcwlrUJ1LhkMLxSNwr78WH4zAd/ILHfEFWORJHgNilzyqyBMZutCtPHhDIBnzkgqfgv1eE6EcDozRT+Q==
Signing requests
Requests with body
The Signature header is required for endpoints that usually modify customer money balance or create new customers. The signature is calculated for the submitted request body if the HTTP method is one of:
-
POST
-
PUT
-
PATCH
The request body is usually a JSON string.
Important: The received JSON string must not be pretty-formatted before calculating the HMAC-SHA256 signature.
Example: (Using the HMAC secret key displayed above)
{"id":1,"name":"John Smith"}
Signature: cQPmKNg51k2mAcp8y6eh2oOl0OSbDwbK+chWLuifUxU=
{
"id": 1,
"name": "John Smith"
}
Signature: lwjnjjixwi/ZX/IBvuH1P6ng6GLycHaUuF648jny4O0=
The HMAC-SHA256 signatures for both JSON contents are different as they differ in white spaces and end-of-line characters.
Requests without body
If the request does not contain a body, but still requires Signature, then the signature is calculated against the URL path.
Example:
DELETE /customers/1234567890
The signature is calculated against /customers/1234567890.
Errors
If an API endpoint requires Signature but no signature, or an invalid one has been provided, the endpoints will return HTTP code 400 Bad Request with the following additional error details:
HTTP Status Code | Error Code | Message |
---|---|---|
400 | DW-SIGNATURE-HEADER-REQUIRED | Signature header is required. |
400 | DW-HMAC-SIGNATURE-INVALID | Signature is invalid. |
Implementation hints
Example code in JSON:
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.io.IOUtils;
import java.util.Base64;
public class HmacSignature {
/**
* Calculate signature using HMAC-SHA256 algorithm.
*
* @param content The message to be signed
* @param keyBase64 Base64 encoded secret key
*
* @return Base64 encoded signature
*/
public String calculateSignature(String content, String keyBase64) {
byte[] key = Base64.getDecoder().decode(keyBase64);
HmacUtils hmacUtils = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key);
byte[] signatureBytes = hmacUtils.hmac(content.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(signatureBytes);
}
}