diff --git a/README.md b/README.md
index a376ddd..5a188fc 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,13 @@ docker compose up --detach
##### 9. [Страница после оплаты](src/Examples/returnPage.php)
+##### 10. Подключение продавцов
+1. [Подключение продавца-организации (отправка анкеты)](src/Examples/qstCreateOrg.php)
+2. [Подключение продавца-ИП (отправка анкеты)](src/Examples/qstCreateIp.php)
+3. [Получение статуса анкеты](src/Examples/qstStatus.php)
+4. [Печать анкеты](src/Examples/qstPrint.php)
+5. [Список анкет](src/Examples/qstList.php)
+
## Ссылки
- [НКО «Твои Платежи»](https://YPMN.ru/)
- [Докуметация API](https://ypmn.ru/ru/documentation/)
diff --git a/example.php b/example.php
index 11e9ab9..0bb7cb0 100644
--- a/example.php
+++ b/example.php
@@ -53,6 +53,12 @@
case 'getFasterPayment':
case 'getBindingFasterPayment':
case 'paymentByFasterBinding':
+ case 'qstCreateOrg':
+ case 'qstCreateIp':
+ case 'qstStatus':
+ case 'qstPrint':
+ case 'SOMGetPaymentLink':
+ case 'qstList':
require './src/Examples/start.php';
@include './src/Examples/'.$_GET['function'] . '__prepend.php';
require './src/Examples/'.$_GET['function'] . '.php';
diff --git a/example_list.php b/example_list.php
index f280a35..58b635e 100644
--- a/example_list.php
+++ b/example_list.php
@@ -131,9 +131,39 @@
'link' => '',
],
'SOMGetPaymentLink' => [
- 'name' => 'Самая простая кнопка оплаты',
+ 'name' => 'Оплата зарубежными картами',
'about' => 'В этом примере показана простая реализация оплаты заказа зарубежной картой.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payment-api',
'link' => '',
],
+ 'qstCreateOrg' => [
+ 'name' => 'Подключение продавца-организации (отправка анкеты)',
+ 'about' => 'В этом примере показана реализация отправки анкеты подключаемого продавца-организации на проверку в YPMN.',
+ 'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1create/post',
+ 'link' => '',
+ ],
+ 'qstCreateIp' => [
+ 'name' => 'Подключение продавца-ИП (отправка анкеты)',
+ 'about' => 'В этом примере показана реализация отправки анкеты подключаемого продавца-ИП на проверку в YPMN.',
+ 'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1create/post',
+ 'link' => '',
+ ],
+ 'qstStatus' => [
+ 'name' => 'Получение статуса анкеты',
+ 'about' => 'В этом примере показано получение статуса анкеты по её ID.
ID анкеты возвращается при отправке анкеты на проверку.',
+ 'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1status~1%7Bid%7D/get',
+ 'link' => '',
+ ],
+ 'qstPrint' => [
+ 'name' => 'Печать анкеты',
+ 'about' => 'В этом примере показано получение заполненной pdf версии анкеты по её ID.
ID анкеты возвращается при отправке анкеты на проверку.
Распечатать можно только одобренную анкету - в статусе approved.',
+ 'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1print~1%7Bid%7D/get',
+ 'link' => '',
+ ],
+ 'qstList' => [
+ 'name' => 'Список анкет',
+ 'about' => 'В этом примере показано получение списка анкет.',
+ 'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1list/get',
+ 'link' => '',
+ ],
];
diff --git a/src/ApiRequest.php b/src/ApiRequest.php
index f88b65c..7a9aab8 100644
--- a/src/ApiRequest.php
+++ b/src/ApiRequest.php
@@ -24,6 +24,10 @@ class ApiRequest implements ApiRequestInterface
const REPORT_ORDERS_API_V4 = '/api/v4/reports/orders';
const REPORT_ORDER_DETAILS_API = '/api/v4/reports/order-details';
const PODELI_MERCHANT_REGISTRATION_API = '/api/v4/registration/merchant/podeli';
+ const QST_CREATE_API = '/api/v4/qst/create';
+ const QST_STATUS_API = '/api/v4/qst/status';
+ const QST_PRINT_API = '/api/v4/qst/print';
+ const QST_LIST_API = '/api/v4/qst/list';
const HOST = 'https://secure.ypmn.ru';
const SANDBOX_HOST = 'https://sandbox.ypmn.ru';
const LOCAL_HOST = 'http://127.0.0.1';
@@ -40,6 +44,9 @@ class ApiRequest implements ApiRequestInterface
/** @var bool Режим Отладки (вывод системных сообщений) */
private bool $debugModeIsOn = false;
+ /** @var bool Отображать заголовки ответа в режим отладки */
+ private bool $debugShowResponseHeaders = true;
+
/** @var bool Формат результата в режиме отладки */
private bool $jsonDebugResponse = true;
@@ -220,6 +227,12 @@ private function sendGetRequest(string $api): array
]
];
+ $headers = [];
+
+ if ($this->getDebugShowResponseHeaders()) {
+ $this->addCurlOptHeaderFunction($setopt_array, $headers);
+ }
+
curl_setopt_array($curl, $setopt_array);
$response = curl_exec($curl);
@@ -231,11 +244,16 @@ private function sendGetRequest(string $api): array
$this->echoDebugMessage($this->getHost() . $api);
$this->echoDebugMessage('Ответ от сервера Ypmn:');
if ($this->getJsonDebugResponse()) {
- $this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT));
+ $this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
} else {
$this->echoDebugMessage($response);
}
+ if ($this->getDebugShowResponseHeaders()) {
+ $this->echoDebugMessage('Заголовки ответа от сервера Ypmn:');
+ $this->echoDebugMessage(implode("\n", $headers));
+ }
+
if (mb_strlen($err) > 0) {
$this->echoDebugMessage('Ошибка');
echo '
Вы можете отправить запрос на поддержку на itsupport@ypmn.ru';
@@ -296,7 +314,7 @@ public function sendPostRequest($data, string $api): array
$date = (new DateTime())->format(DateTimeInterface::ATOM);
$requestHttpVerb = 'POST';
- curl_setopt_array($curl, [
+ $setOptArray = [
CURLOPT_URL => $this->getHost() . $api,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
@@ -318,7 +336,15 @@ public function sendPostRequest($data, string $api): array
$encodedJsonDataHash
)
]
- ]);
+ ];
+
+ $headers = [];
+
+ if ($this->getDebugShowResponseHeaders()) {
+ $this->addCurlOptHeaderFunction($setOptArray, $headers);
+ }
+
+ curl_setopt_array($curl, $setOptArray);
$response = curl_exec($curl);
$err = curl_error($curl);
@@ -328,7 +354,12 @@ public function sendPostRequest($data, string $api): array
$this->echoDebugMessage('POST-Запрос к серверу Ypmn:');
$this->echoDebugMessage($encodedJsonData);
$this->echoDebugMessage('Ответ от сервера Ypmn:');
- $this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT));
+ $this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
+
+ if ($this->getDebugShowResponseHeaders()) {
+ $this->echoDebugMessage('Заголовки ответа от сервера Ypmn:');
+ $this->echoDebugMessage(implode("\n", $headers));
+ }
if (mb_strlen($err) > 0) {
$this->echoDebugMessage('Ошибка');
@@ -594,4 +625,60 @@ public function sendPodeliRegistrationMerchantRequest(PodeliMerchant $merchant):
{
return $this->sendPostRequest($merchant, self::PODELI_MERCHANT_REGISTRATION_API);
}
+
+ /** @inheritdoc */
+ public function sendQstCreateRequest(QstInterface $qst): array
+ {
+ return $this->sendPostRequest($qst, self::QST_CREATE_API);
+ }
+
+ /** @inheritdoc */
+ public function sendQstStatusRequest(int $qstId): array
+ {
+ return $this->sendGetRequest(self::QST_STATUS_API . '/' . $qstId);
+ }
+
+ /** @inheritdoc */
+ public function sendQstPrintRequest(int $qstId): array
+ {
+ return $this->sendGetRequest(self::QST_PRINT_API . '/' . $qstId);
+ }
+
+ /** @inheritdoc */
+ public function sendQstListRequest(): array
+ {
+ return $this->sendGetRequest(self::QST_LIST_API);
+ }
+
+ /** @inheritdoc */
+ public function getDebugShowResponseHeaders(): bool
+ {
+ return $this->debugShowResponseHeaders;
+ }
+
+ /** @inheritdoc */
+ public function setDebugShowResponseHeaders(bool $debugShowResponseHeaders = true): self
+ {
+ $this->debugShowResponseHeaders = $debugShowResponseHeaders;
+ return $this;
+ }
+
+ /**
+ * @param array $curlOptArr
+ * @param array $headers
+ * @return void
+ */
+ private function addCurlOptHeaderFunction(array &$curlOptArr, array &$headers): void
+ {
+ $curlOptArr += [
+ CURLOPT_HEADERFUNCTION => static function($curl, $header) use (&$headers)
+ {
+ if (strlen(trim($header)) > 0) {
+ $headers[] = trim($header);
+ }
+
+ return strlen($header);
+ }
+ ];
+ }
}
diff --git a/src/ApiRequestInterface.php b/src/ApiRequestInterface.php
index ad54168..eaed9f5 100644
--- a/src/ApiRequestInterface.php
+++ b/src/ApiRequestInterface.php
@@ -146,4 +146,44 @@ public function setHost(string $host) : self;
* @return array
*/
public function sendPodeliRegistrationMerchantRequest(PodeliMerchant $merchant): array;
+
+ /**
+ * Отправить запрос на создание и отправку анкеты (по добавлению продавцов) на проверку
+ * @param Qst $qst
+ * @return array
+ */
+ public function sendQstCreateRequest(QstInterface $qst): array;
+
+ /**
+ * Получить статус анкеты
+ * @param int $qstId
+ * @return array
+ */
+ public function sendQstStatusRequest(int $qstId): array;
+
+ /**
+ * Распечатать анкету
+ * @param int $qstId
+ * @return array
+ */
+ public function sendQstPrintRequest(int $qstId): array;
+
+ /**
+ * Получить список анкет
+ * @return array
+ */
+ public function sendQstListRequest(): array;
+
+ /**
+ * Получить установлен ли режим показывать заголовки ответа в режиме отладки
+ * @return bool
+ */
+ public function getDebugShowResponseHeaders(): bool;
+
+ /**
+ * Установить показывать заголовки ответа в режиме отладки
+ * @param bool $debugShowResponseHeaders
+ * @return self
+ */
+ public function setDebugShowResponseHeaders(bool $debugShowResponseHeaders = true): self;
}
diff --git a/src/Examples/getToken.php b/src/Examples/getToken.php
index cfc8250..efac48b 100644
--- a/src/Examples/getToken.php
+++ b/src/Examples/getToken.php
@@ -33,7 +33,7 @@
Вот он: ' . $responseData['token'] . '
-
Тперь его можно использовать в платежах вместо данных карты
+
Теперь его можно использовать в платежах вместо данных карты
',
]);
}
diff --git a/src/Examples/qstCreateIp.php b/src/Examples/qstCreateIp.php
new file mode 100644
index 0000000..ec03f68
--- /dev/null
+++ b/src/Examples/qstCreateIp.php
@@ -0,0 +1,89 @@
+setInn('773200328662');
+
+/* Данные продавца */
+$qstSchema = new QstSchema();
+$qstSchema->addPhone('+7 495 1234567, доб. 123');
+$qstSchema->addEmail('example@ypmn.com');
+
+$qstLegalAddress = (new QstSchemaLegalAddress())
+ ->setZip('123456')
+ ->setRegion('Москва')
+ ->setCity('Москва')
+ ->setStreet('ул. Охотный ряд')
+ ->setHouse('1');
+$qstSchema->setLegalAddress($qstLegalAddress);
+
+$qstActualAddress = (new QstSchemaActualAddress())->setChecked(true);
+$qstSchema->setActualAddress($qstActualAddress);
+
+$qstPostAddress = (new QstSchemaPostAddress())->setChecked(true);
+$qstSchema->setPostAddress($qstPostAddress);
+
+$qstIdentityDoc = (new QstSchemaIdentityDoc())
+ ->setSeries('1234')
+ ->setNumber('123456')
+ ->setIssueDate('2000-01-30')
+ ->setIssuedBy('МВД')
+ ->setIssuedByKP('123-456');
+
+$qstSchema
+ ->setBirthDate('1969-02-23')
+ ->setBirthPlace('Москва')
+ ->setIdentityDoc($qstIdentityDoc);
+
+$qstBankAccount = (new QstSchemaBankAccount())
+ ->setBankBIK('044525700')
+ ->setBankCorAccount('30101810200000000700')
+ ->setBankAccount('40702810100002400756');
+
+$qstSchema->addBankAccount($qstBankAccount);
+
+$qstSchema->setAdditionalFieldByKey(1, 'Доп. поле');
+
+$qst->setSchema($qstSchema);
+
+/* Создадим HTTP-запрос к API */
+$apiRequest = new ApiRequest($merchant);
+
+// Включить режим отладки (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setDebugMode();
+// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setSandboxMode();
+
+/* Запрос на отправку анкеты */
+$responseData = $apiRequest->sendQstCreateRequest($qst);
+
+/* Преобразуем ответ из JSON в массив */
+try {
+ $responseData = json_decode((string) $responseData["response"], true);
+ if (isset($responseData['id'])) {
+ echo "Анкета #{$responseData['id']} создана и отправлена на проверку";
+ } else {
+ echo "Анкета не создана, см. причину в ответа от сервера YPMN";
+ }
+} catch (Exception $exception) {
+ echo "Ошибка запроса: {$exception->getMessage()}";
+ throw new Exception($exception->getMessage());
+}
diff --git a/src/Examples/qstCreateOrg.php b/src/Examples/qstCreateOrg.php
new file mode 100644
index 0000000..4a062fd
--- /dev/null
+++ b/src/Examples/qstCreateOrg.php
@@ -0,0 +1,94 @@
+setInn('7704217370');
+
+/* Данные продавца */
+$qstSchema = new QstSchema();
+$qstSchema->addPhone('+7 495 1234567, доб. 123');
+$qstSchema->addPhone('+7 499 7654321, доб. 321');
+$qstSchema->addEmail('example@ypmn.com');
+
+$qstLegalAddress = (new QstSchemaLegalAddress())
+ ->setZip('123112')
+ ->setRegion('Москва')
+ ->setCity('Москва')
+ ->setStreet('Пресненская наб.')
+ ->setHouse('д. 10')
+ ->setFlat('эт. 41, Пом. I, комн. 6');
+$qstSchema->setLegalAddress($qstLegalAddress);
+
+$qstActualAddress = (new QstSchemaActualAddress())->setChecked(true);
+$qstSchema->setActualAddress($qstActualAddress);
+
+$qstCeoIdentityDoc = (new QstSchemaIdentityDoc())
+ ->setSeries('1234')
+ ->setNumber('123456')
+ ->setIssueDate('2000-01-30')
+ ->setIssuedBy('МВД')
+ ->setIssuedByKP('123-456');
+
+$qstCeo = (new QstSchemaCeo())
+ ->setIdentityDoc($qstCeoIdentityDoc)
+ ->setBirthDate('1980-01-30')
+ ->setBirthPlace('Москва')
+ ->setRegistrationAddress('г. Москва, ул. Ленина, д. 1, кв. 1');
+$qstSchema->setCeo($qstCeo);
+
+$qstOwner = (new QstSchemaOwner())->setOwner('Иванов Иван Иванович')->setShare('100');
+$qstSchema->addOwner($qstOwner);
+
+$qstBankAccount = (new QstSchemaBankAccount())
+ ->setBankBIK('044525700')
+ ->setBankCorAccount('30101810200000000700')
+ ->setBankAccount('40702810100002400756');
+
+$qstSchema->addBankAccount($qstBankAccount);
+
+$qstSchema->setAdditionalFieldByKey(1, 'Доп. поле');
+
+$qst->setSchema($qstSchema);
+
+/* Создадим HTTP-запрос к API */
+$apiRequest = new ApiRequest($merchant);
+
+// Включить режим отладки (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setDebugMode();
+// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setSandboxMode();
+
+/* Запрос на отправку анкеты */
+$responseData = $apiRequest->sendQstCreateRequest($qst);
+
+/* Преобразуем ответ из JSON в массив */
+try {
+ $responseData = json_decode((string) $responseData["response"], true);
+ if (isset($responseData['id'])) {
+ echo "Анкета #{$responseData['id']} создана и отправлена на проверку";
+ } else {
+ echo "Анкета не создана, см. причину в ответа от сервера YPMN";
+ }
+} catch (Exception $exception) {
+ echo "Ошибка запроса: {$exception->getMessage()}";
+ throw new Exception($exception->getMessage());
+}
diff --git a/src/Examples/qstList.php b/src/Examples/qstList.php
new file mode 100644
index 0000000..28ef173
--- /dev/null
+++ b/src/Examples/qstList.php
@@ -0,0 +1,19 @@
+setDebugMode();
+// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setSandboxMode();
+
+/* Запрос на получение списка анкет */
+$responseData = $apiRequest->sendQstListRequest();
diff --git a/src/Examples/qstPrint.php b/src/Examples/qstPrint.php
new file mode 100644
index 0000000..c01d100
--- /dev/null
+++ b/src/Examples/qstPrint.php
@@ -0,0 +1,22 @@
+setDebugMode();
+// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setSandboxMode();
+
+/* id анкеты, полученный при создании анкеты */
+$qstId = 1;
+
+/* Запрос на получение pdf анкеты */
+$apiRequest->sendQstPrintRequest($qstId);
diff --git a/src/Examples/qstStatus.php b/src/Examples/qstStatus.php
new file mode 100644
index 0000000..37d4f1d
--- /dev/null
+++ b/src/Examples/qstStatus.php
@@ -0,0 +1,22 @@
+setDebugMode();
+// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
+$apiRequest->setSandboxMode();
+
+/* id анкеты, полученный при создании анкеты */
+$qstId = 1;
+
+/* Запрос на получение статуса анкеты */
+$responseData = $apiRequest->sendQstStatusRequest($qstId);
diff --git a/src/Qst.php b/src/Qst.php
new file mode 100644
index 0000000..0c80513
--- /dev/null
+++ b/src/Qst.php
@@ -0,0 +1,55 @@
+inn;
+ }
+
+ /** @inheritdoc */
+ public function setInn(string $inn): self
+ {
+ $this->inn = $inn;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getSchema(): QstSchemaInterface
+ {
+ return $this->schema;
+ }
+
+ /** @inheritdoc */
+ public function setSchema(QstSchemaInterface $schema): self
+ {
+ $this->schema = $schema;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function jsonSerialize(): string
+ {
+ $requestData = [
+ 'inn' => $this->getInn(),
+ 'schema' => $this->getSchema()->toArray()
+ ];
+
+ return json_encode($requestData, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_LINE_TERMINATORS);
+ }
+}
diff --git a/src/QstInterface.php b/src/QstInterface.php
new file mode 100644
index 0000000..ac4bfb2
--- /dev/null
+++ b/src/QstInterface.php
@@ -0,0 +1,34 @@
+foreignName;
+ }
+
+ /** @inheritdoc */
+ public function setForeignName(string $foreignName): self
+ {
+ $this->foreignName = $foreignName;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getPhones(): array
+ {
+ return $this->phones;
+ }
+
+ /** @inheritdoc */
+ public function addPhone(string $phone): self
+ {
+ $this->phones[] = compact('phone');
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getEmails(): array
+ {
+ return $this->emails;
+ }
+
+ /** @inheritdoc */
+ public function addEmail(string $email): self
+ {
+ $this->emails[] = compact('email');
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getLegalAddress(): QstSchemaAddressInterface
+ {
+ return $this->legalAddress;
+ }
+
+ /** @inheritdoc */
+ public function setLegalAddress(QstSchemaAddressInterface $legalAddress): self
+ {
+ $this->legalAddress = $legalAddress;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getPostAddress(): ?QstSchemaAddressInterface
+ {
+ return $this->postAddress;
+ }
+
+ /** @inheritdoc */
+ public function setPostAddress(QstSchemaAddressInterface $postAddress): self
+ {
+ $this->postAddress = $postAddress;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getActualAddress(): QstSchemaAddressInterface
+ {
+ return $this->actualAddress;
+ }
+
+ /** @inheritdoc */
+ public function setActualAddress(QstSchemaAddressInterface $actualAddress): self
+ {
+ $this->actualAddress = $actualAddress;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getCeo(): ?QstSchemaCeoInterface
+ {
+ return $this->ceo;
+ }
+
+ /** @inheritdoc */
+ public function setCeo(QstSchemaCeoInterface $ceo): self
+ {
+ $this->ceo = $ceo;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getOwners(): array
+ {
+ return $this->owners;
+ }
+
+ /** @inheritdoc */
+ public function addOwner(QstSchemaOwnerInterface $owner): self
+ {
+ $this->owners[] = $owner;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBoardOfDirectors(): ?string
+ {
+ return $this->boardOfDirectors;
+ }
+
+ /** @inheritdoc */
+ public function setBoardOfDirectors(string $boardOfDirectors): self
+ {
+ $this->boardOfDirectors = $boardOfDirectors;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getManagementBoard(): ?string
+ {
+ return $this->managementBoard;
+ }
+
+ /** @inheritdoc */
+ public function setManagementBoard(string $managementBoard): self
+ {
+ $this->managementBoard = $managementBoard;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getOtherManagementBodies(): ?string
+ {
+ return $this->otherManagementBodies;
+ }
+
+ /** @inheritdoc */
+ public function setOtherManagementBodies(string $otherManagementBodies): self
+ {
+ $this->otherManagementBodies = $otherManagementBodies;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getAddressLocation(): ?string
+ {
+ return $this->addressLocation;
+ }
+
+ /** @inheritdoc */
+ public function setAddressLocation(string $addressLocation): self
+ {
+ $this->addressLocation = $addressLocation;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBirthDate(): ?string
+ {
+ return $this->birthDate;
+ }
+
+ /** @inheritdoc */
+ public function setBirthDate(string $birthDate): self
+ {
+ $this->birthDate = $birthDate;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBirthPlace(): ?string
+ {
+ return $this->birthPlace;
+ }
+
+ /** @inheritdoc */
+ public function setBirthPlace(string $birthPlace): self
+ {
+ $this->birthPlace = $birthPlace;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getIdentityDoc(): ?QstSchemaIdentityDocInterface
+ {
+ return $this->identityDoc;
+ }
+
+ /** @inheritdoc */
+ public function setIdentityDoc(QstSchemaIdentityDocInterface $identityDoc): self
+ {
+ $this->identityDoc = $identityDoc;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBankAccounts(): array
+ {
+ return $this->bankAccounts;
+ }
+
+ /** @inheritdoc */
+ public function addBankAccount(QstSchemaBankAccountInterface $bankAccount): self
+ {
+ $this->bankAccounts[] = $bankAccount;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getLicense(): ?string
+ {
+ return $this->license;
+ }
+
+ /** @inheritdoc */
+ public function setLicense(string $license): self
+ {
+ $this->license = $license;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getActionInFavor(): ?string
+ {
+ return $this->actionInFavor;
+ }
+
+ /** @inheritdoc */
+ public function setActionInFavor(string $actionInFavor): self
+ {
+ $this->actionInFavor = $actionInFavor;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getCommission(): ?string
+ {
+ return $this->commission;
+ }
+
+ /** @inheritdoc */
+ public function setCommission(string $commission): self
+ {
+ $this->commission = $commission;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getAdditionalFields(): array
+ {
+ return $this->additionalFields;
+ }
+
+ /** @inheritdoc */
+ public function getAdditionalFieldByKey(int $key): ?string
+ {
+ return $this->additionalFields[$key] ?? null;
+ }
+
+ /** @inheritdoc */
+ public function setAdditionalFieldByKey(int $key, string $value): self
+ {
+ $this->additionalFields[$key] = $value;
+
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): array
+ {
+ $array = [
+ 'foreignName' => $this->getForeignName(),
+ 'phones' => $this->getPhones(),
+ 'emails' => $this->getEmails(),
+ 'legalAddress' => $this->getLegalAddress()->toArray(),
+ 'postAddress' => $this->getPostAddress() ? $this->getPostAddress()->toArray() : null,
+ 'actualAddress' => $this->getActualAddress()->toArray(),
+ 'ceo' => $this->getCeo() ? $this->getCeo()->toArray() : null,
+ 'owners' =>
+ !empty($this->getOwners())
+ ? array_map(static fn (QstSchemaOwnerInterface $owner) => $owner->toArray(), $this->getOwners())
+ : null,
+ 'boardOfDirectors' => $this->getBoardOfDirectors(),
+ 'managementBoard' => $this->getManagementBoard(),
+ 'otherManagementBodies' => $this->getOtherManagementBodies(),
+ 'addressLocation' => $this->getAddressLocation(),
+ 'birthDate' => $this->getBirthDate(),
+ 'birthPlace' => $this->getBirthPlace(),
+ 'identityDoc' => $this->getIdentityDoc() ? $this->getIdentityDoc()->toArray() : null,
+ 'bankAccounts' => array_map(
+ static fn (QstSchemaBankAccountInterface $bankAccount) => ['bankAccount' => $bankAccount->toArray()],
+ $this->getBankAccounts()
+ ),
+ 'license' => $this->getLicense(),
+ 'actionInFavor' => $this->getActionInFavor(),
+ 'commission' => $this->getCommission(),
+ ];
+
+ foreach ($this->additionalFields as $key => $value) {
+ $array['additionalField' . $key] = $value;
+ }
+
+ return array_filter($array, static fn ($value) => $value !== null);
+ }
+}
diff --git a/src/QstSchemaActualAddress.php b/src/QstSchemaActualAddress.php
new file mode 100644
index 0000000..5331a78
--- /dev/null
+++ b/src/QstSchemaActualAddress.php
@@ -0,0 +1,27 @@
+isChecked()) {
+ return [
+ 'isEqualToLegalAddress' => true
+ ];
+ }
+
+ return parent::toArray();
+ }
+}
diff --git a/src/QstSchemaAddressAbstract.php b/src/QstSchemaAddressAbstract.php
new file mode 100644
index 0000000..65b93d0
--- /dev/null
+++ b/src/QstSchemaAddressAbstract.php
@@ -0,0 +1,111 @@
+zip;
+ }
+
+ /** @inheritdoc */
+ public function setZip(string $zip): self
+ {
+ $this->zip = $zip;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getRegion(): string
+ {
+ return $this->region;
+ }
+
+ /** @inheritdoc */
+ public function setRegion(string $region): self
+ {
+ $this->region = $region;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getCity(): string
+ {
+ return $this->city;
+ }
+
+ /** @inheritdoc */
+ public function setCity(string $city): self
+ {
+ $this->city = $city;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getStreet(): string
+ {
+ return $this->street;
+ }
+
+ /** @inheritdoc */
+ public function setStreet(string $street): self
+ {
+ $this->street = $street;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getHouse(): string
+ {
+ return $this->house;
+ }
+
+ /** @inheritdoc */
+ public function setHouse(string $house): self
+ {
+ $this->house = $house;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getFlat(): ?string
+ {
+ return $this->flat;
+ }
+
+ /** @inheritdoc */
+ public function setFlat(string $flat): self
+ {
+ $this->flat = $flat;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): ?array
+ {
+ $array = [
+ 'zip' => $this->getZip(),
+ 'region' => $this->getRegion(),
+ 'city' => $this->getCity(),
+ 'street' => $this->getStreet(),
+ 'house' => $this->getHouse(),
+ 'flat' => $this->getFlat()
+ ];
+
+ return array_filter($array, static fn ($value) => $value !== null);
+ }
+}
diff --git a/src/QstSchemaAddressInterface.php b/src/QstSchemaAddressInterface.php
new file mode 100644
index 0000000..bfbe68d
--- /dev/null
+++ b/src/QstSchemaAddressInterface.php
@@ -0,0 +1,86 @@
+bankBIK;
+ }
+
+ /** @inheritdoc */
+ public function setBankBIK(string $bankBIK): self
+ {
+ $this->bankBIK = $bankBIK;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBankCorAccount(): string
+ {
+ return $this->bankCorAccount;
+ }
+
+ /** @inheritdoc */
+ public function setBankCorAccount(string $bankCorAccount): self
+ {
+ $this->bankCorAccount = $bankCorAccount;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBankAccount(): string
+ {
+ return $this->bankAccount;
+ }
+
+ /** @inheritdoc */
+ public function setBankAccount(string $bankAccount): self
+ {
+ $this->bankAccount = $bankAccount;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): array
+ {
+ return [
+ 'bankBIK' => $this->getBankBIK(),
+ 'bankCorAccount' => $this->getBankCorAccount(),
+ 'bankAccount' => $this->getBankAccount()
+ ];
+ }
+}
\ No newline at end of file
diff --git a/src/QstSchemaBankAccountInterface.php b/src/QstSchemaBankAccountInterface.php
new file mode 100644
index 0000000..7725f42
--- /dev/null
+++ b/src/QstSchemaBankAccountInterface.php
@@ -0,0 +1,47 @@
+citizenship;
+ }
+
+ /** @inheritdoc */
+ public function setCitizenship(string $citizenship): self
+ {
+ $this->citizenship = $citizenship;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBirthDate(): string
+ {
+ return $this->birthDate;
+ }
+
+ /** @inheritdoc */
+ public function setBirthDate(string $birthDate): self
+ {
+ $this->birthDate = $birthDate;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getBirthPlace(): string
+ {
+ return $this->birthPlace;
+ }
+
+ /** @inheritdoc */
+ public function setBirthPlace(string $birthPlace): self
+ {
+ $this->birthPlace = $birthPlace;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getIdentityDoc(): QstSchemaIdentityDocInterface
+ {
+ return $this->identityDoc;
+ }
+
+ /** @inheritdoc */
+ public function setIdentityDoc(QstSchemaIdentityDocInterface $identityDoc): self
+ {
+ $this->identityDoc = $identityDoc;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getRegistrationAddress(): string
+ {
+ return $this->registrationAddress;
+ }
+
+ /** @inheritdoc */
+ public function setRegistrationAddress(string $registrationAddress): self
+ {
+ $this->registrationAddress = $registrationAddress;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): ?array
+ {
+ $array = [
+ 'citizenship' => $this->getCitizenship(),
+ 'birthDate' => $this->getBirthDate(),
+ 'birthPlace' => $this->getBirthPlace(),
+ 'identityDoc' => $this->getIdentityDoc()->toArray(),
+ 'registrationAddress' => $this->getRegistrationAddress()
+ ];
+
+ return array_filter($array, static fn ($value) => $value !== null);
+ }
+}
\ No newline at end of file
diff --git a/src/QstSchemaCeoInterface.php b/src/QstSchemaCeoInterface.php
new file mode 100644
index 0000000..2f44d30
--- /dev/null
+++ b/src/QstSchemaCeoInterface.php
@@ -0,0 +1,73 @@
+checked;
+ }
+
+ /**
+ * Установить свойство isChecked для поля в анкете
+ * @param bool|null $checked
+ * @return $this
+ */
+ public function setChecked(bool $checked)
+ {
+ $this->checked = $checked;
+ return $this;
+ }
+}
diff --git a/src/QstSchemaIdentityDoc.php b/src/QstSchemaIdentityDoc.php
new file mode 100644
index 0000000..cb57624
--- /dev/null
+++ b/src/QstSchemaIdentityDoc.php
@@ -0,0 +1,116 @@
+ 'PASSPORT',
+ 'other' => 'OTHER'
+ ];
+
+ private ?string $type = null;
+ private string $series;
+ private string $number;
+ private string $issueDate;
+ private string $issuedBy;
+ private string $issuedByKP;
+
+ /** @inheritdoc */
+ public function getType(): ?string
+ {
+ return $this->type;
+ }
+
+ /** @inheritdoc */
+ public function setType(string $type): self
+ {
+ $this->type = $type;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getSeries(): string
+ {
+ return $this->series;
+ }
+
+ /** @inheritdoc */
+ public function setSeries(string $series): self
+ {
+ $this->series = $series;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getNumber(): string
+ {
+ return $this->number;
+ }
+
+ /** @inheritdoc */
+ public function setNumber(string $number): self
+ {
+ $this->number = $number;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getIssueDate(): string
+ {
+ return $this->issueDate;
+ }
+
+ /** @inheritdoc */
+ public function setIssueDate(string $issueDate): self
+ {
+ $this->issueDate = $issueDate;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getIssuedBy(): string
+ {
+ return $this->issuedBy;
+ }
+
+ /** @inheritdoc */
+ public function setIssuedBy(string $issuedBy): self
+ {
+ $this->issuedBy = $issuedBy;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getIssuedByKP(): string
+ {
+ return $this->issuedByKP;
+ }
+
+ /** @inheritdoc */
+ public function setIssuedByKP(string $issuedByKP): self
+ {
+ $this->issuedByKP = $issuedByKP;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): ?array
+ {
+ $array = [
+ 'type' => $this->getType(),
+ 'series' => $this->getSeries(),
+ 'number' => $this->getNumber(),
+ 'issueDate' => $this->getIssueDate(),
+ 'issuedBy' => $this->getIssuedBy(),
+ 'issuedByKP' => $this->getIssuedByKP()
+ ];
+
+ return array_filter($array, static fn ($value) => $value !== null);
+ }
+}
\ No newline at end of file
diff --git a/src/QstSchemaIdentityDocInterface.php b/src/QstSchemaIdentityDocInterface.php
new file mode 100644
index 0000000..aa4da1d
--- /dev/null
+++ b/src/QstSchemaIdentityDocInterface.php
@@ -0,0 +1,90 @@
+owner;
+ }
+
+ /** @inheritdoc */
+ public function setOwner(string $owner): self
+ {
+ $this->owner = $owner;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function getShare(): string
+ {
+ return $this->share;
+ }
+
+ /** @inheritdoc */
+ public function setShare(string $share): self
+ {
+ $this->share = $share;
+ return $this;
+ }
+
+ /** @inheritdoc */
+ public function toArray(): array
+ {
+ return [
+ 'owner' => $this->getOwner(),
+ 'share' => $this->getShare(),
+ ];
+ }
+}
\ No newline at end of file
diff --git a/src/QstSchemaOwnerInterface.php b/src/QstSchemaOwnerInterface.php
new file mode 100644
index 0000000..7423f1a
--- /dev/null
+++ b/src/QstSchemaOwnerInterface.php
@@ -0,0 +1,34 @@
+isChecked()) {
+ return [
+ 'isEqualToLegalAddress' => true
+ ];
+ }
+
+ return parent::toArray();
+ }
+}
diff --git a/src/QstToArrayInterface.php b/src/QstToArrayInterface.php
new file mode 100644
index 0000000..9aa88f4
--- /dev/null
+++ b/src/QstToArrayInterface.php
@@ -0,0 +1,13 @@
+