rwadurian/backend/services/referral-service/src/infrastructure/external/wallet-service.client.ts

103 lines
2.9 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
export interface ConfirmPlantingDeductionRequest {
userId: string;
accountSequence?: string;
orderId: string;
}
export interface ConfirmPlantingDeductionResult {
success: boolean;
error?: string;
}
@Injectable()
export class WalletServiceClient {
private readonly logger = new Logger(WalletServiceClient.name);
private readonly baseUrl: string;
constructor(private readonly configService: ConfigService) {
this.baseUrl =
this.configService.get<string>('WALLET_SERVICE_URL') ||
'http://localhost:3002';
}
/**
* 确认认种扣款
* 将冻结的资金正式扣除,资金进入"待分配"状态
*
* 由 referral-service 在发送 planting.order.paid 事件前调用
*/
async confirmPlantingDeduction(
request: ConfirmPlantingDeductionRequest,
): Promise<ConfirmPlantingDeductionResult> {
const maxRetries = 3;
let lastError: Error | null = null;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
this.logger.log(
`Confirming planting deduction for order ${request.orderId} (attempt ${attempt}/${maxRetries})`,
);
const response = await fetch(
`${this.baseUrl}/api/v1/wallets/confirm-planting-deduction`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
},
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
this.logger.error(
`Failed to confirm deduction for order ${request.orderId}:`,
errorData,
);
return {
success: false,
error:
errorData.message ||
`Confirm deduction failed with status ${response.status}`,
};
}
this.logger.log(
`Successfully confirmed deduction for order ${request.orderId}`,
);
return { success: true };
} catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
this.logger.warn(
`Failed to confirm planting deduction (attempt ${attempt}/${maxRetries}): ${lastError.message}`,
);
if (attempt < maxRetries) {
await this.sleep(1000 * attempt);
}
}
}
// 在开发环境模拟成功
if (this.configService.get('NODE_ENV') === 'development') {
this.logger.warn(
'Development mode: simulating successful deduction confirmation',
);
return { success: true };
}
return {
success: false,
error: `Failed to confirm deduction after ${maxRetries} attempts: ${lastError?.message}`,
};
}
private sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}