PHP

Here you'll find a few samples of code to implement the Authentication and perform specific actions in PHP.

You'll need the phpseclib library in order to implement the code below, this is a third party library and Soldo is not affiliated with it.

📘

Make sure to read all articles under Getting Started before proceeding with the implementation.

Card creation

This code sample shows how to perform Authentication and create a new card in PHP.

<?php
#####################################################################################################
#Script Name	: Standard authentication and Advanced Authentication for card creation PHP example #
#Description	: This script uses the Business APIs V2 in order to create a virtual card and       #
#                 retrieve its PAN and CVV, this is just an example STORE YOUR CREDENTIALS SAFELY   #
#####################################################################################################

error_reporting(E_ALL);

# import external library
include "Crypt/RSA.php";

# set the environment configuration
$demo = true;

if ($demo) {
	# set the demo business api domain
	$baseUrl = "https://api-demo.soldocloud.net";
	
	# set your demo private and public key path
	$privateKeyPath = "C:\\keys\\demo\\private.key";
	$publicKeyPath = "C:\\keys\\demo\\public.key";
	
	# set your demo API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
} else {
	# set the production business api domain
	$baseUrl = "https://api.soldo.com";
	
	# set your production private and public key path
	$privateKeyPath = "C:\\keys\\prod\\private.key";
	$publicKeyPath = "C:\\keys\\prod\\public.key";
	
	# set your production API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
};

# set details of the card to be created
$ownerType = "XXXXXX";
$ownerPublicId = "XXXXXX";
$walletId = "XXXXXX";
$cardName = "XXXXXX";
$line4 = "XXXXXX";

# function used to get your private and public key from your file system
# input arguments are: your private and public key path
# it returns an array  containing your private key at index 0 and your public key at index 1
function getKeyPair($myPrivateKeyPath, $myPublicKeyPath){
	try{
		if (!is_file($myPrivateKeyPath)) {
			throw new Exception(sprintf("Private key file not found in %s", $myPrivateKeyPath));
		}
		if (!is_file($myPublicKeyPath)) {
			throw new Exception(sprintf("Public key file not found in %s", $myPublicKeyPath));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	return [trim(file_get_contents($myPrivateKeyPath)), trim(file_get_contents($myPublicKeyPath))];
}

# function used to get the access token using the standard authentication
# input arguments are: business api domain, your clientId and your clientSecret 
# it returns the access token to be used in order to authenticate your next requests
function getAccessToken($myBaseUrl, $myClientId, $myClientSecret) {
	# standard authentication request body
	$body = "client_id=" . $myClientId . "&client_secret=" . $myClientSecret;
	
	# standard authentication request header
	$headers = [
		"Content-Type: application/x-www-form-urlencoded"
	];
	
	$ch = curl_init($myBaseUrl . "/oauth/authorize");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error authenticating, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return access token
	return json_decode($response)->access_token;
}

# function to be used to generate the hashed fingerprint and the fingerprint signature
# input arguments are: fingerprint order concatenated string, your private key and your public key
# it returns an array containing the fingerprint at index 0 and the fingerprint signature at index 1
function getAdvancedAuthentication($myFingerprintOrder, $myPrivateKey, $myPublicKey) {
	
	# hashing the fingerprint order concatenated string with SHA512 algorithm 
    $fingerprint = hash("sha512", $myFingerprintOrder);

	# your private 2048 RSA key
    $private_key_pem = openssl_pkey_get_private($myPrivateKey);

	# your public 2048 RSA key
    $public_key_pem = openssl_pkey_get_public($myPublicKey);

	try {
		# openssl function to sign the hashed fingerprint with SHA512withRSA algorithm
		openssl_sign($fingerprint, $signature, $private_key_pem, OPENSSL_ALGO_SHA512);
		if (!openssl_verify($fingerprint, $signature, $public_key_pem, "sha512WithRSAEncryption")) {
			throw new Exception("Signature failed, please check your keys!");
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}

	# Base64 encoding is required
    $signature_base64_encoded = base64_encode($signature);
	
	# fingerprint is the fingerprint hash for X-Soldo-Fingerprint header
	# signature_base64_encoded is the fingerprint hash signature for X-Soldo-Fingerprint-Signature header
    return [$fingerprint, $signature_base64_encoded];
}

# function to be used to decrypt data encrypted by Soldo using your private key (Algorithm: RSA/ECB/OAEPWithSHA-256ANDMGF1Padding)
# input arguments are: encrypted string and your private key
# it returns the decrypted string
function decryptData($myCiphertext, $myPrivatekey) {
    $rsa = new \Crypt_RSA();
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
    $rsa->setMGFHash("sha256");
    $rsa->setHash("sha256");
    $rsa->loadKey($myPrivatekey);
    return $rsa->decrypt($myCiphertext);
}

# function to be used to create a new virtual card
# input arguments are: business api domain, access token, card details, token provided by Soldo and your key pair
# it returns the card order id 
function addCard($myBaseUrl, $myAccessToken, $myOwnerType, $myOwnerPublicId, $myWalletId, $myCardName, $myLine4, $myToken, $myKeyPair) {
	# fingerprint order for card creation is: request_timestamp, owner_type, owner_public_id, wallet_id, token (http://apidoc-demo.soldo.com/v2/zgxiaxtcyapyoijojoef.html#add-card)
	$rt = strval(intval(microtime(true) * 1000));
	$fingerprintOrder = ($rt . $myOwnerType . $myOwnerPublicId . $myWalletId . $myToken);
	$dataEncrypted = getAdvancedAuthentication($fingerprintOrder, $myKeyPair[0], $myKeyPair[1]);
	
	# card creation request body
	$body = '{
		"request_timestamp": ' . $rt . ',
		"owner_type": "' . $myOwnerType . '",
		"owner_public_id": "' . $myOwnerPublicId . '",
		"wallet_id": "' . $myWalletId . '",
		"type": "VIRTUAL",
		"name": "' . $myCardName . '",
		"emboss_line4": "' . $myLine4  . '"
	}';
			
	# card creation request header
	$headers = [
		"Authorization: Bearer $myAccessToken",
		"X-Soldo-Fingerprint: {$dataEncrypted[0]}",
		"X-Soldo-Fingerprint-Signature: {$dataEncrypted[1]}",
		"Content-Type: application/json"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/cards");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error adding card, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return order id
	return json_decode($response)->id;
}

# function to be used to loop over the order waiting for it completion and get the card id
# input arguments are: business api domain, access token and order id
# it returns the card id
function getCardId($myBaseUrl, $myAccessToken, $myOrderId) {
	
	# get order request header
	$headers = [
		"Authorization: Bearer $myAccessToken"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/orders/".$myOrderId);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	
	$cardId = "";
	$i = 0;
	try{
		# execute the request multiple times until the card is created
		do {
			$response = curl_exec($ch);
			$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
			
			if ($httpcode != 200) {
				throw new Exception(sprintf("%s - Error getting order, response body: %s", $httpcode, $response));
			}
			$obj = json_decode($response);
			
			# check order status
			switch ($obj->status) {
				# order completed, the card is created, exit both switch and do while
				case "COMPLETED":
					$arr = $obj->items;
					$cardId = $arr[0]->id;
					break 2;
				# order won't be fullfilled, exit loop and throw error
				case "ERROR":
				case "CANCELLED":
					throw new Exception(sprintf("%s - Error processing card order, response body: %s", $httpcode, $response));
				# order hasn't be fullfilled yet, sleep for 6 seconds and reiterate over the loop 
				default:
					sleep (6);
					$i++;
			}
			# stops after 10 iteration (60 seconds) and throw error
		} while ($i < 10);
		
		curl_close($ch);
		
		if ($cardId == ""){
			throw new Exception(sprintf("%s - Maximum tentative exceeded, response body: %s", $httpcode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return card id
	return $cardId;
}

# function to be used to get and decrypt the card sensitive details
# input arguments are: business api domain, access token, card id and your key pair
# it returns an array containing the decrypted pan at index 0 and the decrypted cvv at index 1
function getSensitiveDetails($myBaseUrl, $myAccessToken, $myCardId, $myKeyPair) {
	$ch = curl_init($myBaseUrl . "/business/v2/cards/".$myCardId."?showSensitiveData=true");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	
	# get card header
	$headers = [
		"Authorization: Bearer $myAccessToken"
	];
	
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	
	try{
		$response = curl_exec($ch);
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpcode != 200) {
			throw new Exception(sprintf("%s - Error getting card sensitive details, response body: %s", $httpcode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and get encrypted pan/cvv
	$cardEncPan = json_decode($response)->sensitive_data->encrypted_full_pan;
	$cardEncCvv = json_decode($response)->sensitive_data->encrypted_cvv;
	
	# decode and decrypt pan/cvv using your private key
	return [decryptData(base64_decode($cardEncPan), $myKeyPair[0]), decryptData(base64_decode($cardEncCvv), $myKeyPair[0])];
}

$accessToken = getAccessToken($baseUrl, $clientId, $clientSecret);

$keyPair = getKeyPair($privateKeyPath, $publicKeyPath);

$orderId = addCard($baseUrl, $accessToken, $ownerType, $ownerPublicId, $walletId, $cardName, $line4, $token, $keyPair);

$cardId = getCardId($baseUrl, $accessToken, $orderId);

$sensitiveDetails = getSensitiveDetails($baseUrl, $accessToken, $cardId, $keyPair);
echo ("PAN: " . $sensitiveDetails[0] . " - CVV: " . $sensitiveDetails[1]);

?>

Internal transfer

This code sample shows how to perform Authentication and make a money transfer between wallets in PHP.

<?php
#######################################################################################################
#Script Name	: Standard authentication and Advanced Authentication for transfer PHP example 	        #
#Description	: This script uses the Business APIs V2 in order to execute an internal transfer and    #
#                 return its response object, this is just an example STORE YOUR CREDENTIALS SAFELY   #
#######################################################################################################

error_reporting(E_ALL);

# import external library
include "Crypt/RSA.php";

# set the environment configuration
$demo = true;

if ($demo) {
	# set the demo business api domain
	$baseUrl = "https://api-demo.soldocloud.net";
	
	# set your demo private and public key path
	$privateKeyPath = "C:\\keys\\demo\\private.key";
	$publicKeyPath = "C:\\keys\\demo\\public.key";
	
	# set your demo API credentials
	$clientId = "";
	$clientSecret = ""; 
	$token = "";
} else {
	# set the production business api domain
	$baseUrl = "https://api.soldo.com";
	
	# set your production private and public key path
	$privateKeyPath = "C:\\keys\\prod\\private.key";
	$publicKeyPath = "C:\\keys\\prod\\public.key";
	
	# set your production API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
};

# set details of the wallet to be created
$amount = 10;
$currency = "XXX";
$walletFrom = "XXXXXXXXXX";
$walletTo = "XXXXXXXXXX";

# function used to get your private and public key from your file system
# input arguments are: your private and public key path
# it returns an array  containing your private key at index 0 and your public key at index 1
function getKeyPair($myPrivateKeyPath, $myPublicKeyPath){
	try{
		if (!is_file($myPrivateKeyPath)) {
			throw new Exception(sprintf("Private key file not found in %s", $myPrivateKeyPath));
		}
		if (!is_file($myPublicKeyPath)) {
			throw new Exception(sprintf("Public key file not found in %s", $myPublicKeyPath));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	return [trim(file_get_contents($myPrivateKeyPath)), trim(file_get_contents($myPublicKeyPath))];
}

# function used to get the access token using the standard authentication
# input arguments are: business api domain, your clientId and your clientSecret 
# it returns the access token to be used in order to authenticate your next requests
function getAccessToken($myBaseUrl, $myClientId, $myClientSecret) {
	# standard authentication request body
	$body = "client_id=" . $myClientId . "&client_secret=" . $myClientSecret;
	
	# standard authentication request header
	$headers = [
		"Content-Type: application/x-www-form-urlencoded"
	];
	
	$ch = curl_init($myBaseUrl . "/oauth/authorize");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error authenticating, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return access token
	return json_decode($response)->access_token;
}

# function to be used to generate the hashed fingerprint and the fingerprint signature
# input arguments are: fingerprint order concatenated string, your private key and your public key
# it returns an array containing the fingerprint at index 0 and the fingerprint signature at index 1
function getAdvancedAuthentication($myFingerprintOrder, $myPrivateKey, $myPublicKey) {
	
	# hashing the fingerprint order concatenated string with SHA512 algorithm 
    $fingerprint = hash("sha512", $myFingerprintOrder);

	# your private 2048 RSA key
    $private_key_pem = openssl_pkey_get_private($myPrivateKey);

	# your public 2048 RSA key
    $public_key_pem = openssl_pkey_get_public($myPublicKey);

	try {
		# openssl function to sign the hashed fingerprint with SHA512withRSA algorithm
		openssl_sign($fingerprint, $signature, $private_key_pem, OPENSSL_ALGO_SHA512);
		if (!openssl_verify($fingerprint, $signature, $public_key_pem, "sha512WithRSAEncryption")) {
			throw new Exception("Signature failed, please check your keys!");
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}

	# Base64 encoding is required
    $signature_base64_encoded = base64_encode($signature);
	
	# fingerprint is the fingerprint hash for X-Soldo-Fingerprint header
	# signature_base64_encoded is the fingerprint hash signature for X-Soldo-Fingerprint-Signature header
    return [$fingerprint, $signature_base64_encoded];
}

function internalTransfer($myBaseUrl, $myAccessToken, $myAmount, $myCurrency, $myWalletFrom, $myWalletTo, $myToken, $myKeyPair) {
		# fingerprint order for internal transfer is: amount, currencyCode, fromWalletId, toWalletId, token (http://apidoc-demo.soldo.com/v2/zgxiaxtcyapyoijojoef.html#internal-transfer)
        $fingerprintOrder = ($myAmount . $myCurrency . $myWalletFrom . $myWalletTo . $myToken);
        $dataEncrypted = getAdvancedAuthentication($fingerprintOrder, $myKeyPair[0], $myKeyPair[1]);

		# internal transfer request body
		$body = "amount=" . $myAmount . "&currencyCode=" . $myCurrency;

		# internal transfer request header
        $headers = [
            "Authorization: Bearer $myAccessToken",
			"X-Soldo-Fingerprint: {$dataEncrypted[0]}",
			"X-Soldo-Fingerprint-Signature: {$dataEncrypted[1]}",
            "Content-Type: application/x-www-form-urlencoded"
        ];

        $ch = curl_init($myBaseUrl . "/business/v2/wallets/internalTransfer/" . $myWalletFrom . "/" . $myWalletTo);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error executing internal transfer, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return internal transfer object
	return json_decode($response);

}

$accessToken = getAccessToken($baseUrl, $clientId, $clientSecret);

$keyPair = getKeyPair($privateKeyPath, $publicKeyPath);

$transfer = internalTransfer($baseUrl, $accessToken, $amount, $currency, $walletFrom, $walletTo, $token, $keyPair);

echo ("Transfer Datetime: " . ($transfer)->datetime . " Amount: " . ($transfer)->amount);

?>

Wallet creation

This code sample shows how to perform Authentication and create a new wallet in PHP.

<?php
#######################################################################################################
#Script Name	: Standard authentication and Advanced Authentication for wallet creation PHP example   #
#Description	: This script uses the Business APIs V2 in order to create a wallet and                 #
#                 return its public ID, this is just an example STORE YOUR CREDENTIALS SAFELY         #
#######################################################################################################

error_reporting(E_ALL);

# import external library
include "Crypt/RSA.php";

# set the environment configuration
$demo = true;

if ($demo) {
	# set the demo business api domain
	$baseUrl = "https://api-demo.soldocloud.net";
	
	# set your demo private and public key path
	$privateKeyPath = "C:\\keys\\demo\\private.key";
	$publicKeyPath = "C:\\keys\\demo\\public.key";
	
	# set your demo API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
} else {
	# set the production business api domain
	$baseUrl = "https://api.soldo.com";
	
	# set your production private and public key path
	$privateKeyPath = "C:\\keys\\prod\\private.key";
	$publicKeyPath = "C:\\keys\\prod\\public.key";
	
	# set your production API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
};

# set details of the wallet to be created
$ownerType = "company";
$currency = "XXX";
$name = "XXXXXX";

# function used to get your private and public key from your file system
# input arguments are: your private and public key path
# it returns an array  containing your private key at index 0 and your public key at index 1
function getKeyPair($myPrivateKeyPath, $myPublicKeyPath){
	try{
		if (!is_file($myPrivateKeyPath)) {
			throw new Exception(sprintf("Private key file not found in %s", $myPrivateKeyPath));
		}
		if (!is_file($myPublicKeyPath)) {
			throw new Exception(sprintf("Public key file not found in %s", $myPublicKeyPath));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	return [trim(file_get_contents($myPrivateKeyPath)), trim(file_get_contents($myPublicKeyPath))];
}

# function used to get the access token using the standard authentication
# input arguments are: business api domain, your clientId and your clientSecret 
# it returns the access token to be used in order to authenticate your next requests
function getAccessToken($myBaseUrl, $myClientId, $myClientSecret) {
	# standard authentication request body
	$body = "client_id=" . $myClientId . "&client_secret=" . $myClientSecret;
	
	# standard authentication request header
	$headers = [
		"Content-Type: application/x-www-form-urlencoded"
	];
	
	$ch = curl_init($myBaseUrl . "/oauth/authorize");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error authenticating, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return access token
	return json_decode($response)->access_token;
}

# function to be used to generate the hashed fingerprint and the fingerprint signature
# input arguments are: fingerprint order concatenated string, your private key and your public key
# it returns an array containing the fingerprint at index 0 and the fingerprint signature at index 1
function getAdvancedAuthentication($myFingerprintOrder, $myPrivateKey, $myPublicKey) {
	
	# hashing the fingerprint order concatenated string with SHA512 algorithm 
    $fingerprint = hash("sha512", $myFingerprintOrder);

	# your private 2048 RSA key
    $private_key_pem = openssl_pkey_get_private($myPrivateKey);

	# your public 2048 RSA key
    $public_key_pem = openssl_pkey_get_public($myPublicKey);

	try {
		# openssl function to sign the hashed fingerprint with SHA512withRSA algorithm
		openssl_sign($fingerprint, $signature, $private_key_pem, OPENSSL_ALGO_SHA512);
		if (!openssl_verify($fingerprint, $signature, $public_key_pem, "sha512WithRSAEncryption")) {
			throw new Exception("Signature failed, please check your keys!");
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}

	# Base64 encoding is required
    $signature_base64_encoded = base64_encode($signature);
	
	# fingerprint is the fingerprint hash for X-Soldo-Fingerprint header
	# signature_base64_encoded is the fingerprint hash signature for X-Soldo-Fingerprint-Signature header
    return [$fingerprint, $signature_base64_encoded];
}

# function to be used to decrypt data encrypted by Soldo using your private key (Algorithm: RSA/ECB/OAEPWithSHA-256ANDMGF1Padding)
# input arguments are: encrypted string and your private key
# it returns the decrypted string
function decryptData($myCiphertext, $myPrivatekey) {
    $rsa = new \Crypt_RSA();
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
    $rsa->setMGFHash("sha256");
    $rsa->setHash("sha256");
    $rsa->loadKey($myPrivatekey);
    return $rsa->decrypt($myCiphertext);
}

# function to be used to create a new wallet
# input arguments are: business api domain, access token, wallet details, token provided by Soldo and your key pair
# it returns the wallet order id 
function addWallet($myBaseUrl, $myAccessToken, $myOwnerType, $myCurrency, $myName, $myToken, $myKeyPair) {
	# fingerprint order for wallet creation is: request_timestamp, owner_type, currency, name, token (http://apidoc-demo.soldo.com/v2/zgxiaxtcyapyoijojoef.html#add-wallet)
	$rt = strval(intval(microtime(true) * 1000));
	$fingerprintOrder = ($rt . $myOwnerType . $myCurrency . $myName . $myToken);
	$dataEncrypted = getAdvancedAuthentication($fingerprintOrder, $myKeyPair[0], $myKeyPair[1]);
	
	# wallet creation request body
	$body = '{
		"request_timestamp": ' . $rt . ',
		"owner_type": "' . $myOwnerType . '",
		"currency": "' . $myCurrency . '",
		"name": "' . $myName . '"
	}';
	
	# wallet creation request header
	$headers = [
		"Authorization: Bearer $myAccessToken",
		"X-Soldo-Fingerprint: {$dataEncrypted[0]}",
		"X-Soldo-Fingerprint-Signature: {$dataEncrypted[1]}",
		"Content-Type: application/json"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/wallets");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error adding wallet, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return order id
	return json_decode($response)->id;
}

# function to be used to loop over the order waiting for it completion and get the wallet id
# input arguments are: business api domain, access token and order id
# it returns the wallet id
function getWalletId($myBaseUrl, $myAccessToken, $myOrderId) {
	
	# get order request header
	$headers = [
		"Authorization: Bearer $myAccessToken"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/orders/".$myOrderId);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	
	$walletId = "";
	$i = 0;
	try{
		# execute the request multiple times until the wallet is created
		do {
			$response = curl_exec($ch);
			$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
			
			if ($httpcode != 200) {
				throw new Exception(sprintf("%s - Error getting order, response body: %s", $httpcode, $response));
			}
			$obj = json_decode($response);
			
			# check order status
			switch ($obj->status) {
				# order completed, the wallet is created, exit both switch and do while
				case "COMPLETED":
					$arr = $obj->items;
					$walletId = $arr[0]->id;
					break 2;
				# order won't be fullfilled, exit loop and throw error
				case "ERROR":
				case "CANCELLED":
					throw new Exception(sprintf("%s - Error processing wallet order, response body: %s", $httpcode, $response));
				# order hasn't be fullfilled yet, sleep for 6 seconds and reiterate over the loop 
				default:
					sleep (6);
					$i++;
			}
			# stops after 10 iteration (60 seconds) and throw error
		} while ($i < 10);
		
		curl_close($ch);
		
		if ($walletId == ""){
			throw new Exception(sprintf("%s - Maximum tentative exceeded, response body: %s", $httpcode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return wallet id
	return $walletId;
}

$accessToken = getAccessToken($baseUrl, $clientId, $clientSecret);

$keyPair = getKeyPair($privateKeyPath, $publicKeyPath);

$orderId = addWallet($baseUrl, $accessToken, $ownerType, $currency, $name, $token, $keyPair);

$walletId = getwalletId($baseUrl, $accessToken, $orderId);

echo ("Wallet ID: " . $walletId);

?>

User creation

This code sample shows how to perform Authentication and create a new user in PHP.

<?php
#####################################################################################################
#Script Name	: Standard authentication and Advanced Authentication for user creation PHP example   #
#Description	: This script uses the Business APIs V2 in order to create a user and                 #
#                 return its public ID, this is just an example STORE YOUR CREDENTIALS SAFELY       #
#####################################################################################################

error_reporting(E_ALL);

# import external library
include "Crypt/RSA.php";

# set the environment configuration
$demo = true;

if ($demo) {
	# set the demo business api domain
	$baseUrl = "https://api-demo.soldocloud.net";
	
	# set your demo private and public key path
	$privateKeyPath = "C:\\keys\\demo\\private.key";
	$publicKeyPath = "C:\\keys\\demo\\public.key";
	
	# set your demo API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
} else {
	# set the production business api domain
	$baseUrl = "https://api.soldo.com";
	
	# set your production private and public key path
	$privateKeyPath = "C:\\keys\\prod\\private.key";
	$publicKeyPath = "C:\\keys\\prod\\public.key";
	
	# set your production API credentials
	$clientId = "XXXXXX";
	$clientSecret = "XXXXXX"; 
	$token = "XXXXXX";
};

# set details of the user to be created
$name = "Mark";
$middlename = "";
$surname = "Facebook";
$jobTitle = "CEO";
$email = "[email protected]";
$dob = "1984-05-14";
$mobile = "+177777777";
$mobilePrefix = "+1";
$mobileAccess = "false";
$webAccess = "false";
$customReferenceId = "0003";

# function used to get your private and public key from your file system
# input arguments are: your private and public key path
# it returns an array  containing your private key at index 0 and your public key at index 1
function getKeyPair($myPrivateKeyPath, $myPublicKeyPath){
	try{
		if (!is_file($myPrivateKeyPath)) {
			throw new Exception(sprintf("Private key file not found in %s", $myPrivateKeyPath));
		}
		if (!is_file($myPublicKeyPath)) {
			throw new Exception(sprintf("Public key file not found in %s", $myPublicKeyPath));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	return [trim(file_get_contents($myPrivateKeyPath)), trim(file_get_contents($myPublicKeyPath))];
}

# function used to get the access token using the standard authentication
# input arguments are: business api domain, your clientId and your clientSecret 
# it returns the access token to be used in order to authenticate your next requests
function getAccessToken($myBaseUrl, $myClientId, $myClientSecret) {
	# standard authentication request body
	$body = "client_id=" . $myClientId . "&client_secret=" . $myClientSecret;
	
	# standard authentication request header
	$headers = [
		"Content-Type: application/x-www-form-urlencoded"
	];
	
	$ch = curl_init($myBaseUrl . "/oauth/authorize");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error authenticating, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return access token
	return json_decode($response)->access_token;
}

# function to be used to generate the hashed fingerprint and the fingerprint signature
# input arguments are: fingerprint order concatenated string, your private key and your public key
# it returns an array containing the fingerprint at index 0 and the fingerprint signature at index 1
function getAdvancedAuthentication($myFingerprintOrder, $myPrivateKey, $myPublicKey) {
	
	# hashing the fingerprint order concatenated string with SHA512 algorithm 
    $fingerprint = hash("sha512", $myFingerprintOrder);

	# your private 2048 RSA key
    $private_key_pem = openssl_pkey_get_private($myPrivateKey);

	# your public 2048 RSA key
    $public_key_pem = openssl_pkey_get_public($myPublicKey);

	try {
		# openssl function to sign the hashed fingerprint with SHA512withRSA algorithm
		openssl_sign($fingerprint, $signature, $private_key_pem, OPENSSL_ALGO_SHA512);
		if (!openssl_verify($fingerprint, $signature, $public_key_pem, "sha512WithRSAEncryption")) {
			throw new Exception("Signature failed, please check your keys!");
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}

	# Base64 encoding is required
    $signature_base64_encoded = base64_encode($signature);
	
	# fingerprint is the fingerprint hash for X-Soldo-Fingerprint header
	# signature_base64_encoded is the fingerprint hash signature for X-Soldo-Fingerprint-Signature header
    return [$fingerprint, $signature_base64_encoded];
}

# function to be used to decrypt data encrypted by Soldo using your private key (Algorithm: RSA/ECB/OAEPWithSHA-256ANDMGF1Padding)
# input arguments are: encrypted string and your private key
# it returns the decrypted string
function decryptData($myCiphertext, $myPrivatekey) {
    $rsa = new \Crypt_RSA();
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
    $rsa->setMGFHash("sha256");
    $rsa->setHash("sha256");
    $rsa->loadKey($myPrivatekey);
    return $rsa->decrypt($myCiphertext);
}

# function to be used to create a new user
# input arguments are: business api domain, access token, user details, token provided by Soldo and your key pair
# it returns the user order id 
function addUser($myBaseUrl, $myAccessToken, $myName, $myMiddlename, $mySurname, $myJobTitle, $myEmail, $myDob, $myMobile, $myMobilePrefix, $myMobileAccess, $myWebAccess, $myCustomReferenceId, $myToken, $myKeyPair) {
	# fingerprint order for user creation is: request_timestamp, name, surname, mobile_access, web_access, token (http://apidoc-demo.soldo.com/v2/zgxiaxtcyapyoijojoef.html#add-user)
	$rt = strval(intval(microtime(true) * 1000));
	$fingerprintOrder = ($rt . $myName . $mySurname . $myMobileAccess . $myWebAccess . $myToken);
	$dataEncrypted = getAdvancedAuthentication($fingerprintOrder, $myKeyPair[0], $myKeyPair[1]);
	
	# user creation request body
	$body = '{
		"request_timestamp": ' . $rt . ',
		"name": "' . $myName . '",
		"middlename": "' . $myMiddlename . '",
		"surname": "' . $mySurname . '",
		"job_title": "' . $myJobTitle . '",
		"email": "' . $myEmail . '",
		"dob": "' . $myDob . '",
		"mobile": "' . $myMobile  . '",
		"mobile_prefix": "' . $myMobilePrefix  . '",
		"mobile_access": "' . $myMobileAccess  . '",
		"web_access": "' . $myWebAccess  . '",
		"custom_reference_id": "' . $myCustomReferenceId  . '"
	}';
			
	# user creation request header
	$headers = [
		"Authorization: Bearer $myAccessToken",
		"X-Soldo-Fingerprint: {$dataEncrypted[0]}",
		"X-Soldo-Fingerprint-Signature: {$dataEncrypted[1]}",
		"Content-Type: application/json"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/employees");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
	
	try{
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
	
		if ($httpCode != 200) {
			throw new Exception(sprintf("%s - Error adding user, response body: %s", $httpCode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return order id
	return json_decode($response)->id;
}

# function to be used to loop over the order waiting for it completion and get the user id
# input arguments are: business api domain, access token and order id
# it returns the user id
function getUserId($myBaseUrl, $myAccessToken, $myOrderId) {
	
	# get order request header
	$headers = [
		"Authorization: Bearer $myAccessToken"
	];
	
	$ch = curl_init($myBaseUrl . "/business/v2/orders/".$myOrderId);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	
	$userId = "";
	$i = 0;
	try{
		# execute the request multiple times until the user is created
		do {
			$response = curl_exec($ch);
			$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
			
			if ($httpcode != 200) {
				throw new Exception(sprintf("%s - Error getting order, response body: %s", $httpcode, $response));
			}
			$obj = json_decode($response);
			
			# check order status
			switch ($obj->status) {
				# order completed, the user is created, exit both switch and do while
				case "COMPLETED":
					$arr = $obj->items;
					$userId = $arr[0]->id;
					break 2;
				# order won't be fullfilled, exit loop and throw error
				case "ERROR":
				case "CANCELLED":
					throw new Exception(sprintf("%s - Error processing user order, response body: %s", $httpcode, $response));
				# order hasn't be fullfilled yet, sleep for 6 seconds and reiterate over the loop 
				default:
					sleep (6);
					$i++;
			}
			# stops after 10 iteration (60 seconds) and throw error
		} while ($i < 10);
		
		curl_close($ch);
		
		if ($userId == ""){
			throw new Exception(sprintf("%s - Maximum tentative exceeded, response body: %s", $httpcode, $response));
		}
	} catch( Exception $e ) {
		$message = $e->getMessage();
		die( $message );
	}
	
	# read json response and return user id
	return $userId;
}

$accessToken = getAccessToken($baseUrl, $clientId, $clientSecret);

$keyPair = getKeyPair($privateKeyPath, $publicKeyPath);

$orderId = addUser($baseUrl, $accessToken, $name, $middlename, $surname, $jobTitle, $email, $dob, $mobile, $mobilePrefix, $mobileAccess, $webAccess, $customReferenceId, $token, $keyPair);

$userId = getUserId($baseUrl, $accessToken, $orderId);

echo ("User ID: " . $userId);

?>