Общая документация по интеграции с эквайринговой системой ARIASOFT 1.3.4 Help

Внутренняя интеграция

Раздел предназначен для разработчиков, которые хотят добавить функциональность AriaPaymentSDK в приложения. Здесь описаны шаги для успешной установки, настройки и использования SDK, а также приведены блоки кода и рекомендации.

Актуальные файлы для скачивания

Файл библиотеки SDK (версия 1.0.29.111)

Файл библиотеки SDK (версия 1.0.37.0)

Файл библиотеки SDK (версия 1.0.37.2)

Файл демонстрационного приложения (версия 1.0.29.111)

Файл демонстрационного приложения (версия 1.0.37.0)

Файл демонстрационного приложения (версия 1.0.37.2)

Минимальные требования

  • Минимальная версия Android: 5.0

  • Среда разработки: Android Studio

  • Интернет-соединение

Установка и настройка Graddle/Maven

//project build.gradle buildscript { repositories { // Если вы хотите использовать flat файловую систему в качестве репозитория flatDir { dirs 'libs' } } }

Подключение зависимости на SDK:

//app build.gradle dependencies { implementation(name: "sdk-pos-release", ext: 'aar') }

Схемы взаимодействия

Общая схема взаимодействия узлов процессинга и аттестации с SDK

Sdk outside

На схеме изображен процесс обработки транзакций с использованием SDK от ARIASOFT и различных систем проверки.

Зона банка:

  1. В центре находится защищенная внутренняя сеть процессинга, которая включает хост эквайера/процессинга и систему ARIASOFT.HOST с модулем "финальной аттестации" для ARIASOFT SDK.

  2. Обработка транзакций проходит через хост эквайера/процессинг и ARIASOFT.HOST.

  3. Устройства проходят аттестацию через существующий входной Gate банка.

Внутренние компоненты платежного SDK

Sdk inside

Описание стрелок:

  • ADEP протокол – протокол взаимодействия с CA NADEKS. Получение цепочки сертификатов для взаимодействия с ARIASOFT.HOST. Выполняется первичный On-Boarding телефонной трубки Merchant’а.

  • ATCP протокол – взаимодействие с ARIASOFT.HOST по зарегистрированному устройству (протокол ATCP). Добавление профилей терминалов/трубок осуществляется «пакетно».

SDK

Интерфейс к библиотеке описан в следующем разделе.

Инициализация SDK

Получение разрешений

Следующим шагом является проверка необходимых разрешений для приложения и их запрос у пользователя.

public String[] getPermissions() { return AbstractTerminal.getInstance().getPermissions(); }

В новой версии тестового приложения запрос разрешений происходит во время выполнения обработчика клика кнопки init_terminal.

findViewById(R.id.init_terminal).setOnClickListener(view -> { setInfoText("Start terminal init. Please wait.", false); try { TerminalFactory.getInstance().initTerminal(device); // Инициализация терминала } catch (Exception e) { setInfoText("Fail terminal init", true); // Обработка ошибки return; } ArrayList<String> denyPermissions = checkAndCollectDenyPermission( AriaPaymentSDK.getInstance().getPermissions() // Получение разрешений ); requestDenyPermissions(denyPermissions); // Запрос недостающих разрешений });

Необходимые разрешения нужно указать в XML-файле AndroidManifest:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • INTERNET – доступ к сети Интернет

  • ACCESS_NETWORK_STATE – доступ к информации о состоянии подключения к сети

Конфигурация SDK

Здесь создается конфигурация SDK и настраиваются различные параметры:

  • таймаут запросов,

  • имя пакета,

  • адреса серверов.

Получение клиентских и приватных ключей

Клиентские и приватные ключи используются для установления связи приложения с сервером. После выставления этой связи с УЦ выгружаются отдельные для аутентификации клиента и сервера с УЦ.

  • Клиентский ключ:

public void setClientCertificates(String certificates) throws SDKException { try { ASAPClient.getInstance().setCertChain(certificates); // Устанавливаем цепочку сертификатов. } catch (IncorrectCertChainException | OtherRequestInProgressException e) { e.printStackTrace(); throw new SDKException(e); // Преобразование исключений в SDKException. } }
  • Приватный ключ:

public void setClientPrivateKey(String privateKey) throws SDKException { try { ASAPClient.getInstance().setPrivateKey(privateKey); // Устанавливаем приватный ключ. } catch (OtherRequestInProgressException | IncorrectKeyException e) { e.printStackTrace(); throw new SDKException(e); // Преобразование исключений в SDKException. } }

В новой версии тестового приложения реализация методов теперь находится внутри библиотеки AriaPaymentSDK. Эти методы вызываются строго после успешной инициализации SDK внутри коллбэка onSuccess():

AriaPaymentSDK.getInstance().init(buildSdkConfig(), new InitCallback() { @Override public void onSuccess() { try { // Установка происходит ЗДЕСЬ AriaPaymentSDK.getInstance().setClientCertificates(correctCertsPem); AriaPaymentSDK.getInstance().setClientPrivateKey(correctPrivateKeyPem); ...

Конфигурация

Этот метод настраивает SDK, используя переданные параметры конфигурации и контекста:

SDKConfig sdkConfig = new SDKConfig(); sdkConfig.setRequestTimeout(2*60*1000); // Установка тайм-аута (в милисекундах) sdkConfig.setPackageName(getPackageName()); // Получение имени пакета sdkConfig.setAriaAddress(new SDKConfig.Address( BuildConfig.ARIA_URL, // Установление адреса ARIASOFT.HOST BuildConfig.ARIA_PORT, // Установление порта ARIASOFT.HOST ("http".equals(BuildConfig.ARIA_PROTOCOL) ? Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения к ARIASOFT.HOST ("ip".equals(BuildConfig.ARIA_TYPE) ? AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения к ARIASOFT.HOST )); if (TerminalFactory.getInstance().getDevice() == Device.TAP2PHONE) { sdkConfig.setCaAddress(new SDKConfig.Address( T2PRemoteConfig.DEFAULT_IP, T2PRemoteConfig.DEFAULT_PORT, (Protocol.HTTP == T2PRemoteConfig.DEFAULT_PROTOCOL || Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения Tap2Phone (AddressType.IP == T2PRemoteConfig.DEFAULT_ADDRESS_TYPE || AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения Tap2Phone )); } else { sdkConfig.setCaAddress(new SDKConfig.Address( BuildConfig.CA_URL, BuildConfig.CA_PORT, ("http".equals(BuildConfig.CA_PROTOCOL) ? Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения к УЦ ("ip".equals(BuildConfig.CA_TYPE) ? AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения к УЦ )); } return sdkConfig; }

Основное изменение - это передача контекста в конструктор SDKConfig и замена класса T2PRemoteConfig на T2PCARemoteConfig для конфигурации TAP2Phone.

private SDKConfig buildSdkConfig() { SDKConfig sdkConfig = new SDKConfig(this); // Передается контекст sdkConfig.setRequestTimeout(2 * 60 * 1000); sdkConfig.setPackageName(getPackageName()); sdkConfig.setAriaAddress(new SDKConfig.Address( BuildConfig.ARIA_URL, BuildConfig.ARIA_PORT, ("http".equals(BuildConfig.ARIA_PROTOCOL) ? Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения к ARIASOFT.HOST ("ip".equals(BuildConfig.ARIA_TYPE) ? AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения к ARIASOFT.HOST )); if (TerminalFactory.getInstance().getDevice() == Device.TAP2PHONE) { sdkConfig.setCaAddress(new SDKConfig.Address( T2PCARemoteConfig.DEFAULT_IP, T2PCARemoteConfig.DEFAULT_PORT, (Protocol.HTTP == T2PCARemoteConfig.DEFAULT_PROTOCOL ? Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения Tap2Phone (AddressType.IP == T2PCARemoteConfig.DEFAULT_ADDRESS_TYPE ? AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения Tap2Phone )); } else { sdkConfig.setCaAddress(new SDKConfig.Address( BuildConfig.CA_URL, BuildConfig.CA_PORT, ("http".equals(BuildConfig.CA_PROTOCOL) ? Protocol.HTTP : Protocol.HTTPS), // Выбор протокола HTTP или HTTPS для подключения к УЦ ("ip".equals(BuildConfig.CA_TYPE) ? AddressType.IP : AddressType.DNS) // Выбор IP или DNS адреса для подключения к УЦ )); } return sdkConfig; }

Адреса сервера, УЦ и хоста

Для демонстрационного приложения используются демо-адреса УЦ и ARIASOFT.HOST указанные в таблице ниже.

Для работы с конкретным продуктом используются другие адреса. Чтобы их получить, обратитесь по электронной почте support@nadeks.ru.

Назначение

Адрес:порт

Сервер ARIASOFT.HOST

DNS: aria-demo.nadeks.ru:10443
IP: 212.42.50.77:10443
Для зарубежных интеграций:
45.153.186.184:8181

Сервер УЦ

DNS: im1.ca1.nadeks.ru:7777
Для зарубежных интеграций:
45.153.186.184:7771

Пример кода:

sdkConfig.setAriaAddress(new SDKConfig.Address( "aria-demo.nadeks.ru" // URL сервера ARIASOFT.HOST "10443 с SSL/7770 без SSL" // Порт сервера ARIASOFT.HOST SDKConfig.Address.Protocol.HTTP || SDKConfig.Address.Protocol.HTTPS), // Протокол HTTP или HTTPS SDKConfig.Address.AddressType.IP || SDKConfig.Address.AddressType.DNS) // Тип адреса IP или DNS )); sdkConfig.setCaAddress(new SDKConfig.Address( "im1.ca1.nadeks.ru" // URL сервера CA "7777" // Порт сервера CA SDKConfig.Address.Protocol.HTTP || SDKConfig.Address.Protocol.HTTPS), // Протокол HTTP или HTTPS SDKConfig.Address.AddressType.IP || SDKConfig.Address.AddressType.DNS) // Тип адреса IP или DNS ));

Инициализация

Для инициализации SDK в вашей активности используйте созданную конфигурацию, установив клиентские сертификаты и приватный ключ.

try { AriaPaymentSDK.getInstance().init(getApplicationContext(), sdkConfig); // Инициализация SDK AriaPaymentSDK.getInstance().setClientCertificates(correctCertsPem); // Установка клиентских сертификатов AriaPaymentSDK.getInstance().setClientPrivateKey(correctPrivateKeyPem); // Установка приватного ключа клиента }

Инициализация теперь выполняется в фоне, результат возвращается через коллбэк InitCallback, а контекст больше не передается явно (уже содержится в SDKConfig).

// Асинхронная инициализация с коллбэками AriaPaymentSDK.getInstance().init(buildSdkConfig(), new InitCallback() { @Override public void onSuccess() { try { // Установка сертификатов и ключа ВНУТРИ коллбэка AriaPaymentSDK.getInstance().setClientCertificates(correctCertsPem); AriaPaymentSDK.getInstance().setClientPrivateKey(correctPrivateKeyPem); // Дополнительные действия для TAP2Phone if (device == Device.TAP2PHONE) { new Thread(() -> { AriaPaymentSDK.getInstance().startLightOnboarding(); setInfoText("Success terminal init", true); }).start(); } else { setInfoText("Success terminal init", true); } }

Обработка исключений и вывод ошибок

Если происходит ошибка, она обрабатывается и выводится сообщение об ошибке.

catch (SDKException e) { setInfoText("SDKException.ERROR_CODE: " + e.getErrorCode().name()); // Обработка исключений и отображение сообщения об ошибке e.printStackTrace(); return; // Прекращение выполнения в случае ошибки }

В новой версии произошло разделение обработчиков ошибок:

Ошибки инициализации SDK → обрабатываются в onError()

Ошибки установки сертификатов/ключей → обрабатываются в catch (SDKException)

// Для ошибок установки сертификатов: catch (SDKException e) { setInfoText("SDKException.ERROR_CODE: " + e.getErrorCode().name(), true); e.printStackTrace(); } // Для ошибок инициализации SDK: @Override public void onError(Throwable throwable) { TerminalFactory.getInstance().clearTerminal(); setInfoText("Fail terminal init", true); }

Таблица с кодами ошибок

Инициализация на конкретном устройстве

  • При инициализации необходимо указать конкретный POS-терминал для работы:

TerminalFactory.getInstance().initTerminal(device);
try { TerminalFactory.getInstance().initTerminal(device); } catch (Exception e) { setInfoText("Fail terminal init", true); return; }

Список доступных устройств:

Модель устройства

Вендор

P2000L

SmartPeak

T1

TopWise

TAP2PHONE

Для платежей не используется POS-терминал

SUNMI_P2

Sunmi

i9100

Urovo

Метод для работы приложения в главном потоке

Метод предназначен для выполнения кода в главном потоке приложения Android, чтобы избежать проблем с многопоточностью и обеспечить плавную работу приложения.

// Метод для выполнения кода в главном потоке. private void mainThread(Runnable runnable) { // Создает новый обработчик (Handler), связанный с основным циклом сообщений (Looper) главного потока. new Handler(Looper.getMainLooper()).post(runnable); }

В новой версии Метод mainThread() полностью удален из кода, вместо него используется стандартный Android API runOnUiThread()

Пример того как это теперь работает:

runOnUiThread(() -> setInfoText("Formatted SUCCESS", true));
runOnUiThread(() -> ((TextView) findViewById(R.id.response)).setText(text));

Онбординг SDK

Метод отвечает за начало процесса онбординга и обработку результата (успешного или с ошибкой) с использованием SDK в отдельном потоке.

private void startOnboarding() { // Устанавливаем информационный текст, сообщающий о начале процесса setInfoText("Start onboarding. Please wait.", false); // Создаем новый поток для выполнения задачи по запуску процесса онбординга new Thread(() -> { // Запускаем процесс onboarding с помощью AriaPaymentSDK AriaPaymentSDK.getInstance().startOnboarding(MainActivity.this, new AriaPaymentSDK.OnboardingCallback() { @Override public void success() { // Если процесс прошел успешно, обновляем информационный текст setInfoText("Success onboarding", true); } @Override public void error(Throwable throwable) { // Если произошла ошибка, обновляем информационный текст с кодом ошибки setInfoText("Error onboarding: " + ((SDKException) throwable).getErrorCode().name(), true); } }); }).start(); // Запускаем созданный поток }

В новой версии был упрощен API, а SDK теперь самостоятельно управляет контекстом.

private void startOnboarding() { setInfoText("Start onboarding. Please wait.", false); new Thread(() -> AriaPaymentSDK.getInstance().startOnboarding(new AriaPaymentSDK.OnboardingCallback() { @Override public void onSuccess() { setInfoText("Success onboarding", true); } @Override public void onError(Throwable throwable) { setInfoText("Error onboarding: " + ((SDKException) throwable).getErrorCode().name(), true); } })).start(); }

Полный пример:

SDKConfig sdkConfig = buildSdkConfig(); try { AriaPaymentSDK.getInstance().init(getApplicationContext(), sdkConfig, new InitCallback() { @Override public void wasInit() { try { AriaPaymentSDK.getInstance().setClientCertificates(correctCertsPem); AriaPaymentSDK.getInstance().setClientPrivateKey(correctPrivateKeyPem); if (device == Device.TAP2PHONE) { new Thread(() -> { AriaPaymentSDK.getInstance().startLightOnboarding(getApplicationContext()); setInfoText("Success terminal init", true); }).start(); } else { setInfoText("Success terminal init", true); } } catch (SDKException e) { setInfoText("SDKException.ERROR_CODE: " + e.getErrorCode().name(), true); e.printStackTrace(); } } @Override public void wasNotInit(Throwable throwable) { TerminalFactory.getInstance().clearTerminal(); setInfoText("Fail terminal init", true); } }); } catch (SDKException e) { setInfoText("SDKException.ERROR_CODE: " + e.getErrorCode().name(), true); e.printStackTrace(); }
// В методе initAriaPaymentSDK(): AriaPaymentSDK.getInstance().init(buildSdkConfig(), new InitCallback() { @Override public void onSuccess() { try { AriaPaymentSDK.getInstance().setClientCertificates(correctCertsPem); AriaPaymentSDK.getInstance().setClientPrivateKey(correctPrivateKeyPem); if (device == Device.TAP2PHONE) { new Thread(() -> { AriaPaymentSDK.getInstance().startLightOnboarding(); setInfoText("Success terminal init", true); }).start(); } else { setInfoText("Success terminal init", true); } } catch (SDKException e) { setInfoText("SDKException.ERROR_CODE: " + e.getErrorCode().name(), true); e.printStackTrace(); } } @Override public void onError(Throwable throwable) { TerminalFactory.getInstance().clearTerminal(); setInfoText("Fail terminal init", true); } });

Завершение работы с SDK

В случае завершения работы с активностью необходимо закрыть SDK. Это делается следующим образом:

@Override protected void onDestroy(){ super.onDestroy(); AriaPaymentSDK.getInstance().close(); //Закрытие SDK при уничтожении Activity }

В новой версии произошли следующие изменения:

  1. Более безопасное завершение работы

  2. Улучшенная обработка контекста

  3. Правильная последовательность вызовов

@Override protected void onDestroy() { AriaPaymentSDK.getInstance().onDestroy(this); super.onDestroy(); }

Шаги выполнения (для самопроверки при инциализации SDK)

  1. Добавьте необходимые разрешения в AndroidManifest.xml

  2. Инициализируйте SDK в вашей активности

  3. Проверьте и запросите недостающие разрешения:

    • Используйте метод checkAndCollectDenyPermission для проверки необходимых разрешений.

    • Используйте метод requestDenyPermissions для запроса недостающих разрешений.

  4. Создайте и настройте объект конфигурации SDKConfig:

    • Установите таймаут запросов.

    • Установите имя пакета приложения.

    • Установите адреса серверов ARIASOFT.HOST и CA (Удостоверяющий Центр) с соответствующими протоколами и типами адресов.

  5. Инициализируйте SDK и установите клиентские сертификаты и приватный ключ:

    • Вызовите метод init для инициализации SDK.

    • Установите клиентские сертификаты с помощью метода setClientCertificates.

    • Установите приватный ключ клиента с помощью метода setClientPrivateKey.

  6. Обработка ошибок:

    • Обработайте исключения SDKException, чтобы определить, возникли ли ошибки во время инициализации, и выведите сообщение об ошибке.

Основные операции

Основные операции обеспечивают полный спектр функционала для управления транзакциями, проверки баланса, сверки итогов, генерации отчетов и получения логов, что позволяет эффективно использовать SDK для различных финансовых операций в POS-системе.

Для запуска выбранного метода нужно передать в метод start текущую Activity и requestCode по которому в onActivityResult можно будет получить ответ на запрос:

@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Response response = AriaPaymentSDK.getInstance().parseResponse(data); }
@SuppressLint("SetTextI18n") @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Response response = AriaPaymentSDK.getInstance().parseResponse(data); printResponse(response); }

Метод onActivityResult принимает следующие три переменных:

Наименование

Описание

Формат

requestCode

код запроса

string

resultCode

код результата

string

data

возвращенные данные

string

Оплата

Операция Оплата используется для оплаты товаров и услуг с указанием суммы и валюты:

String token = UUID.randomUUID().toString().replace("-", ""); // Генерирует уникальный токен для операции AriaPaymentSDK.getInstance().sale(amount, currency, token).start(activity, 100); // Начинает операцию оплаты с заданной суммой, валютой и токеном

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

amount = result; token = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().sale( amount.replaceAll("\\.", ""), // Форматирование суммы currency, token ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

amount = result; trxNumber = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().sale( amount.replaceAll("\.", ""), // Форматирование суммы currency, trxNumber ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

trxNumber

уникальный идентификатор операции

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа SaleResponse.

Отмена

Операция Отмена используется для аннулирования транзакции оплаты:

String token = UUID.randomUUID().toString().replace("-", ""); // Генерирует уникальный токен для операции AriaPaymentSDK.getInstance().cancel(amount, currency, lastTrxNumber, token).start(activity, 100); // Начинает операцию отмены оплаты с заданной суммой, валютой, номером транзакции и токеном

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

lastTrxNumber

номер последней транзакции

string

token = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().cancel( amount.replaceAll("\\.", ""), // Форматирование суммы currency, lastTrxNumber, token ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

lastTrxNumber

номер последней транзакции

string

trxNumber = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().cancel( amount.replaceAll("\.", ""), // Форматирование суммы currency, invoiceNumber, trxNumber ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

trxNumber

уникальный идентификатор операции

string

invoiceNumber

номер чека

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа VoidResponse.

Возврат

Операция Возврат используется для возврата ранее уплаченной суммы клиенту:

String token = UUID.randomUUID().toString().replace("-", ""); // Генерирует уникальный токен для операции AriaPaymentSDK.getInstance().refund(amount, currency, lastTrxNumber, token).start(activity, 100); // Начинает операцию возврата средств с заданной суммой, валютой, номером транзакции и токеном

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

lastTrxNumber

номер последней транзакции

string

token = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().refund( amount.replaceAll("\\.", ""), // Форматирование суммы currency, lastTrxNumber, token ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

token

уникальный идентификатор операции

string

lastTrxNumber

номер последней транзакции

string

trxNumber = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().refund( amount.replaceAll("\.", ""), // Форматирование суммы currency, serverTrxId, trxNumber ).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

amount

сумма баланса в минимально допустимых единицах

long

currency

валюта

int

serverTrxId

RRN, уникальный идентификатор на стороне банковского хоста

string

trxNumber

уникальный идентификатор операции

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа RefundResponse.

Баланс

Операция Баланс используется для получения информации о текущем балансе:

setInfoText("Start balance operation. Please wait."); // Устанавливает текст информации о начале операции проверки баланса String token = UUID.randomUUID().toString().replace("-", ""); // Генерирует уникальный токен для операции AriaPaymentSDK.getInstance().balance(currency, token).start(activity, 100); // Начинает операцию проверки баланса с заданной валютой и токеном

Метод работает со следующими переменными:

Наименование

Описание

Формат

currency

валюта

int

token

уникальный идентификатор операции

string

setInfoText("Start balance operation. Please wait.", false); token = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().balance(currency, token).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

currency

валюта

int

token

уникальный идентификатор операции

string

trxNumber = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().balance(currency, trxNumber).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

currency

валюта

int

trxNumber

уникальный идентификатор операции

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа BalanceResponse.

Сверка итогов

Операция Сверка итогов используется для сверки транзакций:

setInfoText("Start reconciliation operation. Please wait."); // Устанавливает текст информации о начале операции сверки итогов String token = UUID.randomUUID().toString().replace("-", ""); // Генерирует уникальный токен для операции AriaPaymentSDK.getInstance().reconciliation(token).start(activity, 100); // Начинает операцию сверки итогов с заданным токеном

Метод работает со следующими переменными:

Наименование

Описание

Формат

token

уникальный идентификатор операции

string

setInfoText("Start reconciliation operation. Please wait.", false); token = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().reconciliation(token).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

token

уникальный идентификатор операции

string

trxNumber = UUID.randomUUID().toString().replace("-", ""); AriaPaymentSDK.getInstance().reconciliation(trxNumber).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

trxNumber

уникальный идентификатор операции

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа ReconciliationResponse.

Отчет

Операция Отчет используется для генерации отчета о транзакциях за определенный период или в соответствии с определенными критериями:

setInfoText("Start report operation. Please wait."); // Устанавливает текст информации о начале операции получения отчета AriaPaymentSDK.getInstance().report(null, 3).start(activity, 100); // Начинает операцию получения отчета с заданными параметрами
setInfoText("Start report operation. Please wait.", false); AriaPaymentSDK.getInstance().report(null, 3).start(MainActivity.this, 100);

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа ReportResponse.

Логи ответов

Операция Логи ответов используется для получения логов ответов от SDK для отладки и анализа:

setInfoText("Start log operation. Please wait."); // Устанавливает текст информации о начале операции получения логов AriaPaymentSDK.getInstance().log(token).start(activity, 100); // Начинает операцию получения логов с заданным токеном
setInfoText("Start log operation. Please wait.", false); AriaPaymentSDK.getInstance().log(lastTrxNumber).start(MainActivity.this, 100);

Метод работает со следующими переменными:

Наименование

Описание

Формат

token

уникальный идентификатор операции

string

Результатом операции будет возвращаемое значение в onActivityResult под указанным requestCode в качестве Response типа LogResponse.

Дополнительные операции

Дополнительные операции включают ряд сервисных процедур, которые должны быть реализованы и доступны в специальном сервисном разделе или административном меню технического программного обеспечения (ТПО).

Проверка сертификатов

Эта функция инициализирует кнопку, которая проверяет, загружены ли сертификаты:

boolean success = AriaPaymentSDK.getInstance().checkOnboarding(YOUR_ACTIVITY); //Проверяет, требуется ли загрузка сертификатов. String message = success ? "No need to upload the certificates" : "You need to download the certificates"; setInfoText(message); //Отображает сообщение о результате проверки.
actionOnClick(() -> { setInfoText("Start certificates checking. Please wait.", false); boolean success = AriaPaymentSDK.getInstance().checkOnboarding(); String message = success ? "No need to upload the certificates" : "You need to download the certificates"; setInfoText(message, true); });
  • Метод checkOnboarding() больше не требует передачи контекста активности

  • Добавлено промежуточное уведомление о начале операции

  • Вся операция выполняется в фоновом потоке через actionOnClick()

Загрузка сертификатов

Эта функция инициализирует кнопку, которая загружает сертификаты через процесс онбординга:

AriaPaymentSDK.getInstance().startOnboarding(YOUR_ACTIVITY, new AriaPaymentSDK.OnboardingCallback() { //Запускает процесс онбординга с указанным контекстом и колбэком. @Override public void success() { runOnUiThread(() -> setInfoText("Success onboarding")); //Обновляет текстовое поле информации при успешном завершении онбординга. } @Override public void error(Throwable throwable) { runOnUiThread(() -> setInfoText("Error onboarding: " + ((SDKException) throwable).getErrorCode().name())); //Обновляет текстовое поле информации при ошибке в процессе онбординга, отображая код ошибки. } });
findViewById(R.id.load_certs).setOnClickListener(view -> { actionOnClick(() -> { if (TerminalFactory.getInstance().getDevice() == Device.TAP2PHONE) { showVsnDialog(); } else { startOnboarding(); } }); }); private void startOnboarding() { setInfoText("Start onboarding. Please wait.", false); new Thread(() -> AriaPaymentSDK.getInstance().startOnboarding(new AriaPaymentSDK.OnboardingCallback() { @Override public void onSuccess() { setInfoText("Success onboarding", true); } @Override public void onError(Throwable throwable) { setInfoText("Error onboarding: " + ((SDKException) throwable).getErrorCode().name(), true); } })).start(); }

Ключевые отличия от версии 1.0.29.111:

Аспект

Версия 1.0.29.111

Версия 1.0.37.0+

Параметры метода

Требовалась Activity

Без параметров

Поток выполнения

UI-поток

Фоновый поток

Обработка устройств

Единый подход

Разная логика для Tap2Phone

VSN-валидация

Без валидации

Обязательна для Tap2Phone

Получение информации о сертификатах

Функция получения информации о сертификатах реализована посредством инициализации кнопки, которая при нажатии собирает информацию о сертификатах и отображает её в виде текста.

// Получение информации о сертификатах через SDK: CertificateChain[] certificateChains = AriaPaymentSDK.getInstance().getCertificateInfo(activity.getApplicationContext()); // Создаем объект StringBuilder для построения строки информации о сертификатах. StringBuilder certificatesInfo = new StringBuilder(); for (CertificateChain certificateChain : certificateChains) { //Проходит по каждой цепочке сертификатов и добавляет информацию о ней в StringBuilder. certificatesInfo.append(certificateChain.getType().name()).append(": ").append("\n"); if (certificateChain.getChain() == null || certificateChain.getChain().isEmpty()) { certificatesInfo.append("--- NULL\n"); continue; } for (CertificateInfo certificate : certificateChain.getChain()) { certificatesInfo .append("--- ") .append(certificate.getType()).append("; ") .append(certificate.getStatus()).append("; ") .append(certificate.getExpirationDate()).append(";") .append("\n"); } };
CertificateChain[] certificateChains = AriaPaymentSDK.getInstance().getCertificateInfo(); StringBuilder certificatesInfo = new StringBuilder(); for (CertificateChain certificateChain : certificateChains) { // Добавляем тип цепочки сертификатов certificatesInfo.append(certificateChain.getType().name()) .append(": ") .append("\n"); // Проверяем наличие сертификатов в цепочке if (certificateChain.getChain() == null || certificateChain.getChain().isEmpty()) { certificatesInfo.append("--- NULL\n"); continue; } for (CertificateInfo certificate : certificateChain.getChain()) { certificatesInfo.append("--- ") .append(certificate.getType()).append("; ") .append(certificate.getStatus()).append("; ") .append(certificate.getExpirationDate()).append(";") .append("\n"); } } setInfoText(certificatesInfo.toString(), false); }); }); }

Ключевые отличия от версии 1.0.29.111:

  • Отсутствие зависимости от контекста

  • Упрощенный вызов без параметров

  • Единообразный формат вывода информации

  • Более детальная информация о каждом сертификате

Очистка данных

Эта функция инициализирует кнопку, которая запускает процесс очистки данных:

AriaPaymentSDK.getInstance().format(getApplicationContext(), new AriaPaymentSDK.FormatingCallback() { //Запускает процесс очистки данных (форматирования) с указанным контекстом и колбэком. @Override //В случае успеха метод выводит соответствующее сообщение. public void success() { runOnUiThread(() -> setInfoText("Formatted SUCCESS")); } @Override //В случае ошибки метод выводит соответствующее сообщение. public void failure() { runOnUiThread(() -> setInfoText("Formatted FAILED")); } });
private void initFormatButton() { findViewById(R.id.format).setOnClickListener(view -> { actionOnClick(() -> { // Уведомление о начале процесса setInfoText("Start formating. Please wait.", false); // Вызов API для форматирования AriaPaymentSDK.getInstance().format(new AriaPaymentSDK.FormatingCallback() { @Override public void onSuccess() { // Обработка успешного завершения runOnUiThread(() -> setInfoText("Formatted SUCCESS", true)); } @Override public void onError() { // Обработка ошибки runOnUiThread(() -> setInfoText("Formatted FAILED", true)); } }); }); }); }

Ключевые отличия:

  • Упрощение вызова API

  • Стандартизация колбэков

  • Улучшение UX

  • Безопасность потоков

Выбор терминала (или T2P)

Эта функция инициализирует обработчики кнопок выбора устройства:

findViewById(R.id.p2000l).setOnClickListener(view -> device = Device.P2000L); //Слушатель на кнопку выбора терминала P2000L findViewById(R.id.t1).setOnClickListener(view -> device = Device.T1); //Слушатель на кнопку выбора терминала T1 findViewById(R.id.emulator).setOnClickListener(view -> device = Device.EMULATOR); //Слушатель на кнопку выбора эмулятора findViewById(R.id.tap_2_phone).setOnClickListener(view -> device = Device.TAP2PHONE); //Слушатель на кнопку выбора Tap2Phone findViewById(R.id.sunmi_p2).setOnClickListener(view -> device = Device.SUNMI_P2); //Слушатель на кнопку выбора терминала Sunmi P2 findViewById(R.id.init_terminal).setOnClickListener(view -> { setInfoText("Start terminal init. Please wait.", false); // TerminalFactory.getInstance().initTerminal(device); // Инициализирует терминал с устройством, выбранным ранее. ArrayList<String> denyPermissions = checkAndCollectDenyPermission( //проверяет и собирает список запрещенных разрешений для SDK. AriaPaymentSDK.getInstance().getPermissions() ); requestDenyPermissions(denyPermissions); // запрашивает у пользователя разрешения, которые были собраны на предыдущем шаге. }); }
private void initTerminalButtons() { Spinner deviceSpinner = findViewById(R.id.device_spinner); // Динамическое создание списка устройств из enum String[] deviceNames = Arrays.stream(Device.values()) .map(Device::name) .toArray(String[]::new); // Настройка адаптера для Spinner ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, deviceNames); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); deviceSpinner.setAdapter(adapter); // Восстановление предыдущего выбора int selectedPosition = Arrays.asList(deviceNames).indexOf(device.name()); if (selectedPosition != -1) { deviceSpinner.setSelection(selectedPosition); } // Обработчик выбора устройства deviceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onNothingSelected(AdapterView<?> parent) {} @Override public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) { device = Device.values()[position]; } }); // Инициализация терминала findViewById(R.id.init_terminal).setOnClickListener(view -> { setInfoText("Start terminal init. Please wait.", false); try { TerminalFactory.getInstance().initTerminal(device); } catch (Exception e) { setInfoText("Fail terminal init", true); return; } ArrayList<String> denyPermissions = checkAndCollectDenyPermission( AriaPaymentSDK.getInstance().getPermissions() ); requestDenyPermissions(denyPermissions); }); }

Особенности новой реализации:

  • Динамический список устройств (Новые устройства автоматически появляются в списке без изменения кода)

  • Улучшенное управление состоянием

  • Расширенная обработка ошибок (Предотвращение дальнейших действий при ошибке инициализации, более информативный ответ)

  • Автоматизация работы с разрешениями (Система автоматически запрашивает необходимые разрешения)

Варианты ответа

Метод printResponse обрабатывает различные типы ответов (Response) и обновляет интерфейс пользователя информацией о выполненной операции:

// Проверка типа ответа: SaleResponse if (response instanceof SaleResponse) { operationName = "Sale"; // Установка имени операции check = ((SaleResponse) response).getPrintData(); // Получение данных для печати lastTrxNumber = ((SaleResponse) response).getUniqTrxNumber(); // Сохранение уникального номера транзакции } // Проверка типа ответа: BalanceResponse else if (response instanceof BalanceResponse) { operationName = "Balance"; // Установка имени операции check = ((BalanceResponse) response).getPrintData(); // Получение данных для печати } // Проверка типа ответа: VoidResponse else if (response instanceof VoidResponse) { operationName = "Void"; // Установка имени операции check = ((VoidResponse) response).getPrintData(); // Получение данных для печати } // Проверка типа ответа: RefundResponse else if (response instanceof RefundResponse) { operationName = "Refund"; // Установка имени операции check = ((RefundResponse) response).getPrintData(); // Получение данных для печати } // Проверка типа ответа: ReconciliationResponse else if (response instanceof ReconciliationResponse) { operationName = "Reconciliation"; // Установка имени операции check = ((ReconciliationResponse) response).getPrintData(); // Получение данных для печати } // Проверка типа ответа: LogResponse else if (response instanceof LogResponse) { operationName = "Log"; // Установка имени операции check = ((LogResponse) response).getPrintData(); // Получение данных для печати } // Проверка типа ответа: ReportResponse else if (response instanceof ReportResponse) { operationName = "Report"; // Установка имени операции check = ((ReportResponse) response).getPrintData(); // Получение данных для печати } }
@SuppressLint("SetTextI18n") private void printResponse(Response response) { String operationName = null; String check = null; // Обработка различных типов ответов if (response instanceof SaleResponse) { operationName = "Sale"; check = ((SaleResponse) response).getPrintData(); lastTrxNumber = ((SaleResponse) response).getUniqTrxNumber(); } else if (response instanceof BalanceResponse) { operationName = "Balance"; check = ((BalanceResponse) response).getPrintData(); } else if (response instanceof VoidResponse) { operationName = "Void"; check = ((VoidResponse) response).getPrintData(); } else if (response instanceof RefundResponse) { operationName = "Refund"; check = ((RefundResponse) response).getPrintData(); } else if (response instanceof ReconciliationResponse) { operationName = "Reconciliation"; check = ((ReconciliationResponse) response).getPrintData(); } else if (response instanceof LogResponse) { operationName = "Log"; check = ((LogResponse) response).getPrintData(); } else if (response instanceof ReportResponse) { operationName = "Report"; check = ((ReportResponse) response).getPrintData(); } // Обработка null-ответа if (response == null) { setInfoText("Operation: null", true); return; } // Формирование основной информации об операции setInfoText( "Operation: " + operationName + "; " + "Success: " + (response.isSuccess() ? "True" : "False") + "; " + "ErrorReason: " + response.getErrorReason().name(), false ); // Отображение данных для печати (чека) ((TextView) findViewById(R.id.check_response)).setText(check); }

Основные улучшения в новой реализации:

  • Расширенная информация об операции (Добавлен статус успешности операции, отображается причина ошибки, если она есть)

  • Отдельный вывод чека (в специальном TextView)

  • Защита от NullPointerException

  • Оптимизированное сохранение номера транзакции (Сохраняется только для операций продажи и используется для последующих операций по примеру "отмена", "возврат")

Обработка результата

Каждый ответ является наследником класса Response в котором есть два поля для определения успешного выполнения запрошенной транзакции:

Наименование

Описание

Формат

success

Значение (0 or 1) при (неудаче or успехе) соответственно

int

errorReason

Значение кода ошибки

int

Коды ошибок

BalanceResponse

Для предоставления ответа о балансе в POS-системе используется класс BalanceResponse. Он содержит поля для суммы (amount), валюты (currency), кода операции (operationCode), кода ответа (respCode), статуса транзакции (trxStatus), данных для печати (printData) и даты/времени на внешнем устройстве (extDeviceDateTime):

Наименование

Описание

Формат

amount

сумма баланса (в минимально допустимых единицах)

long

currency

валюта

int

operationCode

операция

int

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

printData

данные для печати

string

extDeviceDateTime

дата и время на внешнем устройстве

string

LogResponse

Для хранения данных ответа в POS-системе используется класс logResponse. Класс содержит следующие поля:

Наименование

Описание

Формат

uniqTrxNumber

уникальный номер транзакции

string

amount

сумма транзакции (в минимально допустимых единицах)

long

currency

код валюты

int

hostDateTime

дата и время на сервере

string

readType

тип чтения

int

pan

номер PAN (Primary Account Number)

string

authCode

авторизационный код

string

refNumber

референсный номер

string

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

extDeviceDateTime

дата и время на внешнем устройстве

string

extDeviceId

идентификатор внешнего устройства

string

merchantId

идентификатор продавца

string

printData

данные для печати

string

serverTrxId

RRN, идентификатор транзакции на стороне финансового хоста

string

acquiringBank

наименование банка эквайера

string

invoiceNumber

номер чека

string

ReconciliationResponse

Класс ReconciliationResponse предназначен для работы с данными ответов по операциям сверки в POS системе. Методы класса управляют информацией о транзакциях, их статуте, данными устройств и продавцов. Класс ReconciliationResponse содержит следующие поля:

Наименование

Описание

Формат

operationCode

код операции

int

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

printData

данные для печати

string

merchantId

идентификатор продавца

string

extDeviceId

идентификатор внешнего устройства

string

uniqTrxNumber

уникальный номер транзакции

string

extDeviceDateTime

дата и время на внешнем устройстве

string

RefundResponse

Для данных с ответами по операциям возврата в POS-системе используется класс RefundResponse. Класс RefundResponse содержит следующие поля:

Наименование

Описание

Формат

amount

сумма возврата (в минимально допустимых единицах)

long

currency

код валюты

int

hostDateTime

дата и время на сервере

string

readType

тип чтения

int

pan

номер PAN (Primary Account Number)

string

authCode

авторизационный код

string

refNumber

референсный номер

string

operationCode

код операции

int

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

printData

данные для печати

string

merchantId

идентификатор продавца

string

extDeviceId

идентификатор внешнего устройства

string

uniqTrxNumber

уникальный номер транзакции

string

extDeviceDateTime

дата и время на внешнем устройстве

string

origTrxNumber

уникальный номер оригинальной транзакции со стороны внешнего устройства

string

serverTrxId

RRN, идентификатор транзакции на стороне финансового хоста

string

acquiringBank

наименование банка эквайера

string

invoiceNumber

номер чека

string

ReportResponse

Класс ReportResponse используется для хранения данных ответа, связанных с операциями создания отчетов в POS-системе. Класс содержит следующие поля:

Наименование

Описание

Формат

commandMode

вариант отчета

int

printData

данные для печати

string

uniqTrxNumber

уникальный код транзакции

string

trxStatus

Статус по коду ответа процессинга

string

SaleResponse

Класс SaleResponse используется для хранения данных ответа, связанных с операциями оплаты, продажи в POS-системе:

Наименование

Описание

Формат

uniqTrxNumber

уникальный номер транзакции

string

amount

сумма транзакции (в минимально допустимых единицах)

long

currency

код валюты

int

hostDateTime

дата и время на сервере

string

readType

тип чтения

int

pan

номер PAN (Primary Account Number)

string

authCode

авторизационный код

string

refNumber

референсный номер

string

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

extDeviceDateTime

дата и время на внешнем устройстве

string

extDeviceId

идентификатор внешнего устройства

string

merchantId

идентификатор продавца

string

printData

данные для печати

string

serverTrxId

RRN, идентификатор транзакции на стороне финансового хоста

string

acquiringBank

наименование банка эквайера

string

invoiceNumber

номер чека

string

VoidResponse

Класс VoidResponse используется для хранения данных ответа, связанных с отменой оплаты в POS-системе. Класс VoidResponse содержит следующие поля:

Наименование

Описание

Формат

amount

сумма возврата (в минимально допустимых единицах)

long

currency

код валюты

int

operationCode

код операции

int

respCode

Код ответа процессинга

string

trxStatus

Статус по коду ответа процессинга

string

printData

данные для печати

string

merchantId

идентификатор продавца

string

extDeviceId

идентификатор внешнего устройства

string

uniqTrxNumber

уникальный номер транзакции

string

extDeviceDateTime

дата и время на внешнем устройстве

string

origTrxNumber

уникальный номер оригинальной транзакции со стороны внешнего устройства

string

serverTrxId

RRN, идентификатор транзакции на стороне финансового хоста

string

acquiringBank

наименование банка эквайера

string

invoiceNumber

номер чека

string

Тестовое приложение

Как работать с примером

В тестовом приложении есть весь необходимый функционал для проверки, конкретно:

  • Инициализация конкретной модели терминала:

    image.png

  • Загрузка, проверка и получение сведений об имеющихся сертификатах:

    CertButtons.png
    А также кнопка очистки данных с устройства. (Erase Cryptodevice Data)

  • Платежные операции:

    PaymentOperations.png

Подробнее о платежных операциях говорится в этом разделе.

Видео-демонстрация

Видео-демонстрация работы основных функций тестового приложения:

Коды ошибок

Для представления различных причин ошибок, которые могут возникнуть в процессе работы POS-системы, используется перечисление ErrorReason. Каждая причина ошибки имеет соответствующее целочисленное значение:

Тип ошибки

Код ошибки

Описание

CANCELLED_BY_USER_OR_USER_TIMEOUT

0

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

REFUSED_BY_HOST

1

Операция была отклонена хостом (сервером).

REFUSED_BY_TERMINAL

2

Операция была отклонена терминалом.

NO_ERROR

3

Ошибок нет.

OTHER_ERROR

4

Другая ошибка.

Обратная связь

В случае возникновения проблем и вопросов по работе SDK, тестового приложения, напишите на почту по адресу support@nadeks.ru.

Last modified: 27 December 2025