Loading...
Outgoing payments

Signing the request

Authenticate your API requests using JWS (JSON Web Signature) for enhanced security.

How do you do this using the API?

We use JWS (JSON Web Signature) as the signature method for each request to authenticate it using a second factor in addition to API credentials.

What happens if you don't sign each API request?

Your request won’t be processed for payment automatically, but will instead appear in a queue for processing in Fuzebox. You will need to login to Fuzebox and authorise the request using a passkey stored on your computer or mobile device. This can be done in bulk or for each individual payment.

Where can you test this?

You can test the signing on sandbox and production. However, we recommend testing it particularly on production before activating it for your shoppers.

Integration steps

  1. Setting up the trusted signing keys.
  2. Creating a JWT (JSON Web Token) for each request, which includes the signature, and including that in the request header.

1. Setting up a key for signing

  • Create private / public key pair.
  • Store the private key in a secure manner.
  • Share public key with Volt and get your assigned public key id.

Create key pair

Technical specifications

  • We support public keys in the following formats: PKCS1, PKCS8 and x509.
  • The public key length should be between 2048 and 4096 bytes.

How to generate your keys

It is recommended that you use your own PKI infrastructure, preferably based on a hardware security module (HSM), to generate a key pair for this use case as this is industry best practice.

However, as not all companies are able to manage such solutions, the following recommendations were prepared:

  • Option 1: Use Fuzebox Go to Configuration > Customers > API Access > Signature Keys > Generate a key pair. Your public key will be automatically saved and you will receive a private key and public key ID in a popup message. Please bear in mind that Volt does not save this private key.

  • Option 2: Generate outside of Fuzebox You can also generate your private / public key pair using a terminal which supports the openssl command. If you generated the key pair outside of Fuzebox, please upload your public key to Fuzebox under Configuration > Customers > API Access > Signature Keys > Upload an existing public key.

Once you upload the public key, you will get a key ID (a UUID) which you’ll need to use when generating your signed token on each refund or payout request. Please keep this ID safe.

Example of an ID: 901659f9-c0fd-4d2e-82b8-a55f51f80d73.

You should never share your private key with Volt, or with any third party. If you believe your private key may be compromised, you should immediately inform Volt, generate a new key pair and send us the new public key.


2. Signing the requests

Once you have the private key and the public key ID, you can proceed with signing the requests. To sign each request, you will need to provide a JWT token in the header of that request.

To generate a signed JWT token, you’ll need:

  • Your private key.
  • Your public key ID.
  • The payload (the JSON body) of the POST request for your Refund or Payout.

Creating your JWT token

You need to create two parts for your JWT token: the header and the signature.

The token header segment The header should be created first as a JSON object:

  • alg: represents the algorithm used to encode/decode the token, in this case it’s RS256 (the RSA+SHA256 algorithm).
  • typ: should be JWT.
  • kid: the ID of the public key that we supplied you (UUID).

Example JSON object:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "ce161c49-4373-4b07-82fa-217998f6b3e8"
}

Encoding the header Remove any extra spaces or line breaks, then encode it using the base64UrlEncoded algorithm.

Example code:

tokenHeader = '{"alg":"RS256","typ":"JWT","kid":"ce161c49-4373-4b07-82fa-217998f6b3e8"}'
encodedHeader = base64UrlEncode(tokenHeader)

Example encoded header:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImNlMTYxYzQ5LTQzNzMtNGIwNy04MmZhLTIxNzk5OGY2YjNlOCJ9

The signature segment To create the signature segment, use the algorithm specified in the header and the private key. You’ll need the payload you’re sending in the POST request.

Remove whitespace to improve validation

Please remove any line breaks or extra spaces in the request payload before encoding. This ensures your signature matches our validation. For example: base64UrlEncode('{"amount":1,"externalReference":"my-external-reference"}')

Example code to generate signature:

tokenHeader = '{"alg": "RS256","typ":"JWT","kid":"ce161c49-4373-4b07-82fa-217998f6b3e8"}'
requestPayload = '{"amount":1,"externalReference":"my-external-reference"}'
signature = RSASHA256( base64UrlEncode(tokenHeader) + "." + base64UrlEncode(requestPayload), privateKey )

Example signature:

oUjLLtQigBniTiYswfE0JAjMiYXtIlNtVi1Lr1jqBx103vXgVtEdWApUMpG3wze3qVXD_APA2Sk8oLV4DGeBb5pN7yRGeCdxoV3IsikCVs6rn2Q2Jat-bReQMX39F7-Rpn7RznjHUsyWWcNbDKy1wRFcEnDJBVdb_1lKdFBPWaKMkB1Yd8t8X2va6mq7pJXPAMS36Gwc37vULZvdw4D-49r8mcbEGnNXwkcuZ08hMk4UsmM0kxLeNcrVD3wZtuU0N43u1trlPnuX9RDOOh9Gz0fEH1fwxdveAZaMOOWr7IPHBeV8nZXHxt1lpwJ-dpAsSDMvCFhr-MHuOQDDdqsfhQ

Build your JWT token

To build the final JWT token, take the encoded header and join it to the signature using two dots ...

Example code:

JWT = base64UrlEncode(header) + ".." + signature

The double dot .. is critical. Validation will fail if you use only one dot.

Example final JWT token:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImNlMTYxYzQ5LTQzNzMtNGIwNy04MmZhLTIxNzk5OGY2YjNlOCJ9..oUjLLtQigBniTiYswfE0JAjMiYXtIlNtVi1Lr1jqBx103vXgVtEdWApUMpG3wze3qVXD_APA2Sk8oLV4DGeBb5pN7yRGeCdxoV3IsikCVs6rn2Q2Jat-bReQMX39F7-Rpn7RznjHUsyWWcNbDKy1wRFcEnDJBVdb_1lKdFBPWaKMkB1Yd8t8X2va6mq7pJXPAMS36Gwc37vULZvdw4D-49r8mcbEGnNXwkcuZ08hMk4UsmM0kxLeNcrVD3wZtuU0N43u1trlPnuX9RDOOh9Gz0fEH1fwxdveAZaMOOWr7IPHBeV8nZXHxt1lpwJ-dpAsSDMvCFhr-MHuOQDDdqsfhQ

Sign your request

Add the X-JWS-Signature header to each request, containing the JWT token you created.

Header name: X-JWS-Signature

Example:

X-JWS-Signature: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImNlMTYxYzQ5LTQzNzMtNGIwNy04MmZhLTIxNzk5OGY2YjNlOCJ9..oUjLLtQigBniTiYswfE0JAjMiYXtIlNtVi1Lr1jqBx103vXgVtEdWApUMpG3wze3qVXD_APA2Sk8oLV4DGeBb5pN7yRGeCdxoV3IsikCVs6rn2Q2Jat-bReQMX39F7-Rpn7RznjHUsyWWcNbDKy1wRFcEnDJBVdb_1lKdFBPWaKMkB1Yd8t8X2va6mq7pJXPAMS36Gwc37vULZvdw4D-49r8mcbEGnNXwkcuZ08hMk4UsmM0kxLeNcrVD3wZtuU0N43u1trlPnuX9RDOOh9Gz0fEH1fwxdveAZaMOOWr7IPHBeV8nZXHxt1lpwJ-dpAsSDMvCFhr-MHuOQDDdqsfhQ

How is this guide?

Last updated on

On this page