Documentation

Overview

The fiskaly Client is a stateless HTTP client which handles requests, has client-side validation for the request schema and communicates with the SMAERS component. It is shipped as a set of shared libraries for different operating systems and architectures on our download page. The client uses a slightly modified version of the JSON-RPC 2.0 Protocol to describe requests, responses and errors. The only deviation from the specification concerns notifications, which are not implemented and cause an error. Please make sure you are familiar with the JSON-RPC 2.0 specification before continuing.

Changelog

v1.1.100. (06.04.2020)

Bugfix

  • fix: adapt validator to v1 changes

Polish

  • refactor: polish user-agent header

v1.1.0. (02.04.2020)

Feature

  • method: echo
    • returns same string that is sent into the fiskaly-client
    • used to check for errors with encoding and communication between sdk and client
  • error: http-timeout-error
    • is returned if the http-request hits the timeout-limit
  • error: request-error
    • is returned if the request is malformed

Bugfix

  • fix: config now returns results properly
  • fix: validation of request bodies only when sending to API v1
  • fix: SMAERS version is now displayed properly

Polish

  • refactor: request-params now bundled and split from context
  • refactor: client-erros removed
  • refactor: http-error now returns server response bundled in response object
  • refactor: debug-file now uses os-standard tmp folder if not set

Functions

The Fiskaly Client exports two functions:

_fiskaly_client_invoke(CString) CString

_fiskaly_client_invoke is used to invoke a JSON-RPC 2.0 method. It takes a complete JSON-RPC 2.0 request as its argument and returns the client response.

_fiskaly_client_free(CString)

_fiskaly_client_free is used to free memory allocated by Invoke.

Methods

Parameters marked with a star (*) are optional.

Configuration

Request

{
"jsonrpc": "2.0",
"method": "config",
"params": {
* "config": {
* "debug_level": int,
* "debug_file": string,
* "client_timeout": int(ms),
* "smaers_timeout": int(ms)
},
"context": string
},
"id": int
}

Result

{
"jsonrpc": "2.0",
"result": {
"config": {
"debug_level": int,
"debug_file": string,
"client_timeout": int,
"smaers_timeout": int
},
"context": string
},
"id": int
}

The config method lets you configure the client and read the current configuration. It always returns all configuration parameters. You can set timeouts for the client and SMAERS independently, as well as enable the debug mode and configure its output. You can find an in-depth description of the debug mode further down the page. Any given parameters from the config property are written to the configuration. If you only want to read the configuration, you can omit the config property completely from the request.

Create new context

Request

{
"jsonrpc": "2.0",
"method": "create-context",
"params": {
"base_url": string,
"api_key": string,
"api_secret": string
},
"id": int
}

Result

{
"jsonrpc": "2.0",
"result": {
"context": string
},
"id": int
}

To make sure the fiskaly Client is stateless we use a context string that holds all needed information. This string needs to be sent with every method (except the version method) and will also be returned in every response. Make sure to update your stored context with the returned one from the response.

To prevent unintentional modification, the context, along with its sha256 hash, is encoded to a base64 string. It is recommended to treat the context as read-only and only use the provided methods to change its contents.

API request

Request

{
"jsonrpc": "2.0",
"method": "request",
"params": {
"request": {
"method": string,
"path": string,
* "query": json_object,
* "headers": json_object,
* "body": base64_string,
* "destination_file": string
},
"context": string
},
"id": int
}

Result

{
"jsonrpc": "2.0",
"result": {
"response": {
"status": string,
"header": json_object,
"body": base64_string
},
"context": string
},
"id": int
}

The request method is used to send HTTP requests. The URL is composed of the Base URL defined in the context and the request path. The Client will automatically validate your inputs. In case of a request to the transaction endpoint of the KassenSichV API the client will also validate the request body and sign it using the SMAERS component.

If your intention is to download a file from one of our APIs (for example in case of an export in the KassenSichV API) you can provide a destination file path. The client will then store the received data in that file. The JSON-RPC response will contain no body in this case.

Version

Request

{
"jsonrpc": "2.0",
"method": "version",
"params": {},
"id": int
}

Result

{
"jsonrpc": "2.0",
"result": {
"client": {
"version": string,
"source_hash": string,
"commit_hash": string
},
"smaers": {
"version": string,
"commit_hash": string
}
},
"id": int
}

The version method returns the version information of the currently used client and SMAERS.

Echo

Request

{
"method": "echo",
"params": json_object
}

Result

{
"result": json_object
}

The echo method returns the params field from the request unmodified. This is used to check if the UTF-8 Encoding in the SDK is done correctly.

Errors

The fiskaly Client will return errors as defined in the JSON-RPC 2.0 specification. To provide more detailed information on the error cause, the following additional, custom-defined errors can be returned by the fiskaly Client:

HTTP Error

{
"jsonrpc": "2.0",
"error": {
"code": -20000,
"message": "HTTP error",
"data": {
"response": {
"status": 400,
"headers": {
"X-Request-Id": ["0123456789"]
},
"body": base64_string
}
}
},
"id": int
}

HTTP Timeout

{
"jsonrpc": "2.0",
"error": {
"code": -21000,
"message": "HTTP timeout"
},
"id": int
}

Request Error

{
"jsonrpc": "2.0",
"error": {
"code": -7353,
"message": "Request Error"
},
"id": int
}

Debug mode

To assist troubleshooting, the fiskaly Client includes a debug mode. When enabled, information with variable granularity will be written to a log file. The verbosity is controlled by the debug_level field in the configuration. Valid debug levels are -1 (no output), 1 (errors only), 2 (errors+warnings) and 3 (errors+warnings+info). The output file can also be set via the config method. Default is /tmp/fiskaly.log.

Integration

1. Load the shared library file

The client is provided as a native library for common target platforms. Implementation-specific details vary between programming languages, therefore detailed instructions cannot be provided in this context. The necessary function signatures can be taken from the Functions section of this document. As all of our SDKs are OSS, you can always use them as a reference implementation.

2. Create a new context

The returned context contains the provided parameters and the default configuration. Store the context for future reuse and send it with every request. Any method call may modify the context, so it is important to always update the stored context with the returned one. Modifying the context directly may lead to undefined behavior and is strongly discouraged.

{
"jsonrpc": "2.0",
"method": "create-context",
"params": {
"api_key": "example_uj3hBUmddscBeWYeU9HRpFjgqp4ZTf",
"api_secret": "gBmxxMXN5s4wVuKaaEZCKMGxrZEBJl0iRZfiAbBZefq",
"base_url": "https://kassensichv.io/api/v1/"
},
"id": 1
}

3. Add custom settings

This step is optional and only needed if you want to override the default configuration parameters.

{
"jsonrpc": "2.0",
"method": "config",
"params": {
"config": {
"debug_level": 2,
"debug_file": "/var/log/fiskaly.log",
"client_timeout": 5000,
"smaers_timeout": 2000
},
"context": "T4QgYdRI6YH7vS_CBw0io7R2uK6DgCd3n2kW0TUdcBZ7IndyYXBwZXJfdmVyc2lvbiI6Ik5vIFdyYXBwZXIgVmVyc2lvbiIsImFwaV9rZXkiOiJleGFtcGxlX3VqM2hCVW1kZHNjQmVXWWVVOUhScEZqZ3FwNFpUZiIsImFwaV9zZWNyZXQiOiJnQm14eE1YTjVzNHdWdUthYUVaQ0tNR3hyWkVCSmwwaVJaZmlBYkJaZWZxIiwiYmFzZV91cmwiOiJodHRwczovL2thc3NlbnNpY2h2LmlvL2FwaS92MS8iLCJhY2Nlc3NfdG9rZW4iOiIiLCJyZWZyZXNoX3Rva2VuIjoiIiwiYWNjZXNzX3Rva2VuX2V4cGlyZXNfYXQiOjAsInJlZnJlc2hfdG9rZW5fZXhwaXJlc19hdCI6MCwiY29uZmlnIjp7ImRlYnVnX2xldmVsIjotMSwiY2xpZW50X3RpbWVvdXQiOjEwMDAsInNtYWVyc190aW1lb3V0IjoxMDAwfX0"
},
"id": 2
}

4. Send requests

The request method receives and returns the message body as base64-encoded binary data. This allows any data format to be uploaded and downloaded.

{
"jsonrpc": "2.0",
"method": "request",
"params": {
"request": {
"method": "PUT",
"path": "/tss/ecb75169-680f-48d1-93b2-52cc10abb9ff/tx/9cbe6566-e24c-42ac-97fe-6a0112fb3c63",
"query": { "last_revision": "0" },
"headers": { "Content-Type": "application/json" },
"body": "eyJzdGF0ZSI6ICJBQ1RJVkUiLCJjbGllbnRfaWQiOiAiYTYyNzgwYjAtMTFiYi00MThhLTk3MzYtZjQ3Y2E5NzVlNTE1In0="
},
"context": "aYqkp0feiGAiyKfcNu9sp0whSGCvaoykbmeC-R90Qcx7IndyYXBwZXJfdmVyc2lvbiI6Ik5vIFdyYXBwZXIgVmVyc2lvbiIsImFwaV9rZXkiOiJleGFtcGxlX3VqM2hCVW1kZHNjQmVXWWVVOUhScEZqZ3FwNFpUZiIsImFwaV9zZWNyZXQiOiJnQm14eE1YTjVzNHdWdUthYUVaQ0tNR3hyWkVCSmwwaVJaZmlBYkJaZWZxIiwiYmFzZV91cmwiOiJodHRwczovL2thc3NlbnNpY2h2LmlvL2FwaS92MS8iLCJhY2Nlc3NfdG9rZW4iOiIiLCJyZWZyZXNoX3Rva2VuIjoiIiwiYWNjZXNzX3Rva2VuX2V4cGlyZXNfYXQiOjAsInJlZnJlc2hfdG9rZW5fZXhwaXJlc19hdCI6MCwiY29uZmlnIjp7ImRlYnVnX2xldmVsIjoyLCJkZWJ1Z19maWxlIjoiL3Zhci9sb2cvZmlza2FseS5sb2ciLCJjbGllbnRfdGltZW91dCI6NTAwMCwic21hZXJzX3RpbWVvdXQiOjIwMDB9fQ"
},
"id": 3
}

Body encoding example

Plain text (JSON)

{
"body": {
"some-field": 23,
"another-field": "hello, world"
}
}

Base64 encoded

{
"body": "ewogICAgInNvbWUtZmllbGQiOiAyMywKICAgICJhbm90aGVyLWZpZWxkIjogImhlbGxvLCB3b3JsZCIKICB9"
}

5. Download files

To store the response body in a file, provide a value to the destination_file property. HTTP status and header information will still be returned in the response, but the body will be written to the provided file path.

{
"jsonrpc": "2.0",
"method": "request",
"params": {
"request": {
"destination_file": "/tmp/output.txt",
"method": "GET",
"path": "/something"
},
"context": "aYqkp0feiGAiyKfcNu9sp0whSGCvaoykbmeC-R90Qcx7IndyYXBwZXJfdmVyc2lvbiI6Ik5vIFdyYXBwZXIgVmVyc2lvbiIsImFwaV9rZXkiOiJleGFtcGxlX3VqM2hCVW1kZHNjQmVXWWVVOUhScEZqZ3FwNFpUZiIsImFwaV9zZWNyZXQiOiJnQm14eE1YTjVzNHdWdUthYUVaQ0tNR3hyWkVCSmwwaVJaZmlBYkJaZWZxIiwiYmFzZV91cmwiOiJodHRwczovL2thc3NlbnNpY2h2LmlvL2FwaS92MS8iLCJhY2Nlc3NfdG9rZW4iOiIiLCJyZWZyZXNoX3Rva2VuIjoiIiwiYWNjZXNzX3Rva2VuX2V4cGlyZXNfYXQiOjAsInJlZnJlc2hfdG9rZW5fZXhwaXJlc19hdCI6MCwiY29uZmlnIjp7ImRlYnVnX2xldmVsIjoyLCJkZWJ1Z19maWxlIjoiL3Zhci9sb2cvZmlza2FseS5sb2ciLCJjbGllbnRfdGltZW91dCI6NTAwMCwic21hZXJzX3RpbWVvdXQiOjIwMDB9fQ"
},
"id": 4
}
Last updated on