Skip to content

Working with Callback API

Kostya edited this page Feb 23, 2022 · 3 revisions

Перед началом работы убедитесь, что Вы имеете ключ доступа от Вашего магазина.
Он здесь тоже нужен, как и при работе с API v3.
Как его получить, описано здесь.

Client instance initialization

Важно: Ключ, используемый в примерах, является демонстративным!
В реальных условиях он не будет таковым, но будет состоять из 32 HEX-символов.

Создание объекта напрямую

Методы для создания клиента можно посмотреть в Javadoc.

// Создадим клиент для работы с Callback API
// В параметрах метода #create передадим ключ доступа
String accessKey = "abcdefghabcdefghabcdefghabcdefgh";

// Обратите внимание на остальные перегрузки метода с другими параметрами
// Вы также можете изменить ещё несколько важных настроек
CallbackApiClient callbackApiClient = CallbackApiClient.create(accessKey);

Использование конструктора

Методы для изменения параметров клиента можно посмотреть в Javadoc.

// Так же объявим переменную для ключа доступа
String accessKey = "abcdefghabcdefghabcdefghabcdefgh";

// Для создания клиента теперь используем #builder,
// где Вы можете изменить любые параметры будущего
// клиента, включая другие важные настройки
CallbackApiClient client = CallbackApiClient.builder()
        .setAccessKey(accessKey)
        .setSignatureVerificationEnabled(true)
        .create();

HTTP requests handling

Поскольку сервер обработки Callback API событий по сути является веб-сервером, то и сами события обрабатываются как входящие HTTP запросы.
Для обработки запросов здесь используется контроллер веб-приложения на основе Spring.

@RestController
public final class CallbackApiController {

    private CallbackApiClient callbackApiClient;

    // обработка тела запроса как события Callback API
    @PostMapping("/callback/handler")
    public String hash(@RequestBody String body) throws JsonSerializationException {
        callbackApiClient.processIncomingPayment(body);
        return "OK";
    }
    
    // --- обработка исключений
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(JsonSerializationException.class)
    public String handleException(JsonSerializationException exception) {
        return "Invalid JSON structure.";
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(SignatureGenerationException.class)
    public String handleException(SignatureGenerationException exception) {
        return "Try again later.";
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(SignatureVerificationException.class)
    public String handleException(SignatureVerificationException exception) {
        return "Signature verification fail.";
    }

}

Event listening

После написания кода Вашего контроллера, при помощи того же экземпляра клиента API зарегистрируйте слушатели событий.
Список всех событий можно найти в Javadoc.

Для начала создайте слушатель событий:

public final class IncomingPaymentListener implements CallbackListener {

    // помечаем метод слушателем нужного нам события
    @Listen
    public void onIncomingPayment(IncomingPaymentEvent event) {
        Payment payment = event.getPayment();
        // TODO дальнейшие действия с объектом платежа
    }

}

А затем зарегистрируйте его:

// экземпляр клиента был создан ранее по инструкции выше
CallbackApiClient client = ...;

// регистрируем новый экземпляр нашего класса в качестве слушателя событий
client.registerListener(new IncomingPaymentListener());

Signature validation

Для подтверждения входящих запросов на их подлинность необходима проверка их подписи.
Данная процедура может выполняться автоматически при обработке запросов, если эта функция была включена при создании экземпляра клиента.

В ином случае Вы можете производить проверку подписи вручную:

// десериализованный объект платежа из тела входящего запроса
Payment payment = ...;

// убедимся, что вместе с объектом пришла и подпись события
String receivedSignature = payment.getSignature();
if(receivedSignature == null || receivedSignature.isEmpty())
    throw new SignatureVerificationException("There are no signature was received from the request body!");

// сгенерируем свою подпись из полученных данных
Signature signature = payment.getSignatureFromData(accessKey);
String generatedSignature = signature.compile();

// сверим полученную и заведомо подлинную подписи
if(!receivedSignature.equalsIgnoreCase(generatedSignature))
    throw new SignatureVerificationException("Signatures mismatch! received: '%s', generated: '%s'", receivedSignature, generatedSignature);

// TODO проверка на подлинность пройдена, дальнейшие действия будут здесь...
Clone this wiki locally