diff --git a/Hcs.Client/Client/Api/Payload/Payments/ImportNotificationsOfOrderExecutionPayload.cs b/Hcs.Client/Client/Api/Payload/Payments/ImportNotificationsOfOrderExecutionPayload.cs
new file mode 100644
index 0000000..961efcb
--- /dev/null
+++ b/Hcs.Client/Client/Api/Payload/Payments/ImportNotificationsOfOrderExecutionPayload.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace Hcs.Client.Api.Payload.Payments
+{
+ // http://open-gkh.ru/Payment/importNotificationsOfOrderExecutionRequest/NotificationOfOrderExecution139Type.html
+ public class ImportNotificationsOfOrderExecutionPayload
+ {
+ ///
+ /// Уникальный номер платежа (идентификатор операции)
+ ///
+ public string orderId;
+
+ ///
+ /// Дата
+ ///
+ public DateTime orderDate;
+
+ ///
+ /// Сумма оплаты (в копейках)
+ ///
+ public decimal amount;
+
+ ///
+ /// Необязательное. Признак онлайн-оплаты.
+ ///
+ public bool? onlinePayment;
+
+ ///
+ /// Необязательное. Год. Указывать совместно с .
+ ///
+ public short? year;
+
+ ///
+ /// Необязательное. Месяц. Указывать совместно с .
+ ///
+ public int? month;
+
+ ///
+ /// Идентификатор платежного документа
+ ///
+ public string paymentDocumentId;
+
+ ///
+ /// GUID платежного документа
+ ///
+ public string paymentDocumentGUID;
+ }
+}
diff --git a/Hcs.Client/Client/Api/PaymentsApi.cs b/Hcs.Client/Client/Api/PaymentsApi.cs
index ec114bb..3e4814f 100644
--- a/Hcs.Client/Client/Api/PaymentsApi.cs
+++ b/Hcs.Client/Client/Api/PaymentsApi.cs
@@ -8,6 +8,18 @@ namespace Hcs.Client.Api
// http://open-gkh.ru/PaymentsServiceAsync/
public class PaymentsApi(ClientBase client) : ApiBase(client)
{
+ ///
+ /// ВИ_ОПЛАТА_ИЗВ. Передать перечень документов "Извещение о принятии к исполнению распоряжения".
+ ///
+ /// Пейлоад документа
+ /// Токен отмены
+ /// true, если операция выполнена успешно, иначе - false
+ public async Task ImportNotificationsOfOrderExecutionAsync(ImportNotificationsOfOrderExecutionPayload payload, CancellationToken token = default)
+ {
+ var request = new ImportNotificationsOfOrderExecutionRequest(client);
+ return await request.ExecuteAsync(payload, token);
+ }
+
///
/// Импорт пакета документов "Извещение о принятии к исполнению распоряжения", размещаемых исполнителем
///
diff --git a/Hcs.Client/Client/Api/Request/Payments/ImportNotificationsOfOrderExecutionRequest.cs b/Hcs.Client/Client/Api/Request/Payments/ImportNotificationsOfOrderExecutionRequest.cs
new file mode 100644
index 0000000..4ef77d8
--- /dev/null
+++ b/Hcs.Client/Client/Api/Request/Payments/ImportNotificationsOfOrderExecutionRequest.cs
@@ -0,0 +1,112 @@
+using Hcs.Client.Api.Payload.Payments;
+using Hcs.Client.Api.Request.Exception;
+using Hcs.Client.Internal;
+using Hcs.Service.Async.Payments;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Hcs.Client.Api.Request.Payments
+{
+ internal class ImportNotificationsOfOrderExecutionRequest(ClientBase client) : PaymentsRequestBase(client)
+ {
+ protected override bool CanBeRestarted => false;
+
+ internal async Task ExecuteAsync(ImportNotificationsOfOrderExecutionPayload payload, CancellationToken token)
+ {
+ ThrowIfPayloadIncorrect(payload);
+
+ // http://open-gkh.ru/Payment/importNotificationsOfOrderExecutionRequest.html
+ var request = new importNotificationsOfOrderExecutionRequest
+ {
+ Id = Constants.SIGNED_XML_ELEMENT_ID,
+ version = "10.0.1.1",
+ Items = [GetNotificationFromPayload(payload)]
+ };
+
+ var result = await SendAndWaitResultAsync(request, async asyncClient =>
+ {
+ var response = await asyncClient.importNotificationsOfOrderExecutionAsync(CreateRequestHeader(), request);
+ return response.AckRequest.Ack;
+ }, token);
+
+ result.Items.OfType().ToList().ForEach(error =>
+ {
+ throw RemoteException.CreateNew(error.ErrorCode, error.Description);
+ });
+
+ result.Items.OfType().ToList().ForEach(commonResult =>
+ {
+ commonResult.Items.OfType().ToList().ForEach(error =>
+ {
+ throw RemoteException.CreateNew(error.ErrorCode, error.Description);
+ });
+ });
+
+ return true;
+ }
+
+ private void ThrowIfPayloadIncorrect(ImportNotificationsOfOrderExecutionPayload payload)
+ {
+ if (string.IsNullOrEmpty(payload.orderId))
+ {
+ throw new ArgumentException($"{nameof(payload.orderId)} is empty");
+ }
+
+ if (payload.month.HasValue && !payload.year.HasValue)
+ {
+ throw new ArgumentException($"{nameof(payload.month)} has value but {nameof(payload.year)} has not");
+ }
+
+ if (!payload.month.HasValue && payload.year.HasValue)
+ {
+ throw new ArgumentException($"{nameof(payload.year)} has value but {nameof(payload.month)} has not");
+ }
+
+ if (string.IsNullOrEmpty(payload.paymentDocumentId))
+ {
+ throw new ArgumentException($"{nameof(payload.paymentDocumentId)} is empty");
+ }
+
+ if (string.IsNullOrEmpty(payload.paymentDocumentGUID))
+ {
+ throw new ArgumentException($"{nameof(payload.paymentDocumentGUID)} is empty");
+ }
+ }
+
+ private importNotificationsOfOrderExecutionRequestNotificationOfOrderExecution139Type GetNotificationFromPayload(ImportNotificationsOfOrderExecutionPayload payload)
+ {
+ var notification = new importNotificationsOfOrderExecutionRequestNotificationOfOrderExecution139Type()
+ {
+ TransportGUID = Guid.NewGuid().ToString(),
+ OrderInfo = new NotificationOfOrderExecution139TypeOrderInfo()
+ {
+ OrderID = payload.orderId,
+ OrderDate = payload.orderDate,
+ Amount = payload.amount,
+ // TODO: Проверить, возможно можно предоставить только один из двух параметров
+ Items = [payload.paymentDocumentId, payload.paymentDocumentGUID],
+ ItemsElementName = [ItemsChoiceType4.PaymentDocumentID, ItemsChoiceType4.PaymentDocumentGUID]
+ }
+ };
+
+ if (payload.onlinePayment.HasValue && payload.onlinePayment.Value)
+ {
+ notification.OrderInfo.OnlinePayment = true;
+ notification.OrderInfo.OnlinePaymentSpecified = true;
+ }
+
+ if (payload.month.HasValue)
+ {
+ notification.OrderInfo.MonthAndYear = new NotificationOfOrderExecution139TypeOrderInfoMonthAndYear()
+ {
+ Year = payload.year.Value,
+ Month = payload.month.Value
+ };
+ }
+
+ return notification;
+ }
+ }
+}
diff --git a/Hcs.Client/Hcs.Client.csproj b/Hcs.Client/Hcs.Client.csproj
index 854af73..1da3804 100644
--- a/Hcs.Client/Hcs.Client.csproj
+++ b/Hcs.Client/Hcs.Client.csproj
@@ -79,6 +79,7 @@
+
@@ -129,6 +130,7 @@
+
diff --git a/Hcs.TestApp/TestApp/Program.cs b/Hcs.TestApp/TestApp/Program.cs
index d655950..4b36cb7 100644
--- a/Hcs.TestApp/TestApp/Program.cs
+++ b/Hcs.TestApp/TestApp/Program.cs
@@ -80,6 +80,7 @@ namespace Hcs.TestApp
//orgRegistryCommonScenario.ExportDataProvider();
//orgRegistryCommonScenario.ExportOrgRegistry();
+ //paymentsScenario.ImportNotificationsOfOrderExecution();
//paymentsScenario.ImportSupplierNotificationsOfOrderExecution();
}
catch (Exception e)
diff --git a/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs b/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs
index 3757127..1131a38 100644
--- a/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs
+++ b/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs
@@ -8,6 +8,26 @@ namespace Hcs.TestApp.Scenario
{
private readonly UniClient client = client;
+ internal void ImportNotificationsOfOrderExecution()
+ {
+ var payload = new ImportNotificationsOfOrderExecutionPayload()
+ {
+ // TODO: Разобраться, что это за айди
+ orderId = "",
+ orderDate = new DateTime(2025, 9, 5),
+ amount = 4000M,
+ onlinePayment = true,
+ year = 2025,
+ month = 8,
+ paymentDocumentId = "00АА095186-02-5081",
+ // TODO: Возможно что не обязательно передавать оба параметра
+ paymentDocumentGUID = ""
+ };
+
+ var result = client.Payments.ImportNotificationsOfOrderExecutionAsync(payload).Result;
+ Console.WriteLine("Scenario execution " + (result ? "succeeded" : "failed"));
+ }
+
internal void ImportSupplierNotificationsOfOrderExecution()
{
var payload = new ImportSupplierNotificationsOfOrderExecutionPayload()