File: //home/marketing.cfbon.ru/public_html/app/Services/IicoCardService.php
<?php
namespace App\Services;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
class IicoCardService
{
    private string $iicoCardHost;
    private string $iicoLogin;
    private string $iicoPassword;
    private string $iicoOrganizationId;
    private string $key = '';
    private string $programName = 'кофе_бон_бонусная';
    private $proxyToken = '7b84459332c6dbcd6cacce71c309eebcb45206c3b15eb9e053c33c97958b8851';
    private $proxyUrl = 'https://api.coffeebon.ru/appApi/v2.0/simple-proxy.php';
    function __construct(string $iicoCardHost, string $iicoLogin, string $iicoPassword, string $iicoOrganizationId)
    {
        $this->iicoCardHost = $iicoCardHost;
        $this->iicoLogin = $iicoLogin;
        $this->iicoPassword = $iicoPassword;
        $this->iicoOrganizationId = $iicoOrganizationId;
    }
    public function proxy(string $url, string $method, string $action, array $data = null): false|string
    {
        try {
            $response = Http::withToken($this->proxyToken)
                ->withHeaders(['Content-Type' => 'application/json'])
                ->withoutVerifying()
                ->send($method, $this->proxyUrl, [
                    'json' => [
                        'url' => $url,
                        'action' => $action,
                        'data' => $data,
                    ]
                ]);
            return $response->successful() ? $response->body() : false;
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }
    public function connect(): void
    {
        $url = "{$this->iicoCardHost}/auth/access_token?user_id={$this->iicoLogin}&user_secret={$this->iicoPassword}";
        try {
            $response = $this->proxy($url, 'get', 'access');
            $this->key = trim($response, '"');
            if (empty($this->key)) {
                throw new \Exception('Empty access token received');
            }
        } catch (RequestException $e) {
            throw new \Exception("Connection to IIKO CARD failed: " . $e->getMessage());
        } catch (ConnectionException $e) {
        }
    }
    public function clientInfoById($cardId) : ?object
    {
        $query = array(
            'access_token' => $this->key,
            'organization' => $this->iicoOrganizationId,
            'id' => $cardId
        );
        $url = $this->iicoCardHost . '/customers/get_customer_by_id?' . http_build_query($query);
        $reply = $this->proxy($url, 'GET', 'get_customer_by_id');
        if (!empty($reply)) return json_decode($reply);
        return null;
    }
    public function getWalletId(array $walletData): ?string
    {
        if (empty($walletData)) return null;
        foreach ($walletData as $wallet) {
            if ($wallet->wallet->name == $this->programName) return $wallet->wallet->id;
        }
        return null;
    }
    public function refillBonus(string $cardId, int $sum, string $message): void
    {
        $data = $this->clientInfoById($cardId);
        $walletId = $this->getWalletId($data->walletBalances);
        $url = $this->iicoCardHost . '/customers/refill_balance?access_token=' . $this->key;
        $data = [
            'customerId' => $cardId,
            'organizationId' => $this->iicoOrganizationId,
            'walletId' => $walletId,
            'sum' => $sum,
            'comment' => $message,
        ];
        $reply = $this->proxy($url, 'POST', 'refill_bonus', $data);
        if (!empty($reply)) throw new \Exception($reply);
    }
    public function withdrawBonus(string $cardId, int $sum, string $message): void
    {
        $data = $this->clientInfoById($cardId);
        $walletId = $this->getWalletId($data->walletBalances);
        $url = $this->iicoCardHost . '/customers/withdraw_balance?access_token=' . $this->key;
        $data = [
            'customerId' => $cardId,
            'organizationId' => $this->iicoOrganizationId,
            'walletId' => $walletId,
            'sum' => $sum,
            'comment' => $message,
        ];
        $reply = $this->proxy($url, 'POST', 'withdraw_bonus', $data);
        if (!empty($reply)) throw new \Exception($reply);
    }
}