Автоматизированное тестирование интеграции платежных шлюзов: не так страшен черт

23/10/23
Технические статьи
Автоматизированное тестирование интеграции платежных шлюзов: не так страшен черт

Введение

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

Задача по автоматизации тестирования платежного шлюза как черного ящика поначалу звучит довольно сложной. Практически сразу у исполнителей в голове возникают вопросы: с чего начать, куда присоединяться, как быть с оплатами, где брать карточки для тестирования платежей и многие другие.

В этой статье мы постараемся развеять эти опасения и рассмотрим тестирование интеграции с платёжными системами на примере сервисов Robokassa и ЮKassa. Мы выбрали эти системы из-за доступных API и возможности быстро настроить демонстрационный магазин для начала тестирования. В некоторых случаях, для интеграции с платежными системами потребуется открытие расчетного счета в их банке, а в других – ожидание одобрения заявки на подключение со стороны отдела продаж. Мы поделимся с вами инструкциями по подключению к обоим системам, проверке статуса оплаты, поиску документации, выбору тестовых карт и магазинов, а также рассмотрим другие потенциальные трудности, с которыми может столкнуться тестировщик в ходе работы.

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

Подключаемся к обеим системам

Обе выбранные нами системы позволяют взаимодействовать с веб-приложением по протоколам REST + HTTP/1.1. Причем все взаимодействия можно разделить на два типа:

  • с предварительным созданием платежа, как в ЮKassa;
  • без предварительного создания платежа, как в сервисе Robokassa.

Все взаимодействия, как правило, проходят через HTTP/1.1 с поддержкой̆ Базовой аутентификации, но есть возможность сгенерировать токен.

В указанном ниже примере при помощи собственных DTO и RestAssured мы создаём платёж в системе ЮKassa , а в качестве результата получаем URL на страницу оплаты:

public String createPayment(String shopId, String shopSecret) { 
        return RestAssured.given() 
            .headers(Headers.headers( 
                new Header("Content-Type", 
"application/json"), 
                new Header("Authorization", "Basic " + 
Base64.getEncoder().encodeToString((shopId + ":" + 
shopSecret).getBytes())), 
                new Header("Idempotence-Key", 
UUID.randomUUID().toString()) 
            )).body( 
                Payment.builder().amount(new Amount("RUB", 
100.0)).confirmation(new 
PaymentConfirmation("https: example.com", 
"redirect")).description("Payment number 8").build() 
).post("https: api.yookassa.ru/v3/payments").andReturn().jso 
nPath().getString("confirmation.confirmation_url"); 
} 

В случае использования платежной системы, не создающей предварительный платёж, в ссылке на оплату обычно содержится контрольная сумма, которая гарантирует целостность переданной̆ информации. Вот так, например, это реализовано в сервисе Robokassa:

public String generatePaymentLink(String shopId, double 
amount, String description, long orderId, String signature) { 
        try { 
            URIBuilder builder = new 
URIBuilder("https: auth.robokassa.ru/Merchant/Index.aspx") 
                .addParameter("MerchantLogin", shopId) 
                .addParameter("OutSum", new 
DecimalFormat("  0.   ", new 
DecimalFormatSymbols(Locale.US)).format(amount)) 
                .addParameter("InvId", 
String.valueOf(orderId)) 
                .addParameter("Desc", description) 
                .addParameter("SignatureValue", signature) 
                .addParameter("IsTest", "1"); 
            return builder.build().toString(); 
        } catch (URISyntaxException e) { 
            throw new RuntimeException(e); 
} }  

Проверка факта оплаты

В типовом сценарии пользователь веб-сервиса (на стадии тестирования – разработчик), имея ссылку, переходит на страницу оплаты, вводит реквизиты (номер карты, электронного кошелька) и нажимает кнопку «оплатить». Но откуда он узнает, что оплата прошла? В реальной жизни платёжная система сама сообщает это по HTTP протоколу. Адрес, на который высылается сообщение об оплате, вводится пользователем в настройках магазина.

Однако, первая сложность для тестировщика возникает уже на этом этапе – адреса для рассылки нет. В этом случае мы рекомендуем использовать доступную простую лямбду в любом облаке (например, Yandex Cloud), которая выводит в свой лог запросы с заголовками. Эти запросы можно будет считывать из лога и выводить в формате curl для последующего переиспользования. Пример такой̆ лямбды приведён ниже:

import json  
def compose_curl_options(event): 
    result = "" 
    headers = event['headers'] 
    for key, value in headers.items(): 
        if not result.startswith('x-amzn'): 
            result += "-H '%s: %s' " % (key, value) 
    if event.get('body') is not None: 
        result += "-d '%s' " % event['body'] 
    return result 
def lambda_handler(event, context): 
    request_context = event['requestContext'] 
    method = request_context['http']['method'] 
    path = request_context['http']['path'] 
    print("curl -X {} https: dev.shop.internal{} 
{}".format(method, path, compose_curl_options(event))) 
    return { 
        'statusCode': 200, 
        'body': json.dumps('Hello from Lambda!') 
    } 

Продемонстрируем, как уведомление о платеже для тестового магазина ЮKassa, полученное из лога функции, будет выглядеть в предлагаемом решении:

{ 
  "type": "notification", 
  "event": "payment.waiting_for_capture", 
  "object": { 
    "id": "2c30819b-000f-5000-a000-1e03a33659f6", 
    "status": "waiting_for_capture", 
    "amount": { 
      "value": "100.00", 
      "currency": "RUB" 
    }, 
    "description": "Payment number 8", 
    "recipient": { 
      "account_id": "223841", 
      "gateway_id": "2094336" 
    }, 
    "payment_method": { 
      "type": "yoo_money", 
      "id": "2c30819b-000f-5000-a000-1e03a33659f6", 
      "saved": false, 
      "title": "YooMoney wallet 410011758831136", 
      "account_number": "410011758831136" 
    }, 
    "created_at": "2023-06-30T05:53:31.652Z", 
    "expires_at": "2023-07-07T05:54:14.285Z", 
    "test": true, 
    "paid": true, 
    "refundable": false, 
    "metadata": {} 
} }  

Если же мы подключились к сервису Robokassa, у которого схема взаимодействия, как мы помним, немного другая, нам в качестве ответа приходит не JSON, а application/x-www-form-urlencoded, который нуждается в дополнительной валидации магазином для того, чтобы платёж считался исполненным. Помимо этого, ответ в строке statusCode, в отличие от сервиса ЮKassa, тоже не должен быть просто числом 200, а должен после OK содержать значение параметра InvId. Например, OK1, если номер заказа 1.

Рисунок 1. Ответ сервиса robokassa, перенаправленный на тестовую функцию

Рисунок 1. Ответ сервиса robokassa, перенаправленный на тестовую функцию

Доступ к API

Оба эти сервиса предоставляют простой и быстрый способ самостоятельного подключения через API. В обоих случаях, чтобы начать принимать платежи через ваше приложение, вам необходимо ознакомиться с условиями использования API, зарегистрировать ваше приложение в системе API кошелька и реализовать взаимодействие по соответствующему протоколу, используя подробную документацию, доступную на официальных веб-сайтах компаний-разработчиков. Для упрощения процесса мы предоставляем ссылки на документацию Robokassa и ЮKassa.

Тестовые карты и магазины

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

Что же касается тестовых банковских карт, то некоторые платёжные системы (для иллюстрации мы используем ЮKassa, но Robocassa предлагает пользователям такой же функционал) поддерживают собственные способы оплаты. Пример реализации приведен на рис. 2

Рисунок 2. Выбор способа оплаты

Рисунок 2. Выбор способа оплаты

Тестировщик может выбрать оплату тестовым кошельком ЮKassa, как показано на рис. 3, либо тестовой картой. При этом, если выбран способ оплаты картой, то в документации платёжной системы, которая выложена в открытом доступе на сайте разработчика, можно обнаружить номера тестовых карт и различных способов оплаты, с подтверждением платежа или без. Есть также карты для тестирования сообщений об ошибках, как продемонстрировано на рис. 4

Рисунок 3. Оплата ЮMonay

Рисунок 3. Оплата ЮMonay

Рисунок 4. Ошибка при оплате банковской картой

Рисунок 4. Ошибка при оплате банковской картой

Хотелось бы напомнить, что многие ошибки, такие как «недостаточный баланс», «счёт заблокирован», «ошибка 3D авторизации», мы на своей стороне не увидим, поскольку они обрабатываются самой платёжной системой.

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

Регистрация в системе приема платежей

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

Среди самых распространённых сложностей можно упомянуть регистрацию в системе приёма платежей̆. Некоторые платежные системы предоставляют собой ограниченный доступ к тестовой среде, часто требуют реквизиты компании, а некоторые даже требуют заключения договора или открытия расчётного счёта для регистрации в системе. Выбранные нами сервисы ЮKassa и Robokassa дают доступ к тестовому магазину без заключения договора, а в качестве ИНН и ОГРН, если у вас ещё нет компании, можно ввести любые общедоступные реквизиты. В случае, если для приложения выбрана система, которая требует регистрации и/или открытия расчетного счета в банке – эта задача лежит на владельце продукта.

Заключение

В данной статье мы рассмотрели процесс тестирования интеграции веб-сервисов с платежными системами на примере Robokassa и ЮKassa. Мы показали, что задача эта не так уж сложна и страшна, как может показаться на первый взгляд. С применением определенных инструментов и подходов мы можем эффективно и безопасно проверять работу наших приложений с различными платежными сервисами.

Если у вас нет достаточных ресурсов или времени для самостоятельной реализации данной интеграции, у нас уже имеется готовый тестовый фреймворк, включающий в себя множество инструментов для автоматизации тестирования, таких как API-тестирование, работа с электронной почтой, генерация отчетов, сравнение скриншотов, взаимодействие с браузерными PUSH-уведомлениями и другие. Наши обученные специалисты, опираясь на этот фреймворк, способны справиться с задачей по автоматизации гораздо быстрее, чем команда, не обладающая подобными ресурсами.

Свяжитесь с нами напрямую

Офисы

Москва

117587, Варшавское ш., д. 125, стр. 16А

Ростов-на-Дону

344002, пр. Буденновский, д. 9, офис 305

Нижний Новгород

603104, ул. Нартова, д. 6, корп. 6, офис 829