From 55bed5087cb86b5e2af5ff2239fa124bd868900e Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 27 Apr 2026 20:55:37 +0800 Subject: [PATCH] fix: resolve public dulupay callback origin --- app/api/payment/dulupay/create/route.ts | 32 ++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/app/api/payment/dulupay/create/route.ts b/app/api/payment/dulupay/create/route.ts index 5dba9236b..8d6555506 100644 --- a/app/api/payment/dulupay/create/route.ts +++ b/app/api/payment/dulupay/create/route.ts @@ -29,6 +29,36 @@ function buildOutTradeNo() { return `DP${Date.now()}${random}`.slice(0, 64); } +function normalizeBaseUrl(value?: string | null) { + const raw = String(value || "").trim(); + if (!raw) return ""; + + try { + const parsed = new URL(raw); + return `${parsed.protocol}//${parsed.host}`; + } catch { + return ""; + } +} + +function resolvePublicOrigin(request: NextRequest) { + const fromEnv = + normalizeBaseUrl(process.env.AUTH_URL) || + normalizeBaseUrl(process.env.NEXTAUTH_URL); + if (fromEnv) return fromEnv; + + const forwardedHost = request.headers.get("x-forwarded-host"); + const host = request.headers.get("host"); + const resolvedHost = String(forwardedHost || host || "").trim(); + if (!resolvedHost) { + return new URL(request.url).origin; + } + + const forwardedProto = request.headers.get("x-forwarded-proto"); + const protocol = String(forwardedProto || "").trim() || "https"; + return `${protocol}://${resolvedHost}`; +} + export async function POST(request: NextRequest) { try { const session = await auth(); @@ -99,7 +129,7 @@ export async function POST(request: NextRequest) { const amountCents = Math.round(amount * 100); const payType = body.payType || dulupayConfig.defaultType || "alipay"; - const defaultOrigin = new URL(request.url).origin; + const defaultOrigin = resolvePublicOrigin(request); const notifyUrl = dulupayConfig.notifyUrl || `${defaultOrigin}/api/payment/dulupay/notify`; const returnUrl = dulupayConfig.returnUrl || `${defaultOrigin}/`;