diff --git a/Hcs.Client/Client/Api/Payload/Payments/ImportSupplierNotificationsOfOrderExecutionPayload.cs b/Hcs.Client/Client/Api/Payload/Payments/ImportSupplierNotificationsOfOrderExecutionPayload.cs
new file mode 100644
index 0000000..af2398e
--- /dev/null
+++ b/Hcs.Client/Client/Api/Payload/Payments/ImportSupplierNotificationsOfOrderExecutionPayload.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace Hcs.Client.Api.Payload.Payments
+{
+ // http://open-gkh.ru/Payment/importSupplierNotificationsOfOrderExecutionRequest/SupplierNotificationOfOrderExecution.html
+ public class ImportSupplierNotificationsOfOrderExecutionPayload
+ {
+ ///
+ /// Дата внесения платы (в случае отсутствия: дата поступления средств)
+ ///
+ public DateTime orderDate;
+
+ ///
+ /// Необязательное. Месяц, за который вносится плата. Указывать совместно с .
+ ///
+ public int? month;
+
+ ///
+ /// Необязательное. Год, за который вносится плата. Указывать совместно с .
+ ///
+ public short? year;
+
+ ///
+ /// Идентификатор платежного документа
+ ///
+ public string paymentDocumentId;
+
+ ///
+ /// Сумма
+ ///
+ public decimal amount;
+
+ ///
+ /// Необязательное. Признак онлайн-оплаты.
+ ///
+ public bool? onlinePayment;
+ }
+}
diff --git a/Hcs.Client/Client/Api/PaymentsApi.cs b/Hcs.Client/Client/Api/PaymentsApi.cs
new file mode 100644
index 0000000..ec114bb
--- /dev/null
+++ b/Hcs.Client/Client/Api/PaymentsApi.cs
@@ -0,0 +1,23 @@
+using Hcs.Client.Api.Payload.Payments;
+using Hcs.Client.Api.Request.Payments;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Hcs.Client.Api
+{
+ // http://open-gkh.ru/PaymentsServiceAsync/
+ public class PaymentsApi(ClientBase client) : ApiBase(client)
+ {
+ ///
+ /// Импорт пакета документов "Извещение о принятии к исполнению распоряжения", размещаемых исполнителем
+ ///
+ /// Пейлоад документа
+ /// Токен отмены
+ /// true, если операция выполнена успешно, иначе - false
+ public async Task ImportSupplierNotificationsOfOrderExecutionAsync(ImportSupplierNotificationsOfOrderExecutionPayload payload, CancellationToken token = default)
+ {
+ var request = new ImportSupplierNotificationsOfOrderExecutionRequest(client);
+ return await request.ExecuteAsync(payload, token);
+ }
+ }
+}
diff --git a/Hcs.Client/Client/Api/Request/Payments/ImportSupplierNotificationsOfOrderExecutionRequest.cs b/Hcs.Client/Client/Api/Request/Payments/ImportSupplierNotificationsOfOrderExecutionRequest.cs
new file mode 100644
index 0000000..94fd933
--- /dev/null
+++ b/Hcs.Client/Client/Api/Request/Payments/ImportSupplierNotificationsOfOrderExecutionRequest.cs
@@ -0,0 +1,97 @@
+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 ImportSupplierNotificationsOfOrderExecutionRequest(ClientBase client) : PaymentsRequestBase(client)
+ {
+ protected override bool CanBeRestarted => false;
+
+ internal async Task ExecuteAsync(ImportSupplierNotificationsOfOrderExecutionPayload payload, CancellationToken token)
+ {
+ ThrowIfPayloadIncorrect(payload);
+
+ // http://open-gkh.ru/Payment/importSupplierNotificationsOfOrderExecutionRequest.html
+ var request = new importSupplierNotificationsOfOrderExecutionRequest
+ {
+ Id = Constants.SIGNED_XML_ELEMENT_ID,
+ version = "10.0.1.1",
+ SupplierNotificationOfOrderExecution = [GetNotificationFromPayload(payload)]
+ };
+
+ var result = await SendAndWaitResultAsync(request, async asyncClient =>
+ {
+ var response = await asyncClient.importSupplierNotificationsOfOrderExecutionAsync(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(ImportSupplierNotificationsOfOrderExecutionPayload payload)
+ {
+ 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");
+ }
+ }
+
+ private importSupplierNotificationsOfOrderExecutionRequestSupplierNotificationOfOrderExecution GetNotificationFromPayload(ImportSupplierNotificationsOfOrderExecutionPayload payload)
+ {
+ var notification = new importSupplierNotificationsOfOrderExecutionRequestSupplierNotificationOfOrderExecution()
+ {
+ TransportGUID = Guid.NewGuid().ToString(),
+ OrderDate = payload.orderDate,
+ Item = payload.paymentDocumentId,
+ ItemElementName = ItemChoiceType1.PaymentDocumentID,
+ Amount = payload.amount
+ };
+
+ if (payload.month.HasValue)
+ {
+ notification.OrderPeriod = new SupplierNotificationOfOrderExecutionTypeOrderPeriod()
+ {
+ Month = payload.month.Value,
+ Year = payload.year.Value
+ };
+ }
+
+ if (payload.onlinePayment.HasValue && payload.onlinePayment.Value)
+ {
+ notification.OnlinePayment = true;
+ notification.OnlinePaymentSpecified = true;
+ }
+
+ return notification;
+ }
+ }
+}
diff --git a/Hcs.Client/Client/Api/Request/Payments/PaymentsRequestBase.cs b/Hcs.Client/Client/Api/Request/Payments/PaymentsRequestBase.cs
new file mode 100644
index 0000000..9bfdc94
--- /dev/null
+++ b/Hcs.Client/Client/Api/Request/Payments/PaymentsRequestBase.cs
@@ -0,0 +1,55 @@
+using Hcs.Client.Api.Request;
+using Hcs.Client.Api.Request.Adapter;
+using Hcs.Service.Async.Payments;
+using System.Threading.Tasks;
+
+namespace Hcs.Service.Async.Payments
+{
+#pragma warning disable IDE1006
+ public partial class getStateResult : IGetStateResultMany { }
+#pragma warning restore IDE1006
+
+ public partial class PaymentPortsTypeAsyncClient : IAsyncClient
+ {
+ public async Task GetStateAsync(RequestHeader header, IGetStateRequest request)
+ {
+ return await getStateAsync(header, (getStateRequest)request);
+ }
+ }
+
+#pragma warning disable IDE1006
+ public partial class getStateResponse : IGetStateResponse
+#pragma warning restore IDE1006
+ {
+ public IGetStateResult GetStateResult => getStateResult;
+ }
+
+ public partial class AckRequestAck : IAck { }
+
+ public partial class ErrorMessageType : IErrorMessage { }
+
+#pragma warning disable IDE1006
+ public partial class getStateRequest : IGetStateRequest { }
+#pragma warning restore IDE1006
+}
+
+namespace Hcs.Client.Api.Request.Payments
+{
+ internal class PaymentsRequestBase(ClientBase client) :
+ RequestBase(client)
+ {
+ protected override EndPoint EndPoint => EndPoint.PaymentsAsync;
+
+ protected override bool EnableMinimalResponseWaitDelay => true;
+
+ protected override bool CanBeRestarted => true;
+
+ protected override int RestartTimeoutMinutes => 20;
+ }
+}
diff --git a/Hcs.Client/Client/UniClient.cs b/Hcs.Client/Client/UniClient.cs
index cf23e38..c1f11a3 100644
--- a/Hcs.Client/Client/UniClient.cs
+++ b/Hcs.Client/Client/UniClient.cs
@@ -23,6 +23,8 @@ namespace Hcs.Client
public OrgRegistryCommonApi OrgRegistryCommon => new(this);
+ public PaymentsApi Payments => new(this);
+
public void SetSigningCertificate(X509Certificate2 cert, string pin = null)
{
pin ??= Constants.DEFAULT_CERTIFICATE_PIN;
diff --git a/Hcs.Client/Hcs.Client.csproj b/Hcs.Client/Hcs.Client.csproj
index 64965c5..ee607ae 100644
--- a/Hcs.Client/Hcs.Client.csproj
+++ b/Hcs.Client/Hcs.Client.csproj
@@ -79,6 +79,8 @@
+
+
@@ -126,6 +128,8 @@
+
+
diff --git a/Hcs.TestApp/Hcs.TestApp.csproj b/Hcs.TestApp/Hcs.TestApp.csproj
index 792f1f2..5133fc2 100644
--- a/Hcs.TestApp/Hcs.TestApp.csproj
+++ b/Hcs.TestApp/Hcs.TestApp.csproj
@@ -76,6 +76,7 @@
+
diff --git a/Hcs.TestApp/TestApp/Program.cs b/Hcs.TestApp/TestApp/Program.cs
index 4946766..f2c7dd2 100644
--- a/Hcs.TestApp/TestApp/Program.cs
+++ b/Hcs.TestApp/TestApp/Program.cs
@@ -42,6 +42,7 @@ namespace Hcs.TestApp
var nsiScenario = new NsiScenario(client);
var nsiCommonScenario = new NsiCommonScenario(client);
var orgRegistryCommonScenario = new OrgRegistryCommonScenario(client);
+ var paymentsScenario = new PaymentsScenario(client);
try
{
//billsScenario.ImportPaymentDocument();
@@ -77,6 +78,8 @@ namespace Hcs.TestApp
//nsiCommonScenario.ExportNsiItem276();
//orgRegistryCommonScenario.ExportOrgRegistry();
+
+ //paymentsScenario.ImportSupplierNotificationsOfOrderExecution();
}
catch (Exception e)
{
diff --git a/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs b/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs
new file mode 100644
index 0000000..3757127
--- /dev/null
+++ b/Hcs.TestApp/TestApp/Scenario/PaymentsScenario.cs
@@ -0,0 +1,27 @@
+using Hcs.Client;
+using Hcs.Client.Api.Payload.Payments;
+using System;
+
+namespace Hcs.TestApp.Scenario
+{
+ internal class PaymentsScenario(UniClient client)
+ {
+ private readonly UniClient client = client;
+
+ internal void ImportSupplierNotificationsOfOrderExecution()
+ {
+ var payload = new ImportSupplierNotificationsOfOrderExecutionPayload()
+ {
+ orderDate = new DateTime(2025, 9, 5),
+ month = 8,
+ year = 2025,
+ paymentDocumentId = "00АА095186-02-5081",
+ amount = 4000M,
+ onlinePayment = true
+ };
+
+ var result = client.Payments.ImportSupplierNotificationsOfOrderExecutionAsync(payload).Result;
+ Console.WriteLine("Scenario execution " + (result ? "succeeded" : "failed"));
+ }
+ }
+}