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

Исходные данные

В нашей системе по умолчанию отводится 30 секунд на то, чтобы транзакция началась и закончилась, т.е. получила финальный статус – «Успех» или «Отказ». Транзакция начинается в момент, когда API запрос, инициирующий транзакцию, входит к нам на платежный шлюз. Дальше с платежного шлюза транзакция передается в разные модули: сначала в Smart Routing, после на коннектор и далее отправляется конечному эквайеру или PSP, от которого мы в итоге ожидаем финальный ответ. На весь этот процесс – с момента входа API запроса к нам в систему до момента получения финального ответа от конечного эквайера или PSP, мы отводим 30 секунд.

Эти 30 секунд необходимы, чтобы не создавать очереди при синхронном режиме интеграции. Пока мы ждем ответ от эквайера или PSP, мы держим с ним сетевое соединение. Количество одновременных соединений всегда ограничено, чтобы самих себя же не задосить (иными словами, у нас не будет свободных сетевых сокетов, чтобы к нам мог кто-нибудь еще присоединиться и сервис станет недоступен). Это нормальная практика, когда эквайер или PSP не поддерживает асинхронный режим интеграции и наша система взаимодействует с платежным шлюзом эквайера в синхронном режиме. В нашем кейсе мы описываем именно этот случай.

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

Асинхронный режим – это режим взаимодействия с другой стороной, когда мы отправляем запрос и больше соединение не держим, а вместо этого ждем так называемый колл-бэк, т.е. обратное уведомление о результате.

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

Обычно 30-ти секунд при синхронном режиме интеграции более чем достаточно, потому что обработка любой транзакции в среднем занимает не более 10 секунд. Но если эквайер (а в нашем случае это был PSP) долго отвечает, и мы не успеваем получить окончательный статус за 30 секунд, то в нашей системе транзакция остается в статусе «Не завершено» (Incomplete). В последствии ей можно вручную назначить финальный статус после сверки с эквайером и/или PSP.

Проблема

С PSP (это был именно PSP, а не банк-эквайер), который не поддерживает асинхронный режим, у нашего арендатора системы работает крупный мерчант, который почему-то наши «Incomplete» статусы воспринимал как финальные неуспешные и вместо того, чтобы разобраться, почему транзакции подвисли, он отправлял их по каскаду дальше к следующему, уже стороннему эквайеру (не к нашему арендатору). Все это приводило к двойному списанию средств у покупателя. Потому что транзакция финализировалась у первого PSP, но так как по истечению 30 секунд мы разрывали канал связи, то не знали об этом. А поскольку мерчант не верно интерпретировал статусы, транзакция уйдя в каскад повторно проходила и успешно финализировалась у второго стороннего эквайера.

Статус «Incomplete» — это промежуточный статус транзакции, который она получает сразу после создания в системе и имеет до получения финального статуса («Successful» или «Declined»).

Пока у транзакции статус «Incomplete», мерчант, разумеется не знает, списаны деньги или не списаны. Но запускать транзакцию в каскад не следует, необходимо дождаться финального статуса или связаться со своим PSP чтобы выяснить, почему транзакция не получила финальный статус. Но конкретно этот крупный мерчант считал, что «Incomplete» = «Declined».

Мы начали разбираться, почему система не уложилась в 30 секунд на обработку транзакции. Логи ответа на стороне PSP показывают, что он отвечает нам за 18 секунд, и даже отдал финальный ответ — успех. Т.е. по идее система нашего арендатора должна была успеть завершить транзакцию, но по какой-то причине не успела. Мы начали смотреть, где же транзакция задержалась более чем на 12 секунд. И обнаружили, что задержалась она в нашем Smart Routing. Ее обработка в Smart Routing на нашей стороне заняла почти половину времени, которое мы отводим на обработку транзакции. Это очень долго! Ведь Smart Routing должен отрабатывать все правила за миллисекунды. 

Мы продолжили изучение кейса и обнаружили, что у нашего арендатора системы было создано 30 правил на уровне PSP (всей системы). То есть эти правила отрабатывались для каждой транзакции, идущей от любого мерчанта. И эти правила по своей природе являлись агрегационными, ограничивающими правилами вида: «Если сумма транзакций больше, чем N за текущий месяц где: валюта транзакции = A, тип транзакции = платеж, статус транзакции = успех, то отказ». Наш арендатор PSP не хотел пропустить через свою систему успешных платежных транзакций на сумму в каждой валюте больше, чем он определил для себя в месяц. Поэтому он сделал такое ограничивающее правило для каждой из 30 валют, с которой он работает.

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

В итоге получилось так, что каждый раз, когда транзакция входила в систему, система в режиме реального времени делала подсчет общей суммы успешных платежей по каждой из 30 валют на момент входа транзакции. И этот процесс повторялся с каждой новой входящей транзакцией. С точки зрения аппаратных ресурсов это были довольно «тяжелые» правила. Каждый раз система обращалась к базе данных, собирала все данные по конкретной валюте с начала месяца, и делала агрегационный расчет. А валют и правил – 30.

Агрегационный расчет – это когда система считает предыдущую совокупность количества платежей или совокупность суммы платежей.

Мы увидели, что по каждой транзакции система обращалась 30 раз к базе данных, чтобы просчитать на какую сумму были сделаны платежи к моменту прохождения каждой очередной транзакции. И поскольку транзакций у мерчанта проходило более одного миллиона в месяц (а в целом по нашей системе за месяц проходят десятки миллионов транзакций), то фактически каждый раз наша система, обращалась к базе данных, выбирала только успешные для данного мерчанта и делала расчет по всем 30 валютам. Хотя на самом деле расчет требовалось делать только по одной валюте – валюте транзакции.

Например, если транзакция идет в евро, то считать и проверять нужно было только превысил ли арендатор 10 миллионов евро в текущем месяце или нет.  Однако ввиду уже упомянутой особенности работы логики Smart Routing, расчет делался как по валюте транзакции, так и по всем 29 остальным валютам, хотя для достижения поставленной цели достаточно было выполнить расчет только по валюте транзакции, чтобы применить только одно правило из 30. И вот на этих операциях мы теряли 18 секунд.

Когда эквайер отвечал нам в стандартных рамках, максимум за 5 секунд, то, проведя 12 секунд в Smart Routing, транзакция финализировалась за отведенной время. Но, в данном конкретном случае, когда эквайер отвечал нам 18 секунд, в нашей системе начались таймауты.

Решение

Для того, чтобы эту ситуацию исправить. Мы добавили в Smart Routing возможность задавать предварительное условие (precondition) для правила, чтобы система могла определять нужно выполнять это правило (и соответственно запускать расчеты всех данных, которые потребуются для проверки по этому правилу) или нет.

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

Если он хочет в каждой валюте не превысить какую-то сумму, то для каждой валюты необходимо создать правило вида: «Если валюта транзакции А, если сумма транзакций больше, чем N за текущий месяц где: валюта транзакции = A, тип транзакции = платеж, статус транзакции = успех, то отказ».

Теперь система смотрит на валюту транзакции в предварительном условии правила, сравнивает его с валютой проверяемой транзакции, и если они совпадают, то запускается расчет необходимых агрегационных величин, которые нужны для дальнейшей проверки транзакции по данному правилу. В противном случае правило к данной транзакции не применяется и соответственно расчет необходимых агрегационных величин не производится. Таким образом теперь из всех 30 правил фактически запускается и отрабатывается только одно — расчет идет только один раз для конкретной валюты конкретной транзакции. Smart Routing прекратил выполнять лишнюю работу и отрабатывает все агрегационные ограничивающие правила меньше, чем за секунду, как и ожидается.

В заключение

Эту проблему мы обнаружили, потому что одновременно сложился ряд обстоятельств:

  1. Большой поток платежных транзакций у нашего арендатора.
  2. Десятки ограничивающих правил на уровне всего PSP (а не отдельного мерчанта или магазина) у нашего арендатора. При одном-двум правиле мы бы не словили такой тайм-аут, так как отработка правил Smart Routing даже при большом массиве транзакций укладывалась бы 1-2 секунды.
  3. Долгий ответ от эквайера или PSP (более 15 секунд), с которым работает наше арендатор.

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

Respectfully, eComCharge TeamВерим в ваш успех, Команда eComCharge
eComCharge develops and delivers the PCI DSS Level 1 certified White Label Payment Platform beGateway for Payment Service Providers and Acquirers.Компания eComCharge разрабатывает и поставляет процессинговую платежную платформу beGateway, сертифицированную по самому высшему уровню стандарта PCI DSS, для поставщиков платежных услуг и банков, которые используют ее под собственным брендом.