feat: 订单来源追踪,保存 src_host / src_url 到订单记录

iframe 嵌入充值页面时 URL 自动附带来源参数,写入数据库用于追踪分析。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erio
2026-03-02 20:40:16 +08:00
parent c083880cbc
commit d952942627
7 changed files with 24 additions and 1 deletions

View File

@@ -31,6 +31,8 @@ interface AdminOrderDetail extends AdminOrder {
failedAt: string | null;
updatedAt: string;
clientIp: string | null;
srcHost: string | null;
srcUrl: string | null;
paymentSuccess?: boolean;
rechargeSuccess?: boolean;
rechargeStatus?: string;

View File

@@ -7,6 +7,8 @@ const createOrderSchema = z.object({
user_id: z.number().int().positive(),
amount: z.number().positive(),
payment_type: z.enum(['alipay', 'wxpay', 'stripe']),
src_host: z.string().optional(),
src_url: z.string().optional(),
});
export async function POST(request: NextRequest) {
@@ -19,7 +21,7 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: '参数错误', details: parsed.error.flatten().fieldErrors }, { status: 400 });
}
const { user_id, amount, payment_type } = parsed.data;
const { user_id, amount, payment_type, src_host, src_url } = parsed.data;
// Validate amount range
if (amount < env.MIN_RECHARGE_AMOUNT || amount > env.MAX_RECHARGE_AMOUNT) {
@@ -42,6 +44,8 @@ export async function POST(request: NextRequest) {
amount,
paymentType: payment_type,
clientIp,
srcHost: src_host,
srcUrl: src_url,
});
// 不向客户端暴露 userName / userBalance 等隐私字段

View File

@@ -38,6 +38,8 @@ function PayContent() {
const theme = searchParams.get('theme') === 'dark' ? 'dark' : 'light';
const uiMode = searchParams.get('ui_mode') || 'standalone';
const tab = searchParams.get('tab');
const srcHost = searchParams.get('src_host') || undefined;
const srcUrl = searchParams.get('src_url') || undefined;
const isDark = theme === 'dark';
const [isIframeContext, setIsIframeContext] = useState(true);
@@ -230,6 +232,8 @@ function PayContent() {
user_id: effectiveUserId,
amount,
payment_type: paymentType,
src_host: srcHost,
src_url: srcUrl,
}),
});