feat: 미결제 서비스 전체 토스페이먼츠 결제 연결

products.ts — 7개 상품 신규 등록:
- prompt_team (249,000원): 팀/기업 프롬프트 패키지
- automation_basic (50,000원): 단순 업무 자동화
- automation_advanced (150,000원): 자동화 심화
- website_starter (200,000원): 홈페이지 스타터
- website_business (1,000,000원): 홈페이지 비즈니스
- website_premium (2,000,000원): 홈페이지 프리미엄

PaymentButton — style prop 추가 (inline-style 페이지 대응)

프롬프트 서비스: 팀/기업 패키지 PaymentButton 연결
업무 자동화: 단순·심화 플랜 PaymentButton 연결 (대형은 협의가격→ContactModal 유지)
웹사이트 제작: 전 플랜 Link 버튼 → PaymentButton 전환

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-22 18:35:18 +09:00
parent 2a52d98c81
commit 2167719c6e
5 changed files with 86 additions and 24 deletions

View File

@@ -8,11 +8,12 @@ import { PRODUCTS } from '@/lib/products';
interface PaymentButtonProps {
productId: string;
className?: string;
style?: React.CSSProperties;
children: React.ReactNode;
returnUrl?: string;
}
export default function PaymentButton({ productId, className, children, returnUrl }: PaymentButtonProps) {
export default function PaymentButton({ productId, className, style, children, returnUrl }: PaymentButtonProps) {
const [loading, setLoading] = useState(false);
const router = useRouter();
const supabase = createClient();
@@ -86,11 +87,12 @@ export default function PaymentButton({ productId, className, children, returnUr
const isTestMode = process.env.NEXT_PUBLIC_TOSS_CLIENT_KEY?.startsWith('test_');
return (
<div style={{ display: 'inline-block', position: 'relative' }}>
<div style={{ display: style ? 'block' : 'inline-block', position: 'relative' }}>
<button
onClick={handlePayment}
disabled={loading}
className={className}
style={style}
>
{loading ? '결제 처리 중...' : children}
</button>

View File

@@ -3,6 +3,7 @@
import { useState } from 'react';
import Link from 'next/link';
import ContactModal from '../../components/ContactModal';
import PaymentButton from '../../components/PaymentButton';
const tools = [
{
@@ -76,9 +77,9 @@ const automationTypes = [
];
const plans = [
{ name: '단순 자동화', price: '5만원~', desc: '단일 작업 · 1~3일 소요', examples: '엑셀 매크로, 단순 스크래핑, 이메일 자동화', highlight: false },
{ name: '자동화 심화', price: '15만원~', desc: '복합 작업 · 1~2주 소요', examples: 'RPA 프로세스, API 연동, 텔레그램 봇', highlight: true },
{ name: '대형 자동화', price: '협의', desc: '시스템 통합 · 2주 이상 소요', examples: '전사 업무 자동화, 멀티 시스템 통합', highlight: false },
{ name: '단순 자동화', price: '5만원~', desc: '단일 작업 · 1~3일 소요', examples: '엑셀 매크로, 단순 스크래핑, 이메일 자동화', highlight: false, productId: 'automation_basic' },
{ name: '자동화 심화', price: '15만원~', desc: '복합 작업 · 1~2주 소요', examples: 'RPA 프로세스, API 연동, 텔레그램 봇', highlight: true, productId: 'automation_advanced' },
{ name: '대형 자동화', price: '협의', desc: '시스템 통합 · 2주 이상 소요', examples: '전사 업무 자동화, 멀티 시스템 통합', highlight: false, productId: null },
];
const process = [
@@ -235,14 +236,25 @@ export default function AutomationPage() {
<div className={`text-xs leading-relaxed mb-6 flex-1 p-3 rounded-xl ${plan.highlight ? 'bg-cyan-400/10 text-cyan-100/70' : 'bg-[#f0f5ff] text-slate-600'}`}>
: {plan.examples}
</div>
<button
onClick={() => openModal(`업무 자동화 - ${plan.name}`)}
className={`block w-full text-center py-3 rounded-xl text-sm font-bold transition ${
plan.highlight ? 'bg-cyan-400 text-[#012030] hover:bg-cyan-300' : 'bg-[#04102b] text-white hover:bg-[#0a1f5c]'
}`}
>
</button>
{plan.productId ? (
<PaymentButton
productId={plan.productId}
className={`block w-full text-center py-3 rounded-xl text-sm font-bold transition ${
plan.highlight ? 'bg-cyan-400 text-[#012030] hover:bg-cyan-300' : 'bg-[#04102b] text-white hover:bg-[#0a1f5c]'
}`}
>
</PaymentButton>
) : (
<button
onClick={() => openModal(`업무 자동화 - ${plan.name}`)}
className={`block w-full text-center py-3 rounded-xl text-sm font-bold transition ${
plan.highlight ? 'bg-cyan-400 text-[#012030] hover:bg-cyan-300' : 'bg-[#04102b] text-white hover:bg-[#0a1f5c]'
}`}
>
</button>
)}
</div>
))}
</div>

View File

@@ -48,7 +48,7 @@ const plans = [
desc: '부서·팀 전체 프롬프트 시스템 구축',
features: ['팀 업무 프로세스 전체 분석', '10개 이상 프롬프트 설계', '팀 공유 프롬프트 라이브러리', '사내 가이드 문서 작성', '전 직원 교육 자료 제공', '3개월 내 업데이트 지원'],
highlight: false,
productId: null,
productId: 'prompt_team',
},
];

View File

@@ -2,6 +2,7 @@
import Link from 'next/link';
import { useState, useEffect, useRef } from 'react';
import PaymentButton from '../../components/PaymentButton';
const samples = [
{
@@ -102,6 +103,7 @@ const plans = [
color: '#38bdf8',
features: ['5페이지 이내', '반응형 디자인', '기본 SEO 설정', '1개월 유지보수', '3~5영업일 납품'],
note: '개인 블로그, 소규모 소개 사이트',
productId: 'website_starter',
},
{
name: '비즈니스',
@@ -111,6 +113,7 @@ const plans = [
featured: true,
features: ['10페이지 이내', '반응형 디자인', '관리자 페이지', 'SEO 최적화', '3개월 유지보수', '1~2주 납품'],
note: '기업 사이트, 브랜드 페이지',
productId: 'website_business',
},
{
name: '프리미엄',
@@ -119,6 +122,7 @@ const plans = [
color: '#f472b6',
features: ['페이지 수 무제한', '맞춤 디자인', '결제/회원 시스템', 'DB 연동', '6개월 유지보수', '일정 협의'],
note: '쇼핑몰, SaaS, 복합 시스템',
productId: 'website_premium',
},
];
@@ -529,16 +533,18 @@ export default function WebsiteServicePage() {
</div>
))}
</div>
<Link href="/freelance?service=website" style={{
display: 'block', textAlign: 'center', padding: '13px',
background: plan.featured ? plan.color : 'rgba(255,255,255,0.04)',
borderRadius: 10, color: plan.featured ? '#1e1b4b' : '#94a3b8',
fontWeight: 700, fontSize: 14, textDecoration: 'none',
border: plan.featured ? 'none' : '1px solid rgba(255,255,255,0.07)',
transition: 'opacity 0.2s',
}}>
</Link>
<PaymentButton
productId={plan.productId}
style={{
display: 'block', width: '100%', textAlign: 'center', padding: '13px',
background: plan.featured ? plan.color : 'rgba(255,255,255,0.04)',
borderRadius: 10, color: plan.featured ? '#1e1b4b' : '#94a3b8',
fontWeight: 700, fontSize: 14, border: plan.featured ? 'none' : '1px solid rgba(255,255,255,0.07)',
transition: 'opacity 0.2s', cursor: 'pointer',
}}
>
</PaymentButton>
</div>
))}
</div>