Payouts - Signing Payout Instructions

Setting Signature and Expires-at headers

Signing requests


Payouts instructions and certain other requests need to be signed for security reasons, Yaspa will verify merchant requests against their registered RSA keys. Signing is done by setting the Signature and Expires-at headers on the HTTPS request.

The action of signing requires the merchant private RSA key, see Instant Payouts - RSA Key Registration. The signature is valid until a given expiry time set by the merchant (max 10 minutes from the time the request is made).


Step 1: Construct the String to Sign

The signature plain text is generated by concatenating the request components, each one separated by the '|' delimiter:

expiryTime | httpMethod | url | requestBody

If the request body is not present in the request then the signature plain text is as follows:

expiryTime | httpMethod | url |
ComponentDescription
expiryTimeInteger UNIX timestamp for signature expiry time
httpMethodString HTTP method (GET, POST etc) in upper case
urlString URL of the endpoint
requestBodyString representation of the JSON request body if present

An example of the signature plain text is as follows:

1613639354|POST|https://testapi.yaspa.com/v2/corporate-account/admin-counter-party|{"customerIdentifier":"1846593725421829","bankCountry":"GB","accountGiro":"FPS","accountCurrency":"GBP","accountName":"Internal Account","accountNumber":"12345678","bankCode":"010203","counterPartyBank":"OPENPAYD","customerType":"CORPORATE"}

Step 2: Sign Request

Merchants need to use their private key to sign their request using a SHA256withRSA algorithm - this is a fairly standard process. The following Java code can be used to help understand how this is done in Java

private HttpHeaders generateHeadersForSignedRequest (
     HttpMethod httpMethod, String url, String requestBody, PrivateKey privateKey)
     throws JsonProcessingException, SignatureException {

     String requestExpiryTime = String.valueOf(Instant.now().getEpochSecond() + 300);

     String textToSign = requestExpiryTime + "|" + httpMethod.name().toUpperCase() + "|" + url + "|";

     if (requestBody != null) {
         textToSign += requestBody;
     }

     String signature = generateSignature(textToSign, privateKey);

     HttpHeaders httpHeaders = new HttpHeaders();
     httpHeaders.set("Signature", signature);
     httpHeaders.set("Expires-at", requestExpiryTime);

     return httpHeaders;
}

private String generateSignature(String plainText, PrivateKey privateKey)
    throws SignatureException {

    try {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(plainText.getBytes("UTF8"));
        byte[] valueSigned = signature.sign();

        return Base64.getEncoder().encodeToString(valueSigned);
    } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
        throw new SignatureException(e);
    }
}


Step 3: Set Instruction Headers

The following header should be present on the HTTPS request.

Header

Description

AuthorizationCitizen

This is the merchant api key from the Admin Dashboard - found on the Company Settings page.

This secures the request to the merchant account

Expires-at

UNIX timestamp for signature expiration

Signature

Base 64 encoded signature