Skip to main content

Documentation

Request Signatures

Generating the signature header parameter for REST requests.

When you send an HTTPS REST request to the Rapyd Payments platform, you must include specified header parameters, including a signature. These headers are required for both the production platform and the sandbox. See Header Parameters. The headers are not required in the response from your remote authorization server.

The signature process helps secure requests in the following ways:

  • Verifies that the requester is an authorized user.

  • Protects data from tampering in transit.

  • Rejects requests from unauthorized persons.

When you send a request, you calculate the signature and insert the result into the signature header. When the platform receives the request, it performs the same signature calculation. If the resulting values do not match, the request is rejected.

The signature is calculated as a hash of a concatenation of specific strings, according to the following formula:

signature =

BASE64 ( HASH ( httpmethod + urlpath + salt + timestamp + accesskey + secretkey + bodystring ) )

where:

  • BASE64 is a Base-64 encoding algorithm.

  • HASH is the HMAC-SHA256 algorithm.

  • httpmethod is the HTTP method, in lower-case letters.

  • urlpath is the portion of the URL after the base URI, such as https://api.rapyd.net. The URL path starts with /v1.

  • salt is a random string for each request. Recommended length: 8-16 characters.

  • timestamp is the time of the request, in Unix time (seconds). The Rapyd platform is synchronized to the actual current time, as defined by public NTP servers. The timestamp must be synchronized to the actual current time, or less than 60 seconds before the actual current time.

  • accesskey is a unique string assigned by Rapyd for each user.

    You can get this value from the Client Portal. See Developers.

  • secretkey is a unique string for each user, assigned by Rapyd. The secret key is like a password, and is transmitted only as part of the calculated signature. Do not share it with your customers or partners, and do not transmit it in plaintext.

    You can get this value from the Client Portal. See Developers.

  • bodystring is a valid JSON string (relevant to requests that contain a body). If the body is empty, it must be empty in the request and in the signature calculation, and not empty curly braces {}.

Note

  • Different languages handle Base-64 encoding differently. You must adequately test your code so that all messages are encoded with all the correct Base-64 options.

  • Python and JavaScript truncate the rightmost zeroes from decimal numbers (12.50 → 12.5), and convert decimals to integers when all digits to the right of the decimal are zero (12.00 → 12). This can sometimes cause issues with the calculation of the signature. If you use rightmost zeroes, you can avoid these problems by sending them as numeric strings instead of JSON numbers, for example, "12.50" or "12.00".

  • The body of a request must not contain any whitespace other than inside a string.

  • The value of a path parameter is a string without any quote marks (").

    • Pretty print

      • {
            "business_vat_id": "123456789",
            "email": "johndoe@rapyd.net",
            "ewallet": "ewallet_ebfe4c4f4d36b076a21369fb0d055f3e",
            "invoice_prefix": "JD-",
            "metadata": {
                "merchant_defined": true
            },
            "name": "John Doe",
            "phone_number": "+14155559993"
        }
    • Whitespace-stripped

      • {"business_vat_id":"123456789","email":"johndoe@rapyd.net","ewallet":"ewallet_ebfe4c4f4d36b076a21369fb0d055f3e","invoice_prefix":"JD-","metadata":{"merchant_defined":true},"name":"JohnDoe","phone_number":"+14155559993"}

The following utilities are required for running the code samples.

    • .NET Core

      • using System; 
        using System.IO; 
        using System.Net; 
        using System.Security.Cryptography; 
        using System.Text;
        
        namespace RapydApiRequestSample 
        	{ public static class Utilities 
        	{ 
        		private const string secretKey = "<your-secret-key>"; // Never transmit the secret key by itself. 
        		private const string accessKey = "<your-access-key>"; // The access key from Client Portal. 
        		private const bool log = false;
        		
        		public static string MakeRequest(string method, string urlPath, string body = null)
        		{
        			try
        			{
        				string httpMethod = method;                    // get|put|post|delete - must be lowercase.
        				Uri httpBaseURL = new Uri("https://sandboxapi.rapyd.net");
        				string httpURLPath = urlPath;                  // Portion after the base URL.
        				string httpBody = body;                        // Stringified JSON without whitespace.
        				string salt = GenerateRandomString(8);         // Randomly generated for each request.
        				long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();   // Current Unix time (seconds).
        				string signature = Sign(httpMethod, httpURLPath, salt, timestamp, httpBody);
        
        				Uri httpRequestURL = new Uri(httpBaseURL, urlPath);
        				WebRequest request = HttpWebRequest.Create(httpRequestURL);
        				request.Method = httpMethod;
        				request.ContentType = "application/json";
        				request.Headers.Add("salt", salt);
        				request.Headers.Add("timestamp", timestamp.ToString());
        				request.Headers.Add("signature", signature);
        				request.Headers.Add("access_key", accessKey);
        
        				if (log)
        				{
        					Console.WriteLine("web request method: " + httpMethod);
        					Console.WriteLine("web request url: " + httpRequestURL);
        					Console.WriteLine("web request body: " + httpBody);
        					Console.WriteLine("web request contentType: " + request.ContentType);
        					Console.WriteLine("web request salt: " + salt);
        					Console.WriteLine("web request timestamp: " + timestamp);
        					Console.WriteLine("web request signature: " + signature);
        					Console.WriteLine("web request access_key: " + accessKey);
        				}
        
        				return HttpRequest(request, body);
        			}
        			catch (Exception ex)
        			{
        				Console.WriteLine("Error generating request options: ", ex);
        				throw;
        			}
        		}
        
        
        		private static string Sign(string method, string urlPath, string salt, long timestamp, string body)
        		{
        
        			try
        			{
        				string bodyString = String.Empty;
        				if (!String.IsNullOrWhiteSpace(body))
        				{
        					bodyString = body == "{}" ? "" : body;
        				}
        
        				string toSign = method.ToLower() + urlPath + salt + timestamp + accessKey + secretKey + bodyString;
        				if (log)
        				{
        					Console.WriteLine("\ntoSign: " + toSign);
        				}
        
        				UTF8Encoding encoding = new UTF8Encoding();
        				byte[] secretKeyBytes = encoding.GetBytes(secretKey);
        				byte[] signatureBytes = encoding.GetBytes(toSign);
        				string signature = String.Empty;
        				using (HMACSHA256 hmac = new HMACSHA256(secretKeyBytes))
        				{
        					byte[] signatureHash = hmac.ComputeHash(signatureBytes);
        					string signatureHex = String.Concat(Array.ConvertAll(signatureHash, x => x.ToString("x2")));
        					signature = Convert.ToBase64String(encoding.GetBytes(signatureHex));
        				}
        
        				if (log)
        				{
        					Console.WriteLine("signature: " + signature);
        				}
        
        				return signature;
        			}
        			catch (Exception)
        			{
        				Console.WriteLine("Error generating signature");
        				throw;
        			}
        
        		}
        		private static string GenerateRandomString(int size)
        		{
        			try
        			{
        				using (RandomNumberGenerator rng = new RNGCryptoServiceProvider())
        				{
        					byte[] randomBytes = new byte[size];
        					rng.GetBytes(randomBytes);
        					return String.Concat(Array.ConvertAll(randomBytes, x => x.ToString("x2")));
        				}
        			}
        			catch (Exception)
        			{
        				Console.WriteLine("Error generating salt");
        				throw;
        			}
        		}
        
        		private static string HttpRequest(WebRequest request, string body)
        		{
        			string response = String.Empty;
        
        			try
        			{
        				if (!String.IsNullOrWhiteSpace(body))
        				{
        					using (Stream requestStream = request.GetRequestStream())
        					{
        						UTF8Encoding encoding = new UTF8Encoding();
        						byte[] bodyBytes = encoding.GetBytes(body);
        						requestStream.Write(bodyBytes, 0, bodyBytes.Length);
        						requestStream.Close();
        					}
        				}
        
        				using (WebResponse webResponse = request.GetResponse())
        				{
        					using (Stream responseStream = webResponse.GetResponseStream())
        					{
        						using (StreamReader streamReader = new StreamReader(responseStream))
        						{
        							response = streamReader.ReadToEnd();
        							if (log)
        							{
        								Console.Write("web response:" + response);
        							}
        						}
        					}
        				}
        			}
        			catch (WebException e)
        			{
        				using (StreamReader streamReader = new StreamReader(e.Response.GetResponseStream()))
        				{
        					response = streamReader.ReadToEnd();
        					if (log)
        					{
        						Console.Write("web response:" + response);
        					}
        				}
        			}
        			catch (Exception e)
        			{
        				Console.WriteLine("Error occurred: " + e.Message);
        			}
        
        			return response;
        		}
        	}
        }
    • NODE.js

      • const https = require('https');
        const crypto = require('crypto');
        const secretKey = "<your-secret-key>";                    // Never transmit the secret key by itself.
        const accessKey = "<your-access-key>";                    // The access key from Client Portal.
        const log = false;
        
        async function makeRequest(method, urlPath, body = null) {
            try {
                httpMethod = method; // get|put|post|delete - must be lowercase.
                httpBaseURL = "sandboxapi.rapyd.net";
                httpURLPath = urlPath;                            // Portion after the base URL.
                salt = generateRandomString(8);                   // Randomly generated for each request.
                idempotency = new Date().getTime().toString();
                timestamp = Math.round(new Date().getTime() / 1000); // Current Unix time (seconds).
                signature = sign(httpMethod, httpURLPath, salt, timestamp, body)
        
                const options = {
                    hostname: httpBaseURL,
                    port: 443,
                    path: httpURLPath,
                    method: httpMethod,
                    headers: {
                        'Content-Type': 'application/json',
                        salt: salt,
                        timestamp: timestamp,
                        signature: signature,
                        access_key: accessKey,
                        idempotency: idempotency
                    }
                }
        
                return await httpRequest(options, body, log);
            }
            catch (error) {
                console.error("Error generating request options");
                throw error;
            }
        }
        
        function sign(method, urlPath, salt, timestamp, body) {
            try {
                let bodyString = "";
                if (body) {
                    bodyString = JSON.stringify(body);      // Stringified JSON without whitespace.
                    bodyString = bodyString == "{}" ? "" : bodyString;
                }
        
                let toSign = method.toLowerCase() + urlPath + salt + timestamp + accessKey + secretKey + bodyString;
                log && console.log(`toSign: ${toSign}`);
        
                let hash = crypto.createHmac('sha256', secretKey);
                hash.update(toSign);
                const signature = Buffer.from(hash.digest("hex")).toString("base64")
                log && console.log(`signature: ${signature}`);
        
                return signature;
            }
            catch (error) {
                console.error("Error generating signature");
                throw error;
            }
        }
        
        function generateRandomString(size) {
            try {
                return crypto.randomBytes(size).toString('hex');
            }
            catch (error) {
                console.error("Error generating salt");
                throw error;
            }
        }
        
        async function httpRequest(options, body) {
        
            return new Promise((resolve, reject) => {
        
                try {
                    
                    let bodyString = "";
                    if (body) {
                        bodyString = JSON.stringify(body);
                        bodyString = bodyString == "{}" ? "" : bodyString;
                    }
        
                    log && console.log(`httpRequest options: ${JSON.stringify(options)}`);
                    const req = https.request(options, (res) => {
                        let response = {
                            statusCode: res.statusCode,
                            headers: res.headers,
                            body: ''
                        };
        
                        res.on('data', (data) => {
                            response.body += data;
                        });
        
                        res.on('end', () => {
        
                            response.body = response.body ? JSON.parse(response.body) : {}
                            log && console.log(`httpRequest response: ${JSON.stringify(response)}`);
        
                            if (response.statusCode !== 200) {
                                return reject(response);
                            }
        
                            return resolve(response);
                        });
                    })
                    
                    req.on('error', (error) => {
                        return reject(error);
                    })
                    
                    req.write(bodyString)
                    req.end();
                }
                catch(err) {
                    return reject(err);
                }
            })
        
        }
        
        exports.makeRequest = makeRequest;
        
    • PHP

      • <?php
        function generate_string($length=12) {
            $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            return substr(str_shuffle($permitted_chars), 0, $length);
        }
        
        
        // make_request method - Includes the logic to communicate with the Rapyd sandbox server.
        function make_request($method, $path, $body = null) {
            $base_url = 'https://sandboxapi.rapyd.net';
            $secret_key = '<your-secret-key>';     // Never transmit the secret key by itself.
            $access_key = '<your-access-key>';     // The access key received from Rapyd.
        
            $idempotency = generate_string();      // Unique for each request.
            $http_method = $method;                // Lower case.
            $salt = generate_string();             // Randomly generated for each request.
            $date = new DateTime();
            $timestamp = $date->getTimestamp();    // Current Unix time.
        
            $body_string = !is_null($body) ? json_encode($body,JSON_UNESCAPED_SLASHES) : '';
            $sig_string = "$http_method$path$salt$timestamp$access_key$secret_key$body_string";
        
            $hash_sig_string = hash_hmac("sha256", $sig_string, $secret_key);
            $signature = base64_encode($hash_sig_string);
        
            $request_data = NULL;
        
            if ($method === 'post') {
                $request_data = array(
                    CURLOPT_URL => "$base_url$path",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => $body_string
                    
                );
            } else {
                $request_data = array(
                    CURLOPT_URL => "$base_url$path",
                    CURLOPT_RETURNTRANSFER => true,
                );
            }
        
            $curl = curl_init();
            curl_setopt_array($curl, $request_data);
        
            curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                "Content-Type: application/json",
                "access_key: $access_key",
                "salt: $salt",
                "timestamp: $timestamp",
                "signature: $signature",
                "idempotency: $idempotency"
            ));
        
            $response = curl_exec($curl);
            $err = curl_error($curl);
            curl_close($curl);
        
            if ($err) {
                throw new Exception("cURL Error #:".$err);
            } else {
                return json_decode($response, true); 
            }
        }
        ?>
    • Python

      • import json
        import random
        import string
        import hmac
        import base64
        import hashlib
        import time
        import requests
        
        base_url = 'https://sandboxapi.rapyd.net'
        secret_key = '(your-secret-key)' # Never transmit the secret key by itself.
        access_key = '(your-access-key)' # The access key received from Rapyd.
        
        # salt: randomly generated for each request.
        def generate_salt(length=12):
            return ''.join(random.sample(string.ascii_letters + string.digits, length))
        
          # Current Unix time (seconds).
        def get_unix_time(days=0, hours=0, minutes=0, seconds=0):
            return int(time.time())
        
        def update_timestamp_salt_sig(http_method, path, body):
            if path.startswith('http'):
                path = path[path.find(f'/v1'):]
            salt = generate_salt()
            timestamp = get_unix_time()
            to_sign = (http_method, path, salt, str(timestamp), access_key, secret_key, body)
            
            h = hmac.new(secret_key.encode('utf-8'), ''.join(to_sign).encode('utf-8'), hashlib.sha256)
            signature = base64.urlsafe_b64encode(str.encode(h.hexdigest()))
            return salt, timestamp, signature
        
        def current_sig_headers(salt, timestamp, signature):
            sig_headers = {'access_key': access_key, 
                           'salt': salt,
                           'timestamp': str(timestamp),
                           'signature': signature,
                           'idempotency': str(get_unix_time()) + salt}
            return sig_headers
        
        # http_method = get|put|post|delete - must be lowercase
        # path = Portion after the base URL.
        # body = JSON body with no whitespace except in strings.
        def pre_call(http_method, path, body=None):
            str_body = json.dumps(body, separators=(',', ':'), ensure_ascii=False) if body else ''
            salt, timestamp, signature = update_timestamp_salt_sig(http_method=http_method, path=path, body=str_body)
            return str_body.encode('utf-8'), salt, timestamp, signature
        
        def create_headers(http_method, url,  body=None):
            body, salt, timestamp, signature = pre_call(http_method=http_method, path=url, body=body)
            return body, current_sig_headers(salt, timestamp, signature)
        
        def make_request(method,path,body=''):
            body, headers = create_headers(method, base_url + path, body) # JSON body goes here. Always empty string for GET; 
            if method == 'get':
                response = requests.get(base_url + path,headers=headers)
            elif method == 'put':
                response = requests.put(base_url + path, data=body, headers=headers)
            elif method == 'delete':
                response = requests.delete(base_url + path, data=body, headers=headers)
            else:
                response = requests.post(base_url + path, data=body, headers=headers)
        
            if response.status_code != 200:
                raise TypeError(response, method,base_url + path)
            return json.loads(response.content)
    • cURL

      • // This example shows how you might transmit the headers, including the signature. You must calculate the signature before the curl call.
        
        curl -X GET https://sandboxapi.rapyd.net/v1/data/countries
             -H "Content-Type: application/json"
             -H "salt: random-number"
             -H "timestamp: current-unix-time"
             -H "access_key: your-access-key"
             -H "signature: your-calculated-signature"
             -d "request_body_goes_here"
    • Ruby

      • require 'digest'
        require 'base64'
        require 'json'
        require 'uri'
        require 'net/http'
        require 'OpenSSL'
        
        o = [('a'..'z')].map( & : to_a).flatten
        SALT = ((0...8).map { o[rand(o.length)] }.join # Randomly generated for each request.
        
        TIMESTAMP = Time.now.to_i.to_s      # Current Unix time.
        
        puts SALT
        puts TIMESTAMP
        
        SECRET_KEY = 'your-secret-key'      # Never transmit the secret key by itself.
        ACCESS_KEY = 'your-access-key'      # The access key received from Rapyd.
        REL_PATH = 'get/v1/data/countries'  # HTTP method (must be lowercase), 
                                            # plus the portion after the base URL. Hardkeyed for this example.
        BODY = ''                           # JSON body goes here. Always empty string for GET; 
                                            # strip nonfunctional whitespace.
        
        def signature body
          to_sign = "#{REL_PATH}#{SALT}#{TIMESTAMP}#{ACCESS_KEY}#{SECRET_KEY}#{BODY}"
          puts to_sign
          mac = OpenSSL::HMAC.hexdigest("SHA256", SECRET_KEY, to_sign)
          puts mac
          temp_BS64 = Base64.urlsafe_encode64(mac)
          puts temp_BS64
          temp_BS64
        end
        
        def set_headers request, body
          puts signature(body)
          request['content-type'] = 'application/json'
          request['signature'] = signature(body)
          request['salt'] = SALT
          request['timestamp'] = TIMESTAMP
          request['access_key'] = ACCESS_KEY
          request
        end
        
        def getFromRapyd(body, url)
          uri = URI(url)
          res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
            request = Net::HTTP::Get.new(uri)
            set_headers request, body
            http.request(request)
          end
        
          puts res.read_body
        end
        
        def getCountries
          body = ''
          getFromRapyd(body, "https://sandboxapi.rapyd.net/v1/data/countries")
        end
        
        getCountries
    • Java

      • import org.apache.http.HttpEntity;
        import org.apache.http.HttpResponse;
        import org.apache.http.client.ClientProtocolException;
        import org.apache.http.client.HttpClient;
        import org.apache.http.client.ResponseHandler;
        import org.apache.http.client.methods.HttpGet;
        import org.apache.http.impl.client.HttpClients;
        import org.apache.http.util.EntityUtils;
        
        import javax.crypto.Mac;
        import javax.crypto.spec.SecretKeySpec;
        import java.io.IOException;
        import java.io.UnsupportedEncodingException;
        import java.security.InvalidKeyException;
        import java.security.MessageDigest;
        import java.security.NoSuchAlgorithmException;
        import java.util.Base64;
        import java.util.Random;
        
        public class GetPOS {
            
            public static String hash256(String data) throws NoSuchAlgorithmException {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                md.update(data.getBytes());
                return bytesToHex(md.digest());
            }
            
            public static String bytesToHex(byte[]bytes) {
                StringBuffer result = new StringBuffer();
                for (byte byt: bytes)
                    result.append(Integer.toString((byt & 0xff) + 0x100, 16).substring(1));
                return result.toString();
            }
            
            public static String hmacDigest(String msg, String keyString, String algo) {
                String digest = null;
                try {
                    SecretKeySpec key = new SecretKeySpec((keyString).getBytes("ASCII"), algo);
                    Mac mac = Mac.getInstance(algo);
                    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;
            }
            
            public static String givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect() {
                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);
                }
                String generatedString = buffer.toString();
                
                return (generatedString);
            }
        
            public static void main(String[]args)throws Exception {
                try {
                    System.out.println("GetPOS Start");
        			      String httpMethod = "get";                           // get|put|post|delete - must be lowercase
        			      String urlPath = "/v1/" + "data/countries";          // hardkeyed for this example
                    String salt = givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect(); // Randomly generated for each request.
                    long timestamp = System.currentTimeMillis() / 1000L; // Unix time (seconds).
                    String accessKey = "AAAAAAAAAAA";                    // The access key received from Rapyd.
                    String secretKey = "SSSSSSSSSSS";                    // Never transmit the secret key by itself.
        			      bodyString = "";                                     // Always empty for GET; strip nonfunctional whitespace.
        			                                                           // Must be a String or an empty String.
                    String toEnc = httpMethod + urlPath + salt + Long.toString(timestamp) + accessKey + secretKey + bodyString;
                    System.out.println("String to be encrypted::" + toEnc);
                    String StrhashCode = hmacDigest(toEnc, secretKey, "HmacSHA256");
                    String signature = Base64.getEncoder().encodeToString(StrhashCode.getBytes());
                    HttpClient httpclient = HttpClients.createDefault();
                    
                    try {
                        HttpGet httpget = new HttpGet("/v1/data/countries");
                        
                        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);
                        
                        // Create a custom response handler
                        ResponseHandler < String > responseHandler = new ResponseHandler < String > () {
                             @ Override
                            public String handleResponse(
                                final HttpResponse response)throws ClientProtocolException,
                            IOException {
                                int status = response.getStatusLine().getStatusCode();
                                HttpEntity entity = response.getEntity();
                                return entity != null ? EntityUtils.toString(entity) : null;
                            }
                        };
                        String responseBody = httpclient.execute(httpget, responseHandler);
                        System.out.println("----------------------------------------");
                        System.out.println(responseBody);
                    }
                    finally {
                    }
                } catch (Exception e) {
                }
            }
        }import org.apache.http.HttpEntity;
        						
            }
        }
    • Postman

      • /* Prerequisites:
        - installed environment variable 'rapyd_secret_key'
        - installed environment variable 'rapyd_access_key'
        */
        
        var timestamp = (Math.floor(new Date().getTime() / 1000) - 10).toString();
        postman.setGlobalVariable("rapyd_request_timestamp", timestamp);
        
        var signature_salt = CryptoJS.lib.WordArray.random(12);
        postman.setGlobalVariable("rapyd_signature_salt", signature_salt);
        
        var body = '';
        if (JSON.stringify(request.data) !== '{}' && request.data !== '' && typeof request.data !=='object' ){
            body = JSON.stringify(JSON.parse(request.data));
        }
        var secret = pm.environment.get('rapyd_secret_key');
        var to_sign = request.method.toLowerCase() + request.url.replace('{{base_uri}}','/v1') + signature_salt + timestamp + pm.environment.get('rapyd_access_key') + secret + body;
        
        console.log("to_sign " + to_sign);
        var rapyd_signature = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(to_sign, secret));
        rapyd_signature = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(rapyd_signature));
        console.log("rapyd_signature " + rapyd_signature);
        postman.setGlobalVariable("rapyd_signature", rapyd_signature);