Compare commits

...

4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
acdf00150b Address code review feedback for docker-entrypoint.sh
- Add error handling with set -e and explicit error checks
- Improve security: change permissions from 755 to 750
- Add quotes around password variable to handle special chars
- Specify socket path explicitly in mysqladmin ping
- Add clear error messages for failures

Co-authored-by: nomeguy <85475922+nomeguy@users.noreply.github.com>
2026-01-30 13:46:42 +00:00
copilot-swe-agent[bot]
94d466f37f Fix MariaDB initialization for ARM platform
- Initialize MariaDB data directory before starting service
- Add proper directory creation and permissions in Dockerfile
- Add wait loop to ensure MariaDB is ready before proceeding

Co-authored-by: nomeguy <85475922+nomeguy@users.noreply.github.com>
2026-01-30 13:44:46 +00:00
copilot-swe-agent[bot]
8b31253b09 Initial plan 2026-01-30 13:42:39 +00:00
Copilot
66a739774f feat: prevent duplicate webhook events from redundant payment notifications (#4936) 2026-01-30 15:14:34 +08:00
4 changed files with 62 additions and 9 deletions

View File

@@ -56,7 +56,10 @@ RUN apt update \
&& apt install -y \
mariadb-server \
mariadb-client \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/mysql /run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /run/mysqld \
&& chmod 755 /run/mysqld
FROM db AS ALLINONE

View File

@@ -1,8 +1,41 @@
#!/bin/bash
set -e # Exit on any error
if [ "${MYSQL_ROOT_PASSWORD}" = "" ] ;then MYSQL_ROOT_PASSWORD=123456 ;fi
service mariadb start
# Initialize MariaDB data directory if it doesn't exist
if [ ! -d "/var/lib/mysql/mysql" ]; then
echo "Initializing MariaDB data directory..."
if ! mysql_install_db --user=mysql --datadir=/var/lib/mysql; then
echo "ERROR: Failed to initialize MariaDB data directory"
exit 1
fi
fi
mysqladmin -u root password ${MYSQL_ROOT_PASSWORD}
# Ensure proper permissions
chown -R mysql:mysql /var/lib/mysql
chmod -R 750 /var/lib/mysql
# Start MariaDB service
if ! service mariadb start; then
echo "ERROR: Failed to start MariaDB service"
exit 1
fi
# Wait for MariaDB to be ready
echo "Waiting for MariaDB to start..."
for i in {1..30}; do
if mysqladmin ping --socket=/run/mysqld/mysqld.sock > /dev/null 2>&1; then
echo "MariaDB is ready!"
break
fi
if [ $i -eq 30 ]; then
echo "ERROR: MariaDB failed to start within 30 seconds"
exit 1
fi
sleep 1
done
mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}"
exec /server --createDatabase=true

View File

@@ -261,18 +261,29 @@ func NotifyPayment(body []byte, owner string, paymentName string, lang string) (
}
// Check if payment is already in a terminal state to prevent duplicate processing
if payment.State == pp.PaymentStatePaid || payment.State == pp.PaymentStateError ||
payment.State == pp.PaymentStateCanceled || payment.State == pp.PaymentStateTimeout {
if pp.IsTerminalState(payment.State) {
return payment, nil
}
// Determine the new payment state
var newState pp.PaymentState
var newMessage string
if err != nil {
payment.State = pp.PaymentStateError
payment.Message = err.Error()
newState = pp.PaymentStateError
newMessage = err.Error()
} else {
payment.State = notifyResult.PaymentStatus
payment.Message = notifyResult.NotifyMessage
newState = notifyResult.PaymentStatus
newMessage = notifyResult.NotifyMessage
}
// Check if the payment state would actually change
// This prevents duplicate webhook events when providers send redundant notifications
if payment.State == newState {
return payment, nil
}
payment.State = newState
payment.Message = newMessage
_, err = UpdatePayment(payment.GetId(), payment)
if err != nil {
return nil, err

View File

@@ -24,6 +24,12 @@ const (
PaymentStateError PaymentState = "Error"
)
// IsTerminalState checks if a payment state is terminal (cannot transition to other states)
func IsTerminalState(state PaymentState) bool {
return state == PaymentStatePaid || state == PaymentStateError ||
state == PaymentStateCanceled || state == PaymentStateTimeout
}
const (
PaymentEnvWechatBrowser = "WechatBrowser"
)