hipay/hipay-wallet-cashout-mirakl-library

View on GitHub
src/Api/HiPay.php

Summary

Maintainability
F
3 days
Test Coverage
<?php

namespace HiPay\Wallet\Mirakl\Api;

use DateTime;
use Exception;
use Guzzle\Http\Message\PostFile;
use HiPay\Wallet\Mirakl\Api\HiPay\ApiInterface;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Rest\BankInfo;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Rest\UserAccount;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Soap\Transfer;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Soap\UserAccountBasic;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Soap\UserAccountDetail;
use HiPay\Wallet\Mirakl\Api\HiPay\Model\Status\Identified;
use HiPay\Wallet\Mirakl\Api\HiPay\Wallet\AccountInfo;
use HiPay\Wallet\Mirakl\Api\Soap\SmileClient;
use HiPay\Wallet\Mirakl\Vendor\Model\VendorInterface;
use Guzzle\Service\Client;
use Guzzle\Service\Description\ServiceDescription;
use Guzzle\Http\Exception\ClientErrorResponseException;
use HiPay\Wallet\Mirakl\Exception\HipayRestResponseException;

/**
 * Make the SOAP & REST call to the HiPay API.
 *
 * @author    HiPay <support.wallet@hipay.com>
 * @copyright 2017 HiPay
 */
class HiPay implements ApiInterface
{
    /** @var  string the hipay webservice login */
    protected $login;

    /** @var  string the hipay webservice password */
    protected $password;

    /** @var  SmileClient the user account webservice client */
    protected $userAccountClient;

    /** @var  SmileClient the transaction webservice client */
    protected $transferClient;

    /** @var  SmileClient the withdrawal webservice client */
    protected $withdrawalClient;

    /** @var string the entity given to the merchant by HiPay */
    protected $entity;

    /** @var string the locale */
    protected $locale;

    /** @var string the timezone */
    protected $timezone;

    /** @var Client guzzle client used for the request */
    protected $restClient;

    // For all types of businesses
    const DOCUMENT_ALL_PROOF_OF_BANK_ACCOUNT = 6;
    // For individual only
    const DOCUMENT_INDIVIDUAL_IDENTITY = 1;
    const DOCUMENT_INDIVIDUAL_PROOF_OF_ADDRESS = 2;
    // For legal entity businesses only
    const DOCUMENT_LEGAL_IDENTITY_OF_REPRESENTATIVE = 3;
    const DOCUMENT_LEGAL_PROOF_OF_REGISTRATION_NUMBER = 4;
    const DOCUMENT_LEGAL_ARTICLES_DISTR_OF_POWERS = 5;
    // For one man businesses only
    const DOCUMENT_SOLE_MAN_BUS_IDENTITY = 7;
    const DOCUMENT_SOLE_MAN_BUS_PROOF_OF_REG_NUMBER = 8;
    const DOCUMENT_SOLE_MAN_BUS_PROOF_OF_TAX_STATUS = 9;
    // For log separator for markdown
    const LINEMKD = "\r";

    /**
     * Constructor.
     *
     * @param string $baseSoapUrl
     * @param string $baseRestUrl
     * @param string $login
     * @param string $password
     * @param string $entity
     * @param string $locale
     * @param string $timeZone
     * @param array $options
     */
    public function __construct(
        $baseSoapUrl,
        $baseRestUrl,
        $login,
        $password,
        $entity,
        $locale = 'fr_FR',
        $timeZone = 'Europe/Paris',
        $options = array(),
        $rest = true
    ) {
        $this->login = $login;
        $this->password = $password;
        $this->entity = $entity;
        $this->timezone = $timeZone;
        $this->locale = $locale;
        $this->rest = $rest;

        $userAgent = "connector-mirakl-hipay-" . self::getLibraryVersion();

        $defaults = array(
            'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
            'cache_wsdl' => WSDL_CACHE_BOTH,
            'soap_version' => SOAP_1_1,
            'encoding' => 'UTF-8',
            'trace' => true,
            'stream_context' => stream_context_create(['http' => ['user_agent' => $userAgent]])
        );

        $options = array_merge($defaults, $options);

        $this->transferClient = new SmileClient($baseSoapUrl . '/soap/transfer?wsdl', $options);

        $this->withdrawalClient = new SmileClient($baseSoapUrl . '/soap/withdrawal?wsdl', $options);

        $this->restClient = new Client();

        $this->restClient->setUserAgent($userAgent);

        $this->description = ServiceDescription::factory(__DIR__ . '../../../data/api/hipay.json');
        $this->description->setBaseUrl($baseRestUrl);
        $this->restClient->setDescription($this->description);
    }

    public function uploadDocument(
        $userSpaceId,
        $accountId,
        $documentType,
        $fileName,
        \DateTime $validityDate = null,
        $back = null
    ) {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath('request.options/headers/php-auth-user', $this->login);

        $this->restClient->getConfig()->setPath('request.options/headers/php-auth-pw', $this->password);

        if (!is_null($accountId)) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $accountId
            );
        }

        if ($back !== null) {
            $back = new PostFile('back', $back);
        }

        $parameters = array(
            'userSpaceId' => $userSpaceId,
            'validityDate' => $validityDate,
            'type' => $documentType,
            'file' => new PostFile('file', $fileName),
            'back' => $back
        );

        $command = $this->restClient->getCommand(
            'UploadDocument',
            $parameters
        );

        return $this->executeRest($command, $parameters);
    }

    public function getDocuments(VendorInterface $vendor)
    {

        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!empty($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        }

        $command = $this->restClient->getCommand('GetDocuments', array());

        $result = $this->executeRest($command);

        return $result['documents'];
    }

    /**
     * Check if given email can be used to create an HiPay wallet
     * Enforce the entity to the one given on object construction if false.
     *
     * @param string $email
     * @param bool $entity
     *
     * @return bool if array is empty
     *
     * @throws Exception
     */
    public function isAvailable($email, $entity = false)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        $parameters = array(
            'userEmail' => $email,
            'entity' => $entity ?: $this->entity
        );
        $command = $this->restClient->getCommand(
            'IsAvailable',
            $parameters
        );

        $result = $this->executeRest($command, $parameters);

        return $result['is_available'];
    }

    public function updateEmail($email, VendorInterface $vendor)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-subaccount-id',
            $vendor->getHiPayId()
        );

        $parameters = array('email' => $email);

        $command = $this->restClient->getCommand('UpdateAccount', $parameters);

        $result = $this->executeRest($command, $parameters);

        return $result;
    }

    /**
     * Create an new account on HiPay wallet
     * Enforce the entity to the one given on object construction
     * Enforce the locale to the one given on object construction if false
     * Enforce the timezone to the one given on object construction if false.
     *
     * @param UserAccountBasic $accountBasic
     * @param UserAccountDetails $accountDetails
     * @param MerchantDataRest $merchantData
     *
     * @return AccountInfo The HiPay Wallet account information
     *
     * @throws Exception
     */
    public function createFullUseraccountV2(UserAccount $userAccount)
    {
        $this->resetRestClient();

        if (!$userAccount->getLocale()) {
            $userAccount->setLocale($this->locale);
        }

        if (!$userAccount->getTimeZone()) {
            $userAccount->setTimeZone($this->timezone);
        }

        if (!$userAccount->getEntityCode()) {
            $userAccount->setEntityCode($this->entity);
        }

        if (!$userAccount->getCredential()) {
            $userAccount->setCredential(
                array(
                    'wslogin' => $this->login,
                    'wspassword' => $this->password,
                )
            );
        }

        $parameters = $userAccount->mergeIntoParameters();

        $command = $this->restClient->getCommand(
            'RegisterNewAccount',
            $parameters['userAccount']
        );

        $result = $this->executeRest($command, $parameters);

        return new AccountInfo(
            $result['account_id'],
            $result['user_space_id'],
            $result['status'] === Identified::YES,
            $result['callback_salt']
        );
    }

    /**
     * Retrieve from HiPay the bank information.
     *
     * @param VendorInterface $vendor
     *
     * @return BankInfo if array is empty
     *
     * @throws Exception
     */
    public function bankInfosCheck(VendorInterface $vendor)
    {
        $this->resetRestClient();

        $bankInfo = new BankInfo();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!is_null($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        }

        $parameters['locale'] = 'en_GB';

        $command = $this->restClient->getCommand(
            'getBankInfo',
            $parameters
        );
        $result = $this->executeRest($command, $parameters);

        return $bankInfo->setHiPayData($result);
    }

    /**
     * Retrieve from HiPay the bank account status in english
     * To be checked against the constant defined in
     * HiPay\Wallet\Mirakl\Api\HiPay\Model\Status\BankInfo.
     *
     * @param UserAccount $userAccount
     *
     * @return string
     *
     * @throws Exception
     */
    public function bankInfosStatus(VendorInterface $vendor)
    {

        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!empty($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        }

        $parameters['locale'] = 'en_GB';

        $command = $this->restClient->getCommand(
            'getBankInfo',
            $parameters
        );
        $result = $this->executeRest($command, $parameters);

        return $result['status_code'];
    }

    /**
     * Create a bank account in HiPay.
     *
     * @param VendorInterface $vendor
     * @param BankInfo $bankInfo
     *
     * @return array|bool if array is empty
     *
     * @throws Exception
     */
    public function bankInfosRegister(
        VendorInterface $vendor,
        BankInfo $bankInfo
    ) {

        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!is_null($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        }

        $parameters = $bankInfo->mergeIntoParameters();

        $command = $this->restClient->getCommand(
            'RegisterBankInfo',
            $parameters
        );
        $result = $this->executeRest($command, $parameters);

        return $result;
    }

    /**
     * Return the hipay account id.
     *
     * @param VendorInterface $vendor
     *
     * @return array|bool if array is empty
     *
     * @throws Exception
     */
    public function getWalletId(VendorInterface $vendor)
    {
        $result = $this->getAccountInfos($vendor);

        return $result['user_account_id'];
    }

    /**
     * Return the hipay account information.
     *
     * @param VendorInterface $vendor
     *
     * @return AccountInfo HiPay Wallet account information
     *
     * @throws Exception
     */
    public function getWalletInfo(UserAccount $userAccount, $vendor)
    {
        $result = $this->getAccountInfos($userAccount, $vendor);

        return new AccountInfo(
            $result['user_account_id'],
            $result['user_space_id'],
            $result['identified'] === 1,
            $result['callback_salt'],
            $result['message']
        );
    }

    /**
     * Return the identified status of the account.
     *
     * @param VendorInterface $vendor
     * @return bool
     * @throws Exception
     */
    public function isIdentified(VendorInterface $vendor)
    {

        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!empty($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        }

        $command = $this->restClient->getCommand(
            'GetUserAccount',
            array()
        );

        $result = $this->executeRest($command);

        return $result['identified'] == 1 ? true : false;
    }

    /**
     * Return various information about a wallet
     *
     * @param VendorInterface $vendor
     *
     * @return array
     *
     * @throws Exception
     */
    public function getAccountInfos(UserAccount $userAccount, $vendor = null)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if ($vendor !== null) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        } elseif (!empty($userAccount->getLogin())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-login',
                $userAccount->getLogin()
            );
        }

        $command = $this->restClient->getCommand(
            'GetUserAccount',
            array()
        );

        try {
            $result = $this->executeRest($command);
        } catch (HipayRestResponseException $e) {

            if ($e->getResponse()->getStatusCode() == '401') {
                /** retry with email in php-auth-subaccount-login */
                $this->restClient->getConfig()->setPath(
                    'request.options/headers/php-auth-subaccount-login',
                    strtolower($userAccount->getEmail())
                );

                $command = $this->restClient->getCommand(
                    'GetUserAccount',
                    array()
                );
                $result = $this->executeRest($command);
            }
        }

        return $result;
    }

    /**
     * Return various information about a wallet
     *
     * @param VendorInterface $vendor
     *
     * @return array
     *
     * @throws Exception
     */
    public function getAccountHiPay($account_id)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!empty($account_id)) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $account_id
            );
        }

        $command = $this->restClient->getCommand(
            'GetUserAccount',
            array()
        );

        $result = $this->executeRest($command);

        return $result;
    }

    public function isWalletExist($account_id)
    {
        try {
            $this->getAccountHiPay($account_id);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Return the wallet current balance
     *
     * @param VendorInterface $vendor
     *
     * @return int
     *
     * @throws Exception
     */
    public function getBalance(VendorInterface $vendor)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!is_null($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        } elseif (!is_null($vendor->getLogin())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-login',
                $vendor->getLogin()
            );
        }

        $command = $this->restClient->getCommand(
            'GetBalance',
            array()
        );

        try {
            $result = $this->executeRest($command);
        } catch (HipayRestResponseException $e) {
            /** retro compatible if old account */
            if ($e->getResponse()->getStatusCode() == '401') {
                /** retry with email in php-auth-subaccount-login */
                $this->restClient->getConfig()->setPath(
                    'request.options/headers/php-auth-subaccount-login',
                    strtolower($vendor->getEmail())
                );
                $command = $this->restClient->getCommand(
                    'GetBalance',
                    array()
                );
                $result = $this->executeRest($command);
            }
        }
        return $result['balances'][0]['balance'];
    }

    /**
     *
     * @param Transfer $transfer
     * @param VendorInterface $vendor
     */
    public function transfer(Transfer $transfer, VendorInterface $vendor = null)
    {
        if ($this->rest) {
            return $this->transferRest($transfer, $vendor);
        } else {
            return $this->transferSoap($transfer);
        }
    }

    /**
     *
     * @param VendorInterface $vendor
     * @param type $amount
     * @param type $label
     * @param type $merchantUniqueId
     */
    public function withdraw(VendorInterface $vendor, $amount, $label, $merchantUniqueId = null)
    {
        if ($this->rest) {
            return $this->withdrawRest($vendor, $amount, $label, $merchantUniqueId);
        } else {
            return $this->withdrawSoap($vendor, $amount, $label);
        }
    }

    /**
     * Return the wallet current balance
     *
     * @param VendorInterface $vendor
     *
     * @return int
     *
     * @throws Exception
     */
    public function getTransaction($transactionId, $accountId)
    {
        $this->resetRestClient();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );


        if (!is_null($accountId)) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $accountId
            );
        }


        $command = $this->restClient->getCommand(
            'GetTransactionInfo',
            array("id" => $transactionId)
        );

        return $this->executeRest($command);
    }

    /**
     * Make a transfer.
     *
     * @param Transfer $transfer
     * @param VendorInterface $vendor
     *
     * @return int
     *
     * @throws Exception
     */
    private function transferSoap(Transfer $transfer, VendorInterface $vendor = null)
    {
        if (!$transfer->getEntity()) {
            $transfer->setEntity($this->entity);
        }
        $parameters = $transfer->mergeIntoParameters();
        if ($vendor) {
            $parameters = $this->mergeSubAccountParameters($vendor);
        }
        $result = $this->callSoap('direct', $parameters);

        return $result['transactionId'];
    }

    /**
     *
     * @param Transfer $transfer
     * @param VendorInterface $vendor
     * @return type
     */
    private function transferRest(Transfer $transfer, VendorInterface $vendor = null)
    {

        $this->resetRestClient();

        if (!$transfer->getEntity()) {
            $transfer->setEntity($this->entity);
        }
        $parameters = $transfer->mergeIntoParameters();

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        $command = $this->restClient->getCommand(
            'transfer',
            $parameters
        );

        $result = $this->executeRest($command, $parameters);

        return $result['transaction_id'];
    }

    /**
     *
     * @param VendorInterface $vendor
     * @param type $amount
     * @param type $label
     * @param type $merchantUniqueId
     * @return type
     */
    private function withdrawRest(VendorInterface $vendor, $amount, $label, $merchantUniqueId)
    {

        $this->resetRestClient();

        $parameters = array('amount' => $amount, 'label' => $label, 'merchantUniqueId' => $merchantUniqueId);

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-user',
            $this->login
        );

        $this->restClient->getConfig()->setPath(
            'request.options/headers/php-auth-pw',
            $this->password
        );

        if (!is_null($vendor->getHiPayId())) {
            $this->restClient->getConfig()->setPath(
                'request.options/headers/php-auth-subaccount-id',
                $vendor->getHiPayId()
            );
        } else {
            throw new Exception("Withdraw require a HiPay ID");
        }

        $command = $this->restClient->getCommand(
            'withdraw',
            $parameters
        );

        $result = $this->executeRest($command, $parameters);

        return $result['transaction_public_id'];
    }

    /**
     * Make a withdrawal.
     *
     * @param VendorInterface $vendor
     * @param $amount
     * @param $label
     *
     * @return int
     *
     * @throws Exception
     */
    private function withdrawSoap(VendorInterface $vendor, $amount, $label)
    {
        $parameters = array('amount' => $amount, 'label' => $label);
        $parameters = $this->mergeSubAccountParameters($vendor, $parameters);
        $result = $this->callSoap('create', $parameters);

        return $result['transactionPublicId'];
    }

    /**
     * Return the mandatory fields bank info fields for a specific vendor.
     *
     * @param $country
     */
    public function getBankInfoFields($country = 'FR')
    {
        $parameters = array('locale' => 'en_GB', 'country' => $country);
        $result = $this->callSoap('bankInfosFields', $parameters);

        return $result['fields'];
    }

    /**
     * @param int $merchantGroupId the id given to HiPay corresponding to the entity
     * @param DateTime $pastDate the maximum wallet creation date
     *
     * @return array
     */
    public function getMerchantsGroupAccounts($merchantGroupId, DateTime $pastDate)
    {
        $parameters = array('merchantGroupId' => $merchantGroupId, 'pastDate' => $pastDate->format('Y-m-d'));
        $data = $this->callSoap('getMerchantsGroupAccounts', $parameters);
        $result = array();
        foreach ($data['dataMerchantsGroupAccounts']->item as $index => $item) {
            $result[] = (array)$item;
        }
        return $result;
    }

    /**
     * Add the api REST login parameters to the parameters.
     *
     * @param array $parameters the call parameters
     *
     * @return array
     */
    protected function mergeLoginParameters(array $parameters = array())
    {
        $parameters = $parameters + array(
                'credential' => array(
                    'wslogin' => $this->login,
                    'wspassword' => $this->password,
                )
            );

        return $parameters;
    }

    /**
     * Add the api SOAP login parameters to the parameters.
     *
     * @param array $parameters the call parameters
     *
     * @return array
     */
    protected function mergeLoginParametersSoap(array $parameters = array())
    {
        $parameters = $parameters + array(
                'wsLogin' => $this->login,
                'wsPassword' => $this->password,
            );
        return $parameters;
    }

    /**
     * Add sub account informations.
     *
     * @param array $parameters the parameters array to add the info to
     * @param VendorInterface $vendor the vendor from which subAccount info is fetched from
     *
     * @return array
     */
    protected function mergeSubAccountParameters(
        $vendor,
        $parameters = array()
    ) {
        $parameters += array(
            'wsSubAccountId' => $vendor->getHiPayId(),
        );

        return $parameters;
    }

    /**
     * Return the correct soap client to use.
     *
     * @param string $name the called method name
     *
     * @return SmileClient
     */
    protected function getClient($name)
    {
        switch ($name) {
            case 'direct':
                return $this->transferClient;
            case 'create':
                return $this->withdrawalClient;
            default:
                return true; //$this->userAccountClient;
        }
    }

    /**
     * @param string $name
     * @param array $parameters
     *
     * @return array
     *
     * @throws Exception
     * @throws \SoapFault
     */
    protected function callSoap($name, array $parameters)
    {
        $parameters = $this->mergeLoginParametersSoap($parameters);
        //Make the call
        $response = $this->getClient($name)->$name(
            array('parameters' => $parameters)
        );

        //Parse the response
        $response = (array)$response;
        $response = (array)current($response);
        if ($response['code'] > 0) {
            throw new Exception(
                "There was an error with the soap call $name" .
                PHP_EOL .
                $response['code'] .
                ' : ' .
                $response['description'] .
                PHP_EOL .
                'Date : ' .
                date('Y-m-d H:i:s') .
                PHP_EOL .
                'Parameters :' .
                PHP_EOL .
                print_r($parameters, true),
                $response['code']
            );
        } else {
            unset($response['code']);
            unset($response['description']);
        }

        return $response ?: true;
    }

    /**
     * Reset Http client config
     */
    private function resetRestClient()
    {
        $this->restClient->getConfig()->clear();
    }

    /**
     * Exec Guzzle command
     * Wallet API doesn't send HTTP error code in case of parameters errors, send 200 instead
     * Error is in request body
     *
     * @param $command
     * @param array $parameters
     * @return array|\Guzzle\Http\Message\Response|mixed
     * @throws HipayRestResponseException
     * @throws \Guzzle\Service\Exception\CommandTransferException
     */
    private function executeRest($command, $parameters = array())
    {
        $this->restClient->getConfig()->setPath(
            'request.options/headers/x-professional-client-origin',
            'hipay-mirakl-connector-v1'
        );

        try {
            $result = $this->restClient->execute($command);
        } catch (ClientErrorResponseException $e) {
            throw new HipayRestResponseException($e, $command, $parameters);
        }


        if (isset($result['code']) && $result['code'] === 0) {
            return $result;
        }

        throw new Exception(
            "There was an error with the Rest call " .
            $command->getName() .
            PHP_EOL .
            $result['code'] .
            ' : ' .
            $result['message'] .
            PHP_EOL .
            print_r($result['errors'], true) .
            PHP_EOL .
            'Parameters : ' .
            print_r($parameters, true) .
            PHP_EOL,
            $result['code']
        );
    }

    /**
     * Get library version from composer.json file
     * @return string
     */
    private static function getLibraryVersion()
    {

        $path = dirname(__FILE__) . '/../../composer.json';

        if (file_exists($path)) {
            $contents = file_get_contents($path);
            $contents = utf8_encode($contents);

            $composer = json_decode($contents, true);
        } else {
            $composer["version"] = "N/A";
        }

        return $composer["version"];
    }
}