From 31e7e2e77e8bb152ede4349e8f9b8fd178a8a168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 2 Jul 2026 07:55:42 +0300 Subject: [PATCH] =?UTF-8?q?feat(external):=20YooKassaLivenessProbe=20?= =?UTF-8?q?=E2=80=94=20=D0=B6=D0=B8=D0=B2=D0=BE=D1=81=D1=82=D1=8C=20=D0=BF?= =?UTF-8?q?=D0=BB=D0=B0=D1=82=D1=91=D0=B6=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=88?= =?UTF-8?q?=D0=BB=D1=8E=D0=B7=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../External/YooKassaLivenessProbe.php | 41 +++++++++++++++++++ app/config/services.php | 3 ++ .../External/YooKassaLivenessProbeTest.php | 38 +++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 app/app/Services/External/YooKassaLivenessProbe.php create mode 100644 app/tests/Unit/External/YooKassaLivenessProbeTest.php diff --git a/app/app/Services/External/YooKassaLivenessProbe.php b/app/app/Services/External/YooKassaLivenessProbe.php new file mode 100644 index 00000000..1e1c1ba5 --- /dev/null +++ b/app/app/Services/External/YooKassaLivenessProbe.php @@ -0,0 +1,41 @@ +timeout(5)->acceptJson()->get($url); + if ($resp->ok()) { + return LivenessReading::alive('yookassa', 'шлюз отвечает'); + } + + return LivenessReading::down('yookassa', 'HTTP '.$resp->status()); + } catch (\Throwable $e) { + return LivenessReading::down('yookassa', $e->getMessage()); + } + } +} diff --git a/app/config/services.php b/app/config/services.php index d68401af..6a12d5b6 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -116,6 +116,9 @@ return [ // опубликованными ЮKassa подсетями: 185.71.76.0/27,185.71.77.0/27,77.75.153.0/25, // 77.75.154.128/25,77.75.156.11,77.75.156.35,2a02:5180::/32. 'yookassa' => [ + 'shop_id' => env('YOOKASSA_SHOP_ID'), + 'secret_key' => env('YOOKASSA_SECRET_KEY'), + 'api_url' => env('YOOKASSA_API_URL', 'https://api.yookassa.ru/v3'), 'webhook_ip_allowlist' => array_values(array_filter(array_map( 'trim', explode(',', (string) env('YOOKASSA_WEBHOOK_IPS', '')), diff --git a/app/tests/Unit/External/YooKassaLivenessProbeTest.php b/app/tests/Unit/External/YooKassaLivenessProbeTest.php new file mode 100644 index 00000000..9a3b1d2e --- /dev/null +++ b/app/tests/Unit/External/YooKassaLivenessProbeTest.php @@ -0,0 +1,38 @@ +set('services.yookassa.shop_id', '1392092'); + config()->set('services.yookassa.secret_key', 'test_secret'); + config()->set('services.yookassa.api_url', 'https://api.yookassa.ru/v3'); +}); + +it('зелёный при 200 от /me', function () { + Http::fake(['api.yookassa.ru/v3/me' => Http::response(['account_id' => '1392092'], 200)]); + $r = (new YooKassaLivenessProbe)->check(); + expect($r->serviceKey)->toBe('yookassa'); + expect($r->light)->toBe('green'); +}); + +it('красный при 401', function () { + Http::fake(['api.yookassa.ru/v3/me' => Http::response(['type' => 'error'], 401)]); + expect((new YooKassaLivenessProbe)->check()->light)->toBe('red'); +}); + +it('серый, когда ключи не заданы', function () { + config()->set('services.yookassa.shop_id', ''); + config()->set('services.yookassa.secret_key', ''); + expect((new YooKassaLivenessProbe)->check()->light)->toBe('grey'); +}); + +it('красный при сетевой ошибке (проба не бросает)', function () { + Http::fake(fn () => throw new RuntimeException('network down')); + expect((new YooKassaLivenessProbe)->check()->light)->toBe('red'); +});