1- using System . Security . Cryptography ;
1+ using System . Globalization ;
2+ using System . Security . Cryptography ;
23using System . Security . Cryptography . X509Certificates ;
34using System . Text ;
45using System . Xml ;
78
89namespace OpenMicroFiscal ;
910
10- public sealed class InvoiceService
11+ public sealed class InvoiceService (
12+ HttpClient httpClient ,
13+ FiscalizationSettings settings ,
14+ ProvideCertificate provideCertificate )
1115{
12- private readonly HttpClient _httpClient ;
13- private readonly ProvideCertificate _provideCertificate ;
14- private readonly FiscalizationSettings _settings ;
15-
16- public InvoiceService (
17- HttpClient httpClient ,
18- FiscalizationSettings settings ,
19- ProvideCertificate provideCertificate )
20- {
21- _httpClient = httpClient ;
22- _settings = settings ;
23- _provideCertificate = provideCertificate ;
24- }
25-
2616 public async Task < CreateInvoiceResult > CreateInvoiceAsync (
2717 CreateInvoiceRequest createInvoiceRequest ,
2818 CancellationToken cancellationToken = default )
@@ -58,7 +48,7 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
5848
5949 var currentDateTime = DateTime . UtcNow . WithoutMilliseconds ( ) ;
6050
61- using var certificate = _provideCertificate ( ) ;
51+ using var certificate = provideCertificate ( ) ;
6252
6353 var ( iicSignatureText , iicHashText ) = ComputeIic (
6454 createInvoiceRequest . OrderNumber , currentDateTime , totalPrice , certificate ) ;
@@ -81,42 +71,42 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
8171 TypeOfInvoice = TypeOfInvoice . NonCash ,
8272 IssuedAt = currentDateTime ,
8373 Number = string . Join ( "/" ,
84- _settings . IssuerBusinessUnitCode ,
74+ settings . IssuerBusinessUnitCode ,
8575 createInvoiceRequest . OrderNumber ,
86- currentDateTime . Year ,
87- _settings . IssuerEnuCode ) ,
76+ createInvoiceRequest . TaxDate . Year ,
77+ settings . IssuerEnuCode ) ,
8878 OrderNumber = createInvoiceRequest . OrderNumber ,
89- EnuCode = _settings . IssuerEnuCode ,
79+ EnuCode = settings . IssuerEnuCode ,
9080 IsIssuerInVat = true ,
9181 TotalPriceWithoutVat = totalPriceWithoutVat ,
9282 TotalVatAmount = totalVatAmount ,
9383 TotalPrice = totalPrice ,
94- OperatorCode = _settings . IssuerOperatorCode ,
95- BusinessUnitCode = _settings . IssuerBusinessUnitCode ,
96- SoftwareCode = _settings . IssuerSoftwareCode ,
84+ OperatorCode = settings . IssuerOperatorCode ,
85+ BusinessUnitCode = settings . IssuerBusinessUnitCode ,
86+ SoftwareCode = settings . IssuerSoftwareCode ,
9787 IssuerInvoiceCodeHash = iicHashText ,
9888 IssuerInvoiceCodeSignature = iicSignatureText ,
99- TaxPeriod = $ "{ currentDateTime . Month : 00} /{ currentDateTime . Year } ",
89+ TaxPeriod = $ "{ createInvoiceRequest . TaxDate . Month : 00} /{ createInvoiceRequest . TaxDate . Year } ",
10090 Note = createInvoiceRequest . Note ,
101- BankNumber = _settings . IssuerBankNumber ,
102- PayDeadline = createInvoiceRequest . PaymentDeadline . ToString ( "yyyy-MM-dd" ) ,
91+ BankNumber = createInvoiceRequest . BankNumber ,
92+ PayDeadline = createInvoiceRequest . PaymentDeadline . ToString ( "yyyy-MM-dd" , CultureInfo . InvariantCulture ) ,
10393 TotalPriceToPay = Math . Max ( totalPrice , 0 ) ,
104- PaymentMethods = new List < PaymentMethod >
105- {
106- new ( )
94+ PaymentMethods =
95+ [
96+ new PaymentMethod
10797 {
10898 Type = createInvoiceRequest . PaymentMethod ,
10999 Amount = totalPrice
110100 }
111- } ,
101+ ] ,
112102 Seller = new Seller
113103 {
114- IdType = _settings . IssuerIdType ,
115- IdNumber = _settings . IssuerIdNumber ,
116- Name = _settings . IssuerName ,
117- Address = _settings . IssuerAddress ,
118- City = _settings . IssuerCity ,
119- Country = _settings . IssuerCountry
104+ IdType = settings . IssuerIdType ,
105+ IdNumber = settings . IssuerIdNumber ,
106+ Name = settings . IssuerName ,
107+ Address = settings . IssuerAddress ,
108+ City = settings . IssuerCity ,
109+ Country = settings . IssuerCountry
120110 } ,
121111 Buyer = createInvoiceRequest . Buyer ,
122112 Items = invoiceItems ,
@@ -149,11 +139,11 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
149139 var envelopedRequestXmlText = requestXmlDocument . ToEnvelopedXmlText ( ) ;
150140
151141 using var httpRequest = new StringContent ( envelopedRequestXmlText , Encoding . UTF8 , "text/xml" ) ;
152- using var httpResult = await _httpClient
142+ using var httpResult = await httpClient
153143 . PostAsync ( "fs-v1" , httpRequest , cancellationToken )
154144 . ConfigureAwait ( false ) ;
155145
156- var responseXmlText = await httpResult . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ;
146+ var responseXmlText = await httpResult . Content . ReadAsStringAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
157147 var responseXmlDocument = new XmlDocument ( ) ;
158148 responseXmlDocument . LoadXml ( responseXmlText ) ;
159149
@@ -173,13 +163,13 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
173163
174164 var urlQueryParams = new Dictionary < string , object >
175165 {
176- [ "tin" ] = _settings . IssuerIdNumber ,
166+ [ "tin" ] = settings . IssuerIdNumber ,
177167 [ "iic" ] = iicHashText ,
178- [ "crtd" ] = currentDateTime . ToString ( "yyyy-MM-ddTHH:mm:ssZ" ) ,
168+ [ "crtd" ] = currentDateTime . ToString ( "yyyy-MM-ddTHH:mm:ssZ" , CultureInfo . InvariantCulture ) ,
179169 [ "ord" ] = createInvoiceRequest . OrderNumber ,
180- [ "bu" ] = _settings . IssuerBusinessUnitCode ,
181- [ "cr" ] = _settings . IssuerEnuCode ,
182- [ "sw" ] = _settings . IssuerSoftwareCode ,
170+ [ "bu" ] = settings . IssuerBusinessUnitCode ,
171+ [ "cr" ] = settings . IssuerEnuCode ,
172+ [ "sw" ] = settings . IssuerSoftwareCode ,
183173 [ "prc" ] = totalPrice . ToFormattedString ( 2 )
184174 } ;
185175
@@ -191,7 +181,7 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
191181 EnvelopedRequestXmlText = envelopedRequestXmlText ,
192182 Fic = responseBodyElement [ "RegisterInvoiceResponse" ] ! [ "FIC" ] ! . InnerText ,
193183 VerificationUrl =
194- $ "{ UriProvider . GetInvoiceVerificationUri ( _settings . Environment ) } ic/#/verify?{ queryString } ",
184+ $ "{ UriProvider . GetInvoiceVerificationUri ( settings . Environment ) } ic/#/verify?{ queryString } ",
195185 InvoiceNumber = request . Invoice . Number ,
196186 Iic = iicHashText ,
197187 TotalPrice = totalPrice ,
@@ -206,22 +196,20 @@ public async Task<CreateInvoiceResult> CreateInvoiceAsync(
206196 X509Certificate2 certificate )
207197 {
208198 var iicPlainText = string . Join ( "|" ,
209- _settings . IssuerIdNumber ,
210- currentDateTime . ToString ( "yyyy-MM-ddTHH:mm:ssZ" ) ,
199+ settings . IssuerIdNumber ,
200+ currentDateTime . ToString ( "yyyy-MM-ddTHH:mm:ssZ" , CultureInfo . InvariantCulture ) ,
211201 orderNumber ,
212- _settings . IssuerBusinessUnitCode ,
213- _settings . IssuerEnuCode ,
214- _settings . IssuerSoftwareCode ,
202+ settings . IssuerBusinessUnitCode ,
203+ settings . IssuerEnuCode ,
204+ settings . IssuerSoftwareCode ,
215205 totalPrice . ToFormattedString ( 2 ) ) ;
216206
217207 var iicSignatureBytes = certificate
218208 . GetRSAPrivateKey ( ) !
219209 . SignData ( Encoding . UTF8 . GetBytes ( iicPlainText ) , HashAlgorithmName . SHA256 , RSASignaturePadding . Pkcs1 ) ;
220- var iicSignatureText = BitConverter . ToString ( iicSignatureBytes ) . Replace ( "-" , string . Empty ) ;
221-
222- using var md5 = MD5 . Create ( ) ;
223- var iicHashBytes = md5 . ComputeHash ( iicSignatureBytes ) ;
224- var iicHashText = BitConverter . ToString ( iicHashBytes ) . Replace ( "-" , string . Empty ) ;
210+ var iicSignatureText = Convert . ToHexString ( iicSignatureBytes ) ;
211+ var iicHashBytes = MD5 . HashData ( iicSignatureBytes ) ;
212+ var iicHashText = Convert . ToHexString ( iicHashBytes ) ;
225213
226214 return ( iicSignatureText , iicHashText ) ;
227215 }
0 commit comments