English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP-имитация эффекта отправки и получения红包 в WeChat

В последнее время проект требует добавления функции红包 на основе чата, требования: имитация WeChat (без留言), но только использование баланса для отправки红包. Поэтому несколько раз использовал WeChat红包, чтобы понять различные интерфейсы взаимодействия и бизнес-требования, такие как показ информации, классификация (личный, обычная группа, групповая лотерея), ограничение количества (100), ограничение суммы (200), время истечения (24 часа) и т.д., затем начал разработку, все упомянутые ниже это интерфейсы API для приложения, так как я phper.

1. Приведем设计方案 таблицы данных

CREATE TABLE `red_packet` (
int(10) unsigned NOT NULL AUTO_INCREMENT,
user_id int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'ID пользователя'
for_id int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Объект выплаты (ID пользователя или группы)'
pay_status tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Статус оплаты: 0 - не оплачен, 1 - оплачен'
type tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Тип: 1 - личный, 2 - обычная группа, 3 - групповая лотерея'
varchar(255) NOT NULL DEFAULT '' COMMENT '简介',
tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '个数',
decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT '总金额',
decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT '单个红包金额(群拼手气时为0)',
decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT '退还金额',
tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否经过cli退款处理:0否,1是',
mediumint(1) unsigned NOT NULL DEFAULT '0' COMMENT '领取消耗时间',
int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
int(10) unsigned NOT NULL DEFAULT '0' COMMENT '支付时间',

KEY `user_id` (`user_id`),
KEY `pay_status` (`pay_status`),
KEY `pay_time` (`pay_time`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='红包发放表';
CREATE TABLE `red_packet_log` (
int(10) unsigned NOT NULL AUTO_INCREMENT,
int(10) unsigned NOT NULL DEFAULT '0' COMMENT '红包id',








Поскольку после успешной оплаты红包 сразу отправляется в интерфейс чата, поэтому при

Все предварительные проверки для получения红包 должны быть сделаны самостоятельно, здесь рассмотрим проблему параллельного получения红包 в группе (несколько человек в группе получают несколько红包), для решения которой используется MQ. При отправке红包, сначала пишем количество红包依次写入MQ, например, если отправляется 3红包, то依次 пишем 1, 2, 3. При получении红包, берем значения из MQ, если можно получить цифру, это означает, что вы получили红包 в порядке, соответствующий номеру红包 в таблице red_packet_log, затем обновляем таблицу red_packet_log с получателем и временем получения, а также с добавлением денег и записью операций, затем возвращаем результат получения; если не можно получить цифру, это означает, что вы не получили红包, и выводится сообщение

Страница результатов получения мыльных денег (т.е. страница просмотра приза) имеет множество видов: результаты для одного и для группы различаются, те, кто раздает мыльные деньги и те, кто их получает, видят по-разному, после истечения срока действия红包 отображается различное уведомление и т.д., не будем перечислять все, это в основном получение данных из базы данных по интерфейсу.

Четвертый раздел, изменение требований, добавление第三方 платежей

Говоря о第三方支付, необходимо упомянуть синхронные и асинхронные вызовы обратного вызова, а также разницу во времени между ними. При успешном синхронном вызове обратного вызова в приложении,红包 уже отправлен (синхронный вызов обратного вызова в приложении напрямую вызывается callback), если в этот момент асинхронный вызов обратного вызова замедлился на одну-две секунды, то пользователь может получить этот红包 с состоянием оплаты 0. Если говорить о том, чтобы приложение вызывало интерфейс длительного подключения, чтобы проверить, был ли успешен асинхронный вызов обратного вызова, и только после этого отправлять红包, то это приведет к较差ому пользовательскому опыту.

# Введение промежуточного состояния
ALTER TABLE `red_packet`
ИЗМЕНЕНИЕ СЛУЖЕБНОЙ КОЛОНКИ `pay_status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Статус оплаты: 0 не оплачен, 1 оплачен, 2 ожидается поступление' ПОСЛЕ `for_id`,
ДОБАВЛЕНИЕ СЛУЖЕБНОЙ КОЛОНКИ `pay_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Способ оплаты: 0 неизвестно, 1 Alipay, 2 WeChat, 3 UnionPay' ПОСЛЕ `pay_status`,
ДОБАВЛЕНИЕ СЛУЖЕБНОЙ КОЛОНКИ `trade_no` varchar(30) NOT NULL DEFAULT '' COMMENT 'Номер транзакции третьей стороны' ПОСЛЕ `pay_type`;
ALTER TABLE `red_packet_log`
ДОБАВЛЕНИЕ СЛУЖЕБНОГО КОЛОНКИ `is_into_account` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Доход на счет: 0 нет, 1 да' ПОСЛЕ `is_good`;

Когда пользователь выигрывает红包, значение is_into_account определяется по состоянию pay_status;

При синхронном вызове обратного вызова на приложение, вызывается интерфейс для изменения состояния оплаты pay_status на 2;

При асинхронном вызове обратного вызова на сервер, состояние оплаты pay_status изменяется на 1, и обрабатываются записи red_packet_log с is_into_account=1.

Но в этих трех шагах необходимо выполнять операцию FOR UPDATE для запроса red_packet, иначе могут возникнуть проблемы с временем выполнения и порядком, что приведет к тому, что некоторые записи red_packet_log останутся не оплаченными с is_into_account=0; кроме того, механизмы блокировки могут замедлить процесс получения红包 пользователями, так как необходимо подождать, пока будет освобожден блок.


Улучшения: (всегда без FOR UPDATE)

Когда пользователь выигрывает红包, значение is_into_account определяется по состоянию pay_status;

При синхронном вызове обратного вызова на приложение, вызывается интерфейс для изменения состояния оплаты pay_status на 2;

При асинхронном вызове обратного вызова на сервер, состояние оплаты pay_status изменяется на 1, и идентификатор红包 (первичный ключ red_packet) помещается в MQ;

Автоматический скрипт на заднем плане, который после получения идентификатора红包 из MQ обрабатывает записи с is_into_account=0, а затем через 5 секунд заново写入红包id в MQ для повторной обработки, чтобы обеспечить полное поступление данных.

Пять: Возврат过期红包

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

Заявление: Контент статьи взяты из интернета, авторские права принадлежат их авторам, контент предоставлен пользователями интернета, сайт не обладает правами собственности, материал не был обработан редакторами, и сайт не несет ответственности за связанные с этим法律责任. Если вы обнаружите спорный контент, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма замените # на @) для отчета,并提供相关证据. При обнаружении факта нарушения авторских прав, сайт немедленно удалит спорный контент.

Рекомендуется для просмотра