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

PHP simulation of WeChat red envelope sending and receiving effect

The recent project needs to add a red envelope function based on chat, requirements: imitate WeChat (excluding messages), but only red envelopes can be sent using the balance. So I used WeChat red envelopes multiple times to understand various interactive interfaces and business requirements, such as displaying information, classification (personal, group general, group lucky draw), and number limit (100), amount limit (200), expiration time (24Hours) and the like, then started to develop, the basic ones mentioned below are all interfaces provided for the app, after all, I am a phper.

一、设计数据表如下

CREATE TABLE `red_packet` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
I. Design the data table as follows10CREATE TABLE `red_packet` (
) unsigned NOT NULL DEFAULT '0' COMMENT 'User id',1`for_id` int(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Distribution target (user or group id)',
) unsigned NOT NULL DEFAULT '0' COMMENT 'Payment status: 0 Unpaid,1`type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Type:2Individual,3Group general,
Group hand luck,255) NOT NULL DEFAULT '' COMMENT 'Introduction',
`number` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Number',
`total_money` decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT 'Total amount',
`single_money` decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT 'Single red packet amount (0 for group hand luck)',
`return_money` decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT 'Refund amount',
`is_cli_handle` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Whether the cli refund processing has been done: 0 No,1is
`expend_time` mediumint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Redemption consumption time',
`add_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Creation time',
`pay_time` int(10unsigned NOT NULL DEFAULT '0' COMMENT 'Payment time',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `pay_status` (`pay_status`),
KEY `pay_time` (`pay_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Red packet distribution table';
CREATE TABLE `red_packet_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`rp_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Red packet ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Redemption person ID',
`money` decimal(10,2) unsigned NOT NULL DEFAULT '0.0' COMMENT 'Redemption amount',
`is_good` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Whether the luckiest: 0 no,1is
`add_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Addition time',
`update_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Redemption time',
PRIMARY KEY (`id`),
KEY `rp_id` (`rp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Red packet redemption log table';

2. Send red packets

Since the red packet is sent to the chat interface immediately after the payment is successful, when inserting the red packet information into the red_packet table (payment status: unpaid) in the left figure 'Money into red packet', and allocating the amount, calculating the luck and shuffling, insert it into the red_packet_log table (the recipient and the time of redemption are empty). After the successful confirmation of payment in the right figure, update the payment status of the red_packet table, and then send out the red packet.

3. Red packet redemption (here only analyzes group red packets)

All kinds of prerequisite checks for red packet redemption should be thought of by yourself. Here is a concurrent problem of grabbing group red packets (a few red packets for several people in the group), and introducing MQ to solve it. When sending red packets, first write the number of red packets sequentially into the MQ, for example, send3red packets, and write them in turn.1,2,3. When snatching red packets, values are taken from the MQ, if a number is obtained, it means that you are the nth one to snatch the red packet, corresponding to the nth red packet in the red_packet_log table. The next step is to update the recipient and collection time in the red_packet_log table, as well as the balance increase and record of business processing, and then return the collection result; if a number cannot be obtained, of course, it means that you did not snatch the red packet, and the interface 'You are too slow' will be displayed directly. In the early stage, it was considered to write the primary key of the red_packet_log table to the MQ, which could save the sorting to get the nth log record, but this would make the update of the 'collection consumption time' field more麻烦; using the MQ to store numbers, you can directly compare whether it is the last red packet (the number obtained is equal to the number of red packets), and then update the consumption time.

The red packet collection result page (i.e., the luck page) has many types: the results for individual and group are different, the sender and the recipient see different things, the prompt is different after the individual and group red packets expire, etc. Here are not listed one by one, basically it is just to check the database according to the interface.

4. Requirement change, add third-party payment

When it comes to third-party payment, it is necessary to mention synchronous and asynchronous callbacks, as well as the callback time difference. When the app side succeeds in synchronous callback, it will send out the red packet (the payment synchronous callback of the app side is a direct call to callback), if the asynchronous callback is slow by one or two seconds at this time, then the user will grab this red packet with payment status 0. If it is said to let the app side call the long connection interface to check whether the asynchronous callback has been successful, and then send out the red packet, then the user experience will be poor.

# Introduce intermediate state
ALTER TABLE `red_packet`
MODIFY COLUMN `pay_status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Payment status: 0 unpaid,1Paid,2Awaiting payment' AFTER `for_id`,
ADD COLUMN `pay_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Payment method: 0 unknown,1Alipay,2WeChat,3UnionPay' AFTER `pay_status`,
ADD COLUMN `trade_no` varchar(30) NOT NULL DEFAULT '' COMMENT 'Third-party payment transaction number' AFTER `pay_type`;
ALTER TABLE `red_packet_log`
ADD COLUMN `is_into_account` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Whether credited: 0 No,'1is 'AFTER `is_good`;

When the user wins the red packet, the value of is_into_account is determined according to pay_status;

When the synchronous callback is to the app end, call the interface to change the payment status pay_status to2;

When the asynchronous callback is to the server, then change the payment status pay_status to1, and check is_into_account=1 records of red_packet_log.

However, the above three steps must perform FOR UPDATE operations on the red_packet query, otherwise there will be execution time and sequence issues, causing some red_packet_log records to not be credited is_into_account=0; in addition, the lock mechanism will make the user's red packet抢 very slow, because it has to wait for the lock to be released.


Improvement as follows: (No FOR UPDATE throughout the process)

When the user wins the red packet, the value of is_into_account is determined according to pay_status;

When the synchronous callback is to the app end, call the interface to change the payment status pay_status to2;

When the asynchronous callback is to the server, then change the payment status pay_status to1, and put the red packet id (primary key of red_packet) into the MQ;

Background automatic script, after obtaining the red packet id from the MQ, process the records where red_packet is_into_account=0, and then delay5Seconds later, write the red packet id back into the MQ for secondary processing to ensure that all data has been credited.

V. Refund of Expired Red Envelopes

There is only one automatic script here, which determines whether it exceeds the pay_time in the red_packet table.24The money not claimed within the hour will be returned to the user's balance.

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You May Also Like