Server Side SDK general module
Overview
Server Side SDK is API wrapper implemented on Java. If you need SDK on another language, please contact us.
Installation
Manually deploy artifacts to your dependency management system.
Examples for local maven repository:
-
sdk.pom
mvn install:install-file -Dfile="sdk.pom" -DpomFile="sdk.pom"
-
core.jar
usingcore.pom
mvn install:install-file -Dfile="core.jar" -DpomFile="core.pom"
-
api-client.jar
usingapi-client.pom
mvn install:install-file -Dfile="api-client.jar" -DpomFile="api-client.pom"
Requirements
- Java 1.8 or later
Gradle users
Add this dependency to your project's build file:
implementation "net.payrdr.integrations:api-client:1.0.0"
Maven users
Add this dependency to your project's POM:
<dependency>
<groupId>net.payrdr.integrations</groupId>
<artifactId>api-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Usage
Basic usage with minimal configuration:
import net.payrdr.integrations.sdk.apiclient.regiserOrder.RegisterOrderResponse;
import net.payrdr.integrations.sdk.apiclient.regiserOrder.RegisterOrderRequest;
import net.payrdr.integrations.sdk.apiclient.ApiClient;
public class ApiExample {
public static void main(String[] args) {
ApiClient client = new ApiClient.Builder()
.username(username)
.password(password)
.baseUrl(baseUrl)
.build();
RegisterOrderRequest request = RegisterOrderRequest.builder()
.setAmount(10000)
.setReturnUrl("https://mybestmerchantreturnurl.com")
.build();
RegisterOrderResponse response = client.registerOrder(request);
}
}
Configuration
Base URL
Static URL prefix for every API method.
Example: https://uat.dskbank.bg/payment/rest/register.do
. Here:
-
https://uat.dskbank.bg/payment
- base prefix -
/rest/register.do
- exact method reference
Request authentication customization
Configured authenticator would be used by default in API client.
Prebuilt authentication options:
- Username and password can be configured using
ApiClient.Builder.username(String)
along withApiClient.Builder.password(String)
methods. Builder would raise aConfigurationException
in case when only username or only password is provided. - Merchant token can be configured via
ApiClient.Builder.token(String)
.ConfigurationException
is thrown when the token is passed with username or password. - Noop authentication. When neither username and password nor token is passed.
If built-in authentication methods are not enough, feel free to extend net.payrdr.integrations.sdk.apiclient.ApiRequestAuthenticator
and provide it to the builder via authenticator(ApiRequestAuthenticator)
method.
Enabling request signature
To have a possibility to sign requests, first contact technical support service to enable signatures for you. Then upload a certificate using Merchant Portal.
You need to provide a key pair to ApiClient to generate a hash and a signature using your secret key in the process of sending a request.
Private RSA key can be configured in two ways:
-
(Default way) Create
net.payrdr.integrations.sdk.apiclient.PrivateKeyInfo
with the parameters:- String
type
- one of "PKCS8", "JKS", "PKCS12" supported keystore types. - String
path
- absolute path to keystore file.ConfigurationException
is thrown if the keystore is not readable. - String
password
- keystore password AND entry password. Both should be protected with the same password. Used with "JKS" and "PKCS12" keystore types. - String
alias
- keystore entry alias for desired key. Used with "JKS" and "PKCS12" keystore types.
import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) .keyInfo(PrivateKeyInfo.builder() .path("/some/absolute/keystore/path/filename.jks") .type("JKS") .password("keystore_and_entry_password") .alias("keystoreEntryAlias") .build()) .build(); } }
- Implement
net.payrdr.integrations.sdk.core.security.PrivateKeyProvider
interface and pass implementation toApiClient.Builder.keyProvider(PrivateKeyProvider)
:
import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) .keyProvider(new PrivateKeyProvider() { @Override public PrivateKey provide() { //Do some magic here and provide private rsa key return null; } }) .build(); } }
- String
Signature algorithm
Default request signature algorithm is SHA256WithRSA. Default net.payrdr.integrations.sdk.core.security.SHA256WithRSASigner
would be initialized using provided java.security.PrivateKey
.
During request execution, the request body would be transformed to hash (X-Hash
) and the signature value (X-Signature
) and passed in the request headers.
X-Hash: GDrobAlCcpdOOlVuqra7Oogl/4s3vToGOXGpf3t/wJ0=
X-Signature: TJrm6jYAf2ssp/iYoDb3B+nuPqQ572oe/3a2RQ4oG2BFbmeRcoiITvR6tybNsbRHvRRlJys/2xFBW9ilee9GCN9WwYJ9h/MDyUEktj6NLZOztBAWi+7S8LDaiEWd+MUdTqe0hdiqo/lY2uIlEMTtkqTB7LsbEhrJ6NhJdpSxrstAnpyGIrGfldt0Vz+gz+YQ5XXrwhD6HyGShqV+tXzxcMdezWJJJ8vH5C0s 4jij2PuoauUSHkTrSc4vIJl/TPMliLJNsC5KCXka4/1hSr0exawFBekRldFnv5YvFakWJUN3kEc8 w3uauzTDh+CG0/Vxs/3gNun7e9ik9kCpwdiSMw==
No additional configuration is needed to use default SHA256WithRSASigner.
Custom algorithm can be implemented using net.payrdr.integrations.sdk.core.security.RequestSigner
interface.
Pass your implementation to ApiClient.Builder.requestSigner(RequestSigner)
method:
import net.payrdr.integrations.sdk.apiclient.ApiClient;
public class ApiExample {
public static void main(String[] args) {
ApiClient client = new ApiClient.Builder()
.username(username)
.password(password)
.baseUrl(baseUrl)
.requestSigner(new RequestSigner() {
@Override
public void init(PrivateKey privateKey) {
//do some magic with provided private key
}
@Override
public void sign(HttpRequest request) {
// Here we can customize request signature. Key would be loaded by KeyProvider
}
})
.build();
}
}
HTTP client customization
By default, built-in HttpClient wraps HttpsUrlConnection
.
Customization handles:
-
Request timeouts.
Default values are 60000 ms for read timeout and 5000 ms for connect timeout.
Read timeout and connect timeout may be customized via corresponding methods inApiClient.Builder
:import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) .readTimeout(1000) // Custom timeouts; .connectTimeout(2000) .build(); } }
-
Default TLS TrustStore can be extended or replaced:
- Append single certificate from file system to trust store via
customCertPath(String path)
method
import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) // Merge certificate from file system into system trust store and provide it to httpClient .customCertPath("/path/to/custom/certificate.cer") // X.509 Certificate file format .build(); } }
- Append all keystore certificates to trust store via
customTrustStore(java.security.KeyStore)
method
import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) // Merge all certificates from provided keystore with system trust store and provide it httpClient .customTrustStore(KeyStore.getInstance("JKS")) // Load it your own way .build(); } }
- Replace default trust store with
java.security.KeyStore
usingtrustStore
method
import net.payrdr.integrations.sdk.apiclient.ApiClient; public class ApiExample { public static void main(String[] args) { ApiClient client = new ApiClient.Builder() .username(username) .password(password) .baseUrl(baseUrl) // Provide custom trust store to httpClient. .trustStore(KeyStore.getInstance("JKS")) //Load it your own way. .build(); } }
- Append single certificate from file system to trust store via
Custom HTTP client implementation
HTTP client can be replaced with your own implementation using net.payrdr.integrations.sdk.core.http.(HttpClient,HttpRequest,HttpResponse)
interfaces:
import net.payrdr.integrations.sdk.apiclient.ApiClient;
import net.payrdr.integrations.sdk.core.http.HttpClient;
import net.payrdr.integrations.sdk.core.http.HttpRequest;
import net.payrdr.integrations.sdk.core.http.HttpResponse;
public class ApiExample {
public static void main(String[] args) {
ApiClient client = new ApiClient.Builder()
.username(username)
.password(password)
.baseUrl(baseUrl)
.httpClient(new HttpClient() {
@Override
public HttpResponse execute(HttpRequest request) {
// do some magic and transform HttpRequest into HttpResponse
return null;
}
@Override
public HttpRequest requestInstance() {
// return some implementation of HttpRequest.
return null;
}
})
.build();
}
}
Serialization/deserialization customization
Content-types supported by default for request serialization:
- application/json" with "application/json; charset=UTF-8" via Gson library
- "application/x-www-form-urlencoded"
Cotent-types supported by default for response deserialization:
- "application/json" and "application/json; charset=UTF-8" via Gson library
- "text/plain;charset=utf-8"
- "application/x-www-form-urlencoded"
- "text/html;charset=iso-8859-1"
Customization
Custom serializer can be implemented using net.payrdr.integrations.sdk.apiclient.serialization.RequestSerializer
and net.payrdr.integrations.sdk.apiclient.serialization.ResponseDeserializer
interfaces.
Implementations can be registered via ApiClient.Builder.registerSerializer(RequestSerializer)
and ApiClient.Builder.registerDeserializer(ResponseDeserializer)
methods.
import net.payrdr.integrations.sdk.apiclient.ApiClient;
public class ApiExample {
public static void main(String[] args) {
ApiClient client = new ApiClient.Builder()
.username(username)
.password(password)
.baseUrl(baseUrl)
.registerSerializer(new RequestSerializer() {
@Override
public ContentType getContentType() {
//register new ContentType in cache
return ContentType.of("custom/content-type");
}
@Override
public String serialize(ApiRequest request) {
return "MY_CUSTOM_SERIALIZATION";
}
})
.registerDeserializer(new ResponseDeserializer() {
@Override
public ContentType getContentType() {
//use registered ContentType from cache
return ContentType.of("custom/content-type");
}
@Override
public <T extends ApiResponse> T deserialize(String responseBody, Class<T> responseType) {
//DO THE DESERIALIZATION MAGIC IN HERE
return (T) new ApiResponse() {};
}
})
.build();
}
}
Also you can customize Gson library configurations using ApiClient.Builder.gson(Gson)
method:
import net.payrdr.integrations.sdk.apiclient.ApiClient;
public class ApiExample {
public static void main(String[] args) {
ApiClient client = new ApiClient.Builder()
.username(username)
.password(password)
.baseUrl(baseUrl)
.gson(new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create())
.build();
}
}
Exceptions
All exceptions are RuntimeException
and can be of the following types:
-
ConfigurationException
- thrown whenApiClient.Builder
cannot properly configure client with provided settings. (For example: creating client without base URL, private key file is not readable, etc.) -
SerializerNotSupportedException
- thrown when corresponding serializer is not registered for request and when deserializer for response content type cannot be found. -
ValidationException
- thrown when the request validation failed. Contains list of errors for every validation failure. -
KeystoreException
- thrown when the private key information is misconfigured in some way. -
RequestExecutionException
- wraps an internal exceptions if something went wrong during request execution.
Building new API methods
Can be done by simple extending of net.payrdr.integrations.sdk.apiclient(ApiRequest,ApiResponse)
classes.
Abstract methods of ApiRequest
:
- abstract List
validate();
- fillsValidationError
list if any validation fails - abstract String
getUrl();
- relative method reference - abstract HttpMethod
getMethod();
- HTTP method for request - abstract ContentType
getContentType()
; - content type used to determine serializer and sent via header - abstract
Class getResponseType();
- response DTO type to deserialize from HTTP response
Default methods of ApiRequest
:
- boolean
hasToBeSigned()
- determines if the API request has to be signed. Bypass configured request signer. Default:true
- boolean
hasToBeAuthenticated()
- determines if the API request has to be authenticated. Bypass configured authenticator. Default:true
-
Map<String, List<String>> getHeaders()
- additional HTTP headers that would be merged into the HTTP request before signing process. Default:null