Rapyd API Request Signatures in PHP
Tags: php, payments, rapyd, api
Published: 2023-11-06 18:27:16

By Amr Abdou

[**Rapyd**](https://www.rapyd.net) is a global payment-processing platform that provides developers with secure and easy-to-use payment solutions that work with over 190 countries. As a global payment services provider, Rapyd is continuously developing new and innovative ways to facilitate online transactions.

The [**Rapyd API**](https://docs.rapyd.net/en/index-en.html) offers a wide range of services that can be used by businesses to accept, and disburse payments, hold funds and issue payment cards. Some of the services offered via the Rapyd API include the following:

- **[Rapyd Collect](https://www.rapyd.net/products/payments/):** to accept payments from customers in their own currency
- **[Rapyd Disburse](https://www.rapyd.net/products/disburse/):** to disburse payments to vendors and suppliers
- **[Rapyd Wallet](https://www.rapyd.net/products/wallet/):** to create branded e-wallets to send, receive, and store money
- **[Rapyd Issuing](https://www.rapyd.net/products/issuing/):** to create virtual and physical payment cards and create loyalty programs
- **[Rapyd Point-of-Sale (POS)](https://www.rapyd.net/products/payments/in-store/):** to offer countertop, wireless, and mobile card machines
- **[Rapyd Verify](https://docs.rapyd.net/build-with-rapyd/reference/rapyd-verify-1):** to gather business information in order to perform KYB verification

In this article, you'll learn how to implement request signatures in PHP in order to authenticate and send requests to the Rapyd API. To do so, you'll create a fresh PHP application that sends requests to the Rapyd API to retrieve the available payment methods for a specific country and displays the response in HTML. PHP powers applications like Facebook, Wordpress, Wikipedia, Slack, Mailchimp, and Etsy. Creating an integration with the Rapyd API can help connect applications around the world. 

## Implementing API Requests to the Rapyd API

A secure connection is necessary when it comes to online payment processing and money transfers. For your requests to be authenticated securely by the Rapyd platform, you must include specific header parameters in the API requests, which you'll learn about more in the following section.

One of these parameters is the signature that is used to verify that the request is coming from an authorized source and has not been tampered with during transmission. In this article, you'll learn how to generate signatures to authorize Rapyd API requests by completing the following actions:

- Obtaining your [API keys](#Obtaining-Your-API-Keys) from the Rapyd Dashboard
- Creating a fresh [PHP app](#Create-a-Fresh-PHP-App)
- Setting [environment variables](#Set-Environment-Variables)
- Creating a [utilities file](#Create-a-Utilities-File)
- Creating a function to retrieve the [available payment methods](#Write-a-Function-to-Retrieve-the-Available-Payment-Methods)
- Running and [testing the application](#Run-and-Test-the-Application)

### Prerequisites

To follow this tutorial and create signatures using the Rapyd API, you need to have [PHP 8+](https://www.php.net/releases/8.0/en.php) and [Composer](https://getcomposer.org/download/) installed on your local machine. You also need a Rapyd account. If you haven't created a Rapyd account yet, go ahead and [sign up](https://dashboard.rapyd.net/sign-up).

### Obtaining Your API Keys

To retrieve your API keys, log in to your [Rapyd account](https://dashboard.rapyd.net/) and activate the **Sandbox** button at the top right corner of your account dashboard.

![Sandbox button](https://i.imgur.com/8nwEOsD.png)

Then, open the **Developers** menu on the left-hand side of your screen to retrieve your Sandbox credentials. Copy these credentials so you can use them as environment variables later in this tutorial:

![Rapyd Developer Dashboard API keys](https://i.imgur.com/rO60Q4k.png)

### Create a Fresh PHP App

To create a fresh PHP app, create a new folder for this project and create these three files inside it:

1. **`.env`:** to store the environment variables
2. **`utilities.php`:** to include the logic for authorizing and sending API requests
3. **`get_payment_methods.php`:** to create a function that retrieves payment methods by country

To set the API keys as environment variables, you need to install the `phpdotenv` package using [Composer](https://getcomposer.org/). Navigate to the project folder in your terminal and run the following command.

```
composer require vlucas/phpdotenv
```

### Set Environment Variables

The `.env` file holds the environment variables that your application will use to authorize the API requests. The two environment variables you'll use here are the API key and the secret key.

To add your API key and secret key as environment variables, open the `.env` file and paste the following code into it:

```php
ACCESS_KEY={your-access-key-here}
SECRET_KEY={your-secret-key-here}
```

Remember to replace `{your-access-key-here}` with your access key and `{your-secret-key-here}` with your secret key.

### Create a Utilities File

The **utilities.php** file contains the logic to create the request signatures and authorize and send HTTP requests.

Open the **utilities.php** file and paste the following code:

```php
<?php
require __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

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 = $_ENV['SECRET_KEY'];     // Never transmit the secret key by itself.
    $access_key = $_ENV['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.

    // Generate Signature
    $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); 
    }
}
?>
```

This code includes two functions: `generate_string` and `make_request`. The `generate_string` function generates a random string that is used to create the `idempotency`, `salt`, and `signature` values that are required to authorize the API request. The `make_request` function creates and sends an API request. This function takes three arguments: the HTTP method, the request URI path, and the request body.

Each Rapyd API request includes the following header parameters:

- **`access_key:`** This is your sandbox API access key.
- **`content-Type:`** This is used to indicate that the data is sent in JSON format.
- **`salt:`** This is a random string generated for each request. This string should be eight to sixteen digits, including special characters. This is a necessity as it's used to generate the request signature.
- **`timestamp:`** This is a timestamp for each request in UNIX format.
- **`idempotency:`** This is an optional parameter to test for [idempotency](https://restfulapi.net/idempotent-rest-apis/). If this value is the same in another request within twenty-four hours, the second request is ignored and the response of the first request is returned.
- **`signature:`** This is a unique signature calculated for each request and is vital for ensuring each request is secure.

###  Calculate the Signature

The request signature is a critical parameter for the security of your requests because it helps secure the requests in these three ways:

- Verifying the requester
- Protecting data from tampering in transit
- Rejecting requests from unauthorized users
 
The Rapyd API request signature is calculated as a hash of a concatenation of strings according to this formula:

```
BASE64 ( HASH ( http_method + url_path + salt + timestamp + access_key + secret_key + body_string ) )
```

Here, `BASE64` is a Base64 encoding algorithm, and `HASH` is the HMAC-SHA256 cryptographic authentication algorithm.

In the **utilities.php** file, the following code is responsible for generating the request signature according to the Rapyd API signature formula:

```php
$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);
```

In this code snippet, the `hash_hmac` PHP function generates the hash value of the signature string using HMAC-SHA256 algorithm, and the `base64_encode` PHP function encodes the hash value with the Base64 encoding algorithm.

When you send a request to Rapyd API, the Rapyd platform creates a signature using the same calculation. If the signatures don't match due to an incorrect formula, the request is rejected and an `UNAUTHENTICATED_API_CALL` error is returned.

### Write a Function to Retrieve the Available Payment Methods

In order to be able to test the API authorization using the header parameters and the signature that you generated, you need to create a method to fetch the available payment methods for a specific country.

To do so, open the **get_payment_methods.php** file and paste the following code in it:

```php
<?php
require __DIR__ . '/utilities.php';
require __DIR__ . '/vendor/autoload.php';

// Get Payment Methods by Country Function
function get_payment_methods_by_country($country_code) {
	$method = 'get';
	$path = '/v1/payment_methods/country?country=' . $country_code;

	// Make the API request
	try {
		return $result = make_request($method, $path);
	} catch(Exception $e) {
		return 'Message: ' .$e->getMessage();
	}
}


// Generate HTML
function generate_payment_methods_html($country_code) {
	$payment_methods = get_payment_methods_by_country($country_code);

	if($payment_methods['data']) {
		// Create the HTML Head
		echo '<!DOCTYPE html>
		<html>
		<head>
		<title>Payment Methods by Country</title>
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
		</head>
		<body>';

		echo '<div class="row">';
		echo '<div class="col-md-2"></div>';
		echo '<div class="col-md-8">';

		echo '<h2>Available Payment Methods</h2>';
		echo '<table class="table table-bordered table-striped">';
		echo '<tr>';
		echo '<th>Name</th>';
		echo '<th>Type</th>';
		echo '<th>Currencies</th>';
		echo '</tr>';

		// Loop The Response
		foreach ($payment_methods['data'] as $key => $value) {
			echo '<tr>';
			echo '<td>'. $value['name'] .'</td>';
			echo '<td>'. $value['type'] .'</td>';
			echo '<td>'. implode(" ", $value['currencies']) .'</td>';
			echo '</tr>';
		}

		echo '</table>';

		// Print the Response data array
		echo '<h2>Response Data</h2>';
		echo '<code>';
		var_dump($payment_methods['data']);
		echo '</code>';

		echo '</div>';
		echo '<div class="col-md-2"></div>';
		echo '</div>';
		echo '</body>';


	}
	else {
		echo $payment_methods;
	}
}


// Get Available Payment Methods in the UK
generate_payment_methods_html('GB');
```

This code starts by importing the **utilities.php** file and a composer instance. The `get_payment_methods_by_country` function retrieves payment methods available in a particular country using the `make_request` function, which is declared in the **utilities.php** file. The function takes one parameter, `$country_code`.

The `generate_payment_methods_html` is a function that generates a basic HTML code to display the payment methods returned in a table and the response data object of the API request in a `<code>` block below the table.

Rapyd API uses two-letter ISO country codes that you'll use when you call the function. Since, in this example, you're fetching the available payment methods in the UK, the country code is "GB".

Finally, the `get_payment_methods_by_country` function is called with the `GB` parameter as its only argument to retrieve payment methods available in the UK.

### Run and Test the Application

Now it's time to run and test your application. You can test the app by navigating to the project folder in your terminal and starting the PHP development server using this command:

```php
php -S localhost:8000
```

Then, open your browser and navigate to [http://localhost:8000/get_payment_methods.php](http://localhost:8000/get_payment_methods.php).

Once the request is done, the available payment methods in the UK will be listed in a table, and the full response will be displayed as an array:

![Available payment methods in the UK test result](https://i.imgur.com/rKlCL45.png)

All the code for this sample application is available in this [**GitHub repo**](https://github.com/Rapyd-Samples/rapyd-request-signatures-php).

## Conclusion

In this article, you learned how to create Rapyd API request signatures in PHP and why they're important. 

[**Rapyd**](https://rapyd.net/) is a global payment platform with a mission to liberate global commerce with all the tools you need to accept, hold, and disburse funds for businesses everywhere. Rapyd's API offers a broad range of services that can be used by businesses to collect payments from customers, disburse payments to vendors and suppliers, create virtual and physical payment cards, and perform real-time business verification checks.