Krajowy system e-Faktur

0

@Stl86: Odpowiem pełnym postem, dam Ci kilka linijek kodu:

Generalnie samo szyfrowanie robisz:

procedure TEncryptor.EncryptAES(const aStream: TStream);
var
	coder: TElAESSymmetricCrypto;
	OutStream: TMemoryStream;
	Key, IV: ByteArray;
begin
	coder := TElAESSymmetricCrypto.Create(SB_ALGORITHM_CNT_AES256, cmCBC);
	coder.KeyMaterial := TElSymmetricKeyMaterial.Create();
	try
		SetLength(Key, Length(fEncryptKey));
		Move(fEncryptKey[0], Key[0], Length(fEncryptKey));
		SetLength(IV, Length(fInitialKey));
		Move(fInitialKey[0], IV[0], Length(fInitialKey));
		coder.KeyMaterial.Key := Key;
		coder.KeyMaterial.IV := IV;
		Coder.Padding := cpPKCS5;
		//Coder.OnProgress := Self.CryptProgress;

		OutStream := TMemoryStream.Create;
		try
			aStream.Position := 0;
			coder.Encrypt(aStream, OutStream);

			OutStream.Position := 0;
			aStream.Size := 0;
			OutStream.SaveToStream(aStream);
		finally
			OutStream.Free;
		end;
	finally
		coder.KeyMaterial.Free;
		coder.Free;
		SetLength(Key, 0);
		SetLength(IV, 0);
	end;
end;

Wcześniej przygotowujesz sobie te dwa klucze:

procedure TEncryptor.InitKeys;
var
	i: Integer;
begin
	Randomize;
	for i := Low(TEncryptKey) to High(TEncryptKey) do
		fEncryptKey[i] := Byte(Random(256));
	for i := Low(TAESInitialKey) to High(TAESInitialKey) do
		fInitialKey[i] := Byte(Random(256));
end;

A same te klucze to nic innego jak:

	TEncryptKey = array[0..31] of Byte;
	TAESInitialKey = array[0..15] of Byte;

Teraz tylko uzupełniasz:

		with Encryption do
		begin
			with EncryptionKey do
			begin
				Encoding := 'Base64';
				Algorithm := 'AES';
				Size := Self.fEnc.KeySize shr 3;
				Value := Self.fEnc.EncryptRSAToBase64(Self.fEnc.EncryptKey);
			end;
			with EncryptionInitializationVector do
			begin
				Encoding := 'Base64';
				Bytes := SizeOf(Self.fEnc.InitialKey);
				Value := StringReplace(System.NetEncoding.TNetEncoding.Base64.EncodeBytesToString(Self.fEnc.InitialKey), sLineBreak, '', [rfReplaceAll]);
			end;
			with EncryptionAlgorithmKey do
			begin
				Algorithm := 'RSA';
				Mode := 'ECB';
				Padding := 'PKCS#1';
			end;
			with EncryptionAlgorithmData do
			begin
				Algorithm := 'AES';
				Mode := 'CBC';
				Padding := 'PKCS#7';
			end;
		end;
0

Ktoś się rozprawił z logowaniem za pomocą tokenu?
Wziąłem ich templatkę (InitSessionTokenRequestExample.xml), podmieniłem Identifier, Challange i zaszyfrowany (mam nadzeję, że prawidłowo) Token i wysłałem, ale interfejs zwraca "Błąd wewnętrzny (A)". Gdzieś wcześniej na tym wątku widziałem, że to jest odpowiednik "Bad request", ale średnio rozumiem co by to miało oznaczać w tym przypadku.
Fakt faktem mogę mieć nieprawidłowo zaszyfrowany token, ale komunikat błędu chyba by jednoznacznie na to wskazywał. Ktoś ma na to pomysł?

Edit:
Do zakodowania tokenu posłużyłem się informacjami z tej strony: https://microeducate.tech/how-to-load-the-rsa-public-key-from-file-in-c/
(Jeśli ktoś ma lepsze źródło/sposób żeby szyfrować token to z chęcią przygarnę)

RSACryptoServiceProvider rsa = DecodeX509PublicKey(Convert.FromBase64String("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWosgHSpiRLadA0fQbzshi5TluliZfDsJujPlyYqp6A3qnzS3WmHxtwgO58uTbemQ1HCC2qwrMwuJqR6l8tgA4ilBMDbEEtkzgbjkJ6xoEqBptgxivP/ovOFYYoAnY6brZhXytCamSvjY9KI0g0McRk24pOueXT0cbb0tlwEEjVZ8NveQNKT2c1EEE2cjmW0XB3UlIBqNqiY2rWF86DcuFDTUy+KzSmTJTFvU/ENNyLTh5kkDOmB1SY1Zaw9/Q6+a4VJ0urKZPw+61jtzWmucp4CO2cfXg9qtF6cxFIrgfbtvLofGQg09Bh7Y6ZA5VfMRDVDYLjvHwDYUHg2dPIk0wIDAQAB"));
string CODEDTOKEN = (Convert.ToBase64String(rsa.Encrypt(Encoding.ASCII.GetBytes(token), false)));

gdzie 'token' to token zwrócony przez api.

Szablon pliku wziąłem z: https://ksef.mf.gov.pl/document/InitSessionTokenRequestExample/1.0
Zmieniałem jedynie trzy rzeczy: <Challange>, <Identifier> (jestem raczej pewny, że obie są prawidłowe, bo robiłem to samo podczas logowania profilem zaufanym i wszystko się zgadzało) oraz <Token> (wrzucam CODEDTOKEN z wstawionego wcześniej kodu).
Nie ruszałem natomiast sekcji Encryption - jest taka jak w pobranym pliku

Edit2:
Edit3:
Plik .xml wygląda tak:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:InitSessionTokenRequest
	xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001"
	xmlns:ns2="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001"
	xmlns:ns3="http://ksef.mf.gov.pl/schema/gtw/svc/online/auth/request/2021/10/01/0001">
	<ns3:Context>
		<Challenge>20220323-CR-1C6F8A5791-E964BE4B8A-77</Challenge>
		<Identifier xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:SubjectIdentifierByCompanyType">
			<ns2:Identifier>6310012429</ns2:Identifier>
		</Identifier>
		<DocumentType>
			<ns2:Service>KSeF</ns2:Service>
			<ns2:FormCode>
				<ns2:SystemCode>FA (1)</ns2:SystemCode>
				<ns2:SchemaVersion>1-0E</ns2:SchemaVersion>
				<ns2:TargetNamespace>http://crd.gov.pl/wzor/2021/11/29/11089/</ns2:TargetNamespace>
				<ns2:Value>FA</ns2:Value>
			</ns2:FormCode>
		</DocumentType>
		<Token>sd+QNY0SKC8u4K554JVQqvbhdCe+f/kEy7n5SSxsj5X8/bYzOaD8IjWP90hP7ReKT2gK2KbVLcPqXBfhavZgNWdyckbLF2YAI9X5xeLvOuJlKCmNyEK60m/lGNZ3UvktyrWwKyeqbadlctVRIrH2ZwYPEYLvvoUVAwh4xc6tjubE0h+UCtH9vp2IjtYrNu0UbaS2v7sxRbEGLLYeUK1eNSxwC7gHUgzQNT+LZ/gB9QxIVDEIkNRbmwpAwqOB47vjdWh71uaUmMxEJPZwo+DY/XbQ+g5b6+lYtpixRJ8J9qCtWtyt0vuj7X1ENDJEapNtFQQgDaiZSlqxDo4HBuikpA==</Token>
	</ns3:Context>
</ns3:InitSessionTokenRequest>

Edit5:
Metoda którą szyfruję RSA:

public string RsaEncryptWithPublic(string clearText, string publicKey)
{
    var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);

    var encryptEngine = new Pkcs1Encoding(new RsaEngine());

    using (var txtreader = new StringReader(publicKey))
    {
        var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();

        encryptEngine.Init(true, keyParameter);
    }

    var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
    return encrypted;

}

Szyfrowanie: (gdzie timestamp to data otrzymana w challange'u, a token wygenerowanym tokenem dla podmiotu)

long unixMilisecondsTimestamp = new DateTimeOffset(timestamp).ToUnixTimeMilliseconds();
String toEncrypt = $"{token}|{unixMilisecondsTimestamp.ToString()}";
String CODEDTOKEN = RsaEncryptWithPublic(toEncrypt, "-----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWosgHSpiRLadA0fQbzshi5TluliZfDsJujPlyYqp6A3qnzS3WmHxtwgO58uTbemQ1HCC2qwrMwuJqR6l8tgA4ilBMDbEEtkzgbjkJ6xoEqBptgxivP/ovOFYYoAnY6brZhXytCamSvjY9KI0g0McRk24pOueXT0cbb0tlwEEjVZ8NveQNKT2c1EEE2cjmW0XB3UlIBqNqiY2rWF86DcuFDTUy+KzSmTJTFvU/ENNyLTh5kkDOmB1SY1Zaw9/Q6+a4VJ0urKZPw+61jtzWmucp4CO2cfXg9qtF6cxFIrgfbtvLofGQg09Bh7Y6ZA5VfMRDVDYLjvHwDYUHg2dPIk0wIDAQAB\r\n-----END PUBLIC KEY-----");

screenshot-20220324085806.png
Czas otrzymany w challange'u (odpowiedź dostałem 8:56 naszego czasu) i jego reprezentacja po przerobieniu metodą z paru linii wyżej: "1648108611842"

0

Ufff... Na podstawie przykładów z tego wątku udało mi się dojść jak utworzyć poprawnie pieczęć do podpisu InitSigned.xml.
Może jeszcze komuś to się przyda.

  1. Utworzyłem plik c:\OpenSSL\pieczec.cnf o zawartości:
oid_section = OIDs

[ req ]
default_bits = 2048
prompt = no
encrypt_key = no
default_md = sha1
distinguished_name = dn
req_extensions = req_ext

[ OIDs ]
SerialNumberOID=2.5.4.97

[ dn ]
CN = Jan Testowy
emailAddress = jan.test@twojafirma.xy
O = Twoja Firma
C = PL
SerialNumberOID=VATPL-..........................  (zamiast kropek Twój numer NIP)

[ req_ext ]
  1. Utworzyłem plik GenPieczec.bat:
call c:\OpenSSL\openssl.exe req -config c:\OpenSSL\pieczec.cnf -newkey -nodes -keyout key.pem -out certificate.csr

call c:\OpenSSL\openssl.exe x509 -req -in certificate.csr -signkey key.pem -out certificate.crt -sha512

call c:\OpenSSL\openssl.exe pkcs12 -export -in certificate.crt -inkey key.pem -out certificate.pfx -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider"
  1. Podpisałem XML i wysłałem do InitSigned i otrzymałem token ! :)

    pozdrawiam
    m.k.

0

Czy ktoś spotkał się z problemem błędu podczas wylogowania? Czy wysłanie faktur uniemożliwia zakończenie sesji, aż do jakiegoś ich częściowego przetworzenia?

{"exception":{"serviceCtx":"srvTEMFB","serviceCode":"20220324-EX-196E1C9A6E-6810758243-22","serviceName":"online.session.session.terminate","timestamp":"2022-03-24T14:49:58.498Z","referenceNumber":null,"exceptionDetailList":[{"exceptionCode":21220,"exceptionDescription":"Sesja interaktywna nie może być zakończona."}]}}
0

SerialNumber czy Fingerprint

Czy ktoś wie jak rozpoznać rodzaj podpisu dla InitSigned?

Pieczęć to będzie <Type>SerialNumber</Type> a podpis z peselem to zapewne <Type>Fingerprint</Type>. Tylko jak to rozpoznać który podpis wybierze użytkownik?

0

Witam,
Mam problem wygenerowanie tokenu sesyjnego za pomocą tokenu autoryzacyjnego zwracany błąd to "Nieprawidłowy czas tokena." W czym może być problem ?
Przykładowy kod:
Date chalengeTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(this.challengeTimestamp);
byte [] kod = (tokanAutoryzacyjny + "|" + String.valueOf(chalengeTime.getTime())).getBytes();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte [] zaszyfrowanyKod = cipher.doFinal(kod);
this.tokenKodowany = Base64.getEncoder().encodeToString(zaszyfrowanyKod);

wywołanie POST
https://ksef-test.mf.gov.pl/api/online/Session/InitToken

0

ksef-test. dziwny problem:

  1. wysłałem wczoraj o 13ej fakture sesją interaktywną, sesji niestety nie zamknąłem ale dziś dokument nadal "wisi" z kodem 315 że Sesja interaktywna aktywna. Komunikacja otwarta.Da się to jakoś zamknąć/wymusić? Było że po dwóch godzinanach sama się zamknie, a token sesji utraciłem.
  2. wysłałem fakture, status ma 200, ale upo jest null

ktoś coś? jakiś pomysł? 😊

0

Czy odebrał ktoś UPO z wysyłki paczki faktur.? Wysłałem na testowy i cały cza mam że jest ZAKOŃCZONY ETAP ŁĄCZENIA ODSZYFROWANYCH DANYCH W ARCHIWUM PIERWOTNE?

0

Wiem, że ten wątek pojawiał się już od czasu do czasu w różnych miejscach, ale pomimo korzystania z różnych podpowiedzi u mnie ciągle jest ten sam komunikat.

Przy próbie wysłania żądania InitSigned otrzymuję błąd: " 21102 Nieprawidłowe wyzwanie autoryzacyjne"

Certyfikat (pieczątka) generowana jest z openssl-a w ten sposób:

openssl req -passout pass:abc -subj "/C=PL/ST=Wojewodztwo/L=Miasto/O=Firma/OU=Firma/CN=Jan Kowalski/emailAddress=myemail@address.com/2.5.4.97=VATPL-4961266333" -new > imie.cert.csr
openssl req -in imie.cert.csr -noout -text -nameopt sep_multiline
openssl rsa -passin pass:abc -in privkey.pem -out imie.key
openssl x509 -req -in imie.cert.csr -out imie.cert -signkey imie.key -days 365
openssl x509 -in imie.cert -out imie.cert.der -outform DER
openssl pkcs12 -passout pass:jakiesHaslo -export -in imie.cert -out imie.cert.p12 -inkey imie.key

plik xml podpisywany jest komercyjną biblioteką nsoftware.SecureBlackbox (podpiywane są nim przesyłana JPK i nie ma problemu) z wygenerowanego powyżej certyfikatu. Podpisany plik wygląda tak:

screenshot-20220331092108.png

Plik xml wysyłany jest na stronę testu i ... właśnie Nieprawidłowe wezwanie autoryzacyjne. Co robie źle ?

0

Widziałem z tego tematu pytania, ale zazwyczaj o jeden z elementów. Jak powinno być przeprowadzone pobieranie faktur?
Przy QueryInvoiceAsyncInit muszę podać subjectType i type - czym są te wartości?
QueryInvoiceAsyncStatus zwraca mi status, czyli najzwyczajniej sprawdzam sobie co jakiś czas czy już przetworzył to o co poprosiłem
I teraz zostaje QueryInvoiceAsyncFetch i QueryInvoiceSync - tu już się w ogóle gubię. W jaki sposób korzystać z PageSize i PageOffset? Czy gdzieś jest jakiś rodzaj filtra po nr lub dniu wystawienia faktury?
Na razie przymykając oko na implementację - jak to w ogóle powinno wyglądać patrząc chociażby na takiego swaggera?

3

Bedzie webinarium "Aplikacja Platnika KSeF"
link

0

Co oznacza "Cannot convert null value to IO.Swagger.Model.QueryInvoiceAsyncStatusResponse+DivisionTypeEnum. Path 'divisionType', line 1, position 339."?

Wysłałem zapytanie QueryInvoiceAsyncInitResponse i chciałem sprawdzić jego status za pomocą QueryInvoiceAsyncStatusResponse co zwróciło powyższy wyjątek

0

Cześć, to masz opisane w KSeF-online.yaml linia 2311.

0

Hej, czy jest gdzieś dostępna lepsza dokumentacja metod API niż to co dali w Swaggerze? (https://ksef-test.mf.gov.pl/swagger/index.html#/) i w tym ogólnym PDF Specyfikacja_Interfejsu_1_0.pdf. Na przykład próbuję wysłać zapytanie do metody https://ksef.mf.gov.pl/api/online/Query/Invoice/Async/Init .

Z opisu wynika, że przyjmuje na wejście taki oto json:

{
  "queryCriteria": {
    "subjectType": "subject1",
    "type": "string"
  }
}

Schema:

QueryInvoiceRequest {
  queryCriteria*	QueryCriteriaInvoiceType {
    subjectType*	stringEnum: [ subject1, subject2, subject3, subjectAuthorized ]
    type*	string
  }
}

O ile subjectType jest w tym wypadku jasny (jedna z wartości wskazanego zbioru), to type jest dla mnie wielką niewiadomą. Co ma być tam wpisane?

Podobna sprawa ma się z https://ksef.mf.gov.pl/api/online/Query/Invoice/Sync . Tu dodatkowo z nagrania dostępnego na YT widzę, że metoda przyjmuje zupełnie nieopisane w dokumentacji wartości np. AcquisitionTimestampThresholdFrom i AcquisitionTimestampThresholdTo przy odpytaniu o zakres. I w nagraniu mowa jest jeszcze o innych wywołaniach po dacie faktur, oraz wyszukiwanie po szczegółach faktury. Ale skąd można wziąć przykłady wywołań lub przynajmniej dokładne wyszczególnienie i opis możliwości?

0

Poszukuję metod sprawdzenia rodzaju użytego certyfikatu (SerialNumber czy FingerPrint). Używam SecureBlackBox. Szukałem w metodach i własnościach ale nie znalazłem. Pomocy.

0

/api/online/Credentials/Status/{elementReference} - Limit żądań osiągnięty!

Po odebraniu Tokena autoryzacyjnego oczekuję na processignCode=200 sprawdzając ProcessingCode w pętli wywołującej co np. 500ms Credentials/Status. Po paru sekundach pojawia się "Limit żądań osiągnięty".

Jak wobec tego poczekać na zakończenie procesu nadawania tokenowi uprawnień?
pozdrawiam

PS. Czasami ProcessingCode=200 jest prawie natychmiast ale czasami nie.

0

Hejka, czy u Was też zapytania o listę faktur (asynchronicznie: https://ksef-test.mf.gov.pl/api/online/Query/Invoice/Async/Status/) tak długo wiszą na statusie 325: "Zakończenie etapu podziału na podzapytania oraz inicjalizacja podprocesów przygotowania części odpowiedzi" ? Wczoraj w ciągu kilku godzin nie doczekałem się przejścia dalej, a dzisiaj odpytując o wczorajsze id (element reference number) dostaję już nie status 325 a błąd 31000: "Nieprawidłowe wywołanie". Dzisiaj 1.5h temu zrobiłem nowe wywołanie (https://ksef-test.mf.gov.pl/api/online/Query/Invoice/Async/Init), ale też wisi na statusie 325..

0

Dziękuję @Dzyszla za naprowadzenie.
Napisałem funkcję do sprawdzania typu certyfikatu dla KSeF.
Sprawdziłem na trzech certyfikatach - pieczęci, podpisie kwalifikowanym z PESELEM i takim bez wymaganych atrybutów. Dla nich zadziałało.
Mam nadzieję, że poprawnie zrozumiałem zasady. Okaże się w praktyce.

function FindCertTypeForKSeF(Cert:TElX509Certificate; out CertType:TKSeFCertType; out Number:string):boolean;
type
  TReqFlags= (undefined,required,unacceptable,optional);
  TOIDRec = record oid: RawByteString; fl: TReqFlags; patt: array of RawByteString; end;
const
  cOIDList: array[TKSeFCertType, 1..4] of TOIDRec = (
    (
    (oid:#85#4#42; fl:required; patt:[]),
    (oid:#85#4#4; fl:required; patt:[]),    
    (oid:#85#4#5; fl:optional; patt:['(PNOPL|PESEL).*?(?<number>\d{11})','(TINPL|NIP).*?(?<number>\d{10})']),
    (oid:#85#4#97; fl:unacceptable; patt:[])
    ),(    
    (oid:#85#4#97; fl:required; patt:['(VATPL).*?(?<number>\d{10})']),
    (oid:#85#4#5; fl:unacceptable; patt:[]),
    (oid:#85#4#42; fl:unacceptable; patt:[]),
    (oid:#85#4#4; fl:unacceptable; patt:[])
    )
    );

  function FindOID(OID:RawByteString; arr:array of TOIDRec; var oidRec:TOIDRec):boolean;
  var
    i: Integer;
  begin
    Result:=false;
    for i := Low(arr) to High(arr) do
      if OID=arr[i].oid then
      begin
        oidRec:=arr[i];
        Exit(true)
      end;
  end;

  function PattOK(value:RawByteString; patt:array of RawByteString):boolean;
  var
    vPatt: RawByteString;
  begin
    Result:=false;
    if (value='') or (Length(patt)=0) then
      Exit;
    for vPatt in patt do
      if TRegEx.IsMatch(UTF8ToString(Value), vPatt) then
        Exit(true)
  end;

var
  iOID:Integer;
  vOID_: ByteArray; vOID: RawByteString absolute vOID_;
  vValue_: ByteArray; vValue: RawByteString absolute vValue_;
  ict: TKSeFCertType;
  vOIDRec: TOIDRec;
  vReqCount,vReqCountOK: Integer;
begin
  Result:=false;
  for ict := Low(cOIDList) to High(cOIDList) do
  begin
    vReqCountOK:=0;
    for iOID:=0 to Cert.SubjectRDN.Count-1 do
    begin
      vOID_:=Cert.SubjectRDN.OIDs[iOID];
      if FindOID(vOID, COIDList[ict], vOIDRec) then
        case vOIDRec.fl of
          undefined: ;
          required,optional:
          begin
            Result:=true;
            CertType:=ict;
            vValue_:=Cert.SubjectRDN.Values[iOID];
            if PattOK(vValue,vOIDRec.patt) then
              Number:=UTF8ToString(vValue);
            if vOIDRec.fl=required then
              Inc(vReqCountOK);
          end;
          unacceptable:
          begin
            Result:=false;
            Break;
          end;
        end;
    end;
    if Result then
    begin
      vReqCount:=0;
      for vOIDRec in cOIDList[ict] do
        if vOIDRec.fl=required then
          Inc(vReqCount);
      if vReqCountOK<vReqCount then
        Result:=false;
    end;
    if Result then
      Exit;
  end;
end;

i użycie:

if FindCertTypeForKSeF(X509KeyData.Certificate,vCertType,vNumber) then
begin
  if vNumber<>'' then
    ContextType:=ct_serialNumber
  else
    ContextType:=ct_fingerPrint;
end else
   SetErr(cError_WrongCert,'Certyfikat nie posiada wymaganych atrybutów: '+cCertReqForKSeF_url);
0

Cześć Wszystkim :). Do czego używacie tych metod /online/Query/Invoice/Async/* :). Jeśli używacie to co to jest ten {PartElementReferenceNumber} ? Nie bardzo rozumiem po co tego używać? W filmie na YT prowadzący odpuścił sobie prezentację tych metod, nie użył żadnej z nich.

Takie coś mam w odpowiedzi o status:
{
"timestamp": "2022-04-06T13:41:50.765Z",
"referenceNumber": "20220406-SE-CC40E22940-5530DE53FF-1D",
"processingCode": 325,
"processingDescription": "Zakończenie etapu podziału na podzapytania oraz inicjalizacja podprocesów przygotowania części odpowiedzi",
"elementReferenceNumber": "20220406-EH-855B645AD0-973E1F0603-F5",
"numberOfParts": null,
"numberOfElements": null,
"divisionType": null,
"partList": []
}

Ale z tego co widzę to nic nie znalazł.

0

Hej, zabieram się za implementację wysyłki wsadowej faktur. Czy jest do tego jakaś dokumentacja? Bo w tej ogólnej prawie nic nie ma w temacie, nawet przykładowego wywołania, nie mówiąc o opisach.
Przejrzałem wcześniejsze wpisy tu na forum i widzę 2 przykłady XMLa do /batch/init - super, że są i ktoś się podzielił, ale fajnie byłoby dodatkowo wiedzieć czym są poszczególne sekcje, zamiast się domyślać. Widziałem też wzmianki w komentarzach, że ksef miał przekazać dodatkową dokumentację w temacie - coś komuś wiadomo?

0

Po wysyłce wsadowej sprawdzając status po referenceNumber dostaję "Błąd etapu weryfikacji wyników podprocesu uwierzytelniania". Mam wrażenie, że to widziałem już tutaj. Ktoś kojarzy co oznacza ten błąd?

0

Cześć, co podajecie w /batch/upload /{Reference Number}/{Part Name} jako numer referencyjny? Jak podaje referenceNumber z /batch/init to wyrzuca błąd 21208 - nieprawidłowy numer referencyjny.
Już nie wiem czy podaje zły numer czy coś źle wstawiłam w /batch/init/.

0

Wysyłam zapytanie /online/Query/Invoice/Async/Status i dostaję w odpowiedzi listę takich oto elementów:
screenshot-20220407114814.png
i teraz na ten podstawie chciałbym podbić do /common/Invoice/KSeF, niestety mam wrażenie, że brakuje mi informacji:
screenshot-20220407114938.png
Przykładowo nie mam tradeName odbiorcy.
To ja przeoczyłem jakieś informacje czy nie da się nimi wypełnić tego zapytania do common?

3

Podsumowanie Webinarium MF o aplikacji KSeF (w tym co ciekawsze pytania z chatu):

  • Aplikacja będzie interfejsem całego API poza systemem wsadowym. Zatem będzie można generować tokeny, zarządzać uprawnieniami
  • Będzie możliwość wystawiania faktur w programie (oraz oczywiście odbierania przez interfejs anonimowy, a więc np. przez os. prywatne)
  • Sama aplikacja jest aplikacją webową (pracującą w przeglądarce)
  • Temat limitów: być może będą zmiany, ale nie wiadomo w którą stronę ;p
  • Apka będzie sprawdzać poprawność semantyczną faktur
  • Z racji braku obsługi systemu wsadowego, nie będzie też można pracować z fakturami >1MB
  • Aktualnie wizualizacja jest w HTML, ma być też w PDF (tak samo w odniesieniu do UPO). Być może kiedyś w API pojawi się opcja wizualizacji też.
  • KSeF i JPK wciąż pozostają rozdzielone, więc wystawienie w KSeF nie obliguje do ujmowania w JPK ani też tego nie zastępuje.
  • Potwierdzono, że przed II kw. 2023 system nie będzie obowiązkowym.
  • Gdy KSeF będzie już wymaganym, to do momentu otrzymania numeru nie powinniśmy dawać odbiorcy faktury.
  • Faktura walutowa - jaki kurs, jeśli nie znamy daty wystawienia (bo to data odebrania przez system)? Tego nikt nie wie! :D (oficjalna odpowiedź na chacie kompletnie nie odpowiada na pytanie)
  • Padła obietnica, że struktura faktury (XML) nie będzie zbyt często zmieniana.
  • Apka na początku będzie tylko w wersji testowej

Aplikacja dostępna pod adresem:
www.podatki.gov.pl/ksef/bezplatne-narzedzia-ksef/

0

Czy ktoś wie jakiego zapytania używają w Panelu Ksef (bezpłatne narzędzia) w zakładce ,,Historia wysyłki", chodzi mi o listowanie sesji wraz z jej statusami? Wspominali że cała aplikacja jest zrobiona za pomocą API więc zakładam że gdzieś ono jest

0

Hej, przy wysyłce wsadowej faktur w zapytaniu batch/init należy przesłać plik XML (InitRequest), mam pytanie o jego część:

...
<EncryptionInitializationVector xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001">
      <Encoding>Base64</Encoding>
      <Bytes>16</Bytes>
      <Value>SHZmI1kI+lknhUB/emCBNg==</Value>
</EncryptionInitializationVector>
...

Co wstawiacie w tagu Value? Jakiś skrót z certyfikatu użytkownika?

0

Invoice/Send - otrzymujemy elementReferenceNumber
Invoice/Status - otrzymamy ksefReferenceNumber o ile się doczekamy.
Jak uzyskać ksefReferenceNumber jeśli nie doczekamy się jej przyjęcia (np. wyłączą prąd w międzyczasie, itp)? W nowej sesji elementReferenceNumber nie jest już oczywiście rozpoznawalny.

0

W specyfikacji jest napisane (Specyfikacja_Interfejsu_1_0.pdf), że dla wysyłki wsadowej wektorem uwierzytelniającym nie może być token (ani odcisk palca certyfikatu). To jak mamy robić wysyłkę automatyczną w nocy dużej ilości faktur? Wydawało mi się, że właśnie do tego token został wymyślony.

0

Takie pytania.

  1. Czy w systemie jest w jakiś sposób widoczne dla odbiorcy kto wystawił fakturę? Tzn. któryś z atrybutów kontekstu użytkownika - PESEL lub certyfikat?
  2. Czy uwzględniacie w systemie to co padło na prezentacji, że należy utrzymać ogólną zasadę ciągłości numeracji faktur w ramach serii? Będziecie nadawać numer własny dopiero w chwili próby wysyłki do KSEF tak żeby nie było ryzyka "dziur" w numeracji?
  3. Czy waszym zadniem metoda /Query/Invoice/Sync dla "type": "incremental" jest właściwa dla niezawodnej synchroniazacji faktur otrzymanych? Tzn. zadajemy zapytanie z acquisitionTimestampThresholdFrom zgodnym z najwyższą dotychczas otrzymaną datą wpływu i zawsze dostaniemy pierwszą (najstarszą) porcję dokumentów których jeszcze nie mamy?
0

@JACA-RARA: To jak to powinno wyglądać w C# ? Co tu jest żle?

 DateTime xCzas = DateTime.Parse(xTimeStamp).ToUniversalTime();
long unixMilisecondsTimestamp = new DateTimeOffset(xCzas).ToUnixTimeMilliseconds();
string xToken = Encrypt(TokenA + "|" + unixMilisecondsTimestamp.ToString());

Paweł

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.