Деньги списали, а заказ не удался! Самое полное решение аномалии оплаченных заказов

Java

предисловие

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

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

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

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

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

Давайте сначала рассмотрим самые распространенные исключения в платежных системах:Потерянный заказ

Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: программа для общения, ежедневный толчок галантерейных товаров. Если вам интересен мой рекомендуемый контент, вы также можете подписаться на мой блог:studyidea.cn

Исключение заказа на сброс

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

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

Возьмем, к примеру, Ctrip, когда на нем инициируется оплата заказа, он будет проходить через три системы:

  1. Ctrip создает заказ и инициирует платежный запрос сторонней платежной компании.
  2. Сторонняя платежная компания создает заказ и инициирует платежный запрос в ICBC.
  3. ICBC завершает операцию списания и возвращает сторонней платежной компании.
  4. Сторонний платеж завершает обновление заказа и возвращается в Ctrip.
  5. Ctrip меняет статус заказа

Вышеупомянутый процесс так же прост, как на следующем рисунке:

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

Большинство описанных выше сценариев отказа от заказов связаны с③, ⑤Вызванный потерей информации о ссылке, мы называем этот отброшенный заказ каквнешняя капля.

Также есть редкий случай, когда③, ⑤ссылка возвращает информацию, но в④, ⑥Внутренняя система ссылки не может обновить статус заказа, что приводит к потере информации об успешном платеже.Этот тип отброшенного заказа обычно называют внутренней проблемой из-за внутренней проблемы.Внутреннее падение.

внешняя капля

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

увеличить время ожидания

Для этого случая первое и самое простое решение,Правильно увеличить тайм-аут.

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

Голос за кадром: Для подключения к внешним каналам обязательноУстановить тайм-аут сетевого подключения и тайм-аут чтения.

Получать асинхронные уведомления

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

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

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

支付系统异常处理-支付异步通知

В этом случае нам нужно обратить внимание на несколько моментов:

  1. Для информации об асинхронном запросе необходимо проверить подпись содержимого уведомления и проверить, соответствует ли возвращенная сумма заказа сумме заказа на стороне продавца, чтобы предотвратить утечку данных, которая может вызвать «ложные уведомления» и привести к потерям. средств.
  2. Асинхронные уведомления будут отправляться несколько раз, поэтому обработка асинхронных уведомлений должна быть идемпотентной.

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

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

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

Если запрос выполнен успешно или явно не выполнен (например, заказ не существует и т. д.), статус заказа может быть обновлен, а отдельная запись таблицы может быть удалена.

Если запрос еще неизвестен, то нужно дождаться результата следующего запроса.

支付系统异常处理-定时查询

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

примирение

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

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

Брат Сяохэй уже писал статью о сверке счетов, если вам интересно, вы можете прочитать ее еще раз:Разговор о дизайне системы выверки

Голос за кадром: в целях безопасности вы можете сначала инициировать запрос, а затем обновить запись заказа в соответствии с результатом запроса.

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

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

Исключение внутреннего заказа на выгрузку

Оплата внутрифирменных отношений заказа

Далее, давайте поговорим об исключении отбрасывания внутреннего ордера.Во-первых, давайте посмотрим, почему возникает исключение отбрасывания внутреннего ордера, которое на самом деле связано с архитектурой нашей системы.

Как показано на рисунке выше, внутренняя таблица сторонней платежной компании обычно представляет собой отношение 1-к-N между платежными поручениями и поручениями канала.

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

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

Зачем вам нужно проектировать эти отношения? вместо того, который использует отношения 1-к-1 ниже?

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

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

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

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

В этом случае система сторонней платежной компании проста, а вся сложность перекладывается на сторонних мерчантов.

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

В этом случае нам понадобится приведенная выше диаграмма отношения порядка 1:N.

Причина исключения внутренних отброшенных ордеров

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

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

На данный момент таблица заказов каналов выполнена успешно, поэтому описанный выше метод внешних заказов сброса не применяется к внутренним заказам сброса.

Внутреннее решение для исключения заказов на выгрузку

Первое решение, распределенные транзакции.

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

В этом случае нам действительно нужно использовать распределенные транзакции.

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

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

Второе решение, асинхронное обновление компенсации.

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

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

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

Другому системному приложению нужно только регулярно сканировать внутреннюю таблицу заказов на доставку, успешно оплатить заказ, а затем удалить внутреннюю запись заказа на доставку.

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

Суммировать

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

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

Ненормальность отбрасываемых заказов обычно может быть вызвана внешними и внутренними системами. Большинство отброшенных заказов вызваны внешними системами. Мы можем увеличить период ожидания, запросить отброшенные заказы и принять асинхронные уведомления, чтобы решить 99% проблем. Оставшийся 1% отброшенных заказов может быть урегулирован только через сверку на следующий день. . . .

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

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

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

  1. Зная, что @天shun говорит об исключениях (1)