From b7de99ef0dae762732014de22cd9b3d8637f267a Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 8 Jun 2026 14:17:41 +0300 Subject: [PATCH 1/2] Fix dynamic transaction response properties --- src/Response/Models/BaseModel.php | 32 +++++++++++- src/Response/Models/TransactionModel.php | 9 ++++ tests/Response/Models/BaseModelTest.php | 18 +++++++ .../Response/Models/TransactionModelTest.php | 49 +++++++++++++++++++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 tests/Response/Models/TransactionModelTest.php diff --git a/src/Response/Models/BaseModel.php b/src/Response/Models/BaseModel.php index cde415e..1333874 100644 --- a/src/Response/Models/BaseModel.php +++ b/src/Response/Models/BaseModel.php @@ -9,13 +9,43 @@ */ class BaseModel { + /** @var array */ + private array $additionalProperties = []; + public function fill(stdClass $fillData): void { $props = get_object_vars($fillData); + $knownProperties = $this->getKnownProperties(); foreach ($props as $key => $value) { $lowerKey = lcfirst($key); - $this->{$lowerKey} = $value; + + if (isset($knownProperties[$lowerKey])) { + $this->{$lowerKey} = $value; + + continue; + } + + $this->additionalProperties[$lowerKey] = $value; } } + + /** + * @return array + */ + private function getKnownProperties(): array + { + $properties = get_class_vars(static::class); + unset($properties['additionalProperties']); + + return array_fill_keys(array_keys($properties), true); + } + + /** + * @return array + */ + public function getAdditionalProperties(): array + { + return $this->additionalProperties; + } } diff --git a/src/Response/Models/TransactionModel.php b/src/Response/Models/TransactionModel.php index f0d2bf6..bed5895 100644 --- a/src/Response/Models/TransactionModel.php +++ b/src/Response/Models/TransactionModel.php @@ -18,6 +18,7 @@ class TransactionModel extends BaseModel public ?int $paymentCurrencyCode = null; public ?string $invoiceId = null; public ?string $accountId = null; + public ?int $trInitiatorCode = null; public ?string $email = null; public ?string $description = null; public ?string $jsonData = null; @@ -69,7 +70,15 @@ class TransactionModel extends BaseModel public ?bool $applePay = null; public ?bool $androidPay = null; public ?bool $masterPass = null; + public ?string $walletType = null; public ?float $totalFee = null; + public ?float $vatAboveTotalFee = null; + public ?float $processorAndPartnerFee = null; + public ?float $vatWithinProcessorFee = null; + public mixed $infoShopData = null; + public mixed $receiver = null; + public mixed $splits = null; + public ?bool $transactionIsInProcess = null; public ?int $escrowAccumulationId = null; /** diff --git a/tests/Response/Models/BaseModelTest.php b/tests/Response/Models/BaseModelTest.php index 7c216c0..bdcad84 100644 --- a/tests/Response/Models/BaseModelTest.php +++ b/tests/Response/Models/BaseModelTest.php @@ -25,4 +25,22 @@ public function testFillBaseModel(): void $this->assertEquals($testObject->b, $model->b); $this->assertEquals($testObject->c, $model->c); } + + /** + * Проверяем, что неизвестные поля не становятся динамическими свойствами. + */ + public function testFillKeepsUnknownFieldsWithoutDynamicProperties(): void + { + $model = new TestModel(); + + $model->fill((object) [ + 'a' => 1, + 'b' => 2, + 'c' => 3, + 'UnknownField' => 'value', + ]); + + $this->assertSame('value', $model->getAdditionalProperties()['unknownField']); + $this->assertArrayNotHasKey('unknownField', get_object_vars($model)); + } } diff --git a/tests/Response/Models/TransactionModelTest.php b/tests/Response/Models/TransactionModelTest.php new file mode 100644 index 0000000..e794dde --- /dev/null +++ b/tests/Response/Models/TransactionModelTest.php @@ -0,0 +1,49 @@ + '1234567890']; + $splits = [ + (object) ['amount' => 10.50], + ]; + $infoShopData = (object) ['name' => 'Shop']; + + $transaction->fill((object) [ + 'TrInitiatorCode' => 0, + 'WalletType' => 'ApplePay', + 'VatAboveTotalFee' => 1.25, + 'ProcessorAndPartnerFee' => 2, + 'VatWithinProcessorFee' => 0.25, + 'InfoShopData' => $infoShopData, + 'Receiver' => $receiver, + 'Splits' => $splits, + 'TransactionIsInProcess' => true, + ]); + + $this->assertSame(0, $transaction->trInitiatorCode); + $this->assertSame('ApplePay', $transaction->walletType); + $this->assertSame(1.25, $transaction->vatAboveTotalFee); + $this->assertSame(2.0, $transaction->processorAndPartnerFee); + $this->assertSame(0.25, $transaction->vatWithinProcessorFee); + $this->assertSame($infoShopData, $transaction->infoShopData); + $this->assertSame($receiver, $transaction->receiver); + $this->assertSame($splits, $transaction->splits); + $this->assertTrue($transaction->transactionIsInProcess); + } +} From 708255476986f26834c2d4b562193124c2510ca5 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 8 Jun 2026 14:27:59 +0300 Subject: [PATCH 2/2] Add PHP 8.1-8.5 test matrix --- .github/workflows/tests.yml | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..bae428a --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,40 @@ +name: Tests + +on: + push: + pull_request: + +jobs: + phpunit: + name: PHPUnit (PHP ${{ matrix.php-version }}) + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: + - '8.1' + - '8.2' + - '8.3' + - '8.4' + - '8.5' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + tools: composer:v2 + + - name: Validate composer + run: composer validate --strict + + - name: Install dependencies + run: composer update --prefer-dist --no-progress --no-interaction + + - name: Run tests + run: composer test