Skip to content

Key Conecpts

This page covers the concepts and contracts behind the client — lifecycle, threading, error handling, and logging. For a minimal end-to-end example, see the Overview.

Building a client

Pick a transport and provide an endpoint and API key:

1
2
3
4
5
6
SynqpayClient client = SynqpayClient.create(SynqpayClient.TransportType.TCP)
        .setEndpoint("10.0.0.1")
        .setApiKey("your-api-key")
        .setConnectionStateCallback(connectionStateCallback)
        .setNotificationCallback(notificationCallback)
        .build();

For SSL, also provide a root CA path with setRootCAPath(...).

Lifecycle

1
2
3
4
5
6
7
8
client.start();
client.connect();

// ... use the client ...

client.disconnect();
client.stop();
client.destroy(); // Java / C# only — releases the native client
  • start()/stop() control the client's internal engine. connect()/disconnect() control the transport connection on top of that.
  • All four are safe to call more than once — a call that's already in that state (already started, already connected, already stopped, already disconnected) is simply ignored.
  • Once start() has succeeded, the client is ready to connect, and the ConnectionStateCallback (if registered) will begin firing.
  • start()/stop() and connect()/disconnect() can be cycled as many times as needed over the client's lifetime — you don't need to rebuild the client to reconnect.
  • The client does not reconnect automatically if the connection drops. Watch for Disconnected / ConnectError on the ConnectionStateCallback and call connect() again yourself if you want to retry.

Info

In C++, the client is returned as a std::unique_ptr, so it's released automatically when it goes out of scope — there's no separate destroy() call. Java and C# hold a handle to the native client and must call destroy() explicitly to release it once you're done with it for good.

Sending requests

1
2
3
4
5
6
int result = client.sendRequest(requestJson, response -> {
    // handle response
});
if (result != 0) {
    // handle send failure — see "Errors" below
}

Each call to sendRequest takes its own callback, which receives the response for that specific request.

Warning

Always check the returned error code. sendRequest can fail synchronously (e.g. the client isn't connected) — in that case the response callback never fires, so this is the only place that failure surfaces. Handling it is not optional.

Notifications

Unlike responses, notifications aren't tied to a specific request — register one NotificationCallback on the client and it will receive all asynchronous events. Notifications are only sent for the transaction command; see transaction events for the payload shapes.

Threading

The API is safe to call from your UI thread. However, response, notification, and connection state callbacks all arrive on the same internal SDK thread — your application should hand off and return from these callbacks as quickly as possible.

API key

The API key you pass to the builder is fixed for that client — there's no setter to change it afterward. The client itself may still update its own internal copy when an authenticate response hands it a new key. Either way, the SDK holds the key only for the current session (in memory) and never persists it to disk — if your application needs it across sessions, saving it is your responsibility.

Logging

Register a LogCallback via the static setLogCallback to receive the SDK's internal log messages (connection attempts, transport errors, and similar):

SynqpayClient.setLogCallback((level, message) -> System.out.println(message));

This is a global, static registration — it applies to the SDK as a whole, not to a single client instance.

Info

Logging is the fastest way to diagnose SDK-level issues. It's recommended to keep it enabled during integration, and to include its output when reporting an issue to the Synqpay dev team.

Errors

There are two separate places errors can show up, and both matter:

  • The sendRequest return code — non-zero means the SDK could not even send the request (e.g. not connected). Pass it to getErrorMessage(code) for a description. The response callback will not fire for these.
  • The JSON-RPC response itself — a successfully sent request can still come back with a business/payment-level error inside the response body. getErrorMessage does not cover these; they're part of the API reference.

Treat both as required error handling, not edge cases — a host application that only wires up the "happy path" response will silently miss send failures.