Общий модуль Server Side SDK
Общее описание
Server Side SDK — это оболочка API, реализованная на Java. Если вам нужен SDK на другом языке, пожалуйста, свяжитесь с нами .
Установка
Вручную разверните артефакты в вашей системе управления зависимостями.
Примеры для локального репозитория maven:
-
sdk.pom
mvn install:install-file -Dfile="sdk.pom" -DpomFile="sdk.pom"
-
core.jar
с использованиемcore.pom
mvn install:install-file -Dfile="core.jar" -DpomFile="core.pom"
-
api-client.jar
с использованиемapi-client.pom
mvn 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://mts.rbsuat.com/payment/rest/register.do
. Здесь:
-
https://mts.rbsuat.com/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