Search Overlay

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:

Y+83Kt6imrf2eQBVojCfVAx9iDNwtgN7UzZydbpqUgNq3WzgJOhiNpdAF5b9UJ4Y mf++HMgdrgClOmwfq8qItCNcVaCT/MPhMGYgiMb+oLtc2K3nmJxvPxTR6caFalI8 qKr6BgX0K1tqKDka2xJZhUZXCVjBsBmKJLT/XQ0+cTSGUfLOwOF+jo0Mgm8oHYnIdOTYlA1XIDJH867WhK8iWe54SONltkRZgNxejUoygtvwdUVxKKa+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);
}
}