HEX
Server: Apache/2
System: Linux aws3 5.14.0-503.38.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Apr 18 08:52:10 EDT 2025 x86_64
User: hucscom (1018)
PHP: 8.1.32
Disabled: exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Upload Files
File: /home/hucscom/public_html/wp-content/plugins/payout-payment-gateway/lib/Payout/Client.php
<?php
/*
 * The MIT License
 *
 * Copyright (c) 2019 Payout, s.r.o. (https://payout.one/)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

namespace Payout;

use Exception;

/**
 * Class Client
 *
 * The Payout API Client PHP Library.
 * https://postman.payout.one/
 *
 * @package    Payout
 * @version    1.0.3
 * @copyright  2021 Payout, s.r.o.
 * @author     Neotrendy s. r. o.
 * @link       https://github.com/payout-one/payout_php
 */
class Client
{
    const LIB_VER = '1.0.3';
    const API_URL = 'https://app.payout.one/api/v1/';
    const API_URL_SANDBOX = 'https://sandbox.payout.one/api/v1/';

    /**
     * @var array $config API client configuration
     * @var string $token Obtained API access token
     * @var Connection $connection Connection instance
     */
    private $config, $token, $connection;

    /**
     * Construct the Payout API Client.
     *
     * @param array $config
     * @throws Exception
     */
    public function __construct(array $config = array())
    {
        if (!function_exists('curl_init')) {
            throw new Exception('Payout needs the CURL PHP extension.');
        }
        if (!function_exists('json_decode')) {
            throw new Exception('Payout needs the JSON PHP extension.');
        }

        $this->config = array_merge(
            [
                'client_id' => '',
                'client_secret' => '',
                'sandbox' => false
            ],
            $config
        );
    }

    /**
     * Get a string containing the version of the library.
     *
     * @return string
     */
    public function getLibraryVersion()
    {
        return self::LIB_VER;
    }

    /**
     * Get an instance of the HTTP connection object. Initializes
     * the connection if it is not already active.
     * Authorize connection and obtain access token.
     *
     * @return Connection
     * @throws Exception
     */
    private function connection()
    {
        if (!$this->connection) {
            $api_url = ($this->config['sandbox']) ? self::API_URL_SANDBOX : self::API_URL;
            $this->connection = new Connection($api_url);
            $this->token = $this->connection->authenticate('authorize', $this->config['client_id'], $this->config['client_secret']);
        }

        return $this->connection;
    }

    /**
     * Create signature as SHA256 hash of message.
     *
     * @param $message
     * @return string
     */
    private function getSignature($message)
    {
        $message = implode('|', $message);
        return hash('sha256', pack('A*', $message));
    }

    /**
     * Verify signature obtained in API response.
     *
     * @param array $message to be signed
     * @param string $signature from response
     * @return bool
     */
    public function verifySignature($message, $signature)
    {
        $message[] = $this->config['client_secret'];

        if (strcmp($this->getSignature($message), $signature) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Generate nonce string. In cryptography, a nonce is an arbitrary number
     * that can be used just once in a cryptographic communication.
     * https://en.wikipedia.org/wiki/Cryptographic_nonce
     *
     * @return string
     */
    private function generateNonce()
    {
        // TODO use more secure nonce https://secure.php.net/manual/en/function.random-bytes.php
        $bytes = openssl_random_pseudo_bytes(32);
        $hash = base64_encode($bytes);
        return $hash;
    }

    /**
     * Verify input data and create checkout and post signed data to API.
     *
     * @param array $data
     * @return mixed
     * @throws Exception
     */
    public function createCheckout($data)
    {
        $checkout = new Checkout();

        $prepared_checkout = $checkout->create($data);
        $idempotency_key = array_key_exists('idempotency_key', $data) ? $data['idempotency_key'] : null;

        $nonce = $this->generateNonce();
        $prepared_checkout['nonce'] = $nonce;

        $message = array($prepared_checkout['amount'], $prepared_checkout['currency'], $prepared_checkout['external_id'], $nonce, $this->config['client_secret']);
        $signature = $this->getSignature($message);
        $prepared_checkout['signature'] = $signature;

        $prepared_checkout = json_encode($prepared_checkout);

        $response = $this->connection()->post('checkouts', $prepared_checkout, $idempotency_key);

        if (!$this->verifySignature(array($response->amount, $response->currency, $response->external_id, $response->nonce), $response->signature)) {
            throw new Exception('Payout error: Invalid signature in API response.');
        }

        return $response;
    }

    /**
     * Get checkout details from API.
     *
     * @param integer $checkout_id
     * @return mixed
     * @throws Exception
     */
    public function getCheckout($checkout_id)
    {
        $url = 'checkouts/' . $checkout_id;
        $response = $this->connection()->get($url);

        if (!$this->verifySignature(array($response->amount, $response->currency, $response->external_id, $response->nonce), $response->signature)) {
            throw new Exception('Payout error: Invalid signature in API response.');
        }

        return $response;
    }


    public function createRefund($data, $log)
    {
        $refund = new Refund();

        $prepared_refund = $refund->create($data);

        $nonce = $this->generateNonce();
        $prepared_refund['nonce'] = $nonce;

        $message = array($prepared_refund['amount'], $prepared_refund['currency'], $prepared_refund['checkout_id'], $prepared_refund['iban'], $nonce, $this->config['client_secret']);
        $signature = $this->getSignature($message);
        $prepared_refund['signature'] = $signature;

        $prepared_refund['checkout_id'] = $prepared_refund['payout_id'];
        unset($prepared_refund['payout_id']);

        $prepared_refund = json_encode($prepared_refund);

        $response = $this->connection()->post('refunds', $prepared_refund, null);

        if (!$this->verifySignature(array($response->amount, $response->currency, $response->external_id, '', $response->nonce), $response->signature)) {
            throw new Exception('Payout error: Invalid signature in API response.');
        }

        if (!is_null($log)) {
            $log->write('Payout :: verifySignature Refund pass!');
        }

        return $response;
    }
}