This commit is contained in:
eric
2026-03-13 10:59:08 -05:00
parent e673bc9b62
commit 0885e00b25
5 changed files with 59 additions and 6 deletions

35
.env.example Normal file
View File

@@ -0,0 +1,35 @@
# ========== 与 payjsapi/digital/cnomadcna 同源 ==========
# 复制为 .env.localPB/Memos 与 payjsapi 保持一致
# ========== PocketBase ==========
NEXT_PUBLIC_POCKETBASE_URL=https://pocketbase.hackrobot.cn
POCKETBASE_EMAIL=xiaoshuang.eric@gmail.com
POCKETBASE_PASSWORD=Xiao4669805@
# ========== 支付payjsapi==========
# 本地开发127.0.0.1 表示本机
# 生产同机部署:设 PAYMENT_API_INTERNAL_URL 避免服务器访问自身公网 IP 失败hairpin NAT
PAYMENT_API_URL=http://127.0.0.1:8007
NEXT_PUBLIC_API_URL=http://127.0.0.1:8007
# 生产同机部署时取消注释Next.js 与 payjsapi 同服务器)
# PAYMENT_API_INTERNAL_URL=http://127.0.0.1:8007
PAYMENT_PROVIDER=zpay
PAYMENT_DEFAULT_AMOUNT=100
NEXT_PUBLIC_SITE_ID=vip
ZPAY_SUBMIT_URL=https://zpayz.cn/submit.php
# ========== Memospay/confirm 创建账号,与 payjsapi MEMOS_TOKEN 同值)==========
MEMOS_API_URL=https://qun.hackrobot.cn
MEMOS_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiaGFja3JvYm90IiwiaXNzIjoibWVtb3MiLCJzdWIiOiIxIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImlhdCI6MTc1NzQwNTE0OX0.Idn7kBlxE-CoSOXwWuZ1tHGIRKHAIeDyXSafGS5OHsg
# ========== MinIO ==========
MINIO_ENDPOINT=minioweb.hackrobot.cn
MINIO_PORT=9035
MINIO_USE_SSL=false
MINIO_BUCKET=hackrobot
MINIO_PUBLIC_URL=https://minioweb.hackrobot.cn/hackrobot
# 如需上传需配置(服务端)
# MINIO_ACCESS_KEY=
# MINIO_SECRET_KEY=
# MINIO_REGION=china

13
.env.local Normal file
View File

@@ -0,0 +1,13 @@
# 本地调试 - 支付测试 1 元、zpay 渠道
NEXT_PUBLIC_POCKETBASE_URL=https://pocketbase.hackrobot.cn
PAYMENT_API_URL=http://127.0.0.1:8007
PAYMENT_PROVIDER=zpay
PAYMENT_DEFAULT_AMOUNT=100
NEXT_PUBLIC_SITE_ID=vip
NEXT_PUBLIC_API_URL=http://127.0.0.1:8007
# 与 payjsapi 同源pay/confirm 写入 payments/site_vip、创建 Memos
POCKETBASE_EMAIL=xiaoshuang.eric@gmail.com
POCKETBASE_PASSWORD=Xiao4669805@
MEMOS_API_URL=https://qun.hackrobot.cn
MEMOS_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiaGFja3JvYm90IiwiaXNzIjoibWVtb3MiLCJzdWIiOiIxIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImlhdCI6MTc1NzQwNTE0OX0.Idn7kBlxE-CoSOXwWuZ1tHGIRKHAIeDyXSafGS5OHsg

2
.gitignore vendored
View File

@@ -31,7 +31,7 @@ yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# .env*
# vercel
.vercel

View File

@@ -130,12 +130,10 @@ export async function POST(request: NextRequest) {
const payConfig = getPaymentConfig();
const hostHeader = request.headers.get("host") || request.headers.get("x-forwarded-host");
// 优先用请求 Host等同 window.location.host推断同机 payjsapi访问 192.168.41.222:3002 即用 192.168.41.222:8007
const apiUrl = (
(hostHeader ? getApiUrlFromRequest(hostHeader) : null) ||
payConfig.apiUrl
)
.replace(/\/$/, "");
).replace(/\/$/, "");
console.log("[pay] 立即加入 apiUrl=%s host=%s", apiUrl, hostHeader);
let user_id = String(body?.user_id || "").trim();
if (user_id.startsWith("{") && user_id.includes("data")) {

View File

@@ -42,17 +42,24 @@ export function getPocketBaseConfig(): PocketBaseConfig {
const PAYJSAPI_PORT = process.env.PAYJSAPI_PORT || "8007";
/**
* 根据请求 Host 推断 payjsapi 地址(同主机:8007
* 根据请求 Host 推断 payjsapi 地址。同机部署时优先用 PAYMENT_API_INTERNAL_URL。
* 访问 192.168.41.222:3000 时自动用 192.168.41.222:8007
*/
export function getApiUrlFromRequest(hostHeader: string | null): string {
const internal = process.env.PAYMENT_API_INTERNAL_URL?.trim();
if (internal) return internal.replace(/\/$/, "");
if (!hostHeader) return isDev ? `http://127.0.0.1:${PAYJSAPI_PORT}` : "https://api.hackrobot.cn";
const hostname = hostHeader.split(":")[0];
return isDev ? `http://${hostname}:${PAYJSAPI_PORT}` : "https://api.hackrobot.cn";
}
/** 生产环境若 PAYMENT_API_URL 指向 localhost则忽略并使用 api 域名 */
/**
* 支付 API 地址。同机部署时优先用 PAYMENT_API_INTERNAL_URL 避免 hairpin NAT 问题。
* 生产环境若 PAYMENT_API_URL 指向 localhost 且未设 INTERNAL则用 api 域名。
*/
function resolvePaymentApiUrl(): string {
const internal = process.env.PAYMENT_API_INTERNAL_URL?.trim();
if (internal) return internal.replace(/\/$/, "");
const url =
process.env.PAYMENT_API_URL ||
process.env.NEXT_PUBLIC_API_URL ||