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:
For SSL, also provide a root CA path with setRootCAPath(...).
Lifecycle
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 theConnectionStateCallback(if registered) will begin firing. start()/stop()andconnect()/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/ConnectErroron theConnectionStateCallbackand callconnect()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
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):
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
sendRequestreturn code — non-zero means the SDK could not even send the request (e.g. not connected). Pass it togetErrorMessage(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.
getErrorMessagedoes 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.