mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-11-11 09:43:53 +01:00
fix credits package bug and improve stale payment logic
This commit is contained in:
@@ -190,11 +190,28 @@ class PaymentHandlers {
|
||||
return;
|
||||
}
|
||||
|
||||
const paymentRequest = await this.gameModeManager.createPaymentRequest(socket.id, paymentType, {
|
||||
// Resolve authoritative userId from session manager (stable across socket reconnects)
|
||||
let sessionUserId = null;
|
||||
if (this.sessionManager?.sessions?.has(socket.id)) {
|
||||
sessionUserId = this.sessionManager.sessions.get(socket.id).id;
|
||||
}
|
||||
|
||||
const paymentRequest = await this.gameModeManager.createPaymentRequest(socket.id, paymentType, {
|
||||
reuseExisting: true,
|
||||
packageId: options.packageId
|
||||
packageId: options.packageId,
|
||||
userId: sessionUserId
|
||||
});
|
||||
const reused = !!paymentRequest.reused;
|
||||
|
||||
// Stop monitoring any expired addresses from previous payment requests
|
||||
if (paymentRequest.expiredAddresses?.length > 0) {
|
||||
for (const addr of paymentRequest.expiredAddresses) {
|
||||
this.walletService.stopPaymentMonitoring(addr);
|
||||
this.walletService.addressToUser.delete(addr);
|
||||
this.walletService.addressToSocket.delete(addr);
|
||||
}
|
||||
}
|
||||
|
||||
const formattedAmount = paymentRequest.amountFormatted ?? this.gameModeManager.formatAtomicHuman(amount, 3);
|
||||
let qrDataUrl = null;
|
||||
try {
|
||||
|
||||
@@ -753,10 +753,9 @@ class SocketHandlers {
|
||||
this.paymentHandlers.stopMonitoringForSocket(socketId);
|
||||
}
|
||||
|
||||
// Clean up wallet Maps to prevent memory leaks (addressToUser, addressToSocket)
|
||||
if (this.walletService && typeof this.walletService.cleanupUserPayments === 'function') {
|
||||
this.walletService.cleanupUserPayments(socketId);
|
||||
}
|
||||
// NOTE: Do NOT call walletService.cleanupUserPayments() here.
|
||||
// addressToUser entries must persist so checkPaymentStatus() can query the wallet
|
||||
// RPC after session resumption. They get cleaned up when payments are confirmed or expired.
|
||||
|
||||
// Clean up movement timestamps
|
||||
this.playerMoveTimestamps.delete(socketId);
|
||||
@@ -815,7 +814,7 @@ class SocketHandlers {
|
||||
try {
|
||||
// Query for pending (unpaid) payment requests for this user
|
||||
const pendingResult = await this.gameModeManager.db.query(`
|
||||
SELECT id, subaddress, expected_amount, payment_type, description, expires_at
|
||||
SELECT id, subaddress, expected_amount, payment_type, description, expires_at, address_index
|
||||
FROM payments
|
||||
WHERE user_id = $1
|
||||
AND status = 'pending'
|
||||
@@ -880,10 +879,25 @@ class SocketHandlers {
|
||||
package: null
|
||||
};
|
||||
|
||||
// Re-register address in wallet service so checkPaymentStatus() can query the wallet RPC.
|
||||
// This is essential after server restart or if the entry was lost during disconnect.
|
||||
if (this.walletService && payment.subaddress) {
|
||||
this.walletService.addressToUser.set(payment.subaddress, {
|
||||
userId: String(dbUserId),
|
||||
socketId: socket.id,
|
||||
amount: Number(payment.expected_amount),
|
||||
addressIndex: payment.address_index ?? 0,
|
||||
accountIndex: 0,
|
||||
detected: false,
|
||||
confirmed: false,
|
||||
status: 'pending'
|
||||
});
|
||||
}
|
||||
|
||||
// Restart payment monitoring
|
||||
// First stop any existing monitoring (unlikely but safe)
|
||||
this.paymentHandlers.stopMonitoringForSocket(socket.id);
|
||||
|
||||
|
||||
// Restart monitoring via paymentHandlers internal method
|
||||
if (typeof this.paymentHandlers._monitorAddress === 'function') {
|
||||
this.paymentHandlers._monitorAddress(
|
||||
|
||||
Reference in New Issue
Block a user