Rapyd API Request Signatures in Java

By: Vikram Aruchamy

Rapyd is a fintech platform that provides solutions for payments and payouts for all business types and sizes. It provides APIs for all kinds of global payments, including Rapyd Collect, Disburse, Wallet, Issuing, Point-of-Sale (POS), and Verification.

Rapyd Collect is a payment-processing API for global businesses that allows accepting payments via credit and debit cards, e-wallets, bank transfers, and cash. Rapyd Disburse lets you disburse payments to people around the globe via bank transfers.

Additionally, Rapyd Wallet lets users hold and transfer funds between the user’s wallets and the subwallets, and Rapyd Issuing allows businesses to issue physical and virtual payment cards around the globe.

Finally, Rapyd POS lets you make your phone, tablet, or computer a card-payment machine that can accept payments in person or online.

In this tutorial, you’ll learn how to get all the payment methods available for a specific country using the Rapyd API. You’ll learn how to create security credentials from the Rapyd developer dashboard, create signatures from the secret keys, and send an HTTP request to receive the payment methods available for a specific country in a Java application.

Implementing API Requests to the Rapyd API

Before you begin this tutorial, you’ll need the following:

  • Your preferred IDE for Java development. IntelliJ IDE was used here.
  • Rapyd credentials (i.e., your access key and secret key). You can generate these keys from the Rapyd dashboard by selecting Developers > Credentials > Details.

Create a Java Application

To begin, create a new Java project with the Gradle build option using IntelliJ IDE. Gradle is a build automation tool that supports compiling, testing, packing, and deploying applications, and it also helps seamlessly manage dependencies.

To create the project in IntelliJ IDE, select File > New > Project. This will open a new project wizard.

Enter a name for your project and the location where the project needs to be stored locally. Select Java as your language of choice and Gradle as the build system. If you don’t want to use the default JDK version, make sure you choose your desired version. Finally, click Create to create the project.

The new project will contain folders for Java sources, test sources, and the file build.gradle. The build.gradle file consists of the project ID, dependencies, and other necessary details to compile, build, and package the application.

Next, add the Apache HTTP Client and the Google Gson libraries by navigating to View > Tool Window > Dependencies. You can check out the Gradle dependencies tutorial for more information on how to add Gradle dependencies.

The Apache HTTP client can be added using the name org.apache.httpcomponents:httpclient:4.5.14, and Google Gson can be added using the name com.google.code.gson:gson:2.10.1.

After you add the dependencies, the build.gradle file will look like this:

The Apache HTTP library is used to create an HTTP request and to send and receive a response. The Google Gson library helps convert Java objects into their JSON representation. Here, you’ll use it to convert the HTTP response into a JSON representation for easier access to the data.

Create a Signature

Signatures provide a mechanism to digitally sign an HTTP request with secret keys. Signing a request helps verify the sender’s identity and that the message is not tampered with during transmission.

To create a signature, you need to create two helper methods:

  1. A function that creates a salt, which is random data added to the function that hashes the message using an HmacSHA256 algorithm
  2. A function that hashes the message using the secret key and a specified hashing algorithm

Before you actually create a signature, you need to create the file RapydDemo.java in the src/main/java directory of the Java application. You’ll add the methods available for this directory later in this tutorial.

Create a Random Salt

The random salt method generates random data consisting of the letters within the ASCII value 97 to 122, which means letters from a to z randomly with the length 10:

 public String generateSalt() {
        String generatedString = null;
        int leftLimit = 97;   // letter 'a'
        int rightLimit = 122; // letter 'z'
        int targetStringLength = 10;

        Random random = new Random();
        StringBuilder buffer = new StringBuilder(targetStringLength);
        for (int i = 0; i < targetStringLength; i++) {
            int randomLimitedInt = leftLimit + (int)
                    (random.nextFloat() * (rightLimit - leftLimit + 1));
            buffer.append((char) randomLimitedInt);
        }
        generatedString = buffer.toString();

        return (generatedString);
    }

Create a Hashing Function

The hashing function method creates a hash of the request message using the secret key and the HmacSHA256 algorithm.

public String getHmacHashValue(String msg, String secretKey, String algorithm) {
        String digest = null;
        try {
            SecretKeySpec key = new SecretKeySpec((secretKey).getBytes("ASCII"), algorithm);
            Mac mac = Mac.getInstance(algorithm);
            mac.init(key);

            byte[] bytes = mac.doFinal(msg.getBytes("UTF-8"));

            StringBuffer hash = new StringBuffer();
            for (int i = 0; i < bytes.length; i++) {
                String hex = Integer.toHexString(0xFF & bytes[i]);
                if (hex.length() == 1) {
                    hash.append('0');
                }
                hash.append(hex);
            }
            digest = hash.toString();
        } catch (UnsupportedEncodingException e) {
            System.out.println("hmacDigest UnsupportedEncodingException");
        } catch (InvalidKeyException e) {
            System.out.println("hmacDigest InvalidKeyException");
        } catch (NoSuchAlgorithmException e) {
            System.out.println("hmacDigest NoSuchAlgorithmException");
        }
        return digest;
    }

Using Salt and HMAC Functions to Create a Signature

Before creating a signature, you need to create a salt and the hashed string. Place the following code snippets in the main() method of the RapydDemo.java file in the src/main/java directory of the Java application. The main() method is the place where you’ll create a signature for the API request.

Use the generateSalt() method to create random data:

 String salt = generateSalt();

Next, concatenate the generated salt data with the following attributes and create a request message:

  • HTTP method: the type of request (i.e., get or post)
  • Service Path: the path of the desired API service (i.e., /v1/payment_methods/countries/US)
  • Salt: random data used as an additional input to an HMAC function that hashes the URL
  • timestamp: the current timestamp in milliseconds
  • accesskey: the access key generated from the Rapyd dashboard
  • Secret Key: the matching key that is generated for the access key, also available in the Rapyd dashboard
String strToCreateSignature = httpMethod + servicePath + salt + Long.toString(timestamp) + accessKey + secretKey;

Now, hash the concatenated request message using the Secret Key and the HmacSHA256 algorithm.

String strHashCode = getHmacHashValue(strToCreateSignature, secretKey, "HmacSHA256");

After you receive the hashed message, encode it into a Base64 string. Encoding to Base64 ensures the data bytes remain unchanged during transmission.

 signature = Base64.getEncoder().encodeToString(strHashCode.getBytes());

At this point, you have all the attributes necessary to send an API request and receive a response.

Using the Signature to Send a Request and Receive a Response

As previously stated in this tutorial, you’ll get the payment methods available for a specific country. For further information about the payment API services, check out the Rapyd Payment documentation.

In order to retrieve the available payment methods for a specific country, you need to define the API platform, either for the sandbox or the production (i.e., https://sandboxapi.rapyd.net/). Then you need to define the service path according to your requirement. To get all the payment methods for a defined country, use ”/v1/" + "payment_methods/countries/US”. The country is appended as the last value.

Once you’ve defined the API platform and the service path, you need to use the signature and service URL to send an HTTP request to the Rapyd API service and receive an HTTP response.

public HttpResponse getHttpResponseFromRapyd(String rapydApiServiceHome, String servicePath, String accessKey, String secretKey, String salt, long timestamp, String signature) throws IOException {

   HttpClient httpclient = HttpClients.createDefault();
   HttpResponse response = null;
   try {
       HttpGet httpget = new HttpGet(rapydApiServiceHome + servicePath);

       httpget.addHeader("Content-Type", "application/json");
       httpget.addHeader("access_key", accessKey);
       httpget.addHeader("salt", salt);
       httpget.addHeader("timestamp", Long.toString(timestamp));
       httpget.addHeader("signature", signature);
       response = httpclient.execute(httpget);

   } catch (IOException e) {
       System.err.println("Error while processing Get request : " + e.getMessage());
   }

   return response;
}

You need to access the response object and retrieve the results. The response object contains two keys: status and data. The status object contains details about the HTTP request and whether it is successful, and the data object contains the data returned by the specific API service.

To retrieve the information from the HTTPresponse object, pass the httpresponse object to the prettyPrintHttpResponse() method, as seen here:

public void prettyPrintHttpResponse(HttpResponse response) throws IOException {

   Gson gson = new GsonBuilder().setPrettyPrinting().create();
   JsonElement je = JsonParser.parseString(EntityUtils.toString(response.getEntity()));
   JsonObject obj = je.getAsJsonObject();

   System.out.println(obj.get("status").getAsJsonObject().get("status"));

   JsonArray dataElement = obj.get("data").getAsJsonArray();

   System.out.println("Available payment methods are..");
   for (JsonElement pa : dataElement) {
       JsonObject paymentObj = pa.getAsJsonObject();
       String     paymentName     = paymentObj.get("name").getAsString();
       System.out.println(paymentName);

   }
}

The output will look like this:

"SUCCESS"

Available payment methods are:
Duane Reade
Cash Payment in US
Walgreens
Kum and Go
Go Mart stores
Stop-N-Go
7Eleven
Sheetz
ACH Debit
Rutters
Same day US ACH debit
US ACH debit
Stripes
Walmart
Discover
Visa Debit
Family Dollar
Mastercard
Royal Farms
Travel Centers of America
Speedway
Pilot Flying
CVS
Dollar General
Kwik Trip

Test the API Request

To test the API request, you need to follow the JUnit test method, which completes the following steps:

  • Creates a salt and an HTTP request signature
  • Sends the HTTP request to the Rapyd API service
  • Receives the response and asserts the status of the HTTP response is SUCCESS. If the HTTP response status is not SUCCESS, the test case will fail.
  • Prints a list of the payment methods available for the country specified in the service URL

Create the file RapydDemoTest.java in the src/test/java directory of the Java application, and add the following test methods to it:

@BeforeEach
void setUp() {

   httpMethod = "get";// get|put|post|delete - must be lowercase
   rapydApiServiceHome = "https://sandboxapi.rapyd.net/";
   servicePath = "/v1/" + "payment_methods/countries/US";
   accessKey = "F633B289E933D3CBCFF2";
   secretKey = "986e86960cf68cf7e176f0cea8e525a22edb9b9592ba8337d7f1834c796356b0c8bbde0b4dd607ca";

   timestamp = System.currentTimeMillis() / 1000L; // Unix time (seconds).

}

@Test
void getHttpResponseFromRapyd() throws IOException {
        RapydDemo rapydDemo = new RapydDemo();
        String salt = rapydDemo.generateSalt();
        String signature = rapydDemo.createSignature(salt, timestamp, httpMethod, servicePath, accessKey, secretKey);
        HttpResponse response = null;
        try {
            response = rapydDemo.getHttpResponseFromRapyd(rapydApiServiceHome, servicePath, accessKey, secretKey, salt, timestamp, signature);

            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            JsonElement je = JsonParser.parseString(EntityUtils.toString(response.getEntity()));
            JsonObject obj = je.getAsJsonObject();
            System.out.println(obj.get("status").getAsJsonObject().get("status"));

            //Success denotes that the API has returned the result successfully.
            assertEquals(obj.get("status").getAsJsonObject().get("status").getAsString(), "SUCCESS");

            JsonArray dataElement = obj.get("data").getAsJsonArray();

            System.out.println("Available payment methods are..");
            for (JsonElement pa : dataElement) {
                JsonObject paymentObj = pa.getAsJsonObject();
                String     paymentName     = paymentObj.get("name").getAsString();
                System.out.println(paymentName);

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

Get the Code

Get the code, build something amazing with the Rapyd API, and share it with us here in the developer community. Hit reply below if you have questions or comments.

1 Like

Get and Post should be lower case in the text.

Thanks, @Bjorn_Halldorsson - we have updated the tutorial.

1 Like