Общий модуль Server Side SDK
Общее описание
Server Side SDK — это оболочка API, реализованная на Java.
Установка
Вручную разверните артефакты в вашей системе управления зависимостями.
Примеры для локального репозитория maven:
-
sdk.pommvn install:install-file -Dfile="sdk.pom" -DpomFile="sdk.pom" -
core.jarс использованиемcore.pommvn install:install-file -Dfile="core.jar" -DpomFile="core.pom" -
api-client.jarс использованиемapi-client.pommvn install:install-file -Dfile="api-client.jar" -DpomFile="api-client.pom"
Требования
- Java 1.8 или новее
Пользователи Gradle
Добавьте эту зависимость в файл сборки вашего проекта:
implementation "net.payrdr.integrations:api-client:1.0.0"Пользователи Maven
Добавьте эту зависимость в POM вашего проекта:
<dependency>
<groupId>net.payrdr.integrations</groupId>
<artifactId>api-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>Использование
Базовое использование с минимальной конфигурацией:
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);
}
}Настройка
Базовый URL
Статический префикс URL для каждого метода API.
Пример: https://3dsec.berekebank.kz/payment/rest/register.do. Здесь:
-
https://3dsec.berekebank.kz/payment- базовый префикс -
/rest/register.do- точная ссылка на метод
Кастомизация аутентификации запросов
Настроенный аутентификатор будет использоваться по умолчанию в клиенте API.
Готовые варианты аутентификации:
- Имя пользователя и пароль можно настроить с помощью методов
ApiClient.Builder.username(String)иApiClient.Builder.password(String). Builder вызоветConfigurationExceptionв случае, если указано только имя пользователя или только пароль. - Токен мерчанта можно настроить с помощью метода
ApiClient.Builder.token(String).ConfigurationExceptionвозникает, когда токен передается вместе с именем пользователя или паролем. - Noop-аутентификация. Когда не передается ни имя пользователя, ни пароль, ни токен.
Если встроенных методов аутентификации недостаточно, вы можете расширить net.payrdr.integrations.sdk.apiclient.ApiRequestAuthenticator и предоставить его сборщику с помощью метода authenticator(ApiRequestAuthenticator).
Включение подписи запроса
Чтобы иметь возможность подписывать запросы, сначала обратитесь в службу технической поддержки, чтобы включить подписи для вас. Затем загрузите сертификат с помощью Портала продавца.
Вам необходимо предоставить пару ключей ApiClient для генерации хэша и подписи с использованием вашего секретного ключа в процессе отправки запроса.
Закрытый ключ RSA можно настроить двумя способами:
-
(Способ по умолчанию) Создайте
net.payrdr.integrations.sdk.apiclient.PrivateKeyInfoс параметрами:- String
type- один из поддерживаемых типов ключей: "PKCS8", "JKS", "PKCS12". - String
path- абсолютный путь к файлу хранилища ключей.ConfigurationExceptionвозникает, если хранилище ключей недоступно. - String
password- пароль хранилища ключей И пароль записи. Они должны быть защищены одним и тем же паролем. Используется с типами хранилища ключей "JKS" и "PKCS12". - String
alias- псевдоним записи в хранилище ключей для нужного ключа. Используется с типами хранилища ключей "JKS" и "PKCS12".
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(); } }- Реализовать интерфейс
net.payrdr.integrations.sdk.core.security.PrivateKeyProviderи передать реализацию вApiClient.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
Алгоритм подписи
Алгоритм подписи запроса по умолчанию — SHA256WithRSA. По умолчанию net.payrdr.integrations.sdk.core.security.SHA256WithRSASigner будет инициализирован с использованием предоставленного java.security.PrivateKey.
Во время выполнения запроса тело запроса будет преобразовано в хэш (X-Hash) и значение подписи (X-Signature) и передано в заголовках запроса.
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==Для использования SHA256WithRSASigner по умолчанию дополнительная настройка не требуется.
Кастомный алгоритм может быть реализован с использованием интерфейса net.payrdr.integrations.sdk.core.security.RequestSigner.
Передайте свою реализацию методу ApiClient.Builder.requestSigner(RequestSigner):
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-клиента
По умолчанию встроенный HttpClient оборачивает HttpsUrlConnection.
Возможности кастомизации:
-
Тайм-ауты запросов.
Значения по умолчанию: 60000 мс для времени ожидания чтения и 5000 мс для времени ожидания соединения.
Время ожидания чтения и время ожидания подключения можно настроить с помощью соответствующих методов вApiClient.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(); } } -
TLS TrustStore по умолчанию можно расширить или заменить:
- Добавьте единый сертификат из файловой системы к доверенному хранилищу с помощью метода
customCertPath(String path):
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(); } }- Чтобы добавить все сертификаты хранилища ключей в доверенное хранилище,используйте метод
customTrustStore(java.security.KeyStore):
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(); } }- Чтобы заменить доверенное хранилище по умолчанию на
java.security.KeyStore, используйте методtrustStore:
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(); } } - Добавьте единый сертификат из файловой системы к доверенному хранилищу с помощью метода
Кастомизация реализации HTTP-клиента
HTTP-клиент можно заменить собственной реализацией с помощью интерфейсов net.payrdr.integrations.sdk.core.http.(HttpClient,HttpRequest,HttpResponse):
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();
}
}Кастомизация сериализации/десериализации
Типы контента, поддерживаемые по умолчанию для сериализации запросов:
- "application/json" с "application/json; charset=UTF-8" через библиотеку Gson
- "application/x-www-form-urlencoded"
Типы контента, поддерживаемые по умолчанию для десериализации ответов:
- "application/json" и " "application/json; charset=UTF-8" через библиотеку Gson
- "text/plain;charset=utf-8"
- "application/x-www-form-urlencoded"
- "text/html;charset=iso-8859-1"
Кастомизация
Кастомный сериализатор может быть реализован с использованием интерфейсов net.payrdr.integrations.sdk.apiclient.serialization.RequestSerializer и net.payrdr.integrations.sdk.apiclient.serialization.ResponseDeserializer .
Реализации могут быть зарегистрированы с помощью методов ApiClient.Builder.registerSerializer(RequestSerializer) и ApiClient.Builder.registerDeserializer(ResponseDeserializer).
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();
}
}Также вы можете настроить конфигурацию библиотеки Gson, используя метод ApiClient.Builder.gson(Gson):
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();
}
}Исключения
Все исключения являются RuntimeException и могут быть следующих типов:
-
ConfigurationExceptionвозникает, когдаApiClient.Builderне может правильно настроить клиент с заданными параметрами. (Например: создание клиента без базового URL, файл закрытого ключа не читается и т.д.) -
SerializerNotSupportedException- возникает, когда соответствующий сериализатор не зарегистрирован для запроса и когда не удается найти десериализатор для типа содержимого ответа. -
ValidationException- возникает, когда проверка запроса не удалась. Содержит список ошибок для каждого сбоя проверки. -
KeystoreException- возникает, когда информация о секретном ключе каким-либо образом неправильно настроена. -
RequestExecutionException- оборачивает внутренние исключения, если что-то пошло не так во время выполнения запроса.
Создание новых методов API
Это можно сделать простым расширением классов net.payrdr.integrations.sdk.apiclient(ApiRequest,ApiResponse).
Абстрактные методы ApiRequest:
- abstract List
validate();- заполняет списокValidationErrorв случае любой неуспешной валидации - abstract String
getUrl();- relative method reference - abstract HttpMethod
getMethod();- HTTP-метод для запроса - abstract ContentType
getContentType(); - тип контента, используемый для определения сериализатора и отправляемый через заголовок - abstract
Class getResponseType();- тип ответа DTO для десериализации из ответа HTTP
Методы по умолчанию ApiRequest:
- boolean
hasToBeSigned()- определяет, должен ли запрос API быть подписан. По-умолчанию:true - boolean
hasToBeAuthenticated()- определяет, должен ли запрос API быть аутентифицирован. По-умолчанию:true -
Map<String, List<String>> getHeaders()- дополнительные заголовки HTTP, которые будут объединены в HTTP-запрос перед процессом подписания. По умолчанию:null