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 . "¤cyCode=" . $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);
?>