Authentication

You'll need to authenticate your requests to access any of the endpoints in the Rampable API. In this guide, we'll look at how authentication works. Rampable offers two ways to authenticate your API requests: Using a B2B Client Authentication with Client Secret and HTTP Signature Authentication (For Personal Use).

B2B Client Authentication

B2B Client Authentication is made for business that aim to serve its users, To authenticate using a B2B method you need provide Client Secret in the header of your request. Client Secret is a string that you can get from Rampable. please contact our support admin@rampable.co to get your Client Secret.

In order to work with operation endpoint, Access Token is needed from the user side and they need to login using their email to get the Access Token. The Access Token is valid for 31 days by default. Read more about authenticate using using email and password from Auth resource.

Here's an example how to implementation using a B2B Client Authentication with access token and client secret:

  curl "https://sandbox.rampable.co/v1/user/me" \
  -H "Authorization: Bearer {accessToken}" \
  -H "x-client-secret: YOUR_CLIENT_SECRET"

Authorization is needed to access operation endpoint such as payments, recipients. x-client-secret is needed for all endpoint resources available

HTTP Signature Authentication (Personal Token)

HTTP Signature Authentication is a method of signing HTTP requests to authenticate requests without sending the API key in the request. This means you don't need to interact with /auth endpoint since you already have a personal key generated through the dashboard

Rampable uses asymmetric key encryption to sign requests. The client will generate a signature using their private key and Rampable will use the client's public key to validate the signature.

You need provide signature with client ID and timeStamp in the header of your request. for example:

  curl "https://sandbox.rampable.co/v1/user/me" \
  -H "X-SIGNATURE: YOUR_SIGNATURE" \
  -H "X-TIMESTAMP: TIMESTAMP" \
  -H "X-CLIENT-ID: YOUR_CLIENT_ID"

X-SIGNATURE = Your generated signature
X-TIMESTAMP = format with YYYY-MM-DDTHH:mm:ssZ
X-CLIENT-ID = Your client ID from Rampable

The following steps will explain about Asymmetric key usage without Access Token (SHA256withRSA).

Generate Private and Public Key

which is where rsa_private_key.pem is obtained from Rampable

Digital Signature Generation

  1. Compose the string to sign with format by method:

    • POST, PATCH, PUT = $CLIENT-ID + “:“ + $X-TIMESTAMP + “:“ + LowerCase(HexEncode(SHA-256(Minify($BODY))))
    • GET, DELETE = $CLIENT-ID + “:“ + $X-TIMESTAMP

    $CLIENT-ID is String, $BODY is JSON format, $X-TIMESTAMP timestamp format with YYYY-MM-DDTHH:mm:ssZ

  2. The signature string is generated from string to sign above with applying SHA-256 with RSA-2048 encryption using pkcs8 private key, and then encode the result to base64.

  3. Put the signature string into HTTP header “ X-SIGNATURE“.

Example:

X-SIGNATURE: 85be817c55b2c135157c7e89f52499bf0c25ad6eeebe04a986e8c862561b19a5

Example Generate signature using nodejs

import crypto from 'crypto'
import { readFileSync } from 'fs'
import httpStatus from 'http-status'
import ApiError from 'utils/api-error'

export interface IGenerateAssymetricSignature {
  body?: Object
  timeStamp: string
  method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT'
  clientID: string
}

export const generateAssymetricSignature = ({ body, timeStamp, method, clientID }: IGenerateAssymetricSignature) => {
  const myPemKey = readFileSync('./certs/pkcs8_private_key.pem', {
    encoding: 'utf8'
  })

  // Asymmetric Key Generation

  // Minify the HTTP body
  const minfiedBodyEncrypted = JSON.stringify(body || {})

  // Create a SHA-256 hash object
  const hash = crypto.createHash('sha256')

  // Add the data to the hash object
  hash.update(minfiedBodyEncrypted)

  // Calculate the SHA-256 hash
  const hexSHA = hash.digest('hex')
  const minfiedBodyEncryptedLower = hexSHA.toLowerCase()

  // Generate the string to be signed
  let stringToSign = ''

  // POST, PATCH, PUT = <X-CLIENT-ID> + “:“ + <X-TIMESTAMP> + “:“ + LowerCase(HexEncode(SHA-256(Minify(<HTTP BODY>))))
  // GET, DELETE = <X-CLIENT-ID> + “:“ + <X-TIMESTAMP>

  switch (method) {
    case 'GET':
      stringToSign = `${clientID}:${timeStamp}`
      break
    case 'DELETE':
      stringToSign = `${clientID}:${timeStamp}`
      break
    case 'POST':
      stringToSign = `${clientID}:${timeStamp}:${minfiedBodyEncryptedLower}`
      break
    case 'PATCH':
      stringToSign = `${clientID}:${timeStamp}:${minfiedBodyEncryptedLower}`
      break
    case 'PUT':
      stringToSign = `${clientID}:${timeStamp}:${minfiedBodyEncryptedLower}`
      break
    default:
      stringToSign = ''
      break
  }

  // Throw error if stringToSign is empty
  if (!stringToSign) throw new ApiError(httpStatus.BAD_REQUEST, 'Method not allowed')

  // Create a signer object
  const sign = crypto.createSign('SHA256')

  // Update the signer object with the data to be signed
  sign.update(stringToSign)

  // Sign the data
  const signature = sign.sign(myPemKey, 'hex')

  // Encode the signature to base64
  const base64Signature = Buffer.from(signature, 'hex').toString('base64')

  return base64Signature
}

Was this page helpful?