Некоторые мысли о дизайне архитектуры моей платежной платформы

Архитектура

Общедоступная учетная запись WeChat «Back-end Advanced», ориентированная на совместное использование серверных технологий: Java, Golang, WEB-инфраструктура, распределенное промежуточное программное обеспечение, управление услугами и т. д.
Старый водитель научил тебя всем деньгам и довел до продвинутого уровня, я не успел объяснить и сесть в автобус!

Моей первой задачей в предыдущей компании была разработка единой платежной платформы.В связи с потребностями бизнеса компании был необходим доступ к множеству сторонних платежей.Ранее платежи компании были разбросаны по разным проектам,что не способствовало оплате управления., так что агрегируя трехсторонний платеж, на меня ложится задача унификации платежной платформы.Можно сказать, что дизайн полностью с 0. После просмотра собственно боевой сводки, я придумал некоторые архитектурные дизайн-мышление. Я написал свои собственные архитектурные идеи дизайна, но я еще этого не сделал. Некоторые люди задавали связанные вопросы в технической группе несколько дней назад. Я думаю, что это необходимо написать, чтобы помочь большему количеству разработчиков, которым нужно развивать платежные платформы.

шаблон компонента

Поскольку у компании есть бизнес во многих регионах и ей необходимо предоставить различные платежные каналы для развития бизнеса, разработанная платежная платформа должна иметь доступ к различным сторонним платежным каналам, таким как: оплата WeChat, оплата Alipay, PayPal, IPayLinks и т.д., все мы знаем, что у каждого стороннего платежа есть свой набор внешних API, а у официального есть набор SDK для реализации этих API, как нам организовать эти API?

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

Через режим Builder соответствующий объект компонента строится по параметрам запроса, компонент отделяется от внешнего мира, а реализация построения компонента скрывается. Режим компонента + режим Builder обеспечивает высокую масштабируемость платежной платформы.

система мультиаккаунтов

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

Итак, я представил систему с несколькими учетными записями.Самая важная основная концепция системы с несколькими учетными записями заключается в использовании учетной записи в качестве детализированной для доступа к нескольким сторонним платежам, унификации параметров учетной записи и создания единой системы платежных учетных записей. Платформа не должна заботиться о различных платежах.Различия между учетными записями и количеством учетных записей для сторонних платежей.

На этом этапе я добавляю слой учетной записи на диаграмму архитектуры платежной платформы:

Внешний интерфейс должен передать только accountId, а платежная платформа может запросить соответствующую платежную учетную запись в соответствии с accountId, а затем создать компонентный объект, соответствующий платежной учетной записи, в режиме Builder, полностью скрывая различия между различными платежами. В системе с несколькими учетными записями он может поддерживать неограниченный платежный счет, полностью отвечающий потребностям развития бизнеса компании.

Унифицированный обратный вызов и асинхронная обработка распределения

Учащиеся, которые разрабатывали платежи, знают, что текущий сторонний платеж имеет функцию, то есть после успешного платежа/возврата будет функция обратного вызова платежа/возврата, цель которой состоит в том, чтобы позволить торговой платформе проверить платеж. заказ сам по себе Является ли это законным, например: чтобы клиент не мог злонамеренно изменить такие параметры, как сумма при оплате, то после успешной оплаты заказ будет в состоянии оплаты, и вам нужно дождаться обратный звонок стороннего платежа.Если обратный звонок получен в это время, проверьте Когда обнаружится, что сумма заказа не совпадает с оплаченной суммой, то заказ меняется на отказ платежа, чтобы предотвратить потерю средств. Идея обратного звонка в том, чтобы обеспечить окончательную согласованность, поэтому при вызове платежа нам не нужно проверять правильность параметров в это время, нам нужно только проверить это во время обратного звонка.

После разговора о цели обратного вызова, как мы спроектируем обратный вызов платежной платформы?

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

Для механизма раздачи я предлагаю использовать RocketMQ для обработки.Некоторые люди могут спросить, если RocketMQ используется для обработки раздачи, как результат проверки может быть возвращен в режиме реального времени на сторонний платеж? Эта проблема тоже была головной болью для меня в то время.Вот некоторые мысли о дизайне обратного вызова:

  1. Система компании основана на микросервисной архитектуре SpringCloud, а микросервисы взаимодействуют через HTTP. В то время многие микросервисы были подключены к моей платежной платформе. Если для рассылки используется HTTP, возврат сообщений в реальном времени может быть гарантирован, но также будет Одна проблема заключается в том, что из-за нестабильной сети возникнет проблема сбоя запроса или тайм-аута, и стабильность интерфейса не может быть гарантирована.
  2. Поскольку сторонний платеж получает ложный ответ, он снова инициирует запрос обратного вызова в следующий период времени. Цель этого состоит в том, чтобы обеспечить вероятность успешного обратного вызова. Для стороннего платежа это не проблема. , но для платежной платформы мерчанта Например, это может быть довольно хитрый дизайн.Подумайте об этом.Предположим, что заказ злонамеренно подделал сумму во время оплаты, проверка обратного вызова не проходит, и возвращает false стороннему платежу. на этот раз сторонний платеж будет повторно отправлять обратный вызов.Независимо от того, сколько раз будет отправлен обратный вызов, проверка завершится ошибкой, что добавляет ненужное взаимодействие.Конечно, здесь также можно использовать идемпотентность.Ниже приведены сценарии применения платежного обратного вызова WeChat:

Исходя из двух вышеперечисленных моментов, считаю ненужным возвращать false стороннему платежу.Для надежности системы я использую очередь сообщений для асинхронной рассылки.Платежная платформа сразу возвращает true после получения запроса обратного вызова. В это время у вас может возникнуть вопрос: если в это время проверка не пройдена, но в это время возвращается true, возникнут ли проблемы? Прежде всего, в случае сбоя проверки заказ должен находиться в состоянии сбоя оплаты.Целью возврата true в это время является сокращение ненужного удаленного взаимодействия со сторонним платежом.

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

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

Совокупный платеж

Платежная платформа агрегирует множество сторонних платежей, поэтому на уровне запроса необходимо проделать большую работу по адаптации, чтобы удовлетворить потребности различных платежей.Может быть, вы думаете, просто добавьте несколько строк if else непосредственно в адаптацию Это нормально, и это также может удовлетворить потребности в нескольких платежах, но задумывались ли вы когда-нибудь о том, что вы будете делать, если добавите сторонний платеж в это время? Вы можете добавить только несколько других условий к исходному методу, что приведет к постоянному изменению кода слоя запроса по мере развития бизнеса, что сделает код чрезвычайно неэлегантным и трудным в обслуживании. В настоящее время мы должны использовать шаблон стратегии. , чтобы устранить эти коды if else. Когда мы добавляем сторонний платеж, нам нужно только создать новый класс стратегии. Как использовать шаблон стратегии, можно увидеть в шаблоне проектирования Dahua.

Поэтому я добавил слой платежной стратегии перед режимом Builder:

обработка запроса

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

Основываясь на этом требовании, я разработал уровень обработчика, прежде чем начинать запрашивать сторонние платежи. Все запросы должны обрабатываться на уровне обработчика. Основные методы обработчика следующие:

public K handle(T t) {
  K k;
  try {
    before(t);
    k = execute(t);
    after(k);
  } catch (Exception e) {
    exception(t, e);
  }
  return k;
}
protected abstract void before(T t);
protected abstract void after(K k);
protected abstract void exception(T t, Exception exception);

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

Ниже приведена архитектурная схема слоя Handler:

напиши в конце

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

公众号「后端进阶」,专注后端技术分享!