From c526d4c08682770dc7ba2ee79ad7cb9f7963dac4 Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:29:28 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=85=D0=BE=D0=B4?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D1=82=202.3.2:=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D0=BD=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=B8=20=D1=81=D1=85=D0=B5=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - версия формата по умолчанию 2.3.2: APIVersion, AvailableAPIVersion, formatVersion создаваемых документов - FormatVersion::setDefault() задаёт версию для клиента и создаваемых документов, например 2.2.2 для банка, который поддерживает только 2.2.x; разобранные документы сохраняют версию из XML - в тестах схемы и официальные примеры 2.3.2, схемы 2.2.2 — в tests/Fixture/xsd/2.2.2; документы каждой версии проходят её схемы - DocKind::LETTER (40) Closes #22 --- src/Client.php | 8 +- src/Dictionary/DefaultValue.php | 2 +- src/Dictionary/DocKind.php | 5 +- src/Dictionary/DocStatus.php | 4 +- src/Dictionary/ErrorCode.php | 2 +- src/Dictionary/PacketStatus.php | 2 +- src/Dictionary/StatementType.php | 2 +- src/FormatVersion.php | 40 + src/Objects/CancelationRequest.php | 2 +- src/Objects/DefaultFormatVersion.php | 19 + src/Objects/DocumentType.php | 2 + src/Objects/Packet.php | 2 +- src/Objects/PayDocRu.php | 2 +- src/Objects/PayRequest.php | 2 +- src/Objects/Probe.php | 2 +- src/Objects/StatementRequest.php | 2 +- src/Objects/StatusRequest.php | 2 +- tests/ClientHttpTest.php | 10 +- tests/ClientSettingsTest.php | 4 +- tests/Dictionary/DictionaryTest.php | 6 +- tests/Fixture/xml/1c/CancelationRequest.xml | 8 +- tests/Fixture/xml/1c/PayDocRu.xml | 10 +- tests/Fixture/xml/1c/PayRequest.xml | 10 +- tests/Fixture/xml/1c/Probe.xml | 8 +- tests/Fixture/xml/1c/Settings.xml | 10 +- .../xml/1c/Settings_Logon_Certificate.xml | 10 +- tests/Fixture/xml/1c/Statement.xml | 14 +- tests/Fixture/xml/1c/StatementRequest.xml | 12 +- tests/Fixture/xml/1c/StatusDocNotice.xml | 6 +- tests/Fixture/xml/1c/StatusRequest.xml | 8 +- tests/Fixture/xml/1c/readme.md | 11 +- tests/Fixture/xsd/1C-Bank_AuthSign.xsd | 2 +- .../xsd/1C-Bank_CancelationRequest.xsd | 2 +- tests/Fixture/xsd/1C-Bank_Exch-Common.xsd | 25 +- tests/Fixture/xsd/1C-Bank_Letter.xsd | 164 +++ tests/Fixture/xsd/1C-Bank_Library.xsd | 3 +- tests/Fixture/xsd/1C-Bank_Packet.xsd | 44 +- tests/Fixture/xsd/1C-Bank_PayDocRu.xsd | 2 +- tests/Fixture/xsd/1C-Bank_PayRequest.xsd | 2 +- tests/Fixture/xsd/1C-Bank_Probe.xsd | 2 +- tests/Fixture/xsd/1C-Bank_ResultBank.xsd | 2 +- tests/Fixture/xsd/1C-Bank_Settings.xsd | 48 +- tests/Fixture/xsd/1C-Bank_Statement.xsd | 2 +- .../Fixture/xsd/1C-Bank_StatementRequest.xsd | 2 +- tests/Fixture/xsd/1C-Bank_StatusDocNotice.xsd | 2 +- .../xsd/1C-Bank_StatusPacketNotice.xsd | 2 +- tests/Fixture/xsd/1C-Bank_StatusRequest.xsd | 2 +- tests/Fixture/xsd/2.2.2/1C-Bank_AuthSign.xsd | 51 + .../xsd/2.2.2/1C-Bank_CancelationRequest.xsd | 58 + .../Fixture/xsd/2.2.2/1C-Bank_Exch-Common.xsd | 1061 ++++++++++++++ tests/Fixture/xsd/2.2.2/1C-Bank_Library.xsd | 17 + tests/Fixture/xsd/2.2.2/1C-Bank_Packet.xsd | 149 ++ tests/Fixture/xsd/2.2.2/1C-Bank_PayDocRu.xsd | 56 + .../Fixture/xsd/2.2.2/1C-Bank_PayRequest.xsd | 56 + tests/Fixture/xsd/2.2.2/1C-Bank_Probe.xsd | 51 + .../Fixture/xsd/2.2.2/1C-Bank_ResultBank.xsd | 191 +++ tests/Fixture/xsd/2.2.2/1C-Bank_Settings.xsd | 303 ++++ tests/Fixture/xsd/2.2.2/1C-Bank_Statement.xsd | 278 ++++ .../xsd/2.2.2/1C-Bank_StatementRequest.xsd | 85 ++ .../xsd/2.2.2/1C-Bank_StatusDocNotice.xsd | 61 + .../xsd/2.2.2/1C-Bank_StatusPacketNotice.xsd | 61 + .../xsd/2.2.2/1C-Bank_StatusRequest.xsd | 48 + tests/Fixture/xsd/2.2.2/camt.053.001.02.xsd | 1298 +++++++++++++++++ tests/Fixture/xsd/2.2.2/pain.001.001.03.xsd | 921 ++++++++++++ tests/Fixture/xsd/readme.md | 9 + tests/FormatVersionTest.php | 110 ++ tests/Objects/PacketTest.php | 2 +- tests/Objects/ServiceDocumentsTest.php | 12 +- tests/Objects/StatementTest.php | 4 +- 69 files changed, 5290 insertions(+), 125 deletions(-) create mode 100644 src/FormatVersion.php create mode 100644 src/Objects/DefaultFormatVersion.php create mode 100644 tests/Fixture/xsd/1C-Bank_Letter.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_AuthSign.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_CancelationRequest.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Exch-Common.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Library.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Packet.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_PayDocRu.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_PayRequest.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Probe.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_ResultBank.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Settings.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_Statement.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_StatementRequest.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_StatusDocNotice.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_StatusPacketNotice.xsd create mode 100644 tests/Fixture/xsd/2.2.2/1C-Bank_StatusRequest.xsd create mode 100644 tests/Fixture/xsd/2.2.2/camt.053.001.02.xsd create mode 100644 tests/Fixture/xsd/2.2.2/pain.001.001.03.xsd create mode 100644 tests/FormatVersionTest.php diff --git a/src/Client.php b/src/Client.php index dec61cc..602d209 100644 --- a/src/Client.php +++ b/src/Client.php @@ -30,9 +30,10 @@ class Client implements ClientInterface protected array $settings = [ 'customerId' => null, - 'apiVersion' => DefaultValue::FORMAT_VERSION, - // Максимальная версия API, которую поддерживает клиент (заголовок AvailableAPIVersion в Logon) - 'availableApiVersion' => DefaultValue::FORMAT_VERSION, + // Версия API обмена данными, по умолчанию FormatVersion::getDefault() + 'apiVersion' => null, + // Максимальная версия API, которую поддерживает клиент (заголовок AvailableAPIVersion) + 'availableApiVersion' => FormatVersion::LATEST, 'userAgent' => null, 'sessionId' => null, 'login' => null, @@ -43,6 +44,7 @@ class Client implements ClientInterface public function __construct(array $settings, private ?LoggerInterface $logger = null) { $this->settings = array_replace($this->settings, $settings); + $this->settings['apiVersion'] ??= FormatVersion::getDefault(); $this->validateSettings($this->settings); } diff --git a/src/Dictionary/DefaultValue.php b/src/Dictionary/DefaultValue.php index aeeea31..4cc59b5 100644 --- a/src/Dictionary/DefaultValue.php +++ b/src/Dictionary/DefaultValue.php @@ -6,7 +6,7 @@ class DefaultValue { - const FORMAT_VERSION = '2.2.2'; + const FORMAT_VERSION = '2.3.2'; //Формат отметки времени в GetPackList: dd.MM.yyyy HH:mm:ss const TIMESTAMP_FORMAT = 'd.m.Y H:i:s'; diff --git a/src/Dictionary/DocKind.php b/src/Dictionary/DocKind.php index f121812..c1815b6 100644 --- a/src/Dictionary/DocKind.php +++ b/src/Dictionary/DocKind.php @@ -7,7 +7,7 @@ /** * Коды видов электронных документов * - * @see https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md#ed + * @see https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md#ed */ class DocKind { @@ -65,6 +65,9 @@ class DocKind //Выписка по валютному счету (1С <-- Банк) const CURRENCY_STATEMENT = '35'; + //Письмо (1С <--> Банк), с версии 2.3.1 + const LETTER = '40'; + //Обязательные виды электронных документов const REQUIRED = [ self::STATUS_DOC_NOTICE, diff --git a/src/Dictionary/DocStatus.php b/src/Dictionary/DocStatus.php index 75a9a52..7606e2e 100644 --- a/src/Dictionary/DocStatus.php +++ b/src/Dictionary/DocStatus.php @@ -7,7 +7,7 @@ /** * Коды статусов электронных документов * - * @see https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md#status + * @see https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md#status */ class DocStatus { @@ -15,7 +15,7 @@ class DocStatus const ACCEPTED = '01'; //Исполнен: платежный документ исполнен банком const EXECUTED = '02'; - //Отклонен банком: платеж не удалось исполнить + //Отклонен банком: платеж не удалось исполнить, запрос не удалось выполнить const REJECTED = '03'; //Приостановлен: платежный документ отложен банком из-за недостатка средств на счете const SUSPENDED = '04'; diff --git a/src/Dictionary/ErrorCode.php b/src/Dictionary/ErrorCode.php index fffee40..bf008c7 100644 --- a/src/Dictionary/ErrorCode.php +++ b/src/Dictionary/ErrorCode.php @@ -7,7 +7,7 @@ /** * Коды ошибок банковского сервиса * - * @see https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md#errors + * @see https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md#errors */ class ErrorCode { diff --git a/src/Dictionary/PacketStatus.php b/src/Dictionary/PacketStatus.php index 737ede8..a21a88d 100644 --- a/src/Dictionary/PacketStatus.php +++ b/src/Dictionary/PacketStatus.php @@ -7,7 +7,7 @@ /** * Коды статусов транспортных контейнеров * - * @see https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md#packet + * @see https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md#packet */ class PacketStatus { diff --git a/src/Dictionary/StatementType.php b/src/Dictionary/StatementType.php index 713c381..05db067 100644 --- a/src/Dictionary/StatementType.php +++ b/src/Dictionary/StatementType.php @@ -7,7 +7,7 @@ /** * Типы выписок банка * - * @see https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md#statementType + * @see https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md#statementType */ class StatementType { diff --git a/src/FormatVersion.php b/src/FormatVersion.php new file mode 100644 index 0000000..469f913 --- /dev/null +++ b/src/FormatVersion.php @@ -0,0 +1,40 @@ +formatVersion = FormatVersion::getDefault(); + } +} diff --git a/src/Objects/DocumentType.php b/src/Objects/DocumentType.php index cea696f..69f2706 100644 --- a/src/Objects/DocumentType.php +++ b/src/Objects/DocumentType.php @@ -7,6 +7,8 @@ class DocumentType { + use DefaultFormatVersion; + /** * @xmlAttribute */ diff --git a/src/Objects/Packet.php b/src/Objects/Packet.php index 9ae8067..b0487cc 100644 --- a/src/Objects/Packet.php +++ b/src/Objects/Packet.php @@ -14,7 +14,7 @@ */ class Packet implements \Stringable { - use MappableTrait, ConvertibleTrait; + use MappableTrait, ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/src/Objects/PayDocRu.php b/src/Objects/PayDocRu.php index 7eee5c2..cf85d6f 100644 --- a/src/Objects/PayDocRu.php +++ b/src/Objects/PayDocRu.php @@ -16,7 +16,7 @@ */ class PayDocRu implements \Stringable { - use ConvertibleTrait; + use ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/src/Objects/PayRequest.php b/src/Objects/PayRequest.php index 46b1dcc..08de7e0 100644 --- a/src/Objects/PayRequest.php +++ b/src/Objects/PayRequest.php @@ -16,7 +16,7 @@ */ class PayRequest implements \Stringable { - use ConvertibleTrait; + use ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/src/Objects/Probe.php b/src/Objects/Probe.php index 999328e..5d3ff6e 100644 --- a/src/Objects/Probe.php +++ b/src/Objects/Probe.php @@ -14,7 +14,7 @@ */ class Probe implements \Stringable { - use ConvertibleTrait; + use ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/src/Objects/StatementRequest.php b/src/Objects/StatementRequest.php index 736cd0a..a1cc374 100644 --- a/src/Objects/StatementRequest.php +++ b/src/Objects/StatementRequest.php @@ -14,7 +14,7 @@ */ class StatementRequest implements \Stringable { - use ConvertibleTrait; + use ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/src/Objects/StatusRequest.php b/src/Objects/StatusRequest.php index 3699ea1..21f58eb 100644 --- a/src/Objects/StatusRequest.php +++ b/src/Objects/StatusRequest.php @@ -14,7 +14,7 @@ */ class StatusRequest implements \Stringable { - use ConvertibleTrait; + use ConvertibleTrait, DefaultFormatVersion; /** * @xmlAttribute diff --git a/tests/ClientHttpTest.php b/tests/ClientHttpTest.php index cd019dd..690edf2 100644 --- a/tests/ClientHttpTest.php +++ b/tests/ClientHttpTest.php @@ -80,7 +80,7 @@ public function testCreateSession() $this->assertSame('/API/v1/directbank/Logon', $request->getUri()->getPath()); $this->assertSame('Basic ' . base64_encode('user:secret'), $request->getHeaderLine('Authorization')); $this->assertSame('40702810000000000000', $request->getHeaderLine('customerid')); - $this->assertSame('2.2.2', $request->getHeaderLine('apiversion')); + $this->assertSame('2.3.2', $request->getHeaderLine('apiversion')); $this->assertFalse($request->hasHeader('sid')); } @@ -96,13 +96,13 @@ public function testHeaders() foreach ([$logon, $sendPack] as $request) { $this->assertSame('application/xml; charset=utf-8', $request->getHeaderLine('Content-Type')); $this->assertSame('40702810000000000000', $request->getHeaderLine('CustomerID')); - $this->assertSame('2.2.2', $request->getHeaderLine('APIVersion')); + $this->assertSame('2.3.2', $request->getHeaderLine('APIVersion')); $this->assertStringStartsWith('GuzzleHttp/', $request->getHeaderLine('User-Agent')); } // Logon: логин и пароль, доступная версия API, без SID $this->assertSame('Basic ' . base64_encode('user:secret'), $logon->getHeaderLine('Authorization')); - $this->assertSame('2.2.2', $logon->getHeaderLine('AvailableAPIVersion')); + $this->assertSame('2.3.2', $logon->getHeaderLine('AvailableAPIVersion')); $this->assertFalse($logon->hasHeader('SID')); // Запросы в рамках сессии: SID, без логина и пароля @@ -481,8 +481,8 @@ public function testGetSettings() $this->assertSame('761700021132', $request->getHeaderLine('Inn')); $this->assertSame('044525888', $request->getHeaderLine('Bic')); $this->assertSame('40802810200000099888', $request->getHeaderLine('Account')); - $this->assertSame('2.2.2', $request->getHeaderLine('APIVersion')); - $this->assertSame('2.2.2', $request->getHeaderLine('AvailableAPIVersion')); + $this->assertSame('2.3.2', $request->getHeaderLine('APIVersion')); + $this->assertSame('2.3.2', $request->getHeaderLine('AvailableAPIVersion')); $this->assertFalse($request->hasHeader('Authorization')); $this->assertSame('', (string) $request->getBody()); } diff --git a/tests/ClientSettingsTest.php b/tests/ClientSettingsTest.php index e040073..e4df44e 100644 --- a/tests/ClientSettingsTest.php +++ b/tests/ClientSettingsTest.php @@ -27,7 +27,9 @@ public function requiredSettingsProvider(): array $cases = []; foreach (['url', 'customerId', 'login', 'password', 'apiVersion'] as $key) { - $cases["$key missing"] = [$key, null]; + if ($key !== 'apiVersion') { + $cases["$key missing"] = [$key, null]; + } $cases["$key empty"] = [$key, '']; $cases["$key not string"] = [$key, 123]; } diff --git a/tests/Dictionary/DictionaryTest.php b/tests/Dictionary/DictionaryTest.php index db5d94e..61412a9 100644 --- a/tests/Dictionary/DictionaryTest.php +++ b/tests/Dictionary/DictionaryTest.php @@ -6,8 +6,8 @@ use PHPUnit\Framework\TestCase; /** - * Коды сверяются с классификаторами стандарта 2.2.2: - * https://github.com/1C-Company/DirectBank/blob/2.2.2/doc/common-section/tables.md + * Коды сверяются с классификаторами стандарта 2.3.2: + * https://github.com/1C-Company/DirectBank/blob/2.3.2/doc/common-section/tables.md */ final class DictionaryTest extends TestCase { @@ -25,7 +25,7 @@ public function testDocKind() '01', '02', '03', '04', '05', '06', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', - '30', '35', + '30', '35', '40', ], $codes); $this->assertSame(['02', '03', '05', '06'], DocKind::REQUIRED); diff --git a/tests/Fixture/xml/1c/CancelationRequest.xml b/tests/Fixture/xml/1c/CancelationRequest.xml index ed67fb4..66a381c 100644 --- a/tests/Fixture/xml/1c/CancelationRequest.xml +++ b/tests/Fixture/xml/1c/CancelationRequest.xml @@ -3,10 +3,10 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="e8caa148-82a3-446d-a10f-ff82ad514b7e" - formatVersion="2.2.1" - creationDate="2016-04-22T10:11:25" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.4.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T10:11:25" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + 05688096-0806-4ef0-af4c-572f75dbaf7c Описание причины отзыва diff --git a/tests/Fixture/xml/1c/PayDocRu.xml b/tests/Fixture/xml/1c/PayDocRu.xml index a33eee4..d384513 100644 --- a/tests/Fixture/xml/1c/PayDocRu.xml +++ b/tests/Fixture/xml/1c/PayDocRu.xml @@ -3,14 +3,14 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="05688096-0806-4ef0-af4c-572f75dbaf7c" - formatVersion="2.2.1" - creationDate="2016-04-22T09:38:51" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.4.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T09:38:51" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + 14 - 2016-04-22 + 2019-04-22 15 Торговый дом "Комплексный" diff --git a/tests/Fixture/xml/1c/PayRequest.xml b/tests/Fixture/xml/1c/PayRequest.xml index 5c535a1..f2cffaa 100644 --- a/tests/Fixture/xml/1c/PayRequest.xml +++ b/tests/Fixture/xml/1c/PayRequest.xml @@ -3,14 +3,14 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="a4d4c2ac-26dd-43ae-a98b-cb4cebdbd1db" - formatVersion="2.2.1" - creationDate="2016-04-22T09:50:09" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.4.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T09:50:09" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + 15 - 2016-04-22 + 2019-04-22 15 ООО "Канцтовары" diff --git a/tests/Fixture/xml/1c/Probe.xml b/tests/Fixture/xml/1c/Probe.xml index dcc12fc..97a0dc1 100644 --- a/tests/Fixture/xml/1c/Probe.xml +++ b/tests/Fixture/xml/1c/Probe.xml @@ -3,9 +3,9 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="eafa28b5-6600-424c-b0d3-3785274d570d" - formatVersion="2.2.1" - creationDate="2016-04-22T09:33:57" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.3.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T09:33:57" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + \ No newline at end of file diff --git a/tests/Fixture/xml/1c/Settings.xml b/tests/Fixture/xml/1c/Settings.xml index 1eabbe3..ef7b851 100644 --- a/tests/Fixture/xml/1c/Settings.xml +++ b/tests/Fixture/xml/1c/Settings.xml @@ -3,15 +3,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="EFD857B5-7FA8-4195-8666-2CCADBC3C8DE" - formatVersion="2.2.1" - creationDate="2016-04-22T09:38:51" + formatVersion="2.3.1" + creationDate="2019-04-22T09:38:51" userAgent="DemoBankService"> - + - 2806 + 82007cb2-dfd1-4193-b903-16cc9b7231c9 https://dbogate.demobank.ru/ - 2.2.1 + 2.3.1 UTF-8 diff --git a/tests/Fixture/xml/1c/Settings_Logon_Certificate.xml b/tests/Fixture/xml/1c/Settings_Logon_Certificate.xml index 9837961..53b3a22 100644 --- a/tests/Fixture/xml/1c/Settings_Logon_Certificate.xml +++ b/tests/Fixture/xml/1c/Settings_Logon_Certificate.xml @@ -3,15 +3,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="EFD857B5-7FA8-4195-8666-2CCADBC3C8DE" - formatVersion="2.2.1" - creationDate="2016-04-22T09:38:51" + formatVersion="2.3.1" + creationDate="2019-04-22T09:38:51" userAgent="DemoBankService"> - + - 2806 + 82007cb2-dfd1-4193-b903-16cc9b7231c9 https://dbogate.demobank.ru/ - 2.2.1 + 2.3.1 UTF-8 false diff --git a/tests/Fixture/xml/1c/Statement.xml b/tests/Fixture/xml/1c/Statement.xml index 16599c0..614136a 100644 --- a/tests/Fixture/xml/1c/Statement.xml +++ b/tests/Fixture/xml/1c/Statement.xml @@ -3,15 +3,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="f7cbc6af-33dd-4c37-b67d-7400e1c327ad" - formatVersion="2.2.1" - creationDate="2016-05-13T13:51:21.829" + formatVersion="2.3.1" + creationDate="2010-05-13T13:51:21.829" userAgent="DemoBankService"> 0 - 2016-05-04T00:00:00.000 - 2016-05-13T11:51:13.000 + 2019-05-04T00:00:00.000 + 2019-05-13T11:51:13.000 40702810500000000001 044525888 @@ -25,7 +25,7 @@ 768 - 2016-05-04 + 2019-05-04 14 Торговый дом Комплексный @@ -52,11 +52,11 @@ 5 - За транспортные услуги по счету № Ек2Тюм003221 от 18 Апреля 2016г. Сумма 2 999-00руб без НДС + За транспортные услуги по счету № Ек2Тюм003221 от 18 Апреля 2019г. Сумма 2 999-00руб без НДС 1 - 2016-05-04 + 2019-05-04 044525888 ДЕМО-БАНК diff --git a/tests/Fixture/xml/1c/StatementRequest.xml b/tests/Fixture/xml/1c/StatementRequest.xml index 91ff6cf..d43a439 100644 --- a/tests/Fixture/xml/1c/StatementRequest.xml +++ b/tests/Fixture/xml/1c/StatementRequest.xml @@ -3,15 +3,15 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="da06dc8f-afbe-4172-89c8-0d4492c2dd25" - formatVersion="2.2.1" - creationDate="2016-04-22T09:52:27" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.4.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T09:52:27" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + 0 - 2016-04-21T00:00:00 - 2016-04-21T23:59:59 + 2019-04-21T00:00:00 + 2019-04-21T23:59:59 40702810500000000001 044525888 diff --git a/tests/Fixture/xml/1c/StatusDocNotice.xml b/tests/Fixture/xml/1c/StatusDocNotice.xml index fe26382..e90a0fb 100644 --- a/tests/Fixture/xml/1c/StatusDocNotice.xml +++ b/tests/Fixture/xml/1c/StatusDocNotice.xml @@ -1,14 +1,14 @@ - + eafa28b5-6600-424c-b0d3-3785274d570d diff --git a/tests/Fixture/xml/1c/StatusRequest.xml b/tests/Fixture/xml/1c/StatusRequest.xml index 023f91f..22e2841 100644 --- a/tests/Fixture/xml/1c/StatusRequest.xml +++ b/tests/Fixture/xml/1c/StatusRequest.xml @@ -3,10 +3,10 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="0fa540c3-1aaa-4e06-8883-2c936fef05a5" - formatVersion="2.2.1" - creationDate="2016-04-22T10:09:11" - userAgent="1С - БЭД: 1.4.1.1; БиблиотекаЭлектронныхДокументов: 1.4.1.1"> - + formatVersion="2.3.1" + creationDate="2019-04-22T10:09:11" + userAgent="1С - БЭД: 1.7.1.1; БиблиотекаЭлектронныхДокументов: 1.7.1.1"> + 05688096-0806-4ef0-af4c-572f75dbaf7c \ No newline at end of file diff --git a/tests/Fixture/xml/1c/readme.md b/tests/Fixture/xml/1c/readme.md index 1bea9d2..e65ca26 100644 --- a/tests/Fixture/xml/1c/readme.md +++ b/tests/Fixture/xml/1c/readme.md @@ -1,11 +1,10 @@ # Примеры 1С -Официальные примеры из описания стандарта 1С:DirectBank, версия 2.2.2. -Файлы скопированы без изменений. +Официальные примеры из описания стандарта 1С:DirectBank. Файлы скопированы без изменений. -- Электронные документы — : +- Электронные документы, версия 2.3.2 — : `CancelationRequest.xml`, `PayDocRu.xml`, `PayRequest.xml`, `Probe.xml`, `Settings.xml`, `Settings_Logon_Certificate.xml`, `Statement.xml`, `StatementRequest.xml`, `StatusDocNotice.xml`, `StatusRequest.xml` -- `GetSettingsResponse.xml` — пример ответа на GetSettings из -- `Packet.xml` — пример запроса SendPack из . - Подпись в примере обрезана и не является корректным base64, поэтому XSD файл не проходит. +- Из описания транспортного протокола, версия 2.2.2 — : + - `GetSettingsResponse.xml` — пример ответа на GetSettings + - `Packet.xml` — пример запроса SendPack. Подпись в примере обрезана и не является корректным base64, поэтому XSD файл не проходит. diff --git a/tests/Fixture/xsd/1C-Bank_AuthSign.xsd b/tests/Fixture/xsd/1C-Bank_AuthSign.xsd index 42fff02..7d96e77 100644 --- a/tests/Fixture/xsd/1C-Bank_AuthSign.xsd +++ b/tests/Fixture/xsd/1C-Bank_AuthSign.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_CancelationRequest.xsd b/tests/Fixture/xsd/1C-Bank_CancelationRequest.xsd index aed92a6..d8e35b1 100644 --- a/tests/Fixture/xsd/1C-Bank_CancelationRequest.xsd +++ b/tests/Fixture/xsd/1C-Bank_CancelationRequest.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_Exch-Common.xsd b/tests/Fixture/xsd/1C-Bank_Exch-Common.xsd index 6c868c7..b45fc4a 100644 --- a/tests/Fixture/xsd/1C-Bank_Exch-Common.xsd +++ b/tests/Fixture/xsd/1C-Bank_Exch-Common.xsd @@ -1,6 +1,5 @@ - - + *************************************************************************************************************** @@ -375,6 +374,28 @@ + + + Электронная подпись + + + + + Электронная подпись + + + + + + Имя издателя сертификата открытого ключа ЭП (значение атрибута "CN"). + + + + + Серийный номер сертификата открытого ключа ЭП + + + Данные платежного поручения diff --git a/tests/Fixture/xsd/1C-Bank_Letter.xsd b/tests/Fixture/xsd/1C-Bank_Letter.xsd new file mode 100644 index 0000000..341e926 --- /dev/null +++ b/tests/Fixture/xsd/1C-Bank_Letter.xsd @@ -0,0 +1,164 @@ + + + + + + Письмо + + + + + + + Отправитель + + + + + Получатель + + + + + Данные письма + + + + + + Номер документа + + + + + Дата составления + + + + + Код типа письма + + + + + + + + + + Тема письма + + + + + + + + + + Текст письма + + + + + Вложение + + + + + + Двоичные данные файла + + + + + + + Уникальный идентификатор вложения + + + + + Полное имя файла с расширением + + + + + + + + + + + Расширение имени файла + + + + + + + + + + Размер файла в байтах + + + + + Контрольная сумма файла (алгоритм CRC32) + + + + + Дата создания + + + + + + + + + Данные электронных подписей + + + + + + + + Объект обсуждения. Например, платежное поручение или требование. + + + + + Идентификатор документа + + + + + Код вида электронного документа, как он задан в описаниии к стандарту + + + + + + + + ID изначального письма + + + + + ID переписки + + + + + + + + + + + diff --git a/tests/Fixture/xsd/1C-Bank_Library.xsd b/tests/Fixture/xsd/1C-Bank_Library.xsd index 980340c..e3a564c 100644 --- a/tests/Fixture/xsd/1C-Bank_Library.xsd +++ b/tests/Fixture/xsd/1C-Bank_Library.xsd @@ -1,5 +1,5 @@ - + @@ -14,4 +14,5 @@ + diff --git a/tests/Fixture/xsd/1C-Bank_Packet.xsd b/tests/Fixture/xsd/1C-Bank_Packet.xsd index 0ef73c6..fe619d5 100644 --- a/tests/Fixture/xsd/1C-Bank_Packet.xsd +++ b/tests/Fixture/xsd/1C-Bank_Packet.xsd @@ -1,5 +1,6 @@ - + + @@ -19,6 +20,26 @@ Электронный документ + + + + + + + + + + + + + + + + + + + + @@ -64,29 +85,10 @@ - + Данные электронных подписей - - - - - Электронная подпись - - - - - - Имя издателя сертификата открытого ключа ЭП (значение атрибута "CN"). - - - - - Серийный номер сертификата открытого ключа ЭП - - - diff --git a/tests/Fixture/xsd/1C-Bank_PayDocRu.xsd b/tests/Fixture/xsd/1C-Bank_PayDocRu.xsd index b49b9dc..26e2e23 100644 --- a/tests/Fixture/xsd/1C-Bank_PayDocRu.xsd +++ b/tests/Fixture/xsd/1C-Bank_PayDocRu.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_PayRequest.xsd b/tests/Fixture/xsd/1C-Bank_PayRequest.xsd index 66f3154..d487fd9 100644 --- a/tests/Fixture/xsd/1C-Bank_PayRequest.xsd +++ b/tests/Fixture/xsd/1C-Bank_PayRequest.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_Probe.xsd b/tests/Fixture/xsd/1C-Bank_Probe.xsd index abc5664..6b026f3 100644 --- a/tests/Fixture/xsd/1C-Bank_Probe.xsd +++ b/tests/Fixture/xsd/1C-Bank_Probe.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_ResultBank.xsd b/tests/Fixture/xsd/1C-Bank_ResultBank.xsd index fd4f05f..fc2d01e 100644 --- a/tests/Fixture/xsd/1C-Bank_ResultBank.xsd +++ b/tests/Fixture/xsd/1C-Bank_ResultBank.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_Settings.xsd b/tests/Fixture/xsd/1C-Bank_Settings.xsd index dc4f482..decc370 100644 --- a/tests/Fixture/xsd/1C-Bank_Settings.xsd +++ b/tests/Fixture/xsd/1C-Bank_Settings.xsd @@ -1,5 +1,5 @@ - + @@ -275,6 +275,52 @@ + + + Свойства писем + + + + + + Максимальный суммартный объем присоединенных файлов (в байтах) + + + + + + + + Возможные типы писем + + + + + + Код типа письма + + + + + + + + + + Наименование письма + + + + + + + + + + + + + diff --git a/tests/Fixture/xsd/1C-Bank_Statement.xsd b/tests/Fixture/xsd/1C-Bank_Statement.xsd index c831ca1..207cc52 100644 --- a/tests/Fixture/xsd/1C-Bank_Statement.xsd +++ b/tests/Fixture/xsd/1C-Bank_Statement.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_StatementRequest.xsd b/tests/Fixture/xsd/1C-Bank_StatementRequest.xsd index dec8d06..26f2dde 100644 --- a/tests/Fixture/xsd/1C-Bank_StatementRequest.xsd +++ b/tests/Fixture/xsd/1C-Bank_StatementRequest.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_StatusDocNotice.xsd b/tests/Fixture/xsd/1C-Bank_StatusDocNotice.xsd index 0f902f6..8a1e30a 100644 --- a/tests/Fixture/xsd/1C-Bank_StatusDocNotice.xsd +++ b/tests/Fixture/xsd/1C-Bank_StatusDocNotice.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_StatusPacketNotice.xsd b/tests/Fixture/xsd/1C-Bank_StatusPacketNotice.xsd index c275df8..9deb110 100644 --- a/tests/Fixture/xsd/1C-Bank_StatusPacketNotice.xsd +++ b/tests/Fixture/xsd/1C-Bank_StatusPacketNotice.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/1C-Bank_StatusRequest.xsd b/tests/Fixture/xsd/1C-Bank_StatusRequest.xsd index 4367bdc..519c533 100644 --- a/tests/Fixture/xsd/1C-Bank_StatusRequest.xsd +++ b/tests/Fixture/xsd/1C-Bank_StatusRequest.xsd @@ -1,5 +1,5 @@ - + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_AuthSign.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_AuthSign.xsd new file mode 100644 index 0000000..42fff02 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_AuthSign.xsd @@ -0,0 +1,51 @@ + + + + + + Описание набора данных по сертификату + + + + + Описание набора данных по сертификату + + + + + Имя издателя сертификата электронной подписи (значение атрибута"CN"). + + + + + Серийный номер сертификата электронной подписи + + + + + Двоичные данные сертификата электронной подписи + + + + + + Идентификатор набора данных + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_CancelationRequest.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_CancelationRequest.xsd new file mode 100644 index 0000000..aed92a6 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_CancelationRequest.xsd @@ -0,0 +1,58 @@ + + + + + + Запрос об отзыве электронного документа + + + + + + + Отправитель + + + + + Получатель + + + + + ID исходного электронного документа, который требуется отозвать + + + + + Причина, основание отзыва электронного документа + + + + + Дайджест запроса + + + + + + Идентификатор запроса + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Exch-Common.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Exch-Common.xsd new file mode 100644 index 0000000..6c868c7 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Exch-Common.xsd @@ -0,0 +1,1061 @@ + + + + + *************************************************************************************************************** + + + + Реквизиты банка + + + + + БИК банка + + + + + + + + + + + Название банка + + + + + + + + + + Город (неселенный пункт) банка + + + + + + + + + + Коррсчет банка + + + + + + + Реквизиты налогоплательщика + + + + + Наименование налогоплательщика + + + + + Идентификационный номера налогоплательщика (ИНН) + + + + + Для платежей в бюджет - указывать обязательно + + + + + + + + + + + Расчетный счет клиента в его банке, независимо от того, прямые расчеты у этого банка или нет. +Номер счета может не указываться в следующих случаях: +в распоряжении, если получателем средств является кредитная организация, филиал кредитной организации, в том числе в целях выдачи наличных денежных средств получателю средств - физическому лицу без открытия банковского счета; +в платежном поручении на общую сумму с реестром, в котором указаны получатели средств, обслуживаемые одним банком, составляемом плательщиком; +в платежном поручении на общую сумму с реестром, в котором указаны плательщики, обслуживаемые одним банком, и получатели средств, обслуживаемые другим банком, составляемом банком плательщика + + + + + Реквизиты банка + + + + + + + Реквизиты прочих налогоплательщиков + + + + + Наименование налогоплательщика + + + + + Идентификационный номера налогоплательщика (ИНН) + + + + + Для платежей в бюджет - указывать обязательно + + + + + + + + + + + Расчетный счет клиента в его банке, независимо от того, прямые расчеты у этого банка или нет + + + + + Реквизиты банка + + + + + + + Данные платежного документа + + + + + Номер документа (поле 3). + + + + + Дата составления (поле 4). + + + + + Сумма документа (поле 7). + + + + + Плательщик +(поля 8, 9, 10, 11, 12, 60, 102). + + + + + Получатель +(поля 13, 14, 15, 16, 17, 61, 103). + + + + + Вид платежа (поле 5). Указывается "срочно", "телеграфом", "почтой", иное значение в порядке, установленном банком. + + + + + + + + + + Вид операции (поле 18). Указывается условное цифровое обозначение документа, согласно установленного ЦБР перечня условных обозначений (шифров) документов, проводимых по счетам в кредитных организациях. + + + + + + + + + + Очередность платежа (поле 21). + + + + + + + + + + Уникальный идентификатор платежа (поле 22). +С 31 марта 2014 года согласно Указанию N 3025-У ЦБР. + + + + + + + + + + Код вида дохода (поле 20) согласно Указанию 5286-У ЦБРФ + + + + + + + + + + Назначение платежа (поле 24). + + + + + + + + + + + + Реквизиты иных банковских документов + + + + + Номер документа + + + + + Дата составления + + + + + Сумма документа + + + + + Плательщик + + + + + Получатель + + + + + Вид операции + + + + + + + + + + Уникальный идентификатор платежа + + + + + + + + + + Назначение + + + + + + + + + + Реквизиты бюджетного документа. См.правила заполнения платежных поручений, утвержденные приказом Минфина России от 12 ноября 2013 года № 107н. + + + + + Статус составителя (поле 101). + + + + + + + + + + + Код бюджетной классификации (КБК) в соответствии с классификацией доходов бюджетов РФ (поле 104). + + + + + + + + + + Значение кода ОКТМО муниципального образования или 0 (ноль) (поле 105). + + + + + + + + + + + Основание налогового платежа или 0 (ноль) (поле 106). + + + + + + + + + + + Налоговый период или 0 (ноль) / код таможенного органа (поле 107). + + + + + + + + + + + Номер налогового документа (поле 108). + + + + + + + + + + Дата налогового документа или 0 (ноль) (поле 109). + + + + + + + + + + + Код выплат (поле 110). + + + + + + + + + + + + + Данные платежного поручения + + + + + + + Реквизиты бюджетного документа. См.правила заполнения платежных поручений, утвержденные приказом Минфина России от 12 ноября 2013 года № 107н. + + + + + + + + + Данные платежного требования + + + + + + + Условие оплаты (поле 35): +1 - заранее данный акцепт плательщика; +2 - требуется получение акцепта плательщика. + + + + + + + + + + Срок для акцепта (поле 36): количество дней. + + + + + Дата отсылки (вручения) плательщику предусмотренных договором документов (поле 37). + + + + + + + + + Данные инкассового поручения + + + + + + + Реквизиты бюджетного документа. См.правила заполнения платежных поручений, утвержденные приказом Минфина России от 12 ноября 2013 года № 107н. + + + + + + + + + Данные платежного ордера + + + + + + + Содержание операции (поле 70). + + + + + + + + + + Номер частичного платежа (поле 38). + + + + + + + + + + Шифр платежного документа (поле 39). + + + + + + + + + + Сумма остатка платежа (поле 42). + + + + + Номер платежного документа (поле 40). + + + + + + + + + + Дата платежного документа (поле 41). + + + + + Реквизиты бюджетного документа. См.правила заполнения платежных поручений, утвержденные приказом Минфина России от 12 ноября 2013 года № 107н. + + + + + + + + + Данные банковского ордера + + + + + + + + Данные мемориального ордера + + + + + Номер документа (поле 3). + + + + + Дата составления (поле 4). + + + + + Свободное поле (поле 5) + + + + + Составитель (поле 6). + + + + + + + + Отделение банка + + + + + + + + + + + + + + + Наименование счета по дебету (поле 7) + + + + + Счет по дебету (поле 8) + + + + + + + + + + + Сумма документа (поле 9). + + + + + Свободное поле (поле 9a) + + + + + Наименование счета по кредиту (поле 10) + + + + + Счет по кредиту (поле 11) + + + + + + + + + + + Шифр документа (поле 13). + + + + + + + + + + Свободное поле (поле 14) + + + + + Свободное поле (поле 15) + + + + + Содержание операции (поле 16). + + + + + Свободное поле (поле 20) + + + + + + + Данные объявления на взнос наличными + + + + + + + От кого + + + + + + ФИО вносителя + + + + + + + + + + Документ, удостоверяющий личность + + + + + + + + + + + + + Указываются цифрами символы, предусмотренные отчетностью по форме 0409202, в соответствии с Указанием Банка России N 2332-У + + + + + + + + + + Указываются источники поступления наличных денег в соответствии с содержанием символов отчетности по форме 0409202 и содержанием операции + + + + + + + + + + + + + + Данные денежного чека + + + + + + + Кому + + + + + + ФИО получателя + + + + + + + + + + Документ, удостоверяющий личность + + + + + + + + + + + + + Данные бумажной формы чека + + + + + + Серия чека + + + + + + + + + + Номер чека + + + + + + + + + + + + + Направления и суммы выдачи + + + + + + Указываются цифрами символы, предусмотренные отчетностью по форме 0409202, в соответствии с Указанием Банка России N 2332-У + + + + + + + + + + Указываются направления (цели) выдачи наличных денег в соответствии с содержанием символов отчетности по форме 0409202 и содержанием операции + + + + + + + + + + Сумма расходов + + + + + + + + + + + *************************************************************************************************************** + + + + Одна из сторон, принимающая участие в обмене электронными документами (Участник) + + + + + Клиент + + + + + Банк + + + + + + + + Идентификатор клиента, как он задан на стороне банка + + + + + Наименование клиента + + + + + + + + + + ИНН клиента + + + + + + + + + + + КПП клиента + + + + + + + + + + + + БИК банка + + + + + + + + + + Название банка + + + + + + + + + + + + + Код ошибки, как он задан в описании к стандарту + + + + + + + + + + Описание ошибки, как оно задано в описании к стандарту + + + + + + + + + + Подробное пояснение к ошибке для пользователя + + + + + + + + + Код статуса, как он задан в описанию к стандарту + + + + + + + + + + Наименование статуса на стороне банка + + + + + + + + + + Дополнительная информация к статусу + + + + + + + + + Ответ в случае возникновения ошибки + + + + + Успешный ответ + + + + + + + + + Данные дайджеста в base64 + + + + + + + Версия алгоритма формирования дайджеста + + + + + + + + + + *************************************************************************************************************** + + + + Номер счета (расчетного, корреспондентского). + + + + + + + + + Сумма в документе + + + + + + + + + Дата строкой в формате ДД.ММ.ГГГГ + + + + + + Тип выписки банка + + + + + + Окончательная выписка + + + + + Промежуточная выписка + + + + + Текущий остаток на счете + + + + + + *************************************************************************************************************** + + + + Вид электронного документа + + + + + + + + Уникальный идентификатор + + + + + + Версия формата + + + + + + + + Версия ПО + + + + + + + + Уникальный идентификатор клиента в банке + + + + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Library.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Library.xsd new file mode 100644 index 0000000..980340c --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Library.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Packet.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Packet.xsd new file mode 100644 index 0000000..0ef73c6 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Packet.xsd @@ -0,0 +1,149 @@ + + + + + + + + + Отправитель + + + + + Получатель + + + + + Электронный документ + + + + + + Идентификатор транспортного контейнера + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + + + + + Данные электронного документа + + + + + + + Имя файла + + + + + Тип контента передаваемого файла + + + + + + + + + Данные электронных подписей + + + + + + Электронная подпись + + + + + + Имя издателя сертификата открытого ключа ЭП (значение атрибута "CN"). + + + + + Серийный номер сертификата открытого ключа ЭП + + + + + + + + Идентификатор электронного документа + + + + + Код вида электронного документа, как он задан в описаниии к стандарту + + + + + Версия формата + + + + + Тестовый документ + + + + + Документ сжат + + + + + Документ зашифрован + + + + + Требуется Ответная Подпись + + + + + Требуется Извещение О Получении + + + + + ID исходного документа, если такой был + + + + + *************************************************************************************************************** + + + + + + + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_PayDocRu.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_PayDocRu.xsd new file mode 100644 index 0000000..b49b9dc --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_PayDocRu.xsd @@ -0,0 +1,56 @@ + + + + + + Платежное поручение + + + + + Платежное поручение + + + + + Отправитель + + + + + Получатель + + + + + Данные платежного поручения + + + + + Дайджест электронного документа + + + + + + Идентификатор платежа + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_PayRequest.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_PayRequest.xsd new file mode 100644 index 0000000..66f3154 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_PayRequest.xsd @@ -0,0 +1,56 @@ + + + + + + Платежное требование + + + + + Платежное требование + + + + + Отправитель + + + + + Получатель + + + + + Данные платежного требования + + + + + Дайджест электронного документа + + + + + + Идентификатор требования + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Probe.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Probe.xsd new file mode 100644 index 0000000..abc5664 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Probe.xsd @@ -0,0 +1,51 @@ + + + + + + Запрос-зонд + + + + + Запрос-зонд + + + + + Отправитель + + + + + Получатель + + + + + Дайджест электронного документа + + + + + + Идентификатор запроса + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_ResultBank.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_ResultBank.xsd new file mode 100644 index 0000000..fd4f05f --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_ResultBank.xsd @@ -0,0 +1,191 @@ + + + + + + + + + + Успешный ответ банка + + + + + Ответ банка в случае возникновения ошибки + + + + + + Версия формата + + + + + Наименование и версия программы + + + + + + + + Отправка транспортного контейнера в банк + + + + + Список ID транспортных контейнеров, готовых к передачи клиенту + + + + + Транспортный контейнер с данными электронных документов для получения клиентом + + + + + Аутентификация по логину + ОТР (опционально) + + + + + Аутентификация по сертификату + + + + + Получение настроек обмена в автоматическом режиме + + + + + + + + + + + + + + Идентификатор транспортного контейнера (GUID), который был ему назначен на стороне банка + + + + + + + + + Идентификатор сессии + + + + + Дополнительная аутентификация. Указывается, если требуется доп. аутентфикация + + + + + + Параметры доп.аутентификации, которые будут направляны клиенту + + + + + Маска телефона или номер клиента + + + + + + + + + + Короткий код сессии, который будет показан при вводе OTP + + + + + + + + + + + + + + + + + + + Идентификатор транспортного контейнера (GUID), по которому его можно получить клиенту + + + + + + Метка времени, на которую вернули всю актуальную информацию + + + + + + + + Зашифрованный Идентификатор сессии + + + + + + + + + + + + + + Настройки обмена с банком + + + + + + + Код вида электронного документа, как он задан в описаниии к стандарту + + + + + + + + + + Идентификатор настроек + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Settings.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Settings.xsd new file mode 100644 index 0000000..dc4f482 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Settings.xsd @@ -0,0 +1,303 @@ + + + + + + Настройки обмена клиента с банком + + + + + Настройки обмена клиента с банком + + + + + Отправитель + + + + + Получатель + + + + + Параметры обмена + + + + + + Уникальный идентификатор организации в банке + + + + + Адрес ресурса банка + + + + + + + + + + Актуальная версия формата обмена данными + + + + + Кодировка файлов обмена + + + + + + + + + + Признак сжатия электронных документов при обмене + + + + + Способ аутентификации на ресурсе банка + + + + + + По логину и паролю + + + + + + Логин пользователя + + + + + + + + + + + + + По сертификату электронной подписи + + + + + + Алгоритм шифрования, например, GOST 28147-89 + + + + + + + + + + + + + + + + Настройки криптографии + + + + + + Имя CSP (cryptographic service provider) + + + + + + + + + + Тип CSP (cryptographic service provider) + + + + + Алгоритм подписи, например, GOST R 34.10-2001 + + + + + + + + + + Алгоритм хэширования, например, GOST R 34.11-94 + + + + + + + + + + + Применение шифрования данных на прикладном уровне + + + + + + Алгоритм шифрования, например, GOST 28147-89 + + + + + + + + + + + + + + Доверенный корневой сертификат УЦ банка + + + + + Сертификат электронной подписи банка + + + + + Карточка электронных подписей клиента + + + + + + Группа электронных подписей + + + + + + Сертификаты электронных подписей сотрудников клиента + + + + + + Номер группы электронных подписей + + + + + + + + + + + + + Адрес-ссылка, откуда надо будет загружаться файл описания внешн.модуля, если он используется в обмене + + + + + + + + Настройки по видам электронных документов, которыми возможен обмен с банком + + + + + + Применение электронной подписи для данного вида электронного документа + + + + + + Правило, задающее наличие электронных подписей для данного вида электронного документа + + + + + + + + + + + + Код вида электронного документа, как он задан в описании к стандарту + + + + + + + Параметры получения выписки в автоматическом режиме + + + + + + Логин, по которому можно получать только выписку банка + + + + + + + + + + Инструкция по получению пароля для вышеуказанного логина + + + + + + + + + + + + Идентификатор набора данных + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_Statement.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_Statement.xsd new file mode 100644 index 0000000..c831ca1 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_Statement.xsd @@ -0,0 +1,278 @@ + + + + + + Выписка банка по лицевому счету + + + + + Выписка банка по лицевому счету + + + + + Отправитель + + + + + Получатель + + + + + Данные выписки по лиц.счету + + + + + + Тип выписки + + + + + Начало периода выписки + + + + + Конец периода выписки + + + + + Номер лиц.счета + + + + + Банк, в котором открыт счет + + + + + Остаток на счете на начало периода + + + + + Общая сумма документов по дебету счета + + + + + Общая сумма документов по кредиту счета + + + + + Остаток на счете на конец периода + + + + + Информация об одной операции по лицевому счету в выписке + + + + + + Данные платежного документа + + + + + + Данные платежного поручения + + + + + Данные платежного требования + + + + + Данные инкассового поручения + + + + + Данные платежного ордера + + + + + Данные банковского ордера + + + + + Данные мемориального ордера + + + + + Данные внутр.банковского документа + + + + + + + + Название типа внутр.банковского документа + + + + + + + + + + + + + + + Данные объявления на взнос наличными + + + + + Данные денежного чека + + + + + + ID платежного документа в банке + + + + + Код вида электронного документа, как он задан в описании к стандарту + + + + + + + Признак дебета/кредита: +1 - дебет, 2 - кредит + + + + + + + Операция по дебету + + + + + Операция по кредиту + + + + + + + + Дата проводки документа по лиц.счету + + + + + ID исходного платежного документа плательщика + + + + + Данные штампа банка по каждому платежному документу + + + + + + + + Отделение банка + + + + + + + + + + Статус платежного документа в банке + + + + + + + + + + + + + Данные штампа банка по выписке в целом + + + + + + + + Отделение банка + + + + + + + + + + + + + + + + + + ID исходного запроса на выписку, если такой был + + + + + + Идентификатор выписки + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_StatementRequest.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_StatementRequest.xsd new file mode 100644 index 0000000..dec8d06 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_StatementRequest.xsd @@ -0,0 +1,85 @@ + + + + + + Запрос выписки банка + + + + + Запрос выписки банка + + + + + Отправитель + + + + + Получатель + + + + + Данные запроса + + + + + + Тип выписки + + + + + Начало периода формирования выписки + + + + + Конец периода формирования выписки + + + + + Номер счета, по которому производится запрос + + + + + Банк, в котором открыт счет + + + + + + + + Дайджест запроса + + + + + + Идентификатор запроса + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_StatusDocNotice.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusDocNotice.xsd new file mode 100644 index 0000000..0f902f6 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusDocNotice.xsd @@ -0,0 +1,61 @@ + + + + + + Извещение о состоянии электронного документа + + + + + Извещение о состоянии электронного документа + + + + + Отправитель + + + + + Получатель + + + + + ID исходного электронного документа, по которому возвращается состояния + + + + + Состояние электронного документа + + + + + ID запроса о состоянии электронного документа, если был такой + + + + + + Идентификатор извещения + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_StatusPacketNotice.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusPacketNotice.xsd new file mode 100644 index 0000000..c275df8 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusPacketNotice.xsd @@ -0,0 +1,61 @@ + + + + + + Извещение о состоянии транспортного контейнера + + + + + Извещение о состоянии транспортного контейнера + + + + + Отправитель + + + + + Получатель + + + + + ID, который сервис вернул в ответ после получения транспортного контейнера + + + + + Состояние транспортного контейнера + + + + + ID исходного транспортного контейнера, по которому возвращается состояния + + + + + + Идентификатор извещения + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/1C-Bank_StatusRequest.xsd b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusRequest.xsd new file mode 100644 index 0000000..4367bdc --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/1C-Bank_StatusRequest.xsd @@ -0,0 +1,48 @@ + + + + + + Запрос о состоянии электронного документа + + + + + + + Отправитель + + + + + Получатель + + + + + ID исходного электронного документа, статус которого требуется получить + + + + + + Идентификатор запроса + + + + + Версия формата + + + + + Дата и время формирования + + + + + Наименование и версия программы + + + + diff --git a/tests/Fixture/xsd/2.2.2/camt.053.001.02.xsd b/tests/Fixture/xsd/2.2.2/camt.053.001.02.xsd new file mode 100644 index 0000000..d43d573 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/camt.053.001.02.xsd @@ -0,0 +1,1298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Fixture/xsd/2.2.2/pain.001.001.03.xsd b/tests/Fixture/xsd/2.2.2/pain.001.001.03.xsd new file mode 100644 index 0000000..8649779 --- /dev/null +++ b/tests/Fixture/xsd/2.2.2/pain.001.001.03.xsd @@ -0,0 +1,921 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Fixture/xsd/readme.md b/tests/Fixture/xsd/readme.md index 035b3d7..401e9c3 100644 --- a/tests/Fixture/xsd/readme.md +++ b/tests/Fixture/xsd/readme.md @@ -14,6 +14,7 @@ + [XML-схема **ответа банковского сервиса**: *1C-Bank_ResultBank.xsd*](#1C-Bank_ResultBank) + [XML-схема **платежного поручения**: *1C-Bank_PayDocRu.xsd*](#1C-Bank_PayDocRu) + [XML-схема **платежного требования**: *1C-Bank_PayRequest.xsd*](#1C-Bank_PayRequest) ++ [XML-схема **письма**: *1C-Bank_Letter.xsd*](#1C-Bank_Letter) + [XML-схема **транспортного контейнера**: *1C-Bank_Packet.xsd*](#1C-Bank_Packet) + [XML-схема **поручения на перевод валюты**: *pain.001.001.03.xsd*](#pain) + [XML-схема **выписки по валютным счетам**: *camt.053.001.02.xsd*](#camt) @@ -143,6 +144,14 @@ ##### Типы + [edo:PayRequest](../common-section/type-tables.md#edo-PayRequest) +## XML-схема **письма**: *1C-Bank_Letter.xsd* + +- [Файл схемы **1C-Bank_Letter.xsd**](1C-Bank_Letter.xsd) + +##### Типы + + [edo:Letter](../common-section/type-tables.md#edo-Letter) + + ## XML-схема транспортного контейнера: *1C-Bank_Packet.xsd* - [Файл схемы **1C-Bank_Packet.xsd**](1C-Bank_Packet.xsd) diff --git a/tests/FormatVersionTest.php b/tests/FormatVersionTest.php new file mode 100644 index 0000000..6bf7157 --- /dev/null +++ b/tests/FormatVersionTest.php @@ -0,0 +1,110 @@ +loadXML($xml); + + $this->assertTrue($dom->schemaValidate($dir . '1C-Bank_' . $schema . '.xsd')); + } + + protected static function probe(): Probe + { + return (new Probe()) + ->setId('eafa28b5-6600-424c-b0d3-3785274d570d') + ->setCreationDate('2026-09-23T10:00:00') + ->setSender((new CustomerPartyType())->setId('2806')) + ->setRecipient((new BankPartyType())->setBic('044525888')); + } + + public function testLatestByDefault() + { + $this->assertSame('2.3.2', FormatVersion::getDefault()); + + $packet = PacketFixture::createPacket(); + + $this->assertSame('2.3.2', $packet->getFormatVersion()); + $this->assertSame('2.3.2', $packet->getDocument()->getFormatVersion()); + $this->assertSame('2.3.2', self::probe()->getFormatVersion()); + $this->assertValid((string) $packet, 'Packet', '2.3.2'); + } + + public function versionProvider(): array + { + return [['2.2.2'], ['2.3.2']]; + } + + /** + * Документы, собранные в каждой поддерживаемой версии, проходят схемы этой версии + * + * @dataProvider versionProvider + */ + public function testDocumentsMatchVersionSchemas(string $version) + { + FormatVersion::setDefault($version); + + $packet = PacketFixture::createPacket(); + $probe = self::probe(); + + $this->assertSame($version, $packet->getFormatVersion()); + $this->assertSame($version, $probe->getFormatVersion()); + $this->assertValid((string) $packet, 'Packet', $version); + $this->assertValid(base64_decode($packet->getDocument()->getData()), 'StatementRequest', $version); + $this->assertValid((string) $probe, 'Probe', $version); + } + + public function testClientHeaders() + { + FormatVersion::setDefault('2.2.2'); + + $mock = new MockHandler([new Response(200, [], 'S')]); + $requests = []; + $handler = function (RequestInterface $request, array $options) use ($mock, &$requests) { + $requests[] = $request; + return $mock($request, $options); + }; + + (new Client([ + 'url' => 'https://bank.example.ru/', 'customerId' => '1', 'login' => 'user', 'password' => 'secret', 'handler' => $handler, + ]))->createSession(); + + $this->assertSame('2.2.2', $requests[0]->getHeaderLine('APIVersion')); + $this->assertSame('2.3.2', $requests[0]->getHeaderLine('AvailableAPIVersion')); + } + + public function testParsedDocumentKeepsVersion() + { + $packet = (new XmlModelMapper())->map(file_get_contents(__DIR__ . '/Fixture/xml/1c/Packet.xml'), new Packet()); + $this->assertSame('2.2.1', $packet->getFormatVersion()); + + $statement = new Statement(); + $statement->mapFromXml(file_get_contents(__DIR__ . '/Fixture/xml/1c/Statement.xml')); + $this->assertSame('2.3.1', $statement->getFormatVersion()); + } + + public function testUnsupportedVersion() + { + $this->expectException(\InvalidArgumentException::class); + + FormatVersion::setDefault('2.1.1'); + } +} diff --git a/tests/Objects/PacketTest.php b/tests/Objects/PacketTest.php index 28bc046..cee1219 100644 --- a/tests/Objects/PacketTest.php +++ b/tests/Objects/PacketTest.php @@ -80,7 +80,7 @@ public function testOfficialStatementRequest() $this->assertSame('7705260699', $request->getSender()->getInn()); $this->assertSame('044525888', $request->getRecipient()->getBic()); $this->assertSame('40702810500000000001', $request->getData()->getAccount()); - $this->assertSame('2016-04-21T00:00:00', $request->getData()->getDateFrom()); + $this->assertSame('2019-04-21T00:00:00', $request->getData()->getDateFrom()); $dom = new \DOMDocument(); $dom->loadXML($request->toXml()); diff --git a/tests/Objects/ServiceDocumentsTest.php b/tests/Objects/ServiceDocumentsTest.php index ea18e48..57c206f 100644 --- a/tests/Objects/ServiceDocumentsTest.php +++ b/tests/Objects/ServiceDocumentsTest.php @@ -56,9 +56,9 @@ public function testStatusDocNotice() $notice->mapFromXml(self::fixture('1c/StatusDocNotice.xml')); $this->assertSame('204e36e4-6910-416d-99b2-e8109e518744', $notice->getId()); - $this->assertSame('2016-04-22T09:34:46+03:00', $notice->getCreationDate()); + $this->assertSame('2019-04-22T09:34:46+03:00', $notice->getCreationDate()); $this->assertSame('044525888', $notice->getSender()->getBank()->getBic()); - $this->assertSame('id:42;s:9999', $notice->getRecipient()->getCustomer()->getId()); + $this->assertSame('82007cb2-dfd1-4193-b903-16cc9b7231c9', $notice->getRecipient()->getCustomer()->getId()); $this->assertSame('eafa28b5-6600-424c-b0d3-3785274d570d', $notice->getExtID()); $this->assertNull($notice->getExtIDStatusRequest()); @@ -147,7 +147,7 @@ public function testProbe() $official = (new XmlModelMapper())->map(self::fixture('1c/Probe.xml'), new Probe()); $this->assertSame('eafa28b5-6600-424c-b0d3-3785274d570d', $official->getId()); - $this->assertSame('id:42;s:9999', $official->getSender()->getId()); + $this->assertSame('82007cb2-dfd1-4193-b903-16cc9b7231c9', $official->getSender()->getId()); $this->assertValid($official->toXml(), 'Probe'); } @@ -187,12 +187,12 @@ public function testSettingsLogin() $this->assertSame('EFD857B5-7FA8-4195-8666-2CCADBC3C8DE', $settings->getId()); $this->assertSame('DemoBankService', $settings->getUserAgent()); $this->assertSame('044525888', $settings->getSender()->getBic()); - $this->assertSame('2806', $settings->getRecipient()->getId()); + $this->assertSame('82007cb2-dfd1-4193-b903-16cc9b7231c9', $settings->getRecipient()->getId()); $data = $settings->getData(); - $this->assertSame('2806', $data->getCustomerID()); + $this->assertSame('82007cb2-dfd1-4193-b903-16cc9b7231c9', $data->getCustomerID()); $this->assertSame('https://dbogate.demobank.ru/', $data->getBankServerAddress()); - $this->assertSame('2.2.1', $data->getFormatVersion()); + $this->assertSame('2.3.1', $data->getFormatVersion()); $this->assertSame('UTF-8', $data->getEncoding()); $this->assertFalse($data->isCompress()); $this->assertSame('user_login', $data->getLogon()->getLogin()->getUser()); diff --git a/tests/Objects/StatementTest.php b/tests/Objects/StatementTest.php index 05b2264..6853984 100644 --- a/tests/Objects/StatementTest.php +++ b/tests/Objects/StatementTest.php @@ -69,7 +69,7 @@ public function testOfficialExample() $data = $statement->getData(); $this->assertSame('40702810500000000001', $data->getAccount()); - $this->assertSame('2016-05-04T00:00:00.000', $data->getDateFrom()); + $this->assertSame('2019-05-04T00:00:00.000', $data->getDateFrom()); $this->assertSame(139280.91, $data->getOpeningBalance()); $this->assertSame(88970.02, $data->getClosingBalance()); $this->assertNull($data->getTotalDebits()); @@ -79,7 +79,7 @@ public function testOfficialExample() $operations = $data->getOperationInfo(); $this->assertCount(1, $operations); $this->assertSame(1, $operations[0]->getDC()); - $this->assertSame('2016-05-04', $operations[0]->getDate()); + $this->assertSame('2019-05-04', $operations[0]->getDate()); $payDoc = $operations[0]->getPayDoc(); $this->assertSame('768', $payDoc->getId()); From fab1aa4da08f6801c97d872b9a6e7ba4a434147b Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:32:38 +0200 Subject: [PATCH 2/6] =?UTF-8?q?=D0=A2=D1=80=D0=B0=D0=BD=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=82=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D0=B9=D0=BD=D0=B5=D1=80=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20=D1=81=20UTF-8=20BOM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit С версии 2.3.x контейнер и файлы вложений всегда передаются с BOM. Входящие ответы и документы с BOM разбираются. Closes #31 --- src/Client.php | 2 +- src/Dictionary/DefaultValue.php | 3 +++ tests/ClientHttpTest.php | 25 +++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Client.php b/src/Client.php index 602d209..8c6c314 100644 --- a/src/Client.php +++ b/src/Client.php @@ -85,7 +85,7 @@ public function confirmOtp(string $sessionId, string $otp): string public function sendPack(Packet $packet): string { - $result = $this->invoke('POST', 'SendPack', (string) $packet); + $result = $this->invoke('POST', 'SendPack', DefaultValue::BOM . $packet); $response = $result->getSuccess()->getSendPacketResponse() ?? throw new UnexpectedResponseException('Bank response to SendPack has no SendPacketResponse.'); diff --git a/src/Dictionary/DefaultValue.php b/src/Dictionary/DefaultValue.php index 4cc59b5..dca01f7 100644 --- a/src/Dictionary/DefaultValue.php +++ b/src/Dictionary/DefaultValue.php @@ -8,6 +8,9 @@ class DefaultValue { const FORMAT_VERSION = '2.3.2'; + //UTF-8 BOM: с версии 2.3.x транспортный контейнер и файлы вложений всегда передаются с ним + const BOM = "\xEF\xBB\xBF"; + //Формат отметки времени в GetPackList: dd.MM.yyyy HH:mm:ss const TIMESTAMP_FORMAT = 'd.m.Y H:i:s'; } \ No newline at end of file diff --git a/tests/ClientHttpTest.php b/tests/ClientHttpTest.php index 690edf2..10ac7e2 100644 --- a/tests/ClientHttpTest.php +++ b/tests/ClientHttpTest.php @@ -7,6 +7,7 @@ use GuzzleHttp\Psr7\Response; use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; +use TTBooking\DirectBank\Dictionary\DefaultValue; use TTBooking\DirectBank\Dictionary\ErrorCode; use TTBooking\DirectBank\Exceptions\ClientException; use TTBooking\DirectBank\Exceptions\OtpRequiredException; @@ -165,7 +166,27 @@ public function testSendPack() $request = $this->requests[0]; $this->assertSame('POST', $request->getMethod()); $this->assertStringEndsWith('/SendPack', $request->getUri()->getPath()); - $this->assertSame((string) $packet, (string) $request->getBody()); + $this->assertSame(DefaultValue::BOM . $packet, (string) $request->getBody()); + $this->assertSame('efbbbf3c3f786d6c', bin2hex(substr((string) $request->getBody(), 0, 8)), 'UTF-8 BOM, затем ]*\?>\s*/', '', (string) $packet); + $xml = str_replace([''], [''], $xml); + + $this->mock->append( + new Response(200, [], DefaultValue::BOM . self::resultBank('SID-1')), + new Response(200, [], DefaultValue::BOM . self::resultBank("$xml")), + ); + + $client = $this->createClient(); + $this->assertSame('SID-1', $client->createSession()); + $this->assertSame($packet->getId(), $client->getPack($packet->getId())->getId()); } public function testGetPackList() @@ -339,7 +360,7 @@ public function testReauthenticateOnSessionError(string $code, int $status) $this->assertSame('SID-1', $this->requests[0]->getHeaderLine('sid')); $this->assertStringEndsWith('/Logon', $this->requests[1]->getUri()->getPath()); $this->assertSame('SID-2', $this->requests[2]->getHeaderLine('sid')); - $this->assertSame((string) $packet, (string) $this->requests[2]->getBody()); + $this->assertSame(DefaultValue::BOM . $packet, (string) $this->requests[2]->getBody()); $this->assertSame('SID-2', $this->requests[3]->getHeaderLine('sid')); } From 158db54386cd373106f55202b5f1d6ca660a5de5 Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:33:36 +0200 Subject: [PATCH 3/6] =?UTF-8?q?SenderFootprint:=20IP-=20=D0=B8=20MAC-?= =?UTF-8?q?=D0=B0=D0=B4=D1=80=D0=B5=D1=81=D0=B0=20=D0=BA=D0=BB=D0=B8=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D0=B9=D0=BD=D0=B5=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #32 --- src/Objects/Packet.php | 18 +++++++++ src/Objects/SenderFootprintType.php | 63 +++++++++++++++++++++++++++++ tests/Objects/PacketTest.php | 17 ++++++++ 3 files changed, 98 insertions(+) create mode 100644 src/Objects/SenderFootprintType.php diff --git a/src/Objects/Packet.php b/src/Objects/Packet.php index b0487cc..ad818e7 100644 --- a/src/Objects/Packet.php +++ b/src/Objects/Packet.php @@ -59,6 +59,13 @@ class Packet implements \Stringable */ protected array $documents = []; + /** + * Цифровой след отправителя, с версии 2.3.2: в схемах 2.2.x элемента нет + * + * @name SenderFootprint + */ + protected ?SenderFootprintType $senderFootprint = null; + /** * @return string */ @@ -213,6 +220,17 @@ public function addDocument(DocumentType $document): Packet return $this; } + public function getSenderFootprint(): ?SenderFootprintType + { + return $this->senderFootprint; + } + + public function setSenderFootprint(?SenderFootprintType $senderFootprint): Packet + { + $this->senderFootprint = $senderFootprint; + return $this; + } + public function __toString() { return $this->toXml(); diff --git a/src/Objects/SenderFootprintType.php b/src/Objects/SenderFootprintType.php new file mode 100644 index 0000000..94edd5f --- /dev/null +++ b/src/Objects/SenderFootprintType.php @@ -0,0 +1,63 @@ +IP = array_values($ip); + $this->MAC = array_values($mac); + } + + /** + * @return string[] + */ + public function getIP(): array + { + return $this->IP; + } + + public function addIP(string $ip): SenderFootprintType + { + $this->IP[] = $ip; + return $this; + } + + /** + * @return string[] + */ + public function getMAC(): array + { + return $this->MAC; + } + + public function addMAC(string $mac): SenderFootprintType + { + $this->MAC[] = $mac; + return $this; + } +} diff --git a/tests/Objects/PacketTest.php b/tests/Objects/PacketTest.php index cee1219..2a309b1 100644 --- a/tests/Objects/PacketTest.php +++ b/tests/Objects/PacketTest.php @@ -162,6 +162,23 @@ public function testDataAttributesAndSignature() $this->assertSame('signature', base64_decode($document->getSignatures()[0]->getSignedData())); } + public function testSenderFootprint() + { + $packet = PacketFixture::createPacket()->setSenderFootprint( + (new SenderFootprintType(['192.168.1.10']))->addIP('2001:db8::ff00:42:8329')->addMAC('00-1A-2B-3C-4D-5E') + ); + + $dom = new \DOMDocument(); + $dom->loadXML($packet->toXml()); + $this->assertTrue($dom->schemaValidate(__DIR__ . '/../Fixture/xsd/1C-Bank_Packet.xsd')); + + $footprint = (new XmlModelMapper())->map($packet->toXml(), new Packet())->getSenderFootprint(); + $this->assertSame(['192.168.1.10', '2001:db8::ff00:42:8329'], $footprint->getIP()); + $this->assertSame(['00-1A-2B-3C-4D-5E'], $footprint->getMAC()); + + $this->assertNull((new XmlModelMapper())->map(PacketFixture::createPacket()->toXml(), new Packet())->getSenderFootprint()); + } + public function testWithoutUserAgent() { $packet = PacketFixture::createPacket(); From 0a6da5dec70f505f369a382c3a87bc20fa0f5595 Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:34:36 +0200 Subject: [PATCH 4/6] =?UTF-8?q?Letters=20=D0=B2=20=D0=BD=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=D1=85=20=D0=BE=D0=B1=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0:=20=D0=BB=D0=B8=D0=BC=D0=B8=D1=82=20=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B8=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D1=8B=20=D0=BF=D0=B8=D1=81=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #33 --- src/Objects/LetterTypeType.php | 27 ++++++++++++++++++++ src/Objects/LettersType.php | 34 ++++++++++++++++++++++++++ src/Objects/SettingsDataType.php | 8 ++++++ tests/Objects/ServiceDocumentsTest.php | 12 ++++++++- 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/Objects/LetterTypeType.php create mode 100644 src/Objects/LettersType.php diff --git a/src/Objects/LetterTypeType.php b/src/Objects/LetterTypeType.php new file mode 100644 index 0000000..cbca326 --- /dev/null +++ b/src/Objects/LetterTypeType.php @@ -0,0 +1,27 @@ +Code; + } + + public function getName(): string + { + return $this->Name; + } +} diff --git a/src/Objects/LettersType.php b/src/Objects/LettersType.php new file mode 100644 index 0000000..243b5f7 --- /dev/null +++ b/src/Objects/LettersType.php @@ -0,0 +1,34 @@ +AttachmentsLimit; + } + + /** + * @return LetterTypeType[] + */ + public function getLetterTypes(): array + { + return $this->LetterType; + } +} diff --git a/src/Objects/SettingsDataType.php b/src/Objects/SettingsDataType.php index 4c52bb1..38a76fb 100644 --- a/src/Objects/SettingsDataType.php +++ b/src/Objects/SettingsDataType.php @@ -39,6 +39,9 @@ class SettingsDataType //Параметры получения выписки в автоматическом режиме protected ?ReceiptStatementType $ReceiptStatement = null; + //Свойства писем, с версии 2.3.1 + protected ?LettersType $Letters = null; + public function getCustomerID(): string { return $this->CustomerID; @@ -96,4 +99,9 @@ public function getReceiptStatement(): ?ReceiptStatementType { return $this->ReceiptStatement; } + + public function getLetters(): ?LettersType + { + return $this->Letters; + } } diff --git a/tests/Objects/ServiceDocumentsTest.php b/tests/Objects/ServiceDocumentsTest.php index 57c206f..0e6582c 100644 --- a/tests/Objects/ServiceDocumentsTest.php +++ b/tests/Objects/ServiceDocumentsTest.php @@ -199,6 +199,7 @@ public function testSettingsLogin() $this->assertNull($data->getLogon()->getCertificate()); $this->assertNull($data->getCryptoParameters()); $this->assertNull($data->getReceiptStatement()); + $this->assertNull($data->getLetters()); $this->assertSame(['03', '05', '10', '11', '14', '30'], $data->getDocKinds()); $this->assertNull($data->getDocuments()[0]->getSigned()); } @@ -249,7 +250,10 @@ public function testSettingsFull() 'QQ==Qg==' . 'https://bank.example.ru/addin.zip', '', - 'statementПозвоните в банк', + 'statementПозвоните в банк' + . '10485760' + . '01Письмо свободного формата' + . '02Запрос документов', ], self::fixture('1c/Settings_Logon_Certificate.xml') ); @@ -274,5 +278,11 @@ public function testSettingsFull() $this->assertSame('02', $data->getDocKinds()[0]); $this->assertSame('statement', $data->getReceiptStatement()->getLogin()); $this->assertSame('Позвоните в банк', $data->getReceiptStatement()->getInstructions()); + + $letters = $data->getLetters(); + $this->assertSame(10485760, $letters->getAttachmentsLimit()); + $this->assertCount(2, $letters->getLetterTypes()); + $this->assertSame('01', $letters->getLetterTypes()[0]->getCode()); + $this->assertSame('Запрос документов', $letters->getLetterTypes()[1]->getName()); } } From 862f3fa9cb920b91927416dd33d16150c4d13fe6 Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:36:29 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9F=D0=B8=D1=81=D1=8C=D0=BC=D0=BE=20(40)?= =?UTF-8?q?:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=81=20=D0=B1=D0=B0=D0=BD=D0=BA=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Letter для отправки и разбора: номер, дата, тип, тема, текст, вложения, связанный документ, ID переписки - BinaryFileType::fromContents() и fromFile() считают размер и CRC32 вложения, isIntact() проверяет их у полученного файла - вложения передаются как есть: BOM для текстовых файлов добавляет вызывающий код Closes #34 --- src/Objects/BinaryFileType.php | 149 ++++++++++++++++++++++++++ src/Objects/Letter.php | 134 ++++++++++++++++++++++++ src/Objects/LetterAttachmentType.php | 42 ++++++++ src/Objects/LetterDataType.php | 150 +++++++++++++++++++++++++++ src/Objects/LinkedDocType.php | 41 ++++++++ tests/Objects/LetterTest.php | 146 ++++++++++++++++++++++++++ 6 files changed, 662 insertions(+) create mode 100644 src/Objects/BinaryFileType.php create mode 100644 src/Objects/Letter.php create mode 100644 src/Objects/LetterAttachmentType.php create mode 100644 src/Objects/LetterDataType.php create mode 100644 src/Objects/LinkedDocType.php create mode 100644 tests/Objects/LetterTest.php diff --git a/src/Objects/BinaryFileType.php b/src/Objects/BinaryFileType.php new file mode 100644 index 0000000..bee2c17 --- /dev/null +++ b/src/Objects/BinaryFileType.php @@ -0,0 +1,149 @@ +value = base64_encode($contents); + $file->id = $id ?? (string) Uuid::uuid4(); + $file->name = $name; + $file->extension = pathinfo($name, PATHINFO_EXTENSION); + $file->size = strlen($contents); + $file->crc = crc32($contents); + $file->creationDate = ($creationDate ?? new \DateTimeImmutable())->format('Y-m-d\TH:i:s'); + + return $file; + } + + public static function fromFile(string $path, ?string $name = null, ?string $id = null): static + { + $contents = @file_get_contents($path); + if ($contents === false) { + throw new \InvalidArgumentException(sprintf('Unable to read file "%s".', $path)); + } + + $modified = (new \DateTimeImmutable())->setTimestamp(filemtime($path)); + + return static::fromContents($contents, $name ?? basename($path), $modified, $id); + } + + /** + * Содержимое файла в base64 + */ + public function getValue(): string + { + return $this->value; + } + + /** + * Содержимое файла + */ + public function getContents(): string + { + $contents = base64_decode($this->value, true); + if ($contents === false) { + throw new \UnexpectedValueException('Attachment data is not valid base64.'); + } + + return $contents; + } + + /** + * Совпадают ли размер и CRC32 содержимого с указанными в описании файла + */ + public function isIntact(): bool + { + $contents = $this->getContents(); + + return strlen($contents) === $this->size && crc32($contents) === $this->crc; + } + + public function getId(): string + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getExtension(): string + { + return $this->extension; + } + + public function getSize(): int + { + return $this->size; + } + + public function getCrc(): int + { + return $this->crc; + } + + public function getCreationDate(): string + { + return $this->creationDate; + } +} diff --git a/src/Objects/Letter.php b/src/Objects/Letter.php new file mode 100644 index 0000000..d658622 --- /dev/null +++ b/src/Objects/Letter.php @@ -0,0 +1,134 @@ + Банк, вид ЭД 40), с версии 2.3.1 + * + * @see \TTBooking\DirectBank\Dictionary\DocKind::LETTER + * + * @xmlRoot Letter + * @xmlEncoding utf-8 + */ +class Letter implements \Stringable +{ + use MappableTrait, ConvertibleTrait, DefaultFormatVersion; + + /** + * @xmlAttribute + */ + protected string $xmlns = 'http://directbank.1c.ru/XMLSchema'; + + /** + * @xmlAttribute + */ + protected string $id; + + /** + * @xmlAttribute + */ + protected string $formatVersion = DefaultValue::FORMAT_VERSION; + + /** + * @xmlAttribute + */ + protected string $creationDate; + + /** + * @xmlAttribute + */ + protected ?string $userAgent = null; + + protected ParticipantType $Sender; + + protected ParticipantType $Recipient; + + protected LetterDataType $Data; + + public function getId(): string + { + return $this->id; + } + + public function setId(string $id): Letter + { + $this->id = $id; + return $this; + } + + public function getFormatVersion(): string + { + return $this->formatVersion; + } + + public function setFormatVersion(string $formatVersion): Letter + { + $this->formatVersion = $formatVersion; + return $this; + } + + public function getCreationDate(): string + { + return $this->creationDate; + } + + public function setCreationDate(string $creationDate): Letter + { + $this->creationDate = $creationDate; + return $this; + } + + public function getUserAgent(): ?string + { + return $this->userAgent; + } + + public function setUserAgent(?string $userAgent): Letter + { + $this->userAgent = $userAgent; + return $this; + } + + public function getSender(): ParticipantType + { + return $this->Sender; + } + + public function setSender(ParticipantType $sender): Letter + { + $this->Sender = $sender; + return $this; + } + + public function getRecipient(): ParticipantType + { + return $this->Recipient; + } + + public function setRecipient(ParticipantType $recipient): Letter + { + $this->Recipient = $recipient; + return $this; + } + + public function getData(): LetterDataType + { + return $this->Data; + } + + public function setData(LetterDataType $data): Letter + { + $this->Data = $data; + return $this; + } + + public function __toString() + { + return $this->toXml(); + } +} diff --git a/src/Objects/LetterAttachmentType.php b/src/Objects/LetterAttachmentType.php new file mode 100644 index 0000000..7a51723 --- /dev/null +++ b/src/Objects/LetterAttachmentType.php @@ -0,0 +1,42 @@ +BinaryFile = $file; + } + + public function getBinaryFile(): BinaryFileType + { + return $this->BinaryFile; + } + + /** + * @return SignatureType[] + */ + public function getSignatures(): array + { + return $this->Signature; + } + + public function addSignature(SignatureType $signature): LetterAttachmentType + { + $this->Signature[] = $signature; + return $this; + } +} diff --git a/src/Objects/LetterDataType.php b/src/Objects/LetterDataType.php new file mode 100644 index 0000000..5e5db15 --- /dev/null +++ b/src/Objects/LetterDataType.php @@ -0,0 +1,150 @@ +linkedID; + } + + public function setLinkedID(?string $linkedID): LetterDataType + { + $this->linkedID = $linkedID; + return $this; + } + + public function getCorrespondenceID(): ?string + { + return $this->correspondenceID; + } + + public function setCorrespondenceID(?string $correspondenceID): LetterDataType + { + $this->correspondenceID = $correspondenceID; + return $this; + } + + public function getDocNum(): string + { + return $this->DocNum; + } + + public function setDocNum(string $docNum): LetterDataType + { + $this->DocNum = $docNum; + return $this; + } + + public function getDocDate(): string + { + return $this->DocDate; + } + + public function setDocDate(string $docDate): LetterDataType + { + $this->DocDate = $docDate; + return $this; + } + + public function getLetterTypeCode(): ?string + { + return $this->LetterTypeCode; + } + + public function setLetterTypeCode(?string $letterTypeCode): LetterDataType + { + $this->LetterTypeCode = $letterTypeCode; + return $this; + } + + public function getTheme(): ?string + { + return $this->Theme; + } + + public function setTheme(?string $theme): LetterDataType + { + $this->Theme = $theme; + return $this; + } + + public function getText(): string + { + return $this->Text; + } + + public function setText(string $text): LetterDataType + { + $this->Text = $text; + return $this; + } + + /** + * @return LetterAttachmentType[] + */ + public function getAttachments(): array + { + return $this->Attachment; + } + + public function addAttachment(LetterAttachmentType $attachment): LetterDataType + { + $this->Attachment[] = $attachment; + return $this; + } + + public function getLinkedDoc(): ?LinkedDocType + { + return $this->LinkedDoc; + } + + public function setLinkedDoc(?LinkedDocType $linkedDoc): LetterDataType + { + $this->LinkedDoc = $linkedDoc; + return $this; + } +} diff --git a/src/Objects/LinkedDocType.php b/src/Objects/LinkedDocType.php new file mode 100644 index 0000000..93c20ab --- /dev/null +++ b/src/Objects/LinkedDocType.php @@ -0,0 +1,41 @@ +id = $id; + $this->dockind = $dockind; + } + + public function getId(): string + { + return $this->id; + } + + public function getDockind(): string + { + return $this->dockind; + } +} diff --git a/tests/Objects/LetterTest.php b/tests/Objects/LetterTest.php new file mode 100644 index 0000000..981a8ee --- /dev/null +++ b/tests/Objects/LetterTest.php @@ -0,0 +1,146 @@ +loadXML($xml); + + $this->assertTrue($dom->schemaValidate(__DIR__ . '/../Fixture/xsd/1C-Bank_' . $schema . '.xsd')); + } + + protected static function letter(): Letter + { + $pdf = "%PDF-1.4\n" . random_bytes(64); + + return (new Letter()) + ->setId('6a2f1c0e-5b3d-4e8a-9c7f-1d2e3f4a5b6c') + ->setCreationDate('2026-09-23T12:00:00') + ->setUserAgent('My App') + ->setSender((new ParticipantType())->setCustomer((new CustomerPartyType())->setId('2806')->setInn('7705260699'))) + ->setRecipient((new ParticipantType())->setBank((new BankPartyType())->setBic('044525888'))) + ->setData( + (new LetterDataType()) + ->setCorrespondenceID('0b9c8d7e-6f5a-4b3c-2d1e-0f9a8b7c6d5e') + ->setDocNum('7') + ->setDocDate('2026-09-23') + ->setLetterTypeCode('01') + ->setTheme('Уточнение назначения платежа') + ->setText("Прошу уточнить назначение платежа по поручению № 14.\nСпасибо.") + ->addAttachment( + (new LetterAttachmentType(BinaryFileType::fromContents($pdf, 'счёт 42.pdf', new \DateTimeImmutable('2026-09-22 10:00:00')))) + ->addSignature((new SignatureType())->setX509IssuerName('CN=Test CA')->setX509SerialNumber('0A1B')->setSignedData(base64_encode('signature'))) + ) + ->addAttachment(new LetterAttachmentType(BinaryFileType::fromContents(DefaultValue::BOM . "", 'act.xml'))) + ->setLinkedDoc(new LinkedDocType('05688096-0806-4ef0-af4c-572f75dbaf7c', DocKind::PAY_DOC_RU)) + ); + } + + public function testLetter() + { + $letter = self::letter(); + + $this->assertSame('2.3.2', $letter->getFormatVersion()); + $this->assertValid((string) $letter, 'Letter'); + + $mapped = new Letter(); + $mapped->mapFromXml((string) $letter); + + $this->assertEquals($letter, $mapped); + + $data = $mapped->getData(); + $this->assertSame('0b9c8d7e-6f5a-4b3c-2d1e-0f9a8b7c6d5e', $data->getCorrespondenceID()); + $this->assertNull($data->getLinkedID()); + $this->assertSame('01', $data->getLetterTypeCode()); + $this->assertSame("Прошу уточнить назначение платежа по поручению № 14.\nСпасибо.", $data->getText()); + $this->assertSame(DocKind::PAY_DOC_RU, $data->getLinkedDoc()->getDockind()); + + [$pdf, $xml] = $data->getAttachments(); + $file = $pdf->getBinaryFile(); + $this->assertSame('счёт 42.pdf', $file->getName()); + $this->assertSame('pdf', $file->getExtension()); + $this->assertSame(73, $file->getSize()); + $this->assertSame(crc32($file->getContents()), $file->getCrc()); + $this->assertTrue($file->isIntact()); + $this->assertSame('2026-09-22T10:00:00', $file->getCreationDate()); + $this->assertCount(1, $pdf->getSignatures()); + $this->assertSame('0A1B', $pdf->getSignatures()[0]->getX509SerialNumber()); + + $this->assertSame(DefaultValue::BOM, substr($xml->getBinaryFile()->getContents(), 0, 3)); + $this->assertSame([], $xml->getSignatures()); + } + + public function testMinimalLetter() + { + $letter = (new Letter()) + ->setId((string) Uuid::uuid4()) + ->setCreationDate('2026-09-23T12:00:00') + ->setSender((new ParticipantType())->setBank((new BankPartyType())->setBic('044525888'))) + ->setRecipient((new ParticipantType())->setCustomer((new CustomerPartyType())->setId('2806'))) + ->setData((new LetterDataType())->setDocNum('1')->setDocDate('2026-09-23')->setText('Уведомление')); + + $this->assertValid((string) $letter, 'Letter'); + + $mapped = new Letter(); + $mapped->mapFromXml((string) $letter); + + $this->assertSame('044525888', $mapped->getSender()->getBank()->getBic()); + $this->assertSame([], $mapped->getData()->getAttachments()); + $this->assertNull($mapped->getData()->getTheme()); + $this->assertNull($mapped->getData()->getLinkedDoc()); + } + + public function testDamagedAttachment() + { + $letter = new Letter(); + $letter->mapFromXml(str_replace(' size="73"', ' size="74"', (string) self::letter())); + + $this->assertFalse($letter->getData()->getAttachments()[0]->getBinaryFile()->isIntact()); + } + + public function testAttachmentFromFile() + { + $path = tempnam(sys_get_temp_dir(), 'db'); + file_put_contents($path, 'contents'); + + try { + $file = BinaryFileType::fromFile($path, 'report.txt'); + } finally { + unlink($path); + } + + $this->assertSame('report.txt', $file->getName()); + $this->assertSame('txt', $file->getExtension()); + $this->assertSame(8, $file->getSize()); + $this->assertSame(crc32('contents'), $file->getCrc()); + $this->assertSame('contents', $file->getContents()); + + $this->expectException(\InvalidArgumentException::class); + BinaryFileType::fromFile($path); + } + + public function testLetterInPacket() + { + $letter = self::letter(); + + $packet = (new Packet()) + ->setId((string) Uuid::uuid4()) + ->setCreationDate('2026-09-23T12:00:00') + ->setSender($letter->getSender()) + ->setRecipient($letter->getRecipient()) + ->setDocument( + (new DocumentType())->setId($letter->getId())->setDockind(DocKind::LETTER)->setData(base64_encode((string) $letter)) + ); + + $this->assertValid((string) $packet, 'Packet'); + } +} From c928a1f91328741c86799c3b1c624928bb891d8c Mon Sep 17 00:00:00 2001 From: Egor Gruzdev Date: Wed, 23 Sep 2026 00:37:01 +0200 Subject: [PATCH 6/6] =?UTF-8?q?README:=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4?= =?UTF-8?q?=D0=B0=D1=80=D1=82=202.3.2,=20FormatVersion,=20=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8C=D0=BC=D0=B0,=20SenderFootprint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 291ba8a..48cb5f7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DirectBank -PHP-клиент для обмена с банком по протоколу **1С:DirectBank** (формат обмена `2.2.2`). +PHP-клиент для обмена с банком по протоколу **1С:DirectBank**, стандарт `2.3.2` (поддерживается и `2.2.2`). Библиотека берёт на себя HTTP-транспорт (аутентификация, сессия, заголовки протокола) и даёт типизированные объекты для транспортного контейнера (`Packet`) и документов @@ -30,15 +30,15 @@ composer require ttbooking/direct-bank ```php use TTBooking\DirectBank\Client; -use TTBooking\DirectBank\Dictionary\DefaultValue; +use TTBooking\DirectBank\FormatVersion; $client = new Client([ 'url' => 'https://bank.example.ru/API/v1/directbank/', // базовый URL сервиса банка 'customerId' => '40702810000000000000', // идентификатор клиента в банке 'login' => 'user', 'password' => 'secret', - 'apiVersion' => DefaultValue::FORMAT_VERSION, // по умолчанию '2.2.2' - 'availableApiVersion' => DefaultValue::FORMAT_VERSION, // заголовок AvailableAPIVersion в Logon, null — не передавать + 'apiVersion' => null, // по умолчанию FormatVersion::getDefault(), '2.3.2' + 'availableApiVersion' => FormatVersion::LATEST, // заголовок AvailableAPIVersion, null — не передавать 'userAgent' => null, // заголовок User-Agent, по умолчанию стандартный Guzzle 'sessionId' => null, // можно передать уже полученный SID 'verify' => true, // проверка SSL-сертификата @@ -59,6 +59,22 @@ $client = new Client([ $client = new Client($settings, $logger); // Psr\Log\LoggerInterface ``` +### Версия стандарта + +По умолчанию клиент и все создаваемые документы используют версию `2.3.2`. Для банка, +который поддерживает только `2.2.x`, версия задаётся один раз: + +```php +use TTBooking\DirectBank\FormatVersion; + +FormatVersion::setDefault('2.2.2'); // APIVersion клиента и formatVersion новых документов +``` + +Разобранные документы сохраняют версию из XML. Элементы 2.3.x — письма, `SenderFootprint`, +`Letters` в настройках — в схемах `2.2.2` отсутствуют. + +Транспортный контейнер отправляется с UTF-8 BOM, как требует стандарт с версии 2.3.x. + ### Сессия Явно вызывать `createSession()` не обязательно: при первом запросе, требующем @@ -260,13 +276,40 @@ $client->sendPack($packet); Исходящие документы собираются в XML через `TTBooking\DirectBank\Mapper\XmlMapper`: поля базовых типов идут раньше полей наследников, как требует XSD. +### Письмо + +Письмо (вид `40`) ходит в обе стороны. Размер и CRC32 вложений считаются по содержимому файла: + +```php +use TTBooking\DirectBank\Objects\{BinaryFileType, Letter, LetterAttachmentType, LetterDataType, LinkedDocType}; + +$letter = (new Letter()) + ->setId((string) Uuid::uuid4()) + ->setCreationDate((new DateTimeImmutable())->format(DATE_ATOM)) + ->setSender((new ParticipantType())->setCustomer($customer)) + ->setRecipient((new ParticipantType())->setBank($bank)) + ->setData( + (new LetterDataType()) + ->setDocNum('7') + ->setDocDate('2026-09-23') + ->setLetterTypeCode('01') // типы писем банка — в настройках: Settings::getData()->getLetters() + ->setTheme('Уточнение назначения платежа') + ->setText('Прошу уточнить назначение платежа по поручению № 14.') + ->addAttachment(new LetterAttachmentType(BinaryFileType::fromFile('/path/to/invoice.pdf'))) + ->setLinkedDoc(new LinkedDocType($payDocRu->getId(), DocKind::PAY_DOC_RU)) + ); +``` + +Вложения передаются как есть: BOM для текстовых файлов добавляет вызывающий код. У полученного +письма содержимое вложения — `getBinaryFile()->getContents()`, проверка размера и CRC32 — `isIntact()`. + ### Получение ответов банка ```php use Mapper\XmlModelMapper; use TTBooking\DirectBank\Dictionary\DocKind; use TTBooking\DirectBank\Dictionary\DocStatus; -use TTBooking\DirectBank\Objects\{Settings, Statement, StatusDocNotice, StatusPacketNotice}; +use TTBooking\DirectBank\Objects\{Letter, Settings, Statement, StatusDocNotice, StatusPacketNotice}; $mapper = new XmlModelMapper(); @@ -281,6 +324,7 @@ foreach ($client->getPackList() ?? [] as $id) { DocKind::STATUS_DOC_NOTICE => $mapper->map($xml, new StatusDocNotice()), DocKind::SETTINGS => $mapper->map($xml, new Settings()), DocKind::BANK_STATEMENT => $mapper->map($xml, new Statement()), + DocKind::LETTER => $mapper->map($xml, new Letter()), default => null, }; @@ -315,7 +359,9 @@ foreach ($client->getPackList() ?? [] as $id) { Все исходящие документы принимают необязательный дайджест: `setDigest(new DigestType($data, $algorithmVersion))`. Как его формировать, стандарт не описывает — это делает внешняя компонента банка. -Входящие: `StatusPacketNotice` (`01`), `StatusDocNotice` (`02`), `Settings` (`06`), `Statement` (`15`). +Входящие: `StatusPacketNotice` (`01`), `StatusDocNotice` (`02`), `Settings` (`06`), `Statement` (`15`), `Letter` (`40`). + +IP- и MAC-адреса клиента передаются в контейнере: `$packet->setSenderFootprint(new SenderFootprintType(['192.168.1.10'], ['00-1A-2B-3C-4D-5E']))`. ## Справочники @@ -355,10 +401,11 @@ foreach ($client->getPackList() ?? [] as $id) { | `CHECK` | `25` | Денежный чек | | `CURRENCY_TRANSFER_ORDER` | `30` | Поручение на перевод валюты | | `CURRENCY_STATEMENT` | `35` | Выписка по валютному счёту | +| `LETTER` | `40` | Письмо | \* обязательные по стандарту. `SHIPPING_CONTAINER_HANDLING_STATUS_NOTIFICATION` — прежнее имя `STATUS_PACKET_NOTICE`. -XSD-схемы формата лежат в [`tests/Fixture/xsd`](tests/Fixture/xsd). +XSD-схемы формата лежат в [`tests/Fixture/xsd`](tests/Fixture/xsd) (версия 2.3.2), схемы 2.2.2 — в [`tests/Fixture/xsd/2.2.2`](tests/Fixture/xsd/2.2.2). ## Тесты