feat: beta promo, zero fee, scout bot, and LLM SEO
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s
This commit is contained in:
@@ -3,9 +3,9 @@ import { ScoutDraftRequestSchema, ScoutDraftResponseSchema, TaskStatus } from "@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import Stripe from "stripe";
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
|
||||
const stripe = process.env.STRIPE_SECRET_KEY ? new Stripe(process.env.STRIPE_SECRET_KEY, {
|
||||
apiVersion: "2026-05-27.dahlia",
|
||||
});
|
||||
}) : null;
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const authHeader = request.headers.get("Authorization");
|
||||
@@ -51,7 +51,28 @@ export async function POST(request: NextRequest) {
|
||||
});
|
||||
|
||||
// Create Stripe Checkout Session
|
||||
// We do a manual capture session so the funds are only captured when Judge passes
|
||||
// 試營運期間:如果賞金小於等於 20 美元 ($20.00 = 2000 cents),則由官方贊助(免刷卡直接 OPEN)
|
||||
if (parsed.reward_amount <= 2000) {
|
||||
await prisma.task.update({
|
||||
where: { id: task.id },
|
||||
data: {
|
||||
status: TaskStatus.OPEN,
|
||||
stripe_checkout_session_id: "promo_free_bounty",
|
||||
stripe_payment_intent_id: "promo_free_bounty_intent" // Skip auth hold
|
||||
}
|
||||
});
|
||||
|
||||
const responseData = {
|
||||
task_id: task.id,
|
||||
checkout_url: `${process.env.NEXT_PUBLIC_SITE_URL || 'https://agent.wooo.work'}/tasks/${task.id}`,
|
||||
status: TaskStatus.OPEN,
|
||||
};
|
||||
|
||||
ScoutDraftResponseSchema.parse(responseData);
|
||||
return NextResponse.json(responseData);
|
||||
}
|
||||
|
||||
if (!stripe) throw new Error("Stripe is not initialized");
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
payment_method_types: ["card"],
|
||||
mode: "payment",
|
||||
@@ -76,8 +97,8 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
},
|
||||
// You should set these to actual frontend URLs
|
||||
success_url: `${process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'}/tasks/${task.id}?success=true`,
|
||||
cancel_url: `${process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'}/tasks/create`,
|
||||
success_url: `${process.env.NEXT_PUBLIC_SITE_URL || 'https://agent.wooo.work'}/tasks/${task.id}?success=true`,
|
||||
cancel_url: `${process.env.NEXT_PUBLIC_SITE_URL || 'https://agent.wooo.work'}/tasks/create`,
|
||||
});
|
||||
|
||||
// Save session ID so webhook can find it
|
||||
|
||||
@@ -3,9 +3,9 @@ import { prisma } from "@/lib/prisma";
|
||||
import Stripe from "stripe";
|
||||
import { TaskStatus } from "@agent-bounty/contracts";
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
|
||||
const stripe = process.env.STRIPE_SECRET_KEY ? new Stripe(process.env.STRIPE_SECRET_KEY, {
|
||||
apiVersion: "2026-05-27.dahlia",
|
||||
});
|
||||
}) : null;
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const payload = await request.text();
|
||||
@@ -18,6 +18,9 @@ export async function POST(request: NextRequest) {
|
||||
let event: Stripe.Event;
|
||||
|
||||
try {
|
||||
if (!stripe) {
|
||||
throw new Error("Stripe SDK is not initialized");
|
||||
}
|
||||
event = stripe.webhooks.constructEvent(
|
||||
payload,
|
||||
signature,
|
||||
|
||||
@@ -10,7 +10,7 @@ export default async function Home() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-950 text-gray-100 p-8 font-sans">
|
||||
<div className="max-w-5xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-10">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-4xl font-extrabold bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-500">
|
||||
VibeWork AI 任務協作網路
|
||||
</h1>
|
||||
@@ -19,6 +19,14 @@ export default async function Home() {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Beta Promo Banner */}
|
||||
<div className="mb-10 bg-gradient-to-r from-purple-600/20 to-blue-600/20 border border-purple-500/30 rounded-2xl p-6 text-center">
|
||||
<h2 className="text-2xl font-bold text-white mb-2">🎉 VibeWork Beta 試營運啟動</h2>
|
||||
<p className="text-purple-200">
|
||||
需求者首單免費體驗(免綁卡)!AI Agent 接案 <strong>0% 手續費</strong>,100% 收益歸開發者!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{tasks.length === 0 ? (
|
||||
<div className="col-span-full text-center py-20 text-gray-500">
|
||||
|
||||
@@ -74,6 +74,7 @@ export default async function TaskDetails({ params }: { params: Promise<{ id: st
|
||||
<h3 className="text-lg font-bold mb-4 text-gray-300">驗收標準 (測試文件)</h3>
|
||||
<pre className="text-xs text-gray-400 overflow-x-auto p-4 bg-black rounded-lg border border-gray-800">
|
||||
{typeof task.acceptance_criteria === "object" && task.acceptance_criteria !== null
|
||||
? JSON.stringify(task.acceptance_criteria, null, 2)
|
||||
: "N/A"}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user