<commit_before><?php

namespace Hyperwallet;

use Hyperwallet\Exception\HyperwalletApiException;
use Hyperwallet\Exception\HyperwalletArgumentException;
use Hyperwallet\Model\AuthenticationToken;
use Hyperwallet\Model\Balance;
use Hyperwallet\Model\BankAccount;
use Hyperwallet\Model\BankAccountStatusTransition;
use Hyperwallet\Model\BankCard;
use Hyperwallet\Model\BankCardStatusTransition;
use Hyperwallet\Model\IProgramAware;
use Hyperwallet\Model\PaperCheck;
use Hyperwallet\Model\PaperCheckStatusTransition;
use Hyperwallet\Model\PayPalAccountStatusTransition;
use Hyperwallet\Model\Transfer;
use Hyperwallet\Model\TransferRefund;
use Hyperwallet\Model\TransferStatusTransition;
use Hyperwallet\Model\Payment;
use Hyperwallet\Model\PaymentStatusTransition;
use Hyperwallet\Model\PayPalAccount;
use Hyperwallet\Model\PrepaidCard;
use Hyperwallet\Model\PrepaidCardStatusTransition;
use Hyperwallet\Model\Program;
use Hyperwallet\Model\ProgramAccount;
use Hyperwallet\Model\Receipt;
use Hyperwallet\Model\TransferMethod;
use Hyperwallet\Model\TransferMethodConfiguration;
use Hyperwallet\Model\User;
use Hyperwallet\Model\UserStatusTransition;
use Hyperwallet\Model\VenmoAccount;
use Hyperwallet\Model\VenmoAccountStatusTransition;
use Hyperwallet\Model\WebhookNotification;
use Hyperwallet\Response\ListResponse;
use Hyperwallet\Util\ApiClient;

/**
 * The Hyperwallet SDK Client
 *
 * @package Hyperwallet
 */
class Hyperwallet {

    /**
     * The program token
     *
     * @var string
     */
    private $programToken;

    /**
     * The internal API client
     *
     * @var ApiClient
     */
    private $client;

    /**
     * Creates a instance of the SDK Client
     *
     * @param string $username The API username
     * @param string $password The API password
     * @param string|null $programToken The program token that is used for some API calls
     * @param string $server The API server to connect to
     * @param string $encryptionData Encryption data to initialize ApiClient with encryption enabled
     *
     * @throws HyperwalletArgumentException
     */
    public function __construct($username, $password, $programToken = null, $server = 'https://api.sandbox.hyperwallet.com', $encryptionData = array()) {
        if (empty($username) || empty($password)) {
            throw new HyperwalletArgumentException('You need to specify your API username and password!');
        }

        $this->programToken = $programToken;
        $this->client = new ApiClient($username, $password, $server, array(), $encryptionData);
    }

    //--------------------------------------
    // Users
    //--------------------------------------

    /**
     * Create a user
     *
     * @param User $user The user data
     * @return User
     *
     * @throws HyperwalletApiException
     */
    public function createUser(User $user) {
        $this->addProgramToken($user);
        $body = $this->client->doPost('/rest/v3/users', array(), $user, array());
        return new User($body);
    }

    /**
     * Get a user
     *
     * @param string $userToken The user token
     * @return User
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getUser($userToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}', array('user-token' => $userToken), array());
        return new User($body);
    }

    /**
     * Update a user
     *
     * @param User $user The user
     * @return User
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function updateUser(User $user) {
        if (!$user->getToken()) {
            throw new HyperwalletArgumentException('token is required!');
        }
        $body = $this->client->doPut('/rest/v3/users/{user-token}', array('user-token' => $user->getToken()), $user, array());
        return new User($body);
    }

    /**
     * List all users
     *
     * @param array $options
     * @return ListResponse
     *
     * @throws HyperwalletApiException
     */
    public function listUsers($options = array()) {
        $body = $this->client->doGet('/rest/v3/users', array(), $options);
        return new ListResponse($body, function ($entry) {
            return new User($entry);
        });
    }

    /**
     * Get a user status transition
     *
     * @param string $userToken The user token
     * @param string $statusTransitionToken The status transition token
     * @return UserStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getUserStatusTransition($userToken, $statusTransitionToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($statusTransitionToken)) {
            throw new HyperwalletArgumentException('statusTransitionToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/status-transitions/{status-transition-token}', array(
            'user-token' => $userToken,
            'status-transition-token' => $statusTransitionToken
        ), array());
        return new UserStatusTransition($body);
    }

    /**
     * List all user status transitions
     *
     * @param string $userToken The user token
     * @param array $options The query parameters
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listUserStatusTransitions($userToken, array $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/status-transitions', array(
            'user-token' => $userToken
        ), $options);
        return new ListResponse($body, function ($entry) {
            return new UserStatusTransition($entry);
        });
    }

    //--------------------------------------
    // Authentication Token
    //--------------------------------------

    /**
     * Get authentication token
     *
     * @param $userToken The user token
     * @return AuthenticationToken
     *
     * @throws HyperwalletApiException
     */
    public function getAuthenticationToken($userToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doPost('/rest/v3/users/{user-token}/authentication-token', array(
            'user-token' => $userToken,
        ), null, array());
        return new AuthenticationToken($body);
    }

    //--------------------------------------
    // Paper Checks
    //--------------------------------------

    /**
     * Create a paper check
     *
     * @param string $userToken The user token
     * @param PaperCheck $paperCheck The paper check data
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createPaperCheck($userToken, PaperCheck $paperCheck) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doPost('/rest/v3/users/{user-token}/paper-checks',
            array('user-token' => $userToken), $paperCheck, array());
        return new PaperCheck($body);
    }

    /**
     * Get a paper check
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getPaperCheck($userToken, $paperCheckToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), array());
        return new PaperCheck($body);
    }

    /**
     * Update a paper check
     *
     * @param string $userToken The user token
     * @param PaperCheck $paperCheck The paper check data
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function updatePaperCheck($userToken, PaperCheck $paperCheck) {
        $body = $this->updateTransferMethod($userToken, $paperCheck, 'paper-checks');
        return new PaperCheck($body);
    }

    /**
     * List all paper checks
     *
     * @param string $userToken The user token
     * @param array $options The query parameters to send
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listPaperChecks($userToken, $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks', array('user-token' => $userToken), $options);
        return new ListResponse($body, function ($entry) {
            return new PaperCheck($entry);
        });
    }

    /**
     * Deactivate a paper check
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function deactivatePaperCheck($userToken, $paperCheckToken) {
        $transition = new PaperCheckStatusTransition();
        $transition->setTransition(PaperCheckStatusTransition::TRANSITION_DE_ACTIVATED);

        return $this->createPaperCheckStatusTransition($userToken, $paperCheckToken, $transition);
    }

    /**
     * Create a paper check status transition
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param PaperCheckStatusTransition $transition The status transition
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createPaperCheckStatusTransition($userToken, $paperCheckToken, PaperCheckStatusTransition $transition) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }

        $body = $this->client->doPost('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), $transition, array());
        return new PaperCheckStatusTransition($body);
    }

    /**
     * Get a paper check status transition
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param string $statusTransitionToken The status transition token
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getPaperCheckStatusTransition($userToken, $paperCheckToken, $statusTransitionToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }
        if (empty($statusTransitionToken)) {
            throw new HyperwalletArgumentException('statusTransitionToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions/{status-transition-token}', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken,
            'status-transition-token' => $statusTransitionToken
        ), array());
        return new PaperCheckStatusTransition($body);
    }

    /**
     * List all paper check status transitions
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param array $options The query parameters
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listPaperCheckStatusTransitions($userToken, $paperCheckToken, array $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), $options);
        return new ListResponse($body, function ($entry) {
            return new PaperCheckStatusTransition($entry);
        });
    }

    //--------------------------------------
    // Transfers
    //--------------------------------------

    /**
     * Create a transfer
     *
     * @param Transfer $transfer The transfer data
     * @return Transfer
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createTransfer(Transfer $transfer) {
        if (empty($transfer->getSourceToken())) {
            throw new HyperwalletArgumentException('sourceToken is required!');
        }
        if (empty($transfer->getDestinationToken())) {
            throw new HyperwalletArgumentException('destinationToken is required!');
        }
        if (empty($transfer->getClientTransferId())) {
            throw new HyperwalletArgumentException('clientTransferId is required!');
        }
        $body = $this->client->doPost('/rest/v3/transfers', array(), $transfer, array());
        return new Transfer($body);
    }

    public function createTransferRefund($transferToken, TransferRefund $transferRefund = null) {
        if (empty($transferRefund)) {
            throw new HyperwalletArgumentException('transferRefund is required!');
        }
        if (empty($transferToken)) {
            throw new HyperwalletArgumentException('transferToken is required!');
        }
        if (empty($transferRefund->getClientRefundId())) {
            throw new HyperwalletArgumentException('clientRefundId is required!');
        }
        $body = $this->client->doPost('/rest/v3/transfers/{transfer-token}/refunds',
            array('transfer-token' => $transferToken), $transferRefund, array());
        return new TransferRefund($body);
    }

    /**
     * Get a transfer
     *
     * @param string $transferToken The transfer token
     * @return Transfer
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getTransfer($transferToken) {
        if (empty($transferToken)) {
            throw new HyperwalletArgumentException('transferToken is required!');
        }<commit_msg>removed initiatiation of parameter in createTransferRefund<commit_after><?php

namespace Hyperwallet;

use Hyperwallet\Exception\HyperwalletApiException;
use Hyperwallet\Exception\HyperwalletArgumentException;
use Hyperwallet\Model\AuthenticationToken;
use Hyperwallet\Model\Balance;
use Hyperwallet\Model\BankAccount;
use Hyperwallet\Model\BankAccountStatusTransition;
use Hyperwallet\Model\BankCard;
use Hyperwallet\Model\BankCardStatusTransition;
use Hyperwallet\Model\IProgramAware;
use Hyperwallet\Model\PaperCheck;
use Hyperwallet\Model\PaperCheckStatusTransition;
use Hyperwallet\Model\PayPalAccountStatusTransition;
use Hyperwallet\Model\Transfer;
use Hyperwallet\Model\TransferRefund;
use Hyperwallet\Model\TransferStatusTransition;
use Hyperwallet\Model\Payment;
use Hyperwallet\Model\PaymentStatusTransition;
use Hyperwallet\Model\PayPalAccount;
use Hyperwallet\Model\PrepaidCard;
use Hyperwallet\Model\PrepaidCardStatusTransition;
use Hyperwallet\Model\Program;
use Hyperwallet\Model\ProgramAccount;
use Hyperwallet\Model\Receipt;
use Hyperwallet\Model\TransferMethod;
use Hyperwallet\Model\TransferMethodConfiguration;
use Hyperwallet\Model\User;
use Hyperwallet\Model\UserStatusTransition;
use Hyperwallet\Model\VenmoAccount;
use Hyperwallet\Model\VenmoAccountStatusTransition;
use Hyperwallet\Model\WebhookNotification;
use Hyperwallet\Response\ListResponse;
use Hyperwallet\Util\ApiClient;

/**
 * The Hyperwallet SDK Client
 *
 * @package Hyperwallet
 */
class Hyperwallet {

    /**
     * The program token
     *
     * @var string
     */
    private $programToken;

    /**
     * The internal API client
     *
     * @var ApiClient
     */
    private $client;

    /**
     * Creates a instance of the SDK Client
     *
     * @param string $username The API username
     * @param string $password The API password
     * @param string|null $programToken The program token that is used for some API calls
     * @param string $server The API server to connect to
     * @param string $encryptionData Encryption data to initialize ApiClient with encryption enabled
     *
     * @throws HyperwalletArgumentException
     */
    public function __construct($username, $password, $programToken = null, $server = 'https://api.sandbox.hyperwallet.com', $encryptionData = array()) {
        if (empty($username) || empty($password)) {
            throw new HyperwalletArgumentException('You need to specify your API username and password!');
        }

        $this->programToken = $programToken;
        $this->client = new ApiClient($username, $password, $server, array(), $encryptionData);
    }

    //--------------------------------------
    // Users
    //--------------------------------------

    /**
     * Create a user
     *
     * @param User $user The user data
     * @return User
     *
     * @throws HyperwalletApiException
     */
    public function createUser(User $user) {
        $this->addProgramToken($user);
        $body = $this->client->doPost('/rest/v3/users', array(), $user, array());
        return new User($body);
    }

    /**
     * Get a user
     *
     * @param string $userToken The user token
     * @return User
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getUser($userToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}', array('user-token' => $userToken), array());
        return new User($body);
    }

    /**
     * Update a user
     *
     * @param User $user The user
     * @return User
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function updateUser(User $user) {
        if (!$user->getToken()) {
            throw new HyperwalletArgumentException('token is required!');
        }
        $body = $this->client->doPut('/rest/v3/users/{user-token}', array('user-token' => $user->getToken()), $user, array());
        return new User($body);
    }

    /**
     * List all users
     *
     * @param array $options
     * @return ListResponse
     *
     * @throws HyperwalletApiException
     */
    public function listUsers($options = array()) {
        $body = $this->client->doGet('/rest/v3/users', array(), $options);
        return new ListResponse($body, function ($entry) {
            return new User($entry);
        });
    }

    /**
     * Get a user status transition
     *
     * @param string $userToken The user token
     * @param string $statusTransitionToken The status transition token
     * @return UserStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getUserStatusTransition($userToken, $statusTransitionToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($statusTransitionToken)) {
            throw new HyperwalletArgumentException('statusTransitionToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/status-transitions/{status-transition-token}', array(
            'user-token' => $userToken,
            'status-transition-token' => $statusTransitionToken
        ), array());
        return new UserStatusTransition($body);
    }

    /**
     * List all user status transitions
     *
     * @param string $userToken The user token
     * @param array $options The query parameters
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listUserStatusTransitions($userToken, array $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/status-transitions', array(
            'user-token' => $userToken
        ), $options);
        return new ListResponse($body, function ($entry) {
            return new UserStatusTransition($entry);
        });
    }

    //--------------------------------------
    // Authentication Token
    //--------------------------------------

    /**
     * Get authentication token
     *
     * @param $userToken The user token
     * @return AuthenticationToken
     *
     * @throws HyperwalletApiException
     */
    public function getAuthenticationToken($userToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doPost('/rest/v3/users/{user-token}/authentication-token', array(
            'user-token' => $userToken,
        ), null, array());
        return new AuthenticationToken($body);
    }

    //--------------------------------------
    // Paper Checks
    //--------------------------------------

    /**
     * Create a paper check
     *
     * @param string $userToken The user token
     * @param PaperCheck $paperCheck The paper check data
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createPaperCheck($userToken, PaperCheck $paperCheck) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doPost('/rest/v3/users/{user-token}/paper-checks',
            array('user-token' => $userToken), $paperCheck, array());
        return new PaperCheck($body);
    }

    /**
     * Get a paper check
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getPaperCheck($userToken, $paperCheckToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), array());
        return new PaperCheck($body);
    }

    /**
     * Update a paper check
     *
     * @param string $userToken The user token
     * @param PaperCheck $paperCheck The paper check data
     * @return PaperCheck
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function updatePaperCheck($userToken, PaperCheck $paperCheck) {
        $body = $this->updateTransferMethod($userToken, $paperCheck, 'paper-checks');
        return new PaperCheck($body);
    }

    /**
     * List all paper checks
     *
     * @param string $userToken The user token
     * @param array $options The query parameters to send
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listPaperChecks($userToken, $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks', array('user-token' => $userToken), $options);
        return new ListResponse($body, function ($entry) {
            return new PaperCheck($entry);
        });
    }

    /**
     * Deactivate a paper check
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function deactivatePaperCheck($userToken, $paperCheckToken) {
        $transition = new PaperCheckStatusTransition();
        $transition->setTransition(PaperCheckStatusTransition::TRANSITION_DE_ACTIVATED);

        return $this->createPaperCheckStatusTransition($userToken, $paperCheckToken, $transition);
    }

    /**
     * Create a paper check status transition
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param PaperCheckStatusTransition $transition The status transition
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createPaperCheckStatusTransition($userToken, $paperCheckToken, PaperCheckStatusTransition $transition) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }

        $body = $this->client->doPost('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), $transition, array());
        return new PaperCheckStatusTransition($body);
    }

    /**
     * Get a paper check status transition
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param string $statusTransitionToken The status transition token
     * @return PaperCheckStatusTransition
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getPaperCheckStatusTransition($userToken, $paperCheckToken, $statusTransitionToken) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }
        if (empty($statusTransitionToken)) {
            throw new HyperwalletArgumentException('statusTransitionToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions/{status-transition-token}', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken,
            'status-transition-token' => $statusTransitionToken
        ), array());
        return new PaperCheckStatusTransition($body);
    }

    /**
     * List all paper check status transitions
     *
     * @param string $userToken The user token
     * @param string $paperCheckToken The paper check token
     * @param array $options The query parameters
     * @return ListResponse
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function listPaperCheckStatusTransitions($userToken, $paperCheckToken, array $options = array()) {
        if (empty($userToken)) {
            throw new HyperwalletArgumentException('userToken is required!');
        }
        if (empty($paperCheckToken)) {
            throw new HyperwalletArgumentException('paperCheckToken is required!');
        }

        $body = $this->client->doGet('/rest/v3/users/{user-token}/paper-checks/{paper-check-token}/status-transitions', array(
            'user-token' => $userToken,
            'paper-check-token' => $paperCheckToken
        ), $options);
        return new ListResponse($body, function ($entry) {
            return new PaperCheckStatusTransition($entry);
        });
    }

    //--------------------------------------
    // Transfers
    //--------------------------------------

    /**
     * Create a transfer
     *
     * @param Transfer $transfer The transfer data
     * @return Transfer
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function createTransfer(Transfer $transfer) {
        if (empty($transfer->getSourceToken())) {
            throw new HyperwalletArgumentException('sourceToken is required!');
        }
        if (empty($transfer->getDestinationToken())) {
            throw new HyperwalletArgumentException('destinationToken is required!');
        }
        if (empty($transfer->getClientTransferId())) {
            throw new HyperwalletArgumentException('clientTransferId is required!');
        }
        $body = $this->client->doPost('/rest/v3/transfers', array(), $transfer, array());
        return new Transfer($body);
    }

    public function createTransferRefund($transferToken, $transferRefund) {
        if (empty($transferRefund)) {
            throw new HyperwalletArgumentException('transferRefund is required!');
        }
        if (empty($transferToken)) {
            throw new HyperwalletArgumentException('transferToken is required!');
        }
        if (empty($transferRefund->getClientRefundId())) {
            throw new HyperwalletArgumentException('clientRefundId is required!');
        }
        $body = $this->client->doPost('/rest/v3/transfers/{transfer-token}/refunds',
            array('transfer-token' => $transferToken), $transferRefund, array());
        return new TransferRefund($body);
    }

    /**
     * Get a transfer
     *
     * @param string $transferToken The transfer token
     * @return Transfer
     *
     * @throws HyperwalletArgumentException
     * @throws HyperwalletApiException
     */
    public function getTransfer($transferToken) {
        if (empty($transferToken)) {
            throw new HyperwalletArgumentException('transferToken is required!');
        }
{'fraction_non_alphanumeric': 0.12879290202393356, 'fraction_numerical': 0.000947238798901203, 'mean_word_length': 2.6035954033450905, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 123, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1761347', 'n_tokens_mistral': 8236, 'n_tokens_neox': 8069, 'n_words': 1929}