Pobierz najnowszą aplikację testową (aktualizacja 25.12.10), która prezentuje większość funkcji dostępnych przez link-Server. Program wykonany w Visual Studio 2022 i C#. Zawiera pełny kod źródłowy oraz wersję skompilowaną.
https://tgsoft.pl/zip/KsefLinkClientTest.zip
Jeżeli jesteś integratorem i już tworzysz rozwiązanie do współpracy z naszym programem lub szukasz uniwersalnego rozwiązania, koniecznie zapoznaj się z tym przykładem. Aplikacja testowa będzie rozwijana o kolejne przykłady.
W poprzednich dokumentach opisaliśmy interaktywną pracę programu, gdzie użytkownik korzystał z wybranych funkcji do tworzenia faktur i komunikacji z KSeF.
Teraz zaprezentujemy możliwość pracy ad-hoc z innym programem ERP. W tym celu przygotujemy demonstracyjny projekt za pomocą Visual Studio i C#.
Aby program mógł przyjmować polecenia od aplikacji zewnętrznej, należy uruchomić link-Server przyciskiem [Start] z prawej strony głównej formy aplikacji. Po prawidłowym uruchomieniu usług http, napis Link Server zostanie wyświetlony kolorem niebieskim.
Główny ekran programu po aktywacji Link Server
Programista (integrator) może skorzystać z naszego API i za pomocą prostych komend wykonywać szereg zaawansowanych poleceń do generowania faktur, wysyłania do KSeF, pobierania statusów, itp. Polecenia http dostępne są w trybie ad-hoc, co pozwoli na automatyzację procesów związanych z KSeF zaraz po wystawieniu faktury w systemie ERP.
W przykładzie poniżej skorzystaliśmy z klas *Dto (do serializacji Json) opisanych w dokumencie https://tgsoft.pl/Blog?id=294
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace KsefLinkClientTest
{
public partial class FormDemo : Form
{
public FormDemo()
{
InitializeComponent();
}
private static string GetInvoiceStr(string nrFry)
{
FakturaDto faktura = new FakturaDto()
{
Nabywca = new KontrahentDto()
{
NIP = "3333333333",
Nazwa = "FHU Trójka Sp. z o.o.",
AdresL1 = "ul. Nowy Świat 1",
AdresL2 = "00-001 Warszawa",
},
P_1 = string.Format("{0:yyyy-MM-dd}", DateTime.Today),
P_2 = nrFry,
P_13_1 = 1000,
P_14_1 = 230,
P_13_2 = 100,
P_14_2 = 8,
P_15 = 1338,
FwItems = new List<FwItemDto>
{
new FwItemDto() { NazwaTowaruUslugi = "Stawka podatkowa 23%", JednostkaMiary = "SZT", Ilosc = 1, CenaJednostkowaNetto = 1000, WartoscNetto = 1000, StrVAT="23"},
new FwItemDto() { NazwaTowaruUslugi = "Stawka podatkowa 8%", JednostkaMiary = "SZT", Ilosc = 1, CenaJednostkowaNetto = 100, WartoscNetto = 100, StrVAT="8"},
}
};
return JsonConvert.SerializeObject(faktura);
}
static string baseAddress = "http://localhost:9000/";
private async void button1_Click(object sender, EventArgs e)
{
try
{
HttpContent httpContent = new StringContent(GetInvoiceStr("0029/09/2025"), Encoding.UTF8, "application/json");
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsync(baseAddress + "api/invoices/ImportJInvoice", httpContent);
if (response != null && response.Content != null)
{
textResponse.Text = await response.Content.ReadAsStringAsync();
var x = JsonConvert.DeserializeObject<LinkResponse>(textResponse.Text);
textBoxID.Text = x.Id.ToString();
textBoxCode.Text = x.Code.ToString();
textBoxKey.Text = x.Key;
textBoxDescription.Text = x.Description;
}
}
}
catch (Exception ex)
{
textException.Text = ex.Message;
}
}
}
}
Przykład C# na wykorzystanie metody api/invoices/ImportJInvoice
Metoda ImportJInvoice przyjmuje strukturę Json faktury, generuje fakturę w formacie FA. Xml (3) i zapisuje do bazy faktur KSeF. Lista faktur dostępna jest w Menu/Kartoteki SQL/Faktury sprzedaży. Przed zapisem aplikacja sprawdza zgodność wygenerowanej faktury xml ze schematem XSD. Błędna faktura zostanie odrzucona, a komunikat przedstawia dokładne informacje o błędach. Poniższe zdjęcie przedstawia próbę wysłania nieprawidłowej faktury z błędnymi danymi:
- Podano NIP 333333333X
- Podano Kwotę w polu P_14_3 zamiast P_14_2
Odpowiedź serwera na błędne dane w strukturze Json
Poprawny zapis nowej faktury do bazy SQL
Wszystkie metody Link-Server zwracają odpowiedź wg tej samej struktury Json serializowanej klasy LinkResponse:
Po deserializacji Json, możemy odczytać poszczególne wartości. W przykładzie otrzymujemy Id=8607 nowego rekordu po dodaniu faktury do listy KSeF. Jeżeli to możliwe, zalecamy zapis tego Id w bazie danych własnego systemu ERP.
public class LinkResponse
{
public bool Success { get; set; }
public int Id { get; set; }
public string Key { get; set; }
public int Code { get; set; }
public string Description { get; set; }
}
Widok listy faktur sprzedaży po dodaniu nowej faktury do bazy SQL
Faktura dodana przez system ERP, od razu widoczna jest w trybie interaktywnym dla użytkownika. Ikona w kolumnie [Status] informuje o nowej fakturze w systemie. Dokument nie został jeszcze wysłany do KSeF. Do wysłania można skorzystać z funkcji programu:
- Przycisk [Wyślij/sprawdź] - wysyła serię faktur
- Przycisk [Wyślij] - wysyła jedną (bieżącą) fakturę
Programista ma też kilka możliwości do dalszego przetwarzania dołączonej faktury:
// Wysyła fakturę z bazy, nie czeka na status przetwarzania
public static async Task<string> SimpleSendInvoiceAsync(int id)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(baseAddress + $"api/invoices/SimpleSendInvoice/{id}");
string responseContent = await response.Content.ReadAsStringAsync();
return $"{response.StatusCode} : {responseContent}";
}
}
// Odczytuje aktualny status faktury, w razie konieczności pobiera niezbędne dane z KSeF
public static async Task<string> GetInvoiceStatusAsync(int id)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(baseAddress + $"api/invoices/GetInvoiceStatus/{id}");
string responseContent = await response.Content.ReadAsStringAsync();
return $"{response.StatusCode} : {responseContent}";
}
}
// Wysyła fakturę z bazy i odbiera status przetwarzania
public static async Task<string> SendInvoiceAsync(int id)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(baseAddress + $"api/invoices/SendInvoice/{id}");
string responseContent = await response.Content.ReadAsStringAsync();
return $"{response.StatusCode} : {responseContent}";
}
}
// Pobiera wygenerowaną strukturę Xml dla podanego Id i zapisuje w katalogu określonym w Parametrach Systemu
public static async Task<string> GetInvoiceXmlAsync(int id)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(baseAddress + $"api/invoices/GetInvoiceXml/{id}");
string responseContent = await response.Content.ReadAsStringAsync();
return $"{response.StatusCode} : {responseContent}";
}
}
Zestaw metod: ImportJInvoice, SimpleSendInvoice, GetInvoiceStatus można zastąpić jednym wywołaniem, które importuje fakturę, wysyła, a następnie pobiera status przetwarzania w KSeF:
// Importuje i od razu wysyła fakturę Json oraz pobiera status faktury.
public static async Task<string> SendJInvoiceAsync(string json)
{
HttpContent httpContent = new StringContent(json, Encoding.UTF8, "application/json");
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsync(baseAddress + "api/invoices/SendJInvoice", httpContent);
string responseContent = await response.Content.ReadAsStringAsync();
return $"{response.StatusCode} : {responseContent}";
}
}
Jeżeli Twój system ERP posiada już możliwość generowania faktur w formacie FA.Xml (3), możesz skorzystać z metody dołączenia gotowego pliku Xml : ImportXmlInvoice, a następnie wysłać i pobrać status przetwarzania.
// Import faktury z pliku Xml do bazy podstawowej
public static async Task<string> ImportXmlInvoiceAsync(string filePath)
{
string xmlContent = System.IO.File.ReadAllText(filePath);
HttpContent httpContent = new StringContent(xmlContent, Encoding.UTF8, "text/plain");
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsync(baseAddress + "api/invoices/ImportXmlInvoice", httpContent);
return await response.Content.ReadAsStringAsync();
}
}
Otwarta faktura w trybie podglądu za pomocą przycisku [Faktura]
Szczegóły wygenerowanej faktury w zakładce [Xml]
Następny dokument 301 : QR KOD I - Weryfikacja i pobieranie faktury z KSeF.